From fe6ab0fa032f243b94977f593d3230b9d21567d1 Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Wed, 23 Jul 2025 20:14:38 +0800 Subject: [PATCH] =?UTF-8?q?2025.7.23=20=E4=BA=BA=E5=91=98=EF=BC=8C?= =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E5=AE=89=E6=8E=92=EF=BC=8C=E9=A3=8E=E9=99=A9?= =?UTF-8?q?=E5=88=86=E5=B8=83=EF=BC=8C=E6=B3=95=E5=BE=8B=E6=B3=95=E8=A7=84?= =?UTF-8?q?=E5=B7=AE=E8=AF=A6=E6=83=85=E5=92=8C=E9=A2=84=E8=A7=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 1 + assets/image/videostart.png | Bin 0 -> 1214 bytes ios/Runner/Info.plist | 4 + lib/customWidget/ItemWidgetFactory.dart | 3 +- lib/customWidget/big_video_viewer.dart | 63 +++ lib/http/ApiService.dart | 155 +++++++ lib/pages/home/home_page.dart | 4 +- lib/pages/home/low_page.dart | 37 +- lib/pages/home/risk/riskControl_page.dart | 180 ++++++++- lib/pages/home/risk/risk_detail_page.dart | 258 ++++++++++-- lib/pages/home/userInfo_page.dart | 56 ++- lib/pages/home/work/custom_driver_drawer.dart | 300 +++++++++++--- lib/pages/home/work/danger_repair_page.dart | 224 ++++++++++- lib/pages/home/work/danger_wait_deawer.dart | 252 +++++++++--- .../home/work/danger_wait_list_page.dart | 37 +- .../home/work/hidden_record_detail_page.dart | 266 ++++++++++++ lib/pages/home/work/laws_list_picker.dart | 169 ++++++++ .../home/work/laws_regulations_page.dart | 358 +++++++++++++++++ lib/pages/home/work/risk_list_picker.dart | 169 ++++++++ lib/pages/home/work/wait_list_picker.dart | 169 ++++++++ lib/pages/home/workSet_page.dart | 188 ++++++++- lib/tools/tools.dart | 6 + pubspec.lock | 380 ++++++++++++------ pubspec.yaml | 4 + 24 files changed, 2961 insertions(+), 322 deletions(-) create mode 100644 assets/image/videostart.png create mode 100644 lib/customWidget/big_video_viewer.dart create mode 100644 lib/pages/home/work/hidden_record_detail_page.dart create mode 100644 lib/pages/home/work/laws_list_picker.dart create mode 100644 lib/pages/home/work/laws_regulations_page.dart create mode 100644 lib/pages/home/work/risk_list_picker.dart create mode 100644 lib/pages/home/work/wait_list_picker.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index ae8c781..ae19d87 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -4,6 +4,7 @@ + diff --git a/assets/image/videostart.png b/assets/image/videostart.png new file mode 100644 index 0000000000000000000000000000000000000000..cbdbfa270c9d9f17005c61c484465dfb89388762 GIT binary patch literal 1214 zcmV;v1VQ_WP)Px(cu7P-RA@uxn@z}7RTPHb7o14s4_E^Sp)?3`qLie8fr45lAr4A3$R9{05gqt9 zQYYFUBvJGO>enD?=0vR=sOZ4YB66ZrzmWqC(x~y0_p*+hdp-A_eeOQ{++%ma$9LiG zz1Dut*>|6{_I?kM$jod8fVTj=0^m6S&-;IU)}QQt?(d#|{sX|zB>zb>;nKh04%9%U_E{&0enmHhgknnz-FeqxEsK#*ntH0 zzX;$C?cK|-D z5}<*$-;>-P8YdXo%&r1h7V5a+cGpP05fU>9*v$02oD<@3gl+yJnLXe84x<#<%z1)Mp#XQ@!JP0@#xZrE>oVTSBrcIVl4E5x}T2sJbum8IqgwPP>3TH$GQ))Dinz zo6o&_fq!kV5NPT;TqLwg93^?gW2nm73*dzWaY9@!B6%|dJ_z7=NUw@*mXo}a^)a)#05b4t6@A4v zKSc854EU1oMa4Sp?cW8Q1Ao=QyB-;J2k-Hxy|EQEvsnQCP86&VI0ycYgKOij37aio zB^gRKQrJM?9Jn?BHPv5AF^HVcO#)Vuy)RLqAYfnAX8WQh@MjZ^=Q9DPECGXob9Z}z zgKtX!Jt1Iid9F#|TrMjE=fGDwxK1zXvI_$K4Zz~MJofk*8aM~8O@2*t@NQezZe0luAN1zm5(I{UGJcEop^K}ORY*g98|TdO38O4?`UuLPU6vu z)Y3s!D+^T5-4xbIE#Cw1Qwr~)nUJz|brkYovs)3udT_nHGfF(D& zl_2{2Bs-f6W~Lf9+s{(%+q5l^{3*Xpdp&{d=q`ZIolNzuYTZ%TB*~=;JiZ(8KJCWm zsKtS`QjgDJnnRDzaj66Ad}(|R#2va#YP(@q^+J{2AW=&jRd=EAebsqovZXew@A|07*qoM6N<$g2g09M*si- literal 0 HcmV?d00001 diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 7b0ffc3..bff5938 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -55,6 +55,10 @@ app需要访问相册以上传图片 NSUserNotificationsUsageDescription app需要发送通知提醒重要信息 + NSLocationWhenInUseUsageDescription + 需要位置权限以提供定位服务 + NSLocationAlwaysUsageDescription + 需要位置权限以提供定位服务 UIApplicationSupportsIndirectInputEvents UILaunchStoryboardName diff --git a/lib/customWidget/ItemWidgetFactory.dart b/lib/customWidget/ItemWidgetFactory.dart index 0d1235b..727aac6 100644 --- a/lib/customWidget/ItemWidgetFactory.dart +++ b/lib/customWidget/ItemWidgetFactory.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; +import '../http/ApiService.dart'; import '../tools/tools.dart'; /// 自定义组件 @@ -115,7 +116,7 @@ class ListItemFactory { spacing: 8, // 水平间距 runSpacing: 8, // 垂直间距 children: List.generate(imageUrls.length, (i) { - final url = imageUrls[i]; + final url =ApiService.baseImgPath + imageUrls[i]; Widget img; if (url.startsWith('http')) { img = Image.network( diff --git a/lib/customWidget/big_video_viewer.dart b/lib/customWidget/big_video_viewer.dart new file mode 100644 index 0000000..9f12746 --- /dev/null +++ b/lib/customWidget/big_video_viewer.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:qhd_prevention/customWidget/video_player_widget.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:video_player/video_player.dart'; +// 查看视频 +class BigVideoViewer extends StatefulWidget { + const BigVideoViewer({Key? key, required this.videoUrl}) : super(key: key); + + final String videoUrl; + + @override + State createState() => _BigVideoViewerState(); +} + +class _BigVideoViewerState extends State { + + VideoPlayerController? _videoController; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _videoController?.removeListener(_controllerListener); + _videoController?.dispose(); + _videoController = VideoPlayerController.networkUrl(Uri.parse(widget.videoUrl)) + ..initialize().then((_) { + _videoController! + ..play() + ..addListener(_controllerListener); + }); + } + + void _controllerListener() { + if (mounted) setState(() {}); + } + + @override + void dispose() { + _videoController?.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + + return Scaffold( + backgroundColor: Colors.black, + appBar: MyAppbar( + backgroundColor: Colors.transparent, title: '', + ), + body: Center( + child: VideoPlayerWidget( + allowSeek: false, + controller: _videoController, + coverUrl:"", + aspectRatio: _videoController?.value.aspectRatio ?? 16/9, + ), + ), + ); + } +} diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 4c3916e..68ba1be 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -838,6 +838,161 @@ U6Hzm1ninpWeE+awIDAQAB ); } + /// 获取隐患记录详情 + static Future> getDangerDetail(String id) { + return HttpManager().request( + basePath, + '/app/hidden/goEdit', + method: Method.post, + data: { + "HIDDEN_ID": id, + "CORPINFO_ID": SessionService.instance.corpinfoId, + "USER_ID": SessionService.instance.loginUserId, + }, + ); + } + + /// 获取个人信息 + static Future> getUserInfo() { + return HttpManager().request( + basePath, + '/app/user/goEditUser', + method: Method.post, + data: { + "CORPINFO_ID": SessionService.instance.corpinfoId, + "USER_ID": SessionService.instance.loginUserId, + }, + ); + } + + + /// 获取本日工作提醒 + static Future> getAnPai() { + return HttpManager().request( + basePath, + '/app/listmanager/checkListIndex', + method: Method.post, + data: { + "tm":DateTime.now().millisecondsSinceEpoch.toString(), + "DEPARTMENT_ID":SessionService.instance.corpinfoId, + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + }, + ); + } + + /// 获取本日日程安排 + static Future> getRiCheng(String data) { + return HttpManager().request( + basePath, + '/app/schedule/getData', + method: Method.post, + data: { + "CDATA": data, + "USERNAME": SessionService.instance.loginUser?["USERNAME"]??"", + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + }, + ); + } + + /// 增加本日日程安排 + static Future> addRiCheng(String data,String title, String content,String id,String urlPath) { + return HttpManager().request( + basePath, + '/app/schedule/$urlPath', + method: Method.post, + data: { + "CDATA": data, + "USERNAME":SessionService.instance.loginUser?["USERNAME"]??"", + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + "SCHEDULE_ID": id, + "TITLE": title, + "FHDESC":content, + }, + ); + } + + + /// 获取风险分布列表 + static Future> getRiskRecordList(int currentPage, + String riskId,String dept,String level,String keyWord) { + return HttpManager().request( + basePath, + '/app/riskpoint/list?showCount=-1¤tPage=$currentPage', + method: Method.post, + data: { + "CORPINFOID": SessionService.instance.corpinfoId, + "RISK_UNIT_ID": riskId, + "DEPARTMENT_ID": dept, + "LEVELID": level, + "IS_APP": 1, + "tm": DateTime.now().millisecondsSinceEpoch.toString(), + "KEYWORDS": keyWord, //关键字模糊查询 + }, + ); + } + + /// 获取风险分布详情 + static Future> getForIdentification(String id) { + return HttpManager().request( + basePath, + '/app/riskpoint/getForIdentification', + method: Method.post, + data: { + "CHECK_IDENTIFICATION_ID": id, + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + }, + ); + } + + /// 获取风险分布详情提交坐标 + static Future> addCoordinate(String id,String longitude,String latitude) { + return HttpManager().request( + basePath, + '/app/riskpoint/editLonAndLat', + method: Method.post, + data: { + "IDENTIFICATIONPARTS_ID": id, + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + "LONGITUDE" : longitude, + "LATITUDE" : latitude, + + }, + ); + } + + /// 获取风险分布列表侧滑菜单第二个选框数据 + static Future> getTreeListUnit(String id) { + return HttpManager().request( + basePath, + '/app/riskpoint/listUnit', + method: Method.post, + data: { + "DEPARTMENT_ID": id, + "tm": DateTime.now().millisecondsSinceEpoch.toString(), + }, + ); + } + + /// 获取法律法规类表 + static Future> getLowList(String keyWord) { + return HttpManager().request( + basePath, + '/app/mfolderStipulate/appListTree', + method: Method.post, + data: { + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + "KEYWORDS":keyWord, + "SHARE": "yes", + }, + ); + } + } diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index c87f8da..187dde2 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -10,6 +10,7 @@ import 'package:qhd_prevention/pages/home/study/study_garden_page.dart'; import 'package:qhd_prevention/pages/home/userInfo_page.dart'; import 'package:qhd_prevention/pages/home/work/danger_page.dart'; import 'package:qhd_prevention/pages/home/work/danger_wait_list_page.dart'; +import 'package:qhd_prevention/pages/home/work/laws_regulations_page.dart'; import 'package:qhd_prevention/pages/home/workSet_page.dart'; import '../../customWidget/hidden_roll_widget.dart'; @@ -206,7 +207,8 @@ class _HomePageState extends State { } else if (index == 2) { pushPage(RiskControlPage(), context); } else if (index == 3) { - pushPage(LowPage(), context); + // pushPage(LowPage(), context); + pushPage(LawsRegulationsPage(), context); } else if (index == 7) { pushPage(StudyGardenPage(), context); } diff --git a/lib/pages/home/low_page.dart b/lib/pages/home/low_page.dart index 26c1647..ce335c5 100644 --- a/lib/pages/home/low_page.dart +++ b/lib/pages/home/low_page.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import '../../http/ApiService.dart'; import '/customWidget/search_bar_widget.dart'; class LowPage extends StatefulWidget { @@ -17,7 +18,35 @@ class _LowPagePageState extends State { 'title': '测试数据标题标题 ${i + 1}', }; }); + final TextEditingController _searchController = TextEditingController(); + String treeJson=""; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _getLowList(); + } + + Future _getLowList() async { + try { + + final result = await ApiService.getHiddenTreatmentListTree(); + if (result['result'] == 'success') { + setState(() { + treeJson= result['zTreeNodes']; + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } @override Widget build(BuildContext context) { @@ -25,7 +54,9 @@ class _LowPagePageState extends State { appBar: MyAppbar( title: "法律法规", ), - body: SafeArea(child: _vcDetailWidget()), + body: SafeArea( + child: _vcDetailWidget() + ), ); } @@ -74,4 +105,8 @@ class _LowPagePageState extends State { ), ); } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } } diff --git a/lib/pages/home/risk/riskControl_page.dart b/lib/pages/home/risk/riskControl_page.dart index 7d76962..5514c81 100644 --- a/lib/pages/home/risk/riskControl_page.dart +++ b/lib/pages/home/risk/riskControl_page.dart @@ -4,6 +4,8 @@ import 'package:qhd_prevention/pages/home/work/custom_driver_drawer.dart'; import 'package:qhd_prevention/pages/home/risk/risk_detail_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import '../../../http/ApiService.dart'; +import '../../../tools/h_colors.dart'; import '/customWidget/search_bar_widget.dart'; class RiskControlPage extends StatefulWidget { @@ -14,16 +16,17 @@ class RiskControlPage extends StatefulWidget { } class _RiskControlPageState extends State { - // 模拟数据 - final List> _dataInfos = List.generate(10, (i) { - bool read = i % 3 == 0; - return { - 'title': '测试数据标题标题 ${i + 1}', - 'label1': '2025-06-${10 + i} 12:3${i}', - 'label2': '2025-06-${1 + i} 2:1${i}', - 'level': getRandomWithNum(1, 4), - }; - }); + + int _page = 1; + String searchKey=""; + int _totalPage=1; + late List _list = []; + bool _isLoading = false; + bool _hasMore = true; + + String treeJson=""; + + // 风险等级颜色 final List _fxColors = [ @@ -38,6 +41,18 @@ class _RiskControlPageState extends State { final List _levelTexts = ["重大风险/A级", "较大风险/B级", "一般风险/C级", "低风险/D级"]; final GlobalKey _scaffoldKey = GlobalKey(); + + @override + void initState() { + super.initState(); + + getListData(false,""); + _getListTree(); + SessionService.instance.setRiskWaitInfo(""); + + } + + @override Widget build(BuildContext context) { // 取屏幕宽度 @@ -60,15 +75,35 @@ class _RiskControlPageState extends State { ), ], ), + + //弹窗 endDrawer: Drawer( // 用 Container 限制宽度为屏幕的 3/5 child: Container( width: screenWidth * 3 / 5, color: Colors.white, - child: const CustomDriverDrawer(), + child: CustomDriverDrawer( + treeJson, + onClose: (String riskId,String dept,String level) { + + // _getDangerRecord(-1,_page,startDate,endDate,hazardLevelOption,investigationMethodOption, + // dangerStatusOption,selectedCategoryId,selectedDepartmentId,"",searchKey,false); + _page=1; + _getRiskRecord(_page,riskId,dept,level,searchKey,false); + + }, + ), ), ), - body: SafeArea(child: _vcDetailWidget()), + + + body: SafeArea( + child: NotificationListener( + onNotification: _onScroll, + child:_vcDetailWidget() + ) + ), + backgroundColor: Colors.white, ); } @@ -81,16 +116,24 @@ class _RiskControlPageState extends State { controller: _searchController, onSearch: (keyboard) { // 输入请求接口 + _page=1; + searchKey=keyboard; + getListData(false,keyboard); }, ), ), - + Container( + height: 5, + color: h_backGroundColor(), + ), Expanded( - child: ListView.separated( + child: _list.isEmpty + ? Center(child: Text('暂无数据')) + : ListView.separated( separatorBuilder: (_, __) => const Divider(height: 1), - itemCount: _dataInfos.length, + itemCount: _list.length, itemBuilder: (context, index) { - final item = _dataInfos[index]; + final item = _list[index]; return _fxitemCell(item); }, ), @@ -99,10 +142,23 @@ class _RiskControlPageState extends State { ); } + + + + Widget _fxitemCell(final item) { - int level = item['level'] as int; + int level; // 确保level在有效范围内 (1-4) - level = level.clamp(1, 4) - 1; + // level = level.clamp(1, 4) - 1; + if(item['LEVELID']=="levelA"){ + level=0; + }else if(item['LEVELID']=="levelB"){ + level=1; + }else if(item['LEVELID']=="levelC"){ + level=2; + }else { + level=3; + } // 使用GestureDetector包裹整个列表项以添加点击事件 return GestureDetector( @@ -129,19 +185,19 @@ class _RiskControlPageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - item['title'] ?? '', + '部位名称:${item['PARTSNAME'] ?? ''}', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), maxLines: 1, overflow: TextOverflow.ellipsis, ), SizedBox(height: 8), Text( - item['label1'] ?? '', + '风险点(单元):${item['RISKUNITNAME'] ?? ''}', style: TextStyle(fontSize: 14, color: Colors.grey), ), SizedBox(height: 4), Text( - item['label2'] ?? '', + '管控部门:${item['DEPT_NAME'] ?? ''}', style: TextStyle(fontSize: 14, color: Colors.grey), ), ], @@ -188,6 +244,88 @@ class _RiskControlPageState extends State { ), ); } + + + void getListData(bool addList,String keyWord){ + _getRiskRecord(_page,"","","",keyWord,addList); + + } + + Future _getRiskRecord(int currentPage, + String riskId,String dept,String level,String keyWord,bool loadMore) async { + try { + if (_isLoading) return; + _isLoading = true; + + + final result = await ApiService.getRiskRecordList( currentPage, + riskId, dept, level, keyWord); + + if (result['result'] == 'success') { + + _totalPage =result["page"]['totalPage'] ?? 1; + final List newList = result['varList'] ?? []; + // setState(() { + // _list.addAll(newList); + // }); + + setState(() { + if (loadMore) { + _list.addAll(newList); + } else { + _list = newList; + } + _hasMore = _page < _totalPage; + // if (_hasMore) _page++; + }); + + }else{ + _showMessage('加载数据失败'); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } finally { + // if (!loadMore) LoadingDialogHelper.hide(context); + _isLoading = false; + } + } + + bool _onScroll(ScrollNotification n) { + if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 && + _hasMore && !_isLoading) { + + _page++; + getListData(true,""); + + } + return false; + } + + + Future _getListTree() async { + try { + + final result = await ApiService.getHiddenTreatmentListTree(); + if (result['result'] == 'success') { + setState(() { + treeJson= result['zTreeNodes']; + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } + } diff --git a/lib/pages/home/risk/risk_detail_page.dart b/lib/pages/home/risk/risk_detail_page.dart index 3d257c2..7965f7e 100644 --- a/lib/pages/home/risk/risk_detail_page.dart +++ b/lib/pages/home/risk/risk_detail_page.dart @@ -1,7 +1,9 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; +import 'package:geolocator/geolocator.dart'; +import '../../../http/ApiService.dart'; import '../../../tools/h_colors.dart'; class RiskDetailPage extends StatefulWidget { @@ -14,25 +16,72 @@ class RiskDetailPage extends StatefulWidget { } class _RiskDetailPageState extends State { - final List> _dataInfos = [ - { - "title": "存在风险", - "detail": ["测试", "测试去外地恰逢其会发起违反去和我i回复IQ请勿凤求凰IQ佛ifi哦好气哦hi哦发i哦前期我放弃"], - }, - { - "title": "主要管控措施", - "detail": ["测试去外地恰逢其会发起违反去和我i回复IQ请勿凤求凰IQ佛ifi哦好气哦hi哦发i哦前期我放"], - }, - { - "title": "管控部门", - "detail": ["哈哈"], - }, - { - "title": "事故类型", - "detail": ["物体打击,车辆伤害"], - }, + + + late List _list = []; + // 风险等级文本 + final List _levelTexts = ["重大风险", "较大风险", "一般风险", "低风险"]; + // 风险等级颜色 + final List _fxColors = [ + const Color(0xFFFADBD9), + const Color(0xFFFCE6D2), + const Color(0xFFFDF2CE), + const Color(0xFFCCE6FF), ]; + @override + void initState() { + // TODO: implement initState + super.initState(); + + _getForIdentification(); + } + + + Future _getForIdentification() async { + try { + + final result = await ApiService.getForIdentification( widget.itemData["IDENTIFICATIONPARTS_ID"]); + + if (result['result'] == 'success') { + final List newList = result['varList'] ?? []; + setState(() { + _list.addAll(newList); + }); + + + }else{ + _showMessage('加载数据失败'); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + + Future _addCoordinate() async { + try { + + Position position = await _determinePosition(); + final result = await ApiService.addCoordinate( widget.itemData["IDENTIFICATIONPARTS_ID"], + position.longitude.toString(),position.latitude.toString()); + if (result['result'] == 'success') { + setState(() { + _showMessage('提交成功'); + Navigator.pop(context); + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + @override @override Widget build(BuildContext context) { @@ -78,17 +127,24 @@ class _RiskDetailPageState extends State { physics: const ClampingScrollPhysics(), child: Column( mainAxisSize: MainAxisSize.min, - children: _dataInfos.map(_itemCell).toList(), + children: [ + _itemCell("存在风险",0), + _itemCell("主要管控措施",1), + _itemCell("管控部门",2), + _itemCell("事故类型",3), + const Divider( + height: .5, + thickness: .5, + color: Colors.grey, + ), + _buildFooter(), + ], + // children: _dataInfos.map(_itemCell).toList(), ), ), ), - const Divider( - height: .5, - thickness: .5, - color: Colors.grey, - ), - _buildFooter(), + ], ), ), @@ -112,12 +168,12 @@ class _RiskDetailPageState extends State { child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - const Text( - "风险点位", + Text( + widget.itemData['RISKUNITNAME']?? "", style: TextStyle(fontSize: 16, color: Colors.black54), ), Text( - widget.itemData?['location'] ?? "未知地区", + widget.itemData['PARTSNAME'] ?? "未知地区", style: const TextStyle(fontSize: 16, color: Colors.black54), ), ], @@ -135,12 +191,12 @@ class _RiskDetailPageState extends State { margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(5), decoration: BoxDecoration( - color: const Color(0xFFFADBD9), + color: _getLevelColor(), borderRadius: BorderRadius.circular(2), ), child: Text( - "风险等级", - style: TextStyle(color: const Color(0xFFE54D42)), + _getLevel(), + style: TextStyle(color: Colors.black), ), ), const Spacer(), @@ -149,6 +205,38 @@ class _RiskDetailPageState extends State { ); } + String _getLevel(){ + int level; + // 确保level在有效范围内 (1-4) + // level = level.clamp(1, 4) - 1; + if(widget.itemData['LEVELID']=="levelA"){ + level=0; + }else if(widget.itemData['LEVELID']=="levelB"){ + level=1; + }else if(widget.itemData['LEVELID']=="levelC"){ + level=2; + }else { + level=3; + } + return _levelTexts[level]; + } + + Color _getLevelColor(){ + int level; + // 确保level在有效范围内 (1-4) + // level = level.clamp(1, 4) - 1; + if(widget.itemData['LEVELID']=="levelA"){ + level=0; + }else if(widget.itemData['LEVELID']=="levelB"){ + level=1; + }else if(widget.itemData['LEVELID']=="levelC"){ + level=2; + }else { + level=3; + } + return _fxColors[level]; + } + // 底部按钮 Widget _buildBottomButton() { return Padding( @@ -167,6 +255,7 @@ class _RiskDetailPageState extends State { ), onPressed: () { // 按钮点击事件 + _addCoordinate(); }, child: const Text( "提交位置", @@ -177,9 +266,11 @@ class _RiskDetailPageState extends State { ); } - // 单项信息组件 - Widget _itemCell(Map item) { - final details = item["detail"] as List; + + + // 多项项信息组件 + Widget _itemCell(String title,int type) { + // final details = item["detail"] as List; return Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: Column( @@ -198,7 +289,7 @@ class _RiskDetailPageState extends State { ), const SizedBox(width: 5), Text( - item["title"], + title, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, @@ -208,13 +299,76 @@ class _RiskDetailPageState extends State { ], ), const SizedBox(height: 10), - // 内容区域 - ...details.map((text) => _textItem(text, false)).toList(), + // // 内容区域 + // ...details.map((text) => _textItem(text, false)).toList(), + + if(0==type||1==type) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + for(int i = 0; i < _list.length; i++) + _getWitchItem(type, i), + ],) + else + _getWitchItemTwo(type, type), + + + + ], ), ); } + + + + Widget _getWitchItem(int type,int position) { + String text=""; + switch(type){ + case 0: + text= "$position.${_list[position]["RISK_DESCR"]}"; + break; + case 1: + text= "$position.${_list[position]["MEASURES"]}"; + break; + // case 2: + // text= _list[position]["RISK_DESCR"]; + // break; + // case 3: + // text= _list[position]["RISK_DESCR"]; + // break; + } + + return _textItem(text,false); + } + + Widget _getWitchItemTwo(int type,int position) { + String text=""; + switch(type){ + // case 0: + // text= _list[position]["RISK_DESCR"]; + // break; + // case 1: + // text= _list[position]["MEASURES"]; + // break; + case 2: + text= widget.itemData["DEPT_NAME"]; + break; + case 3: + for(int i=0;i<_list.length;i++){ + if(text.isEmpty){ + text=_list[i]["ACCIDENTS_NAME"]; + }else{ + text="$text,${_list[i]["ACCIDENTS_NAME"]}"; + } + } + break; + } + + return _textItem(text,false); + } + // 文本项组件 Widget _textItem(String text, bool isInfinity) { return Container( @@ -235,4 +389,36 @@ class _RiskDetailPageState extends State { ), ); } + + Future _determinePosition() async { + bool serviceEnabled; + LocationPermission permission; + + // 检查定位服务是否启用 + serviceEnabled = await Geolocator.isLocationServiceEnabled(); + if (!serviceEnabled) { + return Future.error('Location services are disabled.'); + } + + // 获取权限 + permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied) { + permission = await Geolocator.requestPermission(); + if (permission == LocationPermission.denied) { + return Future.error('Location permissions are denied'); + } + } + + if (permission == LocationPermission.deniedForever) { + return Future.error( + 'Location permissions are permanently denied, we cannot request permissions.'); + } + + // 获取当前位置 + return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); + } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } } diff --git a/lib/pages/home/userInfo_page.dart b/lib/pages/home/userInfo_page.dart index d88f1bb..3cf6e5f 100644 --- a/lib/pages/home/userInfo_page.dart +++ b/lib/pages/home/userInfo_page.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import '../../http/ApiService.dart'; + class UserinfoPage extends StatefulWidget { const UserinfoPage({super.key}); @@ -9,6 +11,35 @@ class UserinfoPage extends StatefulWidget { } class _UserinfoPageState extends State { + + Map user = {}; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _getUserInfo(); + } + + Future _getUserInfo() async { + try { + + final result = await ApiService.getUserInfo(); + if (result['result'] == 'success') { + setState(() { + user= result['pd']; + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -16,9 +47,19 @@ class _UserinfoPageState extends State { body: SafeArea( child: ListView( children: [ - _userItemCell("姓名", "-----", false), - _userItemCell("部门", "-----", false), - _userItemCell("岗位", "-----", true), + _userItemCell("姓名", user["NAME"]??"", false), + Divider(height: 1), + _userItemCell("性别", user["SEX_NAME"]??"", false), + Divider(height: 1), + _userItemCell("部门", user["DEPARTMENT_NAME"]??"", false), + Divider(height: 1), + _userItemCell("岗位", user["DUTIES_NAME"]??"", true), + Divider(height: 1), + _userItemCell("人员类型", user["PERSONNEL_TYPE_NAME"]??"", false), + Divider(height: 1), + _userItemCell("入职时间", user["ENTRY_DATE"]??"", false), + Divider(height: 1), + _userItemCell("工种", user["TYPE_OF_WORK_NAME"]??"", false), ], ), ), @@ -47,11 +88,11 @@ class _UserinfoPageState extends State { mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text(title, style: const TextStyle(fontSize: 16, color: Colors.grey)), + Text(title, style: const TextStyle(fontSize: 16, )), Flexible( child: Text( detail, - style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + style: const TextStyle(fontSize: 16, fontWeight: FontWeight.w500,color: Colors.grey), textAlign: TextAlign.right, maxLines: 2, overflow: TextOverflow.ellipsis, @@ -61,4 +102,9 @@ class _UserinfoPageState extends State { ), ); } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } + } diff --git a/lib/pages/home/work/custom_driver_drawer.dart b/lib/pages/home/work/custom_driver_drawer.dart index 6a1f281..8cd70e8 100644 --- a/lib/pages/home/work/custom_driver_drawer.dart +++ b/lib/pages/home/work/custom_driver_drawer.dart @@ -1,61 +1,145 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/pages/home/work/risk_list_picker.dart'; +import 'package:qhd_prevention/pages/home/work/wait_list_picker.dart'; import '../../../customWidget/bottom_picker.dart'; +import '../../../http/ApiService.dart'; import '../../../tools/h_colors.dart'; import '/customWidget/custom_button.dart'; import '../../../tools/tools.dart'; /// 自定义抽屉 class CustomDriverDrawer extends StatefulWidget { - const CustomDriverDrawer({super.key}); + const CustomDriverDrawer(this.treeJson, {super.key,required this.onClose}); + + final Function(String,String,String) onClose; // 回调函数 + final String treeJson; @override _CustomDriverDrawerState createState() => _CustomDriverDrawerState(); } class _CustomDriverDrawerState extends State { - // 四个选项的单选 index - int _selectedOption = -1; - // 已选择的分类 id - String? _selectedCategoryId; + + // 管控部门 id + String? riskId; + // 风险点(单元)id + String? dept; + + //风险等级 + int _levelOption = -1; + List dangerStatusId = ["levelA", "levelB", "levelC", "levelD"]; + + List jsonList =[]; + String itemNameOne="请选择"; + String itemNameTwo="请选择"; + late List _list = []; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + setState(() { + + try { + String? dangerJson = SessionService.instance.riskJson; + if(null!=dangerJson&&dangerJson.isNotEmpty) { + Map dangerWaitBean = json.decode(dangerJson); + riskId= dangerWaitBean["riskId"]; + dept= dangerWaitBean["dept"]; + _levelOption= dangerWaitBean["levelOption"]; + + itemNameOne= dangerWaitBean["itemNameOne"]; + itemNameTwo= dangerWaitBean["itemNameTwo"]; + } + + jsonList = parseDepartments(widget.treeJson); + } catch (e) { + print("解析失败: $e"); + } + + // // 解析JSON字符串 + // jsonList = json.decode(widget.treeJson); + // departmentList = List>.from(jsonList); + }); + + } + + List parseDepartments(String jsonString) { + // 1. 解码 JSON 字符串 + final List jsonList = json.decode(jsonString); + + // 2. 转换为部门对象列表 + return jsonList + .map((jsonItem) => WaitListBean.fromJson(jsonItem)) + .toList(); + } + + List parseRiskListBean(List jsonList) { + + // 2. 转换为部门对象列表 + return jsonList + .map((jsonItem) => RiskListBean.fromJson(jsonItem)) + .toList(); + } @override Widget build(BuildContext context) { - final List items = ["重大风险", "较大风险", "一般风险", "低风险"]; - final List data = [ - Category( - id: '1', - title: '分类一1', - children: [ - Category(id: '1-1', title: '子项 1-1'), - Category(id: '1-2', title: '子项 1-2'), - ], - ), - Category(id: '2', title: '分类二'), - Category( - id: '3', - title: '分类三', - children: [ - Category(id: '3-1', title: '子项 3-1', children: [ - Category(id: '3-1-1', title: '子项 3-1-1'), - ]), - ], - ), - ]; + final List dangerStatus = ["重大风险", "较大风险", "一般风险", "低风险"]; + // 显示分类选择器 - void showCategoryPicker() { + void showCategoryPicker(String type) { showModalBottomSheet( context: context, isScrollControlled: true, barrierColor: Colors.black54, backgroundColor: Colors.transparent, - builder: (ctx) => DepartmentPicker( - data: data, - onSelected: (selectedId) { + builder: (ctx) => WaitListPicker( + data: jsonList, + onSelected: (item) { setState(() { - _selectedCategoryId = selectedId; + // if("1"==type){ + dept= item?.id; + itemNameOne= item!.name; + // }else{ + riskId = null; + itemNameTwo=""; + // } + + setResult(); }); + _getTreeListUnit(); + }, + ), + ); + } + + // 显示分类选择器 + void showCategoryPickerTwo(String type) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: (ctx) => RiskListPicker( + data: _list, + onSelected: (item) { + setState(() { + // if("1"==type){ + // dept= item?.id; + // itemNameOne= item!.name; + // }else{ + riskId = item?.id; + itemNameTwo=item!.name; + // } + + setResult(); + }); + }, ), ); @@ -77,32 +161,24 @@ class _CustomDriverDrawerState extends State { ), const Divider(height: 24, color: Colors.grey), + // 管控部门 _buildDropdownBox( - "管控部门", - display: _selectedCategoryId ?? '请选择', - onTap: showCategoryPicker, + "管控部门", + display: itemNameOne ?? '请选择', + onTap: () { + showCategoryPicker("1"); + } ), const SizedBox(height: 12), // 风险点(单元) _buildDropdownBox( - "风险点(单元)", - display: '请选择', - onTap: () { - final choice = BottomPicker.show( - context, - items: ['未知'], - itemBuilder: (item) => Text(item, textAlign: TextAlign.center), - initialIndex: 0, - ); - if (choice != null) { - // 用户点击确定并选择了 choice - setState(() { - - }); + "风险点(单元)", + display: itemNameTwo ?? '请选择', + onTap: () { + showCategoryPickerTwo("2"); } - }, ), const SizedBox(height: 24), @@ -114,21 +190,28 @@ class _CustomDriverDrawerState extends State { // 风险等级:一行一个 Column( - children: List.generate(items.length, (idx) { - final bool selected = _selectedOption == idx; + children: List.generate(dangerStatus.length, (idx) { + final bool selected = _levelOption == idx; return GestureDetector( - onTap: () => setState(() => _selectedOption = idx), + onTap: (){ + setState(() { + _levelOption = idx; + + setResult(); + }); + } , + // onTap: () => setState(() => _dangerStatusOption = idx), child: Container( width: double.infinity, margin: const EdgeInsets.only(bottom: 8), - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), decoration: BoxDecoration( color: selected ? Colors.blue : Colors.transparent, borderRadius: BorderRadius.circular(4), border: Border.all(color: Colors.blue, width: 1), ), child: Text( - items[idx], + dangerStatus[idx], style: TextStyle( fontSize: 14, color: selected ? Colors.white : Colors.blue, @@ -150,8 +233,14 @@ class _CustomDriverDrawerState extends State { textStyle: const TextStyle(color: Colors.black45), onPressed: () { setState(() { - _selectedOption = -1; - _selectedCategoryId = null; + + riskId = null; + dept=null; + _levelOption = -1; + itemNameOne="请选择"; + itemNameTwo="请选择"; + // widget.onClose("","","",); + setResult(); }); }, ), @@ -164,6 +253,7 @@ class _CustomDriverDrawerState extends State { backgroundColor: Colors.blue, onPressed: () { // TODO: 提交筛选条件 + Navigator.pop(context); // 关闭加载对话框 }, ), ), @@ -193,7 +283,7 @@ class _CustomDriverDrawerState extends State { const Spacer(), Row( children: [ - Text(display), + Text(_truncateText(display,9)), const Icon(Icons.arrow_drop_down, color: Colors.grey), ], ), @@ -202,4 +292,100 @@ class _CustomDriverDrawerState extends State { ), ); } + + // 文本截取函数 + String _truncateText(String text, int maxLength) { + if (text.runes.length <= maxLength) { + return text; + } + return String.fromCharCodes(text.runes.take(maxLength)) + '...'; + } + + void setResult(){ + + DangerRiskBean waitBean= DangerRiskBean.fromJson( + riskId ?? "", dept?? "", + _levelOption,itemNameOne, itemNameTwo); + + String jsonString = jsonEncode(waitBean.toJson()); + SessionService.instance.setRiskWaitInfo(jsonString); + + widget.onClose( + riskId ?? "", + dept ?? "", + _levelOption!=-1?dangerStatusId[_levelOption]:"", + ); // 触发回调 + } + + Future _getTreeListUnit( ) async { + try { + _list.clear(); + final result = await ApiService.getTreeListUnit( dept!); + + if (result['result'] == 'success') { + final List newList = result['unitList'] ?? []; + + setState(() { + _list.addAll(parseRiskListBean(newList)); + // _list.addAll(newList); + }); + + + }else{ + _showMessage('加载数据失败'); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } + } + + +class DangerRiskBean { + + final String? riskId; + final String? dept; + + //风险等级 + final int levelOption; + + final String itemNameOne; + final String itemNameTwo; + + DangerRiskBean({ + required this.riskId, + required this.dept, + required this.levelOption, + required this.itemNameOne, + required this.itemNameTwo, + + + }); + + + factory DangerRiskBean.fromJson(String riskId, String dept, + int levelOption, + String itemNameOne, String itemNameTwo,) { + return DangerRiskBean( + riskId: riskId, + dept: dept, + levelOption: levelOption, + itemNameOne: itemNameOne, + itemNameTwo: itemNameTwo, + + ); + } + + Map toJson() { + return {"riskId": riskId, "dept": dept, + "levelOption": levelOption, + "itemNameOne": itemNameOne, "itemNameTwo": itemNameTwo,}; + } +} \ No newline at end of file diff --git a/lib/pages/home/work/danger_repair_page.dart b/lib/pages/home/work/danger_repair_page.dart index 5c9ed88..1bcb15c 100644 --- a/lib/pages/home/work/danger_repair_page.dart +++ b/lib/pages/home/work/danger_repair_page.dart @@ -8,12 +8,16 @@ import 'package:qhd_prevention/pages/home/work/danger_wait_list_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/h_colors.dart'; import '../../../customWidget/ItemWidgetFactory.dart'; +import '../../../customWidget/single_image_viewer.dart'; +import '../../../http/ApiService.dart'; +import '../../../tools/tools.dart'; import 'dangerTypeItems/finish/danner_repair_finish.dart'; class DangerRepairPage extends StatefulWidget { - const DangerRepairPage(this.dangerType, {Key? key}) : super(key: key); + const DangerRepairPage(this.dangerType, this.item, {Key? key}) : super(key: key); final DangerType dangerType; + final item; @override State createState() => _DangerRepairPageState(); @@ -22,6 +26,29 @@ class DangerRepairPage extends StatefulWidget { class _DangerRepairPageState extends State { // 是否整改 bool _accepted = false; + List hImgs = []; + List rImgs = []; + dynamic pd; + + @override + void initState() { + // TODO: implement initState + super.initState(); + if (widget.dangerType == DangerType.ristRecord){// 跳转到隐患记录页面 + _getDangerDetail(); + }else if (widget.dangerType == DangerType.wait){// 跳转到待整改隐患页面 + + }else if (widget.dangerType == DangerType.expired){// 跳转到超期未整改页面 + + }else if (widget.dangerType == DangerType.waitAcceptance){// 跳转到隐患验收页面 + + }else{// 跳转到已验收隐患页面 + + } + + } + + Widget build(BuildContext context) { return Scaffold( @@ -37,7 +64,9 @@ class _DangerRepairPageState extends State { crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // 隐患详情 - DangerDetail(), + // DangerDetail(), + DangerPageDetail(), + SizedBox(height: 15), if (widget.dangerType == DangerType.wait) // 隐患整改 _danner_type_wait() @@ -155,4 +184,195 @@ class _DangerRepairPageState extends State { ], ); } + + + Future _getDangerDetail() async { + try { + + final result = await ApiService.getDangerDetail(widget.item['HIDDEN_ID']); + if (result['result'] == 'success') { + setState(() { + hImgs= result['hImgs']; + rImgs= result['rImgs']; + pd= result['pd']; + + }); + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } + + + final List imgUrls = [ + "https://picsum.photos/id/237/200/300", + "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", + ]; + Widget DangerPageDetail() { + return Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ListView( + shrinkWrap: true, + physics: NeverScrollableScrollPhysics(), + children: [ + ListItemFactory.createRowSpaceBetweenItem( + leftText: "隐患描述", + rightText: pd["HIDDENDESCR"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "隐患来源", + rightText: _getSourceDangers(pd), + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "风险点(单元)", + rightText: pd["RISK_UNIT"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "辨识部位", + rightText: pd["IDENTIFICATION"], + ), + Divider(height: 1), + ListItemFactory.createColumnTextItem( + topText: "存在风险", + bottomText: pd["RISK_DESCR"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "风险分级", + rightText: pd["LEVEL"], + ), + Divider(height: 1), + + ListItemFactory.createColumnTextItem( + topText: "检测内容", + bottomText: pd["CHECK_CONTENT"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "隐患部位", + rightText: pd["HIDDENPART"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "发现人", + rightText: pd["CREATORNAME"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "发现时间", + rightText: pd["CREATTIME"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "隐患类型", + rightText: pd["HIDDENTYPE_NAME"], + ), + Divider(height: 1), + ListItemFactory.createRowSpaceBetweenItem( + leftText: "整改类型", + rightText: _getZhengGaiType(pd), + ), + Divider(height: 1), + + + ], + + + + + + + + // itemCount: 16, + // separatorBuilder: (_, __) => const Divider(height: 1), + // itemBuilder: (context, index) { + // Widget item; + // // if (index == 0) { + // // item = ListItemFactory.createAloneTextItem( + // // text: "地坪漆漆未分配全皮肤期漆未分配全皮肤期漆未分配全皮肤期未分配全皮肤期间哦飞机哦脾气金佛怕", + // // ); + // // } else + // if ((index == 0 && index < 4) || + // index == 5 || + // (index > 6 && index < 15)) { + // item = ListItemFactory.createRowSpaceBetweenItem( + // leftText: "隐患来源", + // rightText: "隐患排查", + // ); + // } else if (index == 4 || index == 6) { + // item = ListItemFactory.createColumnTextItem( + // topText: "存在风险", + // bottomText: "哦IQ好然后前后hi前后哦i", + // ); + // } else { + // item = ListItemFactory.createTextImageItem( + // text: "隐患照片", + // imageUrls: imgUrls, + // onImageTapped: (index) { + // present( + // SingleImageViewer(imageUrl: imgUrls[index]), + // context, + // ); + // }, + // ); + // } + // + // // 给每个 item 单独加左右内边距 + // return Padding( + // padding: const EdgeInsets.symmetric( + // horizontal: 12, + // vertical: 8, + // ), + // child: item, + // ); + // }, + ), + ], + ), + ); + } + + String _getSourceDangers(final item) { + String type = item["SOURCE"]; + if("1"==type){ + return "隐患来源:隐患快报"; + }else if("2"==type){ + return "隐患来源:隐患排查清单检查"; + }else if("3"==type){ + return "隐患来源:标准排查清单检查"; + }else if("4"==type){ + return "隐患来源:专项检查"; + }else{ + return "隐患来源:安全检查"; + } + } + + String _getZhengGaiType(final item) { + String type = item["RECTIFICATIONTYPE"]; + if("1"==type){ + return "立即整改"; + }else { + return "限期整改"; + } + } + +} + + diff --git a/lib/pages/home/work/danger_wait_deawer.dart b/lib/pages/home/work/danger_wait_deawer.dart index 1cb19a6..a1a75f8 100644 --- a/lib/pages/home/work/danger_wait_deawer.dart +++ b/lib/pages/home/work/danger_wait_deawer.dart @@ -3,23 +3,97 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/pages/home/work/wait_list_picker.dart'; import '../../../customWidget/bottom_picker.dart'; import '../../../tools/h_colors.dart'; import '/customWidget/custom_button.dart'; import '../../../tools/tools.dart'; + +class DangerWaitBean { + + final String? selectedCategoryId; + final String? selectedDepartmentId; + + // 排查方式 + final int investigationMethodOption; + final int investigationMethodId; + //隐患级别 + final int hazardLevelOption ; + //风险等级 + final int dangerStatusOption ; + + // 新增:开始/结束时间 + final String startTime; + final String endTime; + final String itemNameOne; + final String itemNameTwo; + + DangerWaitBean({ + required this.selectedCategoryId, + required this.selectedDepartmentId, + required this.investigationMethodOption, + required this.investigationMethodId, + required this.hazardLevelOption, + required this.dangerStatusOption, + + required this.startTime, + required this.endTime, + required this.itemNameOne, + required this.itemNameTwo, + + + }); + + + factory DangerWaitBean.fromJson(String selectedCategoryId,String selectedDepartmentId, + int investigationMethodOption, int investigationMethodId, + int hazardLevelOption, int dangerStatusOption, + + String startTime,String endTime, + String itemNameOne,String itemNameTwo, + ) { + return DangerWaitBean( + selectedCategoryId:selectedCategoryId, + selectedDepartmentId:selectedDepartmentId, + investigationMethodOption:investigationMethodOption, + investigationMethodId:investigationMethodId, + hazardLevelOption:hazardLevelOption, + dangerStatusOption:dangerStatusOption, + + startTime:startTime, + endTime:endTime, + itemNameOne:itemNameOne, + itemNameTwo:itemNameTwo, + + ); + } + + Map toJson() { + return {"selectedCategoryId":selectedCategoryId,"selectedDepartmentId":selectedDepartmentId, + "investigationMethodOption":investigationMethodOption,"investigationMethodId":investigationMethodId, + "hazardLevelOption":hazardLevelOption,"dangerStatusOption":dangerStatusOption, + "startTime":startTime,"endTime":endTime, + "itemNameOne":itemNameOne,"itemNameTwo":itemNameTwo,}; + } + +} + /// 自定义抽屉 class DangerWaitDrawer extends StatefulWidget { const DangerWaitDrawer(this.treeJson, {super.key,required this.onClose}); final Function(String,String,String,String,String,String,String) onClose; // 回调函数 final String treeJson; + // final DangerWaitBean waitBean; + + @override - _DangerWaitDrawerState createState() => _DangerWaitDrawerState(); + DangerWaitDrawerState createState() => DangerWaitDrawerState(); } -class _DangerWaitDrawerState extends State { +class DangerWaitDrawerState extends State { // 检查部门分类 id String? _selectedCategoryId; @@ -43,20 +117,64 @@ class _DangerWaitDrawerState extends State { DateTime? _endDate; String startTime=""; String endTime=""; + List jsonList =[]; + String itemNameOne="请选择"; + String itemNameTwo="请选择"; // 转换为List> late List> departmentList ; + + + @override void initState() { // TODO: implement initState super.initState(); - // 解析JSON字符串 - List jsonList = json.decode(widget.treeJson); - departmentList = List>.from(jsonList); + setState(() { + + try { + String? dangerJson = SessionService.instance.dangerJson; + if(null!=dangerJson&&dangerJson.isNotEmpty) { + Map dangerWaitBean = json.decode(dangerJson); + _selectedCategoryId= dangerWaitBean["selectedCategoryId"]; + _selectedDepartmentId= dangerWaitBean["selectedDepartmentId"]; + + _investigationMethodOption= dangerWaitBean["investigationMethodOption"]; + investigationMethodId= dangerWaitBean["investigationMethodId"]; + _hazardLevelOption= dangerWaitBean["hazardLevelOption"]; + _dangerStatusOption= dangerWaitBean["dangerStatusOption"]; + + startTime= dangerWaitBean["startTime"]; + endTime= dangerWaitBean["endTime"]; + itemNameOne= dangerWaitBean["itemNameOne"]; + itemNameTwo= dangerWaitBean["itemNameTwo"]; + } + + jsonList = parseDepartments(widget.treeJson); + } catch (e) { + print("解析失败: $e"); + } + + // // 解析JSON字符串 + // jsonList = json.decode(widget.treeJson); + // departmentList = List>.from(jsonList); + }); + } + List parseDepartments(String jsonString) { + // 1. 解码 JSON 字符串 + final List jsonList = json.decode(jsonString); + + // 2. 转换为部门对象列表 + return jsonList + .map((jsonItem) => WaitListBean.fromJson(jsonItem)) + .toList(); + } + + @override Widget build(BuildContext context) { @@ -67,42 +185,50 @@ class _DangerWaitDrawerState extends State { - final List data = [ - Category( - id: '1', - title: '分类一1', - children: [ - Category(id: '1-1', title: '子项 1-1'), - Category(id: '1-2', title: '子项 1-2'), - ], - ), - Category(id: '2', title: '分类二'), - Category( - id: '3', - title: '分类三', - children: [ - Category(id: '3-1', title: '子项 3-1', children: [ - Category(id: '3-1-1', title: '子项 3-1-1'), - ]), - ], - ), - ]; + // final List data = [ + // Category( + // id: '1', + // title: '分类一1', + // children: [ + // Category(id: '1-1', title: '子项 1-1'), + // Category(id: '1-2', title: '子项 1-2'), + // ], + // ), + // Category(id: '2', title: '分类二'), + // Category( + // id: '3', + // title: '分类三', + // children: [ + // Category(id: '3-1', title: '子项 3-1', children: [ + // Category(id: '3-1-1', title: '子项 3-1-1'), + // ]), + // ], + // ), + // ]; // 显示分类选择器 - void showCategoryPicker() { + void showCategoryPicker(String type) { showModalBottomSheet( context: context, isScrollControlled: true, barrierColor: Colors.black54, backgroundColor: Colors.transparent, - builder: (ctx) => DepartmentPicker( - data: data, - onSelected: (selectedId) { + builder: (ctx) => WaitListPicker( + data: jsonList, + onSelected: (item) { setState(() { - _selectedCategoryId = selectedId; + if("1"==type){ + _selectedCategoryId = item?.id; + itemNameOne= item!.name; + }else{ + _selectedDepartmentId= item?.id; + itemNameTwo=item!.name; + } + + setResult(); }); }, ), @@ -128,29 +254,35 @@ class _DangerWaitDrawerState extends State { // 管控部门 _buildDropdownBox( "检查部门", - display: _selectedCategoryId ?? '请选择', - onTap: showCategoryPicker, + display: itemNameOne ?? '请选择', + onTap: () { + showCategoryPicker("1"); + } ), const SizedBox(height: 6), // 风险点(单元) _buildDropdownBox( "整改部门", - display: '请选择', - onTap: () { - final choice = BottomPicker.show( - context, - items: ['未知'], - itemBuilder: (item) => Text(item, textAlign: TextAlign.center), - initialIndex: 0, - ); - if (choice != null) { - // 用户点击确定并选择了 choice - setState(() { - - }); + display: itemNameTwo ?? '请选择', + onTap: () { + showCategoryPicker("2"); } - }, + // display: '请选择', + // onTap: () { + // final choice = BottomPicker.show( + // context, + // items: ['未知'], + // itemBuilder: (item) => Text(item, textAlign: TextAlign.center), + // initialIndex: 0, + // ); + // if (choice != null) { + // // 用户点击确定并选择了 choice + // setState(() { + // + // }); + // } + // }, ), const SizedBox(height: 12), @@ -329,7 +461,11 @@ class _DangerWaitDrawerState extends State { _startDate = null; _endDate = null; - widget.onClose("","","","","","",""); + itemNameOne="请选择"; + itemNameTwo="请选择"; + + setResult(); + // widget.onClose("","","","","","",""); }); }, @@ -373,7 +509,7 @@ class _DangerWaitDrawerState extends State { const Spacer(), Row( children: [ - Text(display), + Text(_truncateText(display,9)), const Icon(Icons.arrow_drop_down, color: Colors.grey), ], ), @@ -384,6 +520,15 @@ class _DangerWaitDrawerState extends State { } + + // 文本截取函数 + String _truncateText(String text, int maxLength) { + if (text.runes.length <= maxLength) { + return text; + } + return String.fromCharCodes(text.runes.take(maxLength)) + '...'; + } + Future _pickStartDate() async { final now = DateTime.now(); final picked = await showDatePicker( @@ -467,7 +612,18 @@ class _DangerWaitDrawerState extends State { ); } + void setResult(){ + + DangerWaitBean waitBean= DangerWaitBean.fromJson( + _selectedCategoryId ?? "", _selectedDepartmentId?? "", + _investigationMethodOption,investigationMethodId, + _hazardLevelOption, _dangerStatusOption, + startTime, endTime,itemNameOne, itemNameTwo); + + String jsonString = jsonEncode(waitBean.toJson()); + SessionService.instance.setDangerWaitInfo(jsonString); + widget.onClose( _selectedCategoryId ?? "", _selectedDepartmentId ?? "", diff --git a/lib/pages/home/work/danger_wait_list_page.dart b/lib/pages/home/work/danger_wait_list_page.dart index d29b0bf..cbdfe31 100644 --- a/lib/pages/home/work/danger_wait_list_page.dart +++ b/lib/pages/home/work/danger_wait_list_page.dart @@ -9,6 +9,7 @@ import '../../../http/ApiService.dart'; import '../../app/application_page.dart'; import '/customWidget/search_bar_widget.dart'; import 'danger_wait_deawer.dart'; +import 'hidden_record_detail_page.dart'; enum DangerType { @@ -43,6 +44,9 @@ class _DangerWaitListPageState extends State { bool _hasMore = true; String treeJson=""; + // late DangerWaitBean waitBean; + + // 隐患等级颜色 @@ -61,7 +65,7 @@ class _DangerWaitListPageState extends State { super.initState(); getListData(widget.appItem,false,""); - _getListTree(); + SessionService.instance.setDangerWaitInfo(""); } @@ -69,6 +73,7 @@ class _DangerWaitListPageState extends State { switch(widget.appItem ){ case 1://隐患记录 _getDangerRecord(-1,_page,"","","","","","","","",keyWord,addList); + _getListTree(); break; case 2://待整改隐患 _getDangerRecord(2,_page,"","","","","","","","",keyWord,addList); @@ -117,12 +122,14 @@ class _DangerWaitListPageState extends State { child: Container( width: screenWidth * 3 / 5, color: Colors.white, - child: DangerWaitDrawer( treeJson, + child: DangerWaitDrawer( + treeJson, onClose: (String selectedCategoryId,String selectedDepartmentId,String investigationMethodOption, String hazardLevelOption,String dangerStatusOption,String startDate,String endDate) { + _page=1; _getDangerRecord(-1,_page,startDate,endDate,hazardLevelOption,investigationMethodOption, - dangerStatusOption,"","","",searchKey,false); + dangerStatusOption,selectedCategoryId,selectedDepartmentId,"",searchKey,false); }, ), @@ -193,8 +200,25 @@ class _DangerWaitListPageState extends State { // type: item.type, // context: context, // ); - pushPage(DangerRepairPage(widget.dangerType), context); + switch(widget.appItem ){ + case 1://隐患记录 + pushPage(HiddenRecordDetailPage(widget.dangerType,item), context); + break; + case 2://待整改隐患 + // _getDangerRecord(2,_page,"","","","","","","","",keyWord,addList); + break; + case 3://超期未整改 + // _getDangerRecord(5,_page,"","","","","-1","","","",keyWord,addList); + break; + case 4://隐患验收 + // _getDangerRecord(3,_page,"","","","","","3","","",keyWord,addList); + break; + case 5://已验收隐患 + // _getDangerRecord(4,_page,"","","","","","4","","1",keyWord,addList); + break; + + } }, child: Container( // height: 100, @@ -369,14 +393,9 @@ class _DangerWaitListPageState extends State { Future _getListTree() async { try { - if (_isLoading) return; - _isLoading = true; - final result = await ApiService.getHiddenTreatmentListTree(); - if (result['result'] == 'success') { - setState(() { treeJson= result['zTreeNodes']; }); diff --git a/lib/pages/home/work/hidden_record_detail_page.dart b/lib/pages/home/work/hidden_record_detail_page.dart new file mode 100644 index 0000000..ba564ec --- /dev/null +++ b/lib/pages/home/work/hidden_record_detail_page.dart @@ -0,0 +1,266 @@ +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:qhd_prevention/customWidget/big_video_viewer.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'dart:convert'; +import 'package:video_player/video_player.dart'; + +import '../../../customWidget/ItemWidgetFactory.dart'; +import '../../../customWidget/single_image_viewer.dart'; +import '../../../customWidget/video_player_widget.dart'; +import '../../../http/ApiService.dart'; +import '../../../tools/tools.dart'; +import 'danger_wait_list_page.dart'; + + +class HiddenRecordDetailPage extends StatefulWidget { + const HiddenRecordDetailPage(this.dangerType, this.item, {Key? key}) : super(key: key); + + final DangerType dangerType; + final item; + + @override + _HiddenRecordDetailPageState createState() => _HiddenRecordDetailPageState(); +} + +class _HiddenRecordDetailPageState extends State { + late Map pd = {}; + late Map hs = {}; + List files = []; + List files2 = []; + List files4 = []; + List files5 = []; + List files6 = []; + List videoList = []; + List checkList = []; + + bool modalShow = false; + String videoSrc = ""; + VideoPlayerController? _videoController; + + @override + void initState() { + super.initState(); + getData(); + } + + @override + void dispose() { + _videoController?.dispose(); + super.dispose(); + } + + Future getData() async { + try { + final data = await ApiService.getDangerDetail(widget.item['HIDDEN_ID']); + if (data['result'] == 'success') { + + setState(() { + pd = data['pd']; + hs = data['hs'] ?? {}; + + // 处理图片和视频 + for (var img in data['hImgs']) { + if (img['FILEPATH'].toString().endsWith('.mp4')) { + videoList.add(img); + } else { + files.add(img["FILEPATH"]); + } + } + + // List filesZheng = data['rImgs'] ?? []; + for (var img in data['rImgs']) { + files2.add(img["FILEPATH"]); + } + // files2=data['rImgs'] ?? []; + files4 = data['sImgs'] ?? []; + files5 = data['pImgs'] ?? []; + files6 = data['yImgs'] ?? []; + checkList = data['checkList'] ?? []; + }); + } + + } catch (e) { + print('Error fetching data: $e'); + } + } + + + + + + Widget _buildInfoItem(String title, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 120, + child: Text( + title, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + Expanded(child: Text(value,textAlign: TextAlign.right,)), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: "隐患记录-详情"), + body: pd.isEmpty + ? const Center(child: CircularProgressIndicator()) + : LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildInfoItem('隐患描述', pd['HIDDENDESCR'] ?? ''), + + Divider(height: 1), + // 隐患来源 + _buildInfoItem('隐患来源', _getSourceText(pd['SOURCE'])), + Divider(height: 1), + // 条件渲染部分 + if (pd['SOURCE'] == '2') ...[ + _buildInfoItem('风险点(单元)', pd['RISK_UNIT'] ?? ''), + Divider(height: 1), + _buildInfoItem('辨识部位', pd['IDENTIFICATION'] ?? ''), + Divider(height: 1), + _buildInfoItem('存在风险', pd['RISK_DESCR'] ?? ''), + Divider(height: 1), + _buildInfoItem('风险分级', pd['LEVEL'] ?? ''), + Divider(height: 1), + _buildInfoItem('检查内容', pd['CHECK_CONTENT'] ?? ''), + Divider(height: 1), + ], + + _buildInfoItem('隐患部位', pd['HIDDENPART'] ?? ''), + Divider(height: 1), + _buildInfoItem('发现人', pd['CREATORNAME'] ?? ''), + Divider(height: 1), + _buildInfoItem('发现时间', pd['CREATTIME'] ?? ''), + Divider(height: 1), + + if (pd['HIDDEN_CATEGORY']?.isNotEmpty == true) + _buildInfoItem('隐患类别', pd['HIDDEN_CATEGORY_NAME'] ?? ''), + + _buildInfoItem('隐患类型', pd['HIDDENTYPE_NAME'] ?? ''), + Divider(height: 1), + _buildInfoItem('整改类型', _getRectificationType(pd['RECTIFICATIONTYPE'])), + + if (pd['RECTIFICATIONTYPE'] == '2') + _buildInfoItem('整改期限', pd['RECTIFICATIONDEADLINE'] ?? ''), + Divider(height: 1), + // 隐患照片 + // const Text('隐患照片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files, onTap: (index) => _showImageGallery(files, index)), + ListItemFactory.createTextImageItem( + text: "隐患照片", + imageUrls: files, + onImageTapped: (index) { + present( + SingleImageViewer(imageUrl:ApiService.baseImgPath + files[index]), + context, + ); + }, + ), + + + // 隐患视频 + if (videoList.isNotEmpty) ...[ + const SizedBox(height: 16), + const Text('隐患视频', style: TextStyle(fontWeight: FontWeight.bold)), + GestureDetector( + onTap: () { + present( + BigVideoViewer(videoUrl:ApiService.baseImgPath + videoList[0]['FILEPATH']), + context, + ); + }, + // => _playVideo(ApiService.baseImgPath + videoList[0]['FILEPATH']), + child: Image.asset( + 'assets/image/videostart.png', // 替换为你的视频占位图 + color: Colors.blue, + width: 120, + height: 120, + ), + ), + ], + + SizedBox(height: 10,), + // 整改信息部分 + if (pd['STATE'] != null && int.parse(pd['STATE']) >= 2 && int.parse(pd['STATE']) <= 4) ...[ + // const Divider(height: 10,color: Colors.grey,), + const Text('整改信息', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + Divider(height: 1), + _buildInfoItem('整改描述', pd['RECTIFYDESCR'] ?? ''), + Divider(height: 1), + _buildInfoItem('整改部门', pd['RECTIFICATIONDEPTNAME'] ?? ''), + Divider(height: 1), + _buildInfoItem('整改人', pd['RECTIFICATIONORNAME'] ?? ''), + Divider(height: 1), + _buildInfoItem('整改时间', pd['RECTIFICATIONTIME'] ?? ''), + Divider(height: 1), + // const Text('整改后图片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files2, onTap: (index) => _showImageGallery(files2, index)), + ListItemFactory.createTextImageItem( + text: "整改后图片", + imageUrls: files2, + onImageTapped: (index) { + present( + SingleImageViewer(imageUrl: ApiService.baseImgPath +files2[index]), + context, + ); + }, + ), + + // ... 其他整改信息字段 + ], + + // 添加底部安全区域间距 + SizedBox(height: MediaQuery.of(context).padding.bottom + 20), + ], + ), + ), + ), + ); + }, + ), + ); + } + + + + + String _getSourceText(String? source) { + switch (source) { + case '1': return '隐患快报'; + case '2': return '隐患排查清单检查'; + case '3': return '标准排查清单检查'; + case '4': return '专项检查'; + case '5': return '安全检查'; + default: return ''; + } + } + + String _getRectificationType(String? type) { + switch (type) { + case '1': return '立即整改'; + case '2': return '限期整改'; + default: return ''; + } + } +} + diff --git a/lib/pages/home/work/laws_list_picker.dart b/lib/pages/home/work/laws_list_picker.dart new file mode 100644 index 0000000..ceb82df --- /dev/null +++ b/lib/pages/home/work/laws_list_picker.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; + +class LawsListBean { + final String id; + final String name; + final String parentId; + final List children; + + LawsListBean({ + required this.id, + required this.name, + required this.parentId, + this.children = const [], + }); + + factory LawsListBean.fromJson(Map json) { + return LawsListBean( + id: json['id'] ?? '', + name: json['title'] ?? '', + parentId: json['pId'] ?? '', + children: json['children'] != null + ? (json['children'] as List) + .map((child) => LawsListBean.fromJson(child)) + .toList() + : [], + ); + } + +} + +class LawsListPicker extends StatefulWidget { + final List data; + final String? initialSelectedId; + final Set? initialExpandedSet; + final ValueChanged onSelected; + + const LawsListPicker({ + Key? key, + required this.data, + this.initialSelectedId, + this.initialExpandedSet, + required this.onSelected, + }) : super(key: key); + + @override + _LawsListPickerState createState() => _LawsListPickerState(); +} + +class _LawsListPickerState extends State { + late String? selectedId; + late Set expandedSet; + + @override + void initState() { + super.initState(); + selectedId = widget.initialSelectedId; + expandedSet = Set.from(widget.initialExpandedSet ?? {}); + } + + Widget _buildRow(LawsListBean cat, int indent) { + final bool hasChildren = cat.children.isNotEmpty; + final bool isExpanded = expandedSet.contains(cat.id); + final bool isSelected = cat.id == selectedId; + + return Column( + children: [ + InkWell( + onTap: () { + setState(() { + if (hasChildren) { + if (isExpanded) { + expandedSet.remove(cat.id); + } else { + expandedSet.add(cat.id); + } + } + selectedId = cat.id; + widget.onSelected(cat); + }); + }, + child: Container( + color: Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // 左侧缩进 + SizedBox(width: 16.0 * indent), + // 展开/占位图标 + SizedBox( + width: 24, + child: hasChildren + ? Icon( + isExpanded ? Icons.expand_less : Icons.expand_more, + size: 20, + color: Colors.grey[600], + ) + : const SizedBox.shrink(), + ), + const SizedBox(width: 8), + // 标题 + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(cat.name), + ), + ), + // 单选圈保持右侧对齐 + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 16), + // child: Icon( + // isSelected + // ? Icons.radio_button_checked + // : Icons.radio_button_unchecked, + // color: Colors.green, + // ), + // ), + ], + ), + ), + ), + if (hasChildren && isExpanded) + ...cat.children.map((c) => _buildRow(c, indent + 1)), + // const Divider(height: 1), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + color: Colors.transparent, + child: Column( + children: [ + // 顶部操作栏 + // Container( + // color: Colors.white, + // padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + // child: Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // children: [ + // GestureDetector( + // onTap: () => Navigator.of(context).pop(), + // child: const Text('取消', style: TextStyle(fontSize: 16)), + // ), + // GestureDetector( + // onTap: () => Navigator.of(context).pop(selectedId), + // child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.green),), + // ), + // ], + // ), + // ), + // const Divider(height: 1), + // 列表区 + Expanded( + child: Container( + color: Colors.white, + child: ListView.builder( + itemCount: widget.data.length, + itemBuilder: (ctx, idx) => _buildRow(widget.data[idx], 0), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/home/work/laws_regulations_page.dart b/lib/pages/home/work/laws_regulations_page.dart new file mode 100644 index 0000000..cd59e53 --- /dev/null +++ b/lib/pages/home/work/laws_regulations_page.dart @@ -0,0 +1,358 @@ +import 'package:flutter/material.dart'; + +import 'dart:convert'; +import 'package:path_provider/path_provider.dart'; +import 'package:intl/intl.dart'; +import 'package:dio/dio.dart'; +import 'package:qhd_prevention/pages/home/work/risk_list_picker.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; + +import '../../../customWidget/search_bar_widget.dart'; +import '../../../http/ApiService.dart'; +import 'laws_list_picker.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class LawsRegulationsPage extends StatefulWidget { + const LawsRegulationsPage({super.key}); + + @override + State createState() => _LawsRegulationsPage(); +} + +class _LawsRegulationsPage extends State { + final TextEditingController _searchController = TextEditingController(); + List _accordionList = []; + List _fileList = []; + String _keywords = ''; + String treeJson = ""; + + @override + void initState() { + super.initState(); + _getLowList(""); + } + + Future _getLowList(String keyWord) async { + try { + _accordionList.clear(); + _fileList.clear(); + final result = await ApiService.getLowList(keyWord); + if (result['result'] == 'success') { + final List newList = result['varList'] ?? []; + setState(() { + if(keyWord.isEmpty) { + treeJson = result['zTreeNodes']??""; + _accordionList = parseDepartments(treeJson); + }else { + _fileList.addAll(newList); + } + }); + } else { + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + List parseDepartments(String jsonString) { + // 1. 解码 JSON 字符串 + final List jsonList = json.decode(jsonString); + + // 2. 转换为部门对象列表 + return jsonList + .map((jsonItem) => LawsListBean.fromJson(jsonItem)) + .toList(); + } + + void _goToDetail(String id) { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => StudyDetailPage(parentId: id)), + ); + } + + Future _downloadFile(String filePath) async { + //下载 + try { + final Uri url = Uri.parse(ApiService.baseImgPath + filePath); + if (!await launchUrl(url,mode:LaunchMode.externalApplication)) { + throw Exception('Could not launch $url'); + } + } catch (e) { + print(e.toString()); + } + } + + Future _showFile(dynamic file) async { + //预览 + try { + final url =ApiService.baseImgPath + file["FILEPATH"]; + openFile(url); + } catch (e) { + print(e.toString()); + } + } + + + Future openFile(String url) async { + // final Uri _url = Uri.file(filePath); + + if (await canLaunch(url)) { + await launch( + url, + forceSafariVC: false, // 仅在iOS上有效,设置为false以避免使用SafariViewController。 + forceWebView: false, // 设置为false以避免使用WebView。 + enableJavaScript: true, // 启用JavaScript。 + ); + } else { + throw 'Could not launch $url'; + } + + } + + String _formatDate(String dateString) { + try { + final date = DateTime.parse(dateString); + return DateFormat('yyyy-MM-dd HH:mm:ss').format(date); + } catch (e) { + return dateString; + } + } + + String _getFileType(String extension) { + switch (extension) { + case '.docx': + case '.doc': + return '文件属性:文档'; + case '.xls': + case '.xlsx': + return '文件属性:表格'; + case '.ppt': + case '.pptx': + return '文件属性:幻灯片'; + case '.pdf': + return '文件属性:PDF'; + default: + return '文件属性:'; + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: "法律法规"), + body: Column( + children: [ + // 搜索栏 + Padding( + padding: EdgeInsets.all(10), + child: SearchBarWidget( + controller: _searchController, + onSearch: (keyboard) { + // 输入请求接口 + _getLowList(keyboard); + }, + ), + ), + + Expanded(child: _buildContent()), + ], + ), + ); + } + + Widget _buildContent() { + if (_accordionList.isNotEmpty) { + return LawsListPicker( + data: _accordionList, + onSelected: (item) { + setState(() { + // riskId = item?.id; + // itemNameTwo=item!.name; + // setResult(); + }); + + }, + ); + + // return ListView.builder( + // itemCount: _accordionList.length, + // itemBuilder: + // (context, index) => + // CustomCollapse(item: _accordionList[index], onTap: _goToDetail), + // ); + } else if (_fileList.isNotEmpty) { + return ListView.builder( + itemCount: _fileList.length, + itemBuilder: + (context, index) => FileCard( + file: _fileList[index], + onDownload: _downloadFile, + onPreview: _showFile, + formatDate: _formatDate, + getFileType: _getFileType, + ), + ); + } else { + return const Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.folder_open, size: 64, color: Colors.grey), + SizedBox(height: 16), + Text('暂无数据', style: TextStyle(fontSize: 18, color: Colors.grey)), + ], + ), + ); + } + } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } +} + +class CustomCollapse extends StatefulWidget { + final dynamic item; + final Function(String) onTap; + + const CustomCollapse({super.key, required this.item, required this.onTap}); + + @override + State createState() => _CustomCollapseState(); +} + +class _CustomCollapseState extends State { + bool _isExpanded = false; + + @override + Widget build(BuildContext context) { + final hasChildren = + widget.item['children'] != null && + (widget.item['children'] as List).isNotEmpty; + + return Card( + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Column( + children: [ + ListTile( + title: Text( + widget.item['name'] ?? '未命名', + style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16), + ), + trailing: + hasChildren + ? Icon( + _isExpanded ? Icons.expand_less : Icons.expand_more, + color: Colors.blue, + ) + : null, + onTap: + hasChildren + ? () => setState(() => _isExpanded = !_isExpanded) + : () => widget.onTap(widget.item['id'] ?? ''), + ), + if (_isExpanded && hasChildren) + ...(widget.item['children'] as List).map((child) { + return Padding( + padding: const EdgeInsets.only(left: 16.0), + child: ListTile( + title: Text(child['name']), + leading: const Icon(Icons.description, color: Colors.blue), + onTap: () => widget.onTap(child['id'] ?? ''), + ), + ); + }).toList(), + ], + ), + ); + } +} + +class FileCard extends StatelessWidget { + final dynamic file; + final Function(String) onDownload; + final Function(dynamic) onPreview; + final String Function(String) formatDate; + final String Function(String) getFileType; + + const FileCard({ + super.key, + required this.file, + required this.onDownload, + required this.onPreview, + required this.formatDate, + required this.getFileType, + }); + + @override + Widget build(BuildContext context) { + return Card( + margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + file['NAME'] ?? '未命名文件', + style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + const SizedBox(height: 10), + Text( + getFileType(file['extension_name'] ?? ''), + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 5), + Text( + '上传日期:${formatDate(file['CTIME'] ?? '')}', + style: TextStyle(color: Colors.grey[600]), + ), + const SizedBox(height: 15), + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + OutlinedButton.icon( + icon: const Icon(Icons.download, size: 18), + label: const Text('下载'), + onPressed: () => onDownload(file['FILEPATH'] ?? ''), + style: OutlinedButton.styleFrom( + foregroundColor: Colors.blue, + side: const BorderSide(color: Colors.blue), + ), + ), + const SizedBox(width: 10), + ElevatedButton.icon( + icon: const Icon(Icons.visibility, size: 18), + label: const Text('预览'), + onPressed: () => onPreview(file), + style: ElevatedButton.styleFrom( + backgroundColor: Colors.cyan, + foregroundColor: Colors.white, + ), + ), + ], + ), + ], + ), + ), + ); + } +} + +//详情页 +class StudyDetailPage extends StatelessWidget { + final String parentId; + + const StudyDetailPage({super.key, required this.parentId}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar(title: const Text('详情页面')), + body: Center(child: Text('父级ID: $parentId')), + ); + } +} diff --git a/lib/pages/home/work/risk_list_picker.dart b/lib/pages/home/work/risk_list_picker.dart new file mode 100644 index 0000000..ac96453 --- /dev/null +++ b/lib/pages/home/work/risk_list_picker.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; + +class RiskListBean { + final String id; + final String name; + // final String parentId; + // final List children; + + RiskListBean({ + required this.id, + required this.name, + // required this.parentId, + // this.children = const [], + }); + + factory RiskListBean.fromJson(Map json) { + return RiskListBean( + id: json['RISKUNIT_ID'] ?? '', + name: json['RISKUNITNAME'] ?? '', + // parentId: json['PARENT_ID'] ?? '', + // children: json['children'] != null + // ? (json['children'] as List) + // .map((child) => RiskListBean.fromJson(child)) + // .toList() + // : [], + ); + } + +} + +class RiskListPicker extends StatefulWidget { + final List data; + final String? initialSelectedId; + final Set? initialExpandedSet; + final ValueChanged onSelected; + + const RiskListPicker({ + Key? key, + required this.data, + this.initialSelectedId, + this.initialExpandedSet, + required this.onSelected, + }) : super(key: key); + + @override + _RiskListPickerState createState() => _RiskListPickerState(); +} + +class _RiskListPickerState extends State { + late String? selectedId; + late Set expandedSet; + + @override + void initState() { + super.initState(); + selectedId = widget.initialSelectedId; + expandedSet = Set.from(widget.initialExpandedSet ?? {}); + } + + Widget _buildRow(RiskListBean cat, int indent) { + // final bool hasChildren = cat.children.isNotEmpty; + final bool isExpanded = expandedSet.contains(cat.id); + final bool isSelected = cat.id == selectedId; + + return Column( + children: [ + InkWell( + onTap: () { + setState(() { + // if (hasChildren) { + // if (isExpanded) { + // expandedSet.remove(cat.id); + // } else { + // expandedSet.add(cat.id); + // } + // } + selectedId = cat.id; + widget.onSelected(cat); + }); + }, + child: Container( + color: Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // 左侧缩进 + SizedBox(width: 16.0 * indent), + // 展开/占位图标 + // SizedBox( + // width: 24, + // child: hasChildren + // ? Icon( + // isExpanded ? Icons.expand_less : Icons.expand_more, + // size: 20, + // color: Colors.grey[600], + // ) + // : const SizedBox.shrink(), + // ), + const SizedBox(width: 8), + // 标题 + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(cat.name), + ), + ), + // 单选圈保持右侧对齐 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Icon( + isSelected + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: Colors.green, + ), + ), + ], + ), + ), + ), + // if (hasChildren && isExpanded) + // ...cat.children.map((c) => _buildRow(c, indent + 1)), + // const Divider(height: 1), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + color: Colors.transparent, + child: Column( + children: [ + // 顶部操作栏 + Container( + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: const Text('取消', style: TextStyle(fontSize: 16)), + ), + GestureDetector( + onTap: () => Navigator.of(context).pop(selectedId), + child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.green),), + ), + ], + ), + ), + const Divider(height: 1), + // 列表区 + Expanded( + child: Container( + color: Colors.white, + child: ListView.builder( + itemCount: widget.data.length, + itemBuilder: (ctx, idx) => _buildRow(widget.data[idx], 0), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/home/work/wait_list_picker.dart b/lib/pages/home/work/wait_list_picker.dart new file mode 100644 index 0000000..a94a1c0 --- /dev/null +++ b/lib/pages/home/work/wait_list_picker.dart @@ -0,0 +1,169 @@ +import 'package:flutter/material.dart'; + +class WaitListBean { + final String id; + final String name; + final String parentId; + final List children; + + WaitListBean({ + required this.id, + required this.name, + required this.parentId, + this.children = const [], + }); + + factory WaitListBean.fromJson(Map json) { + return WaitListBean( + id: json['id'] ?? '', + name: json['name'] ?? '', + parentId: json['PARENT_ID'] ?? '', + children: json['children'] != null + ? (json['children'] as List) + .map((child) => WaitListBean.fromJson(child)) + .toList() + : [], + ); + } + +} + +class WaitListPicker extends StatefulWidget { + final List data; + final String? initialSelectedId; + final Set? initialExpandedSet; + final ValueChanged onSelected; + + const WaitListPicker({ + Key? key, + required this.data, + this.initialSelectedId, + this.initialExpandedSet, + required this.onSelected, + }) : super(key: key); + + @override + _WaitListPickerState createState() => _WaitListPickerState(); +} + +class _WaitListPickerState extends State { + late String? selectedId; + late Set expandedSet; + + @override + void initState() { + super.initState(); + selectedId = widget.initialSelectedId; + expandedSet = Set.from(widget.initialExpandedSet ?? {}); + } + + Widget _buildRow(WaitListBean cat, int indent) { + final bool hasChildren = cat.children.isNotEmpty; + final bool isExpanded = expandedSet.contains(cat.id); + final bool isSelected = cat.id == selectedId; + + return Column( + children: [ + InkWell( + onTap: () { + setState(() { + if (hasChildren) { + if (isExpanded) { + expandedSet.remove(cat.id); + } else { + expandedSet.add(cat.id); + } + } + selectedId = cat.id; + widget.onSelected(cat); + }); + }, + child: Container( + color: Colors.white, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // 左侧缩进 + SizedBox(width: 16.0 * indent), + // 展开/占位图标 + SizedBox( + width: 24, + child: hasChildren + ? Icon( + isExpanded ? Icons.expand_less : Icons.expand_more, + size: 20, + color: Colors.grey[600], + ) + : const SizedBox.shrink(), + ), + const SizedBox(width: 8), + // 标题 + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(cat.name), + ), + ), + // 单选圈保持右侧对齐 + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Icon( + isSelected + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: Colors.green, + ), + ), + ], + ), + ), + ), + if (hasChildren && isExpanded) + ...cat.children.map((c) => _buildRow(c, indent + 1)), + // const Divider(height: 1), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + color: Colors.transparent, + child: Column( + children: [ + // 顶部操作栏 + Container( + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: const Text('取消', style: TextStyle(fontSize: 16)), + ), + GestureDetector( + onTap: () => Navigator.of(context).pop(selectedId), + child: const Text('确定', style: TextStyle(fontSize: 16, color: Colors.green),), + ), + ], + ), + ), + const Divider(height: 1), + // 列表区 + Expanded( + child: Container( + color: Colors.white, + child: ListView.builder( + itemCount: widget.data.length, + itemBuilder: (ctx, idx) => _buildRow(widget.data[idx], 0), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pages/home/workSet_page.dart b/lib/pages/home/workSet_page.dart index 0c7b4bc..e909fd4 100644 --- a/lib/pages/home/workSet_page.dart +++ b/lib/pages/home/workSet_page.dart @@ -1,3 +1,5 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/home/work_alert.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -5,6 +7,7 @@ import 'package:qhd_prevention/tools/tools.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:intl/intl.dart'; +import '../../http/ApiService.dart'; import '../../tools/h_colors.dart'; class WorkSetPage extends StatefulWidget { @@ -18,11 +21,108 @@ class _WorkSetPageState extends State { DateTime _focusedDay = DateTime.now(); DateTime _selectedDay = DateTime.now(); + Map dayWork = {}; + late List _list = []; + String title=""; + String content=""; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _getAnPai(); + String data= DateFormat('yyyy-MM-dd').format(DateTime.now()); + _getRiCheng(data,false); + } + + Future _getAnPai() async { + try { + + final result = await ApiService.getAnPai(); + if (result['result'] == 'success') { + setState(() { + dayWork= result; + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + Future _getRiCheng(String data, bool bool) async { + try { + _list.clear(); + + final result = await ApiService.getRiCheng(data); + + if (result['result'] == 'success') { + setState(() { + final List newList = result['varList'] ?? []; + _list.addAll(newList); + + }); + if(bool) { + if ( _list.isNotEmpty) { + title = _list[0]["title"]; + content = _list[0]["desc"]; + selectDate(); + } else { + title = ""; + content = ""; + selectDate(); + } + } + }else{ + _showMessage('加载数据失败'); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + + Future _addRiCheng(String title, String content) async { + try { + + String urlPath; + String id; + if(_list.isNotEmpty){ + urlPath="edit"; + id=_list[0]["id"]; + }else{ + urlPath="add"; + id=Random().nextDouble().toString(); + } + String data= DateFormat('yyyy-MM-dd').format(_selectedDay); + final result = await ApiService.addRiCheng(data,title,content,id,urlPath); + if (result['result'] == 'success') { + setState(() { + _showMessage('保存成功'); + String data= DateFormat('yyyy-MM-dd').format(_selectedDay); + _getRiCheng(data,false); + }); + + }else{ + _showMessage('加载数据失败'); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } + } + void _goToToday() { setState(() { _focusedDay = DateTime.now(); _selectedDay = DateTime.now(); - selectDate(); + // selectDate(); + getInfoDate(); }); } @@ -38,23 +138,35 @@ class _WorkSetPageState extends State { }); } + void getInfoDate() { + String data= DateFormat('yyyy-MM-dd').format(_selectedDay); + _getRiCheng(data,true); + } void selectDate() { + print("======$_selectedDay"); + showWorkAlert( context: context, alertTitle: "标题:", inputHint: "请输入", contentHint: "请输入", + initialTitle: title, + initialContent: content, onConfirm: (title, content) { // 处理确定后的逻辑 - print("标题: $title"); - print("内容: $content"); + // print("标题: $title"); + // print("内容: $content"); + + _addRiCheng(title,content); }, onCancel: () { // 处理取消逻辑 print("用户取消了操作"); }, ); + + } @override @@ -81,7 +193,8 @@ class _WorkSetPageState extends State { setState(() { _selectedDay = selectedDay; _focusedDay = focusedDay; - selectDate(); + // selectDate(); + getInfoDate(); }); }, daysOfWeekStyle: DaysOfWeekStyle( @@ -136,8 +249,10 @@ class _WorkSetPageState extends State { ), ), ), - Container(color: h_backGroundColor(), height: 20), + Container(color: h_backGroundColor(), height: 10), _workTipWidget(), + Container(color: h_backGroundColor(), height: 10), + _workRiCheng(), ], ), ); @@ -161,16 +276,54 @@ class _WorkSetPageState extends State { Column( spacing: 5, children: [ - _itemCell("需进行2项隐患排查", true), - _itemCell("需进行2项隐患排查", false), + _itemCell("需进行${dayWork["fxyjcNum"]??"0"}项隐患排查", true), + _itemCell("需进行${dayWork["fxwjcNum"]??"0"}项隐患排查", false), + _itemCell("需进行${dayWork["yhyjcNum"]??"0"}项标准排查", true), + _itemCell("需进行${dayWork["yhwjcNum"]??"0"}项标准排查", false), ], ), + + ], ), ); } + + /// 本日工作题型 + Widget _workRiCheng() { + return Container( + color: Colors.white, + padding: EdgeInsets.all(12), + child: Column( + spacing: 20, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("本日日程安排", style: TextStyle(fontSize: 16)), + Spacer(), + ], + ), + + if(_list.isNotEmpty) + _itemRiCheng(_list[0]["desc"]) + // if(_list.isEmpty) + // ListView.separated( + // separatorBuilder: (_, __) => const Divider(height: 1), + // itemCount: _list.length, + // itemBuilder: (context, index) { + // final item = _list[index]; + // return _itemRiCheng(item); + // }, + // ), + ], + + ), + ); + } + Widget _itemCell(final String title, bool isFinish) { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -186,6 +339,23 @@ class _WorkSetPageState extends State { ], ); } + + Widget _itemRiCheng(final String title) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + spacing: 5, + children: [ + Icon(Icons.circle, size: 10, color: Colors.blue), + Text(title, style: TextStyle(color: Colors.black45),), + ], + ), + + ], + ); + } + ///日历头 Widget _calendarHeader() { return Container( @@ -289,4 +459,8 @@ class _WorkSetPageState extends State { ], ); } + + void _showMessage(String msg) { + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); + } } diff --git a/lib/tools/tools.dart b/lib/tools/tools.dart index a627836..660f0bf 100644 --- a/lib/tools/tools.dart +++ b/lib/tools/tools.dart @@ -155,6 +155,8 @@ class SessionService { String? isRest; List? permission; bool updateInfo = false; + String? dangerJson; + String? riskJson; /// 如果以下任何一项为空,则跳转到登录页 void loginSession(BuildContext context) { @@ -188,6 +190,10 @@ class SessionService { void setUpdateInfo(bool flag) => updateInfo = flag; + void setDangerWaitInfo(String json) => dangerJson = json; + + void setRiskWaitInfo(String json) => riskJson = json; + } diff --git a/pubspec.lock b/pubspec.lock index 9a8e518..9ae05fd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: args sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.7.0" asn1lib: @@ -14,23 +14,23 @@ packages: description: name: asn1lib sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.6.5" async: dependency: transitive description: name: async - sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" + url: "https://pub.flutter-io.cn" source: hosted - version: "2.12.0" + version: "2.13.0" boolean_selector: dependency: transitive description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" camera: @@ -38,7 +38,7 @@ packages: description: name: camera sha256: d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.2" camera_android_camerax: @@ -46,7 +46,7 @@ packages: description: name: camera_android_camerax sha256: "4b6c1bef4270c39df96402c4d62f2348c3bb2bbaefd0883b9dbd58f426306ad0" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.19" camera_avfoundation: @@ -54,7 +54,7 @@ packages: description: name: camera_avfoundation sha256: b389be4a325742a3950e50475067d95a3de2fb32ba3f31bfcc62b0b6d19907a6 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.20+4" camera_platform_interface: @@ -62,7 +62,7 @@ packages: description: name: camera_platform_interface sha256: "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.10.0" camera_web: @@ -70,7 +70,7 @@ packages: description: name: camera_web sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.5" characters: @@ -78,7 +78,7 @@ packages: description: name: characters sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" clock: @@ -86,7 +86,7 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" collection: @@ -94,7 +94,7 @@ packages: description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.19.1" connectivity_plus: @@ -102,7 +102,7 @@ packages: description: name: connectivity_plus sha256: "051849e2bd7c7b3bc5844ea0d096609ddc3a859890ec3a9ac4a65a2620cc1f99" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.4" connectivity_plus_platform_interface: @@ -110,7 +110,7 @@ packages: description: name: connectivity_plus_platform_interface sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.1" convert: @@ -118,7 +118,7 @@ packages: description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.2" cross_file: @@ -126,7 +126,7 @@ packages: description: name: cross_file sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.3.4+2" crypto: @@ -134,7 +134,7 @@ packages: description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.6" csslib: @@ -142,7 +142,7 @@ packages: description: name: csslib sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.2" cupertino_icons: @@ -150,7 +150,7 @@ packages: description: name: cupertino_icons sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.8" dbus: @@ -158,7 +158,7 @@ packages: description: name: dbus sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.11" dio: @@ -166,7 +166,7 @@ packages: description: name: dio sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.8.0+1" dio_web_adapter: @@ -174,7 +174,7 @@ packages: description: name: dio_web_adapter sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" encrypt: @@ -182,7 +182,7 @@ packages: description: name: encrypt sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.3" extended_image: @@ -190,7 +190,7 @@ packages: description: name: extended_image sha256: f6cbb1d798f51262ed1a3d93b4f1f2aa0d76128df39af18ecb77fa740f88b2e0 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "10.0.1" extended_image_library: @@ -198,7 +198,7 @@ packages: description: name: extended_image_library sha256: "1f9a24d3a00c2633891c6a7b5cab2807999eb2d5b597e5133b63f49d113811fe" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.1" extension: @@ -206,23 +206,23 @@ packages: description: name: extension sha256: be3a6b7f8adad2f6e2e8c63c895d19811fcf203e23466c6296267941d0ff4f24 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.6.0" fake_async: dependency: transitive description: name: fake_async - sha256: "6a95e56b2449df2273fd8c45a662d6947ce1ebb7aafe80e550a3f68297f3cacc" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.flutter-io.cn" source: hosted - version: "1.3.2" + version: "1.3.3" ffi: dependency: transitive description: name: ffi sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" file: @@ -230,7 +230,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "7.0.1" file_selector_linux: @@ -238,7 +238,7 @@ packages: description: name: file_selector_linux sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.3+2" file_selector_macos: @@ -246,7 +246,7 @@ packages: description: name: file_selector_macos sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.4+3" file_selector_platform_interface: @@ -254,7 +254,7 @@ packages: description: name: file_selector_platform_interface sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.6.2" file_selector_windows: @@ -262,7 +262,7 @@ packages: description: name: file_selector_windows sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.9.3+4" fixnum: @@ -270,7 +270,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" flutter: @@ -283,7 +283,7 @@ packages: description: name: flutter_html sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" flutter_lints: @@ -291,7 +291,7 @@ packages: description: name: flutter_lints sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.0.0" flutter_plugin_android_lifecycle: @@ -299,7 +299,7 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.28" flutter_test: @@ -317,15 +317,63 @@ packages: description: name: fluttertoast sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "8.2.12" + geolocator: + dependency: "direct main" + description: + name: geolocator + sha256: f4efb8d3c4cdcad2e226af9661eb1a0dd38c71a9494b22526f9da80ab79520e5 + url: "https://pub.flutter-io.cn" + source: hosted + version: "10.1.1" + geolocator_android: + dependency: transitive + description: + name: geolocator_android + sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.6.2" + geolocator_apple: + dependency: transitive + description: + name: geolocator_apple + sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.13" + geolocator_platform_interface: + dependency: transitive + description: + name: geolocator_platform_interface + sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" + url: "https://pub.flutter-io.cn" + source: hosted + version: "4.2.6" + geolocator_web: + dependency: transitive + description: + name: geolocator_web + sha256: "102e7da05b48ca6bf0a5bda0010f886b171d1a08059f01bfe02addd0175ebece" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.2.1" + geolocator_windows: + dependency: transitive + description: + name: geolocator_windows + sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.5" html: dependency: transitive description: name: html sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.15.6" http: @@ -333,7 +381,7 @@ packages: description: name: http sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" http_client_helper: @@ -341,7 +389,7 @@ packages: description: name: http_client_helper sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.0" http_parser: @@ -349,7 +397,7 @@ packages: description: name: http_parser sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.1.2" image_picker: @@ -357,7 +405,7 @@ packages: description: name: image_picker sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.2" image_picker_android: @@ -365,7 +413,7 @@ packages: description: name: image_picker_android sha256: "6fae381e6af2bbe0365a5e4ce1db3959462fa0c4d234facf070746024bb80c8d" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.8.12+24" image_picker_for_web: @@ -373,7 +421,7 @@ packages: description: name: image_picker_for_web sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.6" image_picker_ios: @@ -381,7 +429,7 @@ packages: description: name: image_picker_ios sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.8.12+2" image_picker_linux: @@ -389,7 +437,7 @@ packages: description: name: image_picker_linux sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.1+2" image_picker_macos: @@ -397,7 +445,7 @@ packages: description: name: image_picker_macos sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.1+2" image_picker_platform_interface: @@ -405,7 +453,7 @@ packages: description: name: image_picker_platform_interface sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.10.1" image_picker_windows: @@ -413,7 +461,7 @@ packages: description: name: image_picker_windows sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.1+1" intl: @@ -421,7 +469,7 @@ packages: description: name: intl sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.20.2" js: @@ -429,23 +477,23 @@ packages: description: name: js sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.2" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: c35baad643ba394b40aac41080300150a4f08fd0fd6a10378f8f7c6bc161acec - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" + url: "https://pub.flutter-io.cn" source: hosted - version: "10.0.8" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.9" leak_tracker_testing: @@ -453,7 +501,7 @@ packages: description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.0.1" lints: @@ -461,7 +509,7 @@ packages: description: name: lints sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "5.1.1" list_counter: @@ -469,7 +517,7 @@ packages: description: name: list_counter sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.2" matcher: @@ -477,7 +525,7 @@ packages: description: name: matcher sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.12.17" material_color_utilities: @@ -485,7 +533,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.11.1" meta: @@ -493,7 +541,7 @@ packages: description: name: meta sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.16.0" mime: @@ -501,7 +549,7 @@ packages: description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.0.0" mobile_scanner: @@ -509,7 +557,7 @@ packages: description: name: mobile_scanner sha256: "54005bdea7052d792d35b4fef0f84ec5ddc3a844b250ecd48dc192fb9b4ebc95" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "7.0.1" nested: @@ -517,7 +565,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.0" nm: @@ -525,7 +573,7 @@ packages: description: name: nm sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.5.0" package_info_plus: @@ -533,7 +581,7 @@ packages: description: name: package_info_plus sha256: "7976bfe4c583170d6cdc7077e3237560b364149fcd268b5f53d95a991963b191" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "8.3.0" package_info_plus_platform_interface: @@ -541,7 +589,7 @@ packages: description: name: package_info_plus_platform_interface sha256: "6c935fb612dff8e3cc9632c2b301720c77450a126114126ffaafe28d2e87956c" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.0" path: @@ -549,7 +597,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.9.1" path_provider: @@ -557,7 +605,7 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.5" path_provider_android: @@ -565,7 +613,7 @@ packages: description: name: path_provider_android sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.17" path_provider_foundation: @@ -573,7 +621,7 @@ packages: description: name: path_provider_foundation sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" path_provider_linux: @@ -581,7 +629,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -589,7 +637,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.2" path_provider_windows: @@ -597,7 +645,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.3.0" pdfx: @@ -605,7 +653,7 @@ packages: description: name: pdfx sha256: "29db9b71d46bf2335e001f91693f2c3fbbf0760e4c2eb596bf4bafab211471c1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.9.2" petitparser: @@ -613,7 +661,7 @@ packages: description: name: petitparser sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.0" photo_manager: @@ -621,7 +669,7 @@ packages: description: name: photo_manager sha256: a0d9a7a9bc35eda02d33766412bde6d883a8b0acb86bbe37dac5f691a0894e8a - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.7.1" photo_manager_image_provider: @@ -629,7 +677,7 @@ packages: description: name: photo_manager_image_provider sha256: b6015b67b32f345f57cf32c126f871bced2501236c405aafaefa885f7c821e4f - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.2.0" photo_view: @@ -637,7 +685,7 @@ packages: description: name: photo_view sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.15.0" platform: @@ -645,7 +693,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.1.6" plugin_platform_interface: @@ -653,7 +701,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.8" pointycastle: @@ -661,7 +709,7 @@ packages: description: name: pointycastle sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.9.1" provider: @@ -669,7 +717,7 @@ packages: description: name: provider sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.1.5" shared_preferences: @@ -677,7 +725,7 @@ packages: description: name: shared_preferences sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.5.3" shared_preferences_android: @@ -685,7 +733,7 @@ packages: description: name: shared_preferences_android sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.10" shared_preferences_foundation: @@ -693,7 +741,7 @@ packages: description: name: shared_preferences_foundation sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.5.4" shared_preferences_linux: @@ -701,7 +749,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -709,7 +757,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" shared_preferences_web: @@ -717,7 +765,7 @@ packages: description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.3" shared_preferences_windows: @@ -725,7 +773,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.1" simple_gesture_detector: @@ -733,7 +781,7 @@ packages: description: name: simple_gesture_detector sha256: ba2cd5af24ff20a0b8d609cec3f40e5b0744d2a71804a2616ae086b9c19d19a3 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.2.1" sky_engine: @@ -746,7 +794,7 @@ packages: description: name: source_span sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.10.1" sprintf: @@ -754,7 +802,7 @@ packages: description: name: sprintf sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "7.0.0" stack_trace: @@ -762,7 +810,7 @@ packages: description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.12.1" stream_channel: @@ -770,7 +818,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" stream_transform: @@ -778,7 +826,7 @@ packages: description: name: stream_transform sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.1" string_scanner: @@ -786,23 +834,23 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.1" synchronized: dependency: transitive description: name: synchronized - sha256: "0669c70faae6270521ee4f05bffd2919892d42d1276e6c495be80174b6bc0ef6" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 + url: "https://pub.flutter-io.cn" source: hosted - version: "3.3.1" + version: "3.4.0" table_calendar: dependency: "direct main" description: name: table_calendar sha256: "0c0c6219878b363a2d5f40c7afb159d845f253d061dc3c822aa0d5fe0f721982" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.2.0" term_glyph: @@ -810,7 +858,7 @@ packages: description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.2.2" test_api: @@ -818,7 +866,7 @@ packages: description: name: test_api sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.7.4" typed_data: @@ -826,7 +874,7 @@ packages: description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.4.0" universal_platform: @@ -834,15 +882,79 @@ packages: description: name: universal_platform sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.2" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.16" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" + url: "https://pub.flutter-io.cn" + source: hosted + version: "6.3.3" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.1" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.2.2" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.3.2" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.4.1" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + url: "https://pub.flutter-io.cn" + source: hosted + version: "3.1.4" uuid: dependency: transitive description: name: uuid sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.5.1" vector_math: @@ -850,7 +962,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.1.4" video_player: @@ -858,7 +970,7 @@ packages: description: name: video_player sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.10.0" video_player_android: @@ -866,7 +978,7 @@ packages: description: name: video_player_android sha256: "4a5135754a62dbc827a64a42ef1f8ed72c962e191c97e2d48744225c2b9ebb73" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.8.7" video_player_avfoundation: @@ -874,7 +986,7 @@ packages: description: name: video_player_avfoundation sha256: "9fedd55023249f3a02738c195c906b4e530956191febf0838e37d0dac912f953" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.8.0" video_player_platform_interface: @@ -882,7 +994,7 @@ packages: description: name: video_player_platform_interface sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.4.0" video_player_web: @@ -890,7 +1002,7 @@ packages: description: name: video_player_web sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.4.0" visibility_detector: @@ -898,23 +1010,23 @@ packages: description: name: visibility_detector sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "0.4.0+2" vm_service: dependency: transitive description: name: vm_service - sha256: "0968250880a6c5fe7edc067ed0a13d4bae1577fe2771dcf3010d52c4a9d3ca14" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + url: "https://pub.flutter-io.cn" source: hosted - version: "14.3.1" + version: "15.0.0" web: dependency: transitive description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.1" webview_flutter: @@ -922,7 +1034,7 @@ packages: description: name: webview_flutter sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.13.0" webview_flutter_android: @@ -930,7 +1042,7 @@ packages: description: name: webview_flutter_android sha256: "9573ad97890d199ac3ab32399aa33a5412163b37feb573eb5b0a76b35e9ffe41" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "4.8.2" webview_flutter_platform_interface: @@ -938,7 +1050,7 @@ packages: description: name: webview_flutter_platform_interface sha256: f0dc2dc3a2b1e3a6abdd6801b9355ebfeb3b8f6cde6b9dc7c9235909c4a1f147 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "2.13.1" webview_flutter_wkwebview: @@ -946,7 +1058,7 @@ packages: description: name: webview_flutter_wkwebview sha256: "71523b9048cf510cfa1fd4e0a3fa5e476a66e0884d5df51d59d5023dba237107" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "3.22.1" wechat_assets_picker: @@ -954,7 +1066,7 @@ packages: description: name: wechat_assets_picker sha256: cafe3d32564ed3cacf9822f251941f7b44fe9885c17c8de4fca7e939a459e1ef - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "9.5.1" wechat_picker_library: @@ -962,23 +1074,23 @@ packages: description: name: wechat_picker_library sha256: a42e09cb85b15fc9410f6a69671371cc60aa99c4a1f7967f6593a7f665f6f47a - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.0.5" win32: dependency: transitive description: name: win32 - sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + url: "https://pub.flutter-io.cn" source: hosted - version: "5.13.0" + version: "5.14.0" xdg_directories: dependency: transitive description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "1.1.0" xml: @@ -986,9 +1098,9 @@ packages: description: name: xml sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 - url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" + url: "https://pub.flutter-io.cn" source: hosted version: "6.5.0" sdks: - dart: ">=3.7.0 <4.0.0" + dart: ">=3.8.0 <4.0.0" flutter: ">=3.29.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2fae557..1422250 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -66,6 +66,10 @@ dependencies: flutter_html: ^3.0.0 #pdf、word查看 pdfx: ^2.9.2 + #定位 + geolocator: ^10.0.0 + #打开外部预览app + url_launcher: ^6.0.9 dev_dependencies: