From 3fd86e7ca2f8c84b9f84f75c3f499b99a4fb791b Mon Sep 17 00:00:00 2001 From: hs <873121290@qq.com> Date: Sat, 16 Aug 2025 19:31:17 +0800 Subject: [PATCH] 3 --- lib/http/ApiService.dart | 104 ++++ .../custom/MultiTextFieldWithTitle.dart | 2 +- ...age.dart => safeCheck_sign_list_page.dart} | 85 +--- .../safecheck_sign_detail.dart | 471 +++++++++++++++++ .../CheckPersonSure/check_person_detail.dart | 318 +++++++----- .../check_person_list_page.dart | 46 +- .../safeCheck_assignment_detail_page.dart | 19 + .../DangeCheck/safeCheck_assignment_list.dart | 357 +++++++++++++ ...e.dart => safeCheck_danger_list_page.dart} | 140 +++--- .../DangeCheck/safecheck_danger_detail.dart | 311 ++++++++++++ .../Record/safeCheck_start_list_page.dart | 473 ------------------ .../home/SafeCheck/SafeCheckFormView.dart | 325 +++++++----- .../Start/safeCheck_defend_set_page.dart | 48 ++ .../Start/safeCheck_drawer_page.dart | 2 +- .../Start/safeCheck_start_detail.dart | 156 ++++-- .../Start/safeCheck_start_list_page.dart | 67 ++- .../home/SafeCheck/safeCheck_tab_list.dart | 10 +- lib/pages/home/tap/item_list_widget.dart | 13 +- pubspec.lock | 308 ++++++------ 19 files changed, 2130 insertions(+), 1125 deletions(-) rename lib/pages/home/SafeCheck/CheckPersonSign/{safeCheck_start_list_page.dart => safeCheck_sign_list_page.dart} (85%) create mode 100644 lib/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart create mode 100644 lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart create mode 100644 lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart rename lib/pages/home/SafeCheck/DangeCheck/{safeCheck_start_list_page.dart => safeCheck_danger_list_page.dart} (78%) create mode 100644 lib/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart delete mode 100644 lib/pages/home/SafeCheck/Record/safeCheck_start_list_page.dart create mode 100644 lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 356d607..95b3b53 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -1228,6 +1228,110 @@ U6Hzm1ninpWeE+awIDAQAB }, ); } + // 安全检查确认列表 + static Future> getSafeCheckSureList(String INSPECTION_ID) { + return HttpManager().request( + basePath, + '/app/safetyenvironmental/goShow', + method: Method.post, + data: { + "INSPECTION_ID":INSPECTION_ID, + }, + ); + } + + + + // 安全检查操作 + static Future> SafeCheckStartGoEditMsg( + String imagePath, + String msg, + Map data + ) async { + + Map formData = { + ...data, + }; + if (imagePath.isNotEmpty) { + final file = File(imagePath); + if (!await file.exists()) { + throw ApiException('file_not_found', '图片不存在:$imagePath'); + } + final fileName = file.path.split(Platform.pathSeparator).last; + formData['FFILE'] = + await MultipartFile.fromFile(file.path, filename: fileName); + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/safetyenvironmental/$msg', + fromData: formData, + ); + }else { + return HttpManager().request( + basePath, + '/app/safetyenvironmental/$msg', + data: formData, + ); + } + + } + // 安全检查核实 + static Future> getSafePersonCheck(Map formData, String imagePath) async { + final file = File(imagePath); + if (!await file.exists()) { + throw ApiException('file_not_found', '图片不存在:$imagePath'); + } + final fileName = file.path + .split(Platform.pathSeparator) + .last; + + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/safetyenvironmentalinspector/verify', + fromData: { + ...formData, + 'FFILE': await MultipartFile.fromFile( + file.path, + filename: fileName + ), + } + ); + } + // 安全检查确认 + static Future> getSafePersonSignSure(Map formData, String imagePath) async { + final file = File(imagePath); + if (!await file.exists()) { + throw ApiException('file_not_found', '图片不存在:$imagePath'); + } + final fileName = file.path + .split(Platform.pathSeparator) + .last; + + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/safetyenvironmentalexplain/add', + fromData: { + ...formData, + 'FFILE': await MultipartFile.fromFile( + file.path, + filename: fileName + ), + } + ); + } + // 安全检查隐患指派列表 + static Future> getSafeCheckDangerList(String INSPECTION_ID) { + return HttpManager().request( + basePath, + '/app/hidden/listForSafetyEnvironmental', + method: Method.post, + data: { + "INSPECTION_ID":INSPECTION_ID, + 'INSPECTION_STATUS': '3-7', + 'tm': DateTime.now().millisecondsSinceEpoch.toString(), + 'KEYWORDS' : '' + }, + ); + } diff --git a/lib/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart b/lib/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart index 5be8032..1695bbf 100644 --- a/lib/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart +++ b/lib/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart @@ -285,7 +285,7 @@ class _MultiTextFieldWithTitleState extends State { focusNode: _focusNodes[index], keyboardType: TextInputType.multiline, maxLines: 3, - minLines: 3, + // minLines: 3, style: TextStyle(fontSize: widget.fontSize), ), )), diff --git a/lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_start_list_page.dart b/lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_sign_list_page.dart similarity index 85% rename from lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_start_list_page.dart rename to lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_sign_list_page.dart index 85fdf8a..60feb20 100644 --- a/lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_start_list_page.dart +++ b/lib/pages/home/SafeCheck/CheckPersonSign/safeCheck_sign_list_page.dart @@ -1,5 +1,7 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -9,17 +11,17 @@ import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; import 'package:qhd_prevention/http/ApiService.dart'; -class SafecheckStartListPage extends StatefulWidget { +class SafecheckSignListPage extends StatefulWidget { final String flow; - const SafecheckStartListPage({Key? key, required this.flow}) + const SafecheckSignListPage({Key? key, required this.flow}) : super(key: key); @override - _SafecheckStartListPageState createState() => _SafecheckStartListPageState(); + _SafecheckSignListPageState createState() => _SafecheckSignListPageState(); } -class _SafecheckStartListPageState extends State { +class _SafecheckSignListPageState extends State { // Data and state variables List list = []; int currentPage = 1; @@ -81,10 +83,11 @@ class _SafecheckStartListPageState extends State { try { final data = { 'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '', + 'INSPECTED_SITEUSER_ID': SessionService.instance.loginUserId, 'KEYWORDS': searchKeywords, }; final url = - '/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage'; + '/app/safetyenvironmentalexplain/list?showCount=-1¤tPage=$currentPage'; final response = await ApiService.getSafeCheckSearchList(data, url); setState(() { @@ -110,39 +113,10 @@ class _SafecheckStartListPageState extends State { _fetchData(); } - /// 申请 - void _handleApply() { - // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context); - } - - /// 打开流程图 - Future _openFlowDrawer(String ID) async { - try { - final response = await ApiService.safeCheckFlowList(ID); - final List? newFlow = response['varList']; - if (newFlow == null || newFlow.isEmpty) { - ToastUtil.showNormal(context, '暂无流程图数据'); - return; - } - - setState(() { - flowList = List>.from(newFlow); - }); - Future.microtask(() { - _scaffoldKey.currentState?.openEndDrawer(); - }); - } catch (e) { - print('Error fetching flow data: $e'); - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); - } - } void _goToDetail(Map item) async { - pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context); + await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); setState(() { _fetchData(); @@ -243,7 +217,7 @@ class _SafecheckStartListPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"), + Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis), ], ), const SizedBox(height: 8), @@ -274,19 +248,21 @@ class _SafecheckStartListPageState extends State { ], ), const SizedBox(height: 8), - Row( - children: [ - CustomButton( - text: '流程图', - height: 35, - padding: EdgeInsets.symmetric(horizontal: 12), - margin: EdgeInsets.only(left: 0), - backgroundColor: Colors.blue, - onPressed: () => _openFlowDrawer(item['INSPECTION_ID']), - ), - SizedBox(width: 1), - ], - ), + if (item['INSPECTION_STATUS'] == '2') + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(), + CustomButton( + text: '确认', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.blue, + onPressed: () => _goToDetail(item), + ), + ], + ), ], ), ), @@ -367,16 +343,7 @@ class _SafecheckStartListPageState extends State { key: _scaffoldKey, appBar: MyAppbar( title: '${widget.flow}', - actions: [ - TextButton( - onPressed: _handleApply, - child: const Text( - '发起', - style: TextStyle(color: Colors.white, fontSize: 17), - ), - ), - - ], + actions: [], ), endDrawer: Drawer( child: SafeArea( diff --git a/lib/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart b/lib/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart new file mode 100644 index 0000000..f342b44 --- /dev/null +++ b/lib/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart @@ -0,0 +1,471 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker.dart'; +import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/dotted_border_box.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart'; +import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart'; +import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; +import 'package:qhd_prevention/pages/mine/mine_sign_page.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; + +class SafecheckSignDetail extends StatefulWidget { + const SafecheckSignDetail({ + super.key, + required this.INSPECTION_ID, + required this.INSPECTION_INSPECTOR_ID, + required this.isEdit, + }); + + final String INSPECTION_ID; + final String INSPECTION_INSPECTOR_ID; + final bool isEdit; + + @override + State createState() => _SafecheckSignDetailState(); +} + +class _SafecheckSignDetailState extends State { + String msg = 'add'; + bool _isEdit = false; + bool forbidEdit = false; + List signImages = []; + List signTimes = []; // 签字时间列表 + Map inspectedForm = {}; + List> inspectorRules = [ + {'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'}, + {'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'}, + {'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'}, + ]; + Map form = {}; + + @override + void initState() { + super.initState(); + _isEdit = widget.isEdit; + + WidgetsBinding.instance.addPostFrameCallback((_) { + _getData(); + }); + } + + Future _getData() async { + try { + final result = await ApiService.getSafeCheckSureList( + widget.INSPECTION_ID, + ); + // 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错 + if (!mounted) return; + setState(() { + form = result['pd'] ?? {}; + inspectedForm = { + 'INSPECTION_EXPLAIN_ID': '', // 安全检查人员主键ID + 'INSPECTION_STATUS': '3', + 'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID + 'INSPECTED_EXPLAIN': '', // 申辩内容 + 'INSPECTED_EXPLAIN_FILENAME': '', // 申辩附件名称 + 'INSPECTED_SITEUSER_SIGN_IMG': '', // 被检查单位现场负责人签字 + 'INSPECTED_SITEUSER_SIGN_TIME': '', + }; + List inspectorVerifyList = form['inspectorVerifyList'] ?? []; + for (int i = 0; i < inspectorVerifyList.length; i++) { + dynamic item = inspectorVerifyList[i]; + if (SessionService.instance.loginUserId == + (item['INSPECTION_USER_ID'] ?? '')) { + forbidEdit = true; + } + } + }); + } catch (e, st) { + print('加载单条数据失败: $e\n$st'); + if (mounted) { + ToastUtil.showNormal(context, '加载数据失败:$e'); + } + } + } + + Future _openDrawer(Map hiddenForm, int index) async { + try { + final result = await openCustomDrawer( + context, + SafeCheckDrawerPage( + initialHidden: hiddenForm, + editType: + _isEdit + ? (index < 0 ? SafeCheckEditType.add : SafeCheckEditType.edit) + : SafeCheckEditType.see, + toCheckUnitList: [], + ), + ); + + if (result != null && mounted) { + setState(() { + if (index < 0) { + // 新增 + form['hiddenList'].add(result); + print(form); + } else { + // 修改 + form['hiddenList'][index] = result; + } + }); + } + } catch (e) { + print("打开抽屉失败: $e"); + ToastUtil.showNormal(context, "打开抽屉失败"); + } + } + + Future openCustomDrawer(BuildContext context, Widget child) { + return Navigator.of(context).push( + PageRouteBuilder( + opaque: false, + barrierDismissible: true, + barrierColor: Colors.black54, + pageBuilder: (_, __, ___) { + return Align( + alignment: Alignment.centerRight, + child: FractionallySizedBox( + widthFactor: 4 / 5, + child: Material(color: Colors.white, child: child), + ), + ); + }, + transitionsBuilder: (_, anim, __, child) { + return SlideTransition( + position: Tween( + begin: const Offset(1, 0), + end: Offset.zero, + ).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut)), + child: child, + ); + }, + ), + ); + } + + /// 将 form['situationList'](若存在)转换为 List + List _situationListToStrings() { + final List cur = List.from(form['situationList'] ?? []); + if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致 + return cur.map((e) { + if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString(); + return ''; + }).toList(); + } + + // ------------ 提交入口 ------------ + Future _submit() async { + if (forbidEdit) { + Navigator.of(context).pop(); + return; + } + for (var rule in inspectorRules) { + if ((rule['name'] as String).isEmpty && + !FormUtils.hasValue(inspectedForm, rule['name'])) { + ToastUtil.showNormal(context, rule['message']); + return; + } + } + if (inspectedForm['INSPECTION_STATUS']?.toString() == '-2' && + (inspectedForm['INSPECTED_EXPLAIN']?.toString().trim().isEmpty ?? + true)) { + ToastUtil.showNormal(context, '请填写申辩说明'); + return; + } + + // 签字必填 + if (signImages.isEmpty) { + ToastUtil.showNormal(context, '请签字'); + return; + } + + // 显示加载 + LoadingDialogHelper.show(); + + inspectedForm['CREATOR'] = SessionService.instance.loginUserId; + inspectedForm['ACTION_USER'] = SessionService.instance.username; + inspectedForm['CORPINFO_ID'] = SessionService.instance.corpinfoId; + + try { + // 准备上传文件路径(兼容多种 signImgList 存法) + String filePath = signImages.first; + final resp = await ApiService.getSafePersonSignSure( + inspectedForm, + filePath, + ); + if (resp['result'] == 'success') { + Navigator.of(context).pop(); // 关闭 loading + } else { + ToastUtil.showNormal(context, '提交失败'); + } + LoadingDialogHelper.hide(); + } catch (e) { + LoadingDialogHelper.hide(); + + ToastUtil.showNormal(context, '请求失败:${e.toString()}'); + } + } + + // ========== 罚单提交方法 + Future fnSubmit(Map? ordForm) async { + if (ordForm == null) return false; + + final Map punishRules = { + 'REASON': '请填写处罚原因', + 'AMOUT': '请填写处罚金额', + 'DATE': '请选择下发处罚时间', + }; + // 校验 + for (final entry in punishRules.entries) { + final key = entry.key; + final msg = entry.value; + final val = ordForm[key]; + if (val == null || val.toString().trim().isEmpty) { + ToastUtil.showNormal(context, msg); + return false; + } + } + + final requestData = Map.from(ordForm); + requestData['CORPINFO_ID'] = SessionService.instance.corpinfoId ?? ''; + requestData['CREATOR'] = SessionService.instance.loginUserId ?? ''; + requestData['OPERATOR'] = SessionService.instance.loginUserId ?? ''; + + try { + LoadingDialogHelper.show(); + final res = await ApiService.safeCheckPunishSubmit(requestData); + LoadingDialogHelper.hide(); + if (FormUtils.hasValue(res, 'result') && res['result'] == 'success') { + return true; + } else { + final msg = + res != null + ? (res['msg'] ?? res['msaesge'] ?? res['message'] ?? '提交失败') + : '提交失败'; + ToastUtil.showNormal(context, msg); + return false; + } + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '罚单提交异常:$e'); + return false; + } + } + + /// 签字 + Future _sign() async { + final path = await Navigator.push( + context, + MaterialPageRoute(builder: (context) => MineSignPage()), + ); + if (path != null) { + final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now()); + + setState(() { + signImages = []; + signTimes = []; + signImages.add(path); + signTimes.add(now); + inspectedForm['INSPECTED_SITEUSER_SIGN_TIME'] = now; + FocusHelper.clearFocus(context); + }); + } + } + + Widget _signListWidget() { + return Column( + children: + signImages.map((path) { + return Column( + children: [ + const SizedBox(height: 10), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + child: // 用一个 ConstrainedBox 限制最大尺寸,并改为 BoxFit.contain + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 200, + maxHeight: 150, + ), + child: Image.file( + File(path), + // 改为完整显示 + fit: BoxFit.contain, + ), + ), + onTap: () { + presentOpaque( + SingleImageViewer(imageUrl: path), + context, + ); + }, + ), + Column( + children: [ + Container( + padding: const EdgeInsets.only(right: 5), + child: CustomButton( + text: 'X', + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 10), + backgroundColor: Colors.red, + onPressed: () { + setState(() { + signImages.remove(path); + }); + }, + ), + ), + const SizedBox(height: 80), + ], + ), + ], + ), + ], + ); + }).toList(), + ); + } + + Widget _mainWidget() { + return ListView( + children: [ + Column( + children: [ + SafeCheckFormView( + form: form, + isEdit: false, + onHiddenShow: (item, index) { + _openDrawer(item, index); + }, + ), + + if (!forbidEdit) + Column( + children: [ + SizedBox(height: 10), + ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ListItemFactory.createYesNoSection( + title: '被检查单位现场负责人意见:', + groupValue: + inspectedForm['INSPECTION_STATUS'] == '3' + ? true + : false, + yesLabel: '同意', + noLabel: '申辩', + isEdit: true, + isRequired: false, + horizontalPadding: 3, + verticalPadding: 0, + onChanged: (val) { + // 如果需要把选择写回 form,可以在这里 setState 更新 widget.form + setState(() { + inspectedForm['INSPECTION_STATUS'] = + val ? '3' : '-2'; + }); + }, + ), + const Divider(), + if (inspectedForm['INSPECTION_STATUS'] == '-2') + Column( + children: [ + ItemListWidget.multiLineTitleTextField( + label: '申辩说明', + isEditable: true, + isRequired: false, + hintText: '检查人意见(有异议时必填)', + onChanged: (val) { + inspectedForm['INSPECTED_EXPLAIN'] = val; + }, + ), + const Divider(), + ], + ), + Container( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ListItemFactory.headerTitle('签字:'), + CustomButton( + text: '手写签字', + height: 36, + backgroundColor: Colors.green, + onPressed: _sign, + ), + ], + ), + ), + if (signImages.isNotEmpty) + ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + if (signImages.isNotEmpty) _signListWidget(), + ], + ), + ), + ], + ), + ), + ], + ), + SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 150, + child: CustomButton( + text: !forbidEdit ? '提交' : '返回', + textStyle: TextStyle(color: Colors.white, fontSize: 17), + backgroundColor: Colors.blue, + onPressed: _submit, + ), + ), + ], + ), + ], + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: "安全检查确认", actions: []), + + body: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), + child: form.isNotEmpty ? _mainWidget() : SizedBox(), + ), + ), + ); + } +} diff --git a/lib/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart b/lib/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart index 7f86778..66fc4c2 100644 --- a/lib/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart +++ b/lib/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart @@ -1,27 +1,14 @@ -import 'dart:convert'; import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; -import 'package:qhd_prevention/customWidget/bottom_picker.dart'; -import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; -import 'package:qhd_prevention/customWidget/department_person_picker.dart'; -import 'package:qhd_prevention/customWidget/department_picker.dart'; -import 'package:qhd_prevention/customWidget/dotted_border_box.dart'; -import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/http/ApiService.dart'; -import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart'; -import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart'; -import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart'; -import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; -import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; import 'package:qhd_prevention/pages/mine/mine_sign_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -30,10 +17,12 @@ class CheckPersonDetail extends StatefulWidget { const CheckPersonDetail({ super.key, required this.INSPECTION_ID, + required this.INSPECTION_INSPECTOR_ID, required this.isEdit, }); final String INSPECTION_ID; + final String INSPECTION_INSPECTOR_ID; final bool isEdit; @override @@ -41,15 +30,18 @@ class CheckPersonDetail extends StatefulWidget { } class _CheckPersonDetailState extends State { - String msg = 'add'; bool _isEdit = false; - + bool forbidEdit = false; List signImages = []; List signTimes = []; // 签字时间列表 - - Map form = { - }; + Map inspectorForm = {}; + List> inspectorRules = [ + {'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'}, + {'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'}, + {'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'}, + ]; + Map form = {}; @override void initState() { @@ -59,7 +51,6 @@ class _CheckPersonDetailState extends State { WidgetsBinding.instance.addPostFrameCallback((_) { _getData(); }); - } Future _getData() async { @@ -71,6 +62,23 @@ class _CheckPersonDetailState extends State { if (!mounted) return; setState(() { form = result['pd'] ?? {}; + inspectorForm = { + 'INSPECTION_STATUS': '-1', + 'INSPECTION_INSPECTOR_ID':widget.INSPECTION_INSPECTOR_ID, // 安全检查人员主键ID + 'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID + 'INSPECTION_USER_ID': SessionService.instance.loginUserId, // 检查人 + 'INSPECTION_USER_OPINION': '', // 检查人意见(有异议时必填) + 'INSPECTION_USER_SIGN_IMG': '', // 检查人签字 + 'INSPECTION_USER_SIGN_TIME': '', // 检查人签字时间 + }; + List inspectorVerifyList = form['inspectorVerifyList'] ?? []; + for (int i = 0; i < inspectorVerifyList.length; i++) { + dynamic item = inspectorVerifyList[i]; + if (SessionService.instance.loginUserId == + (item['INSPECTION_USER_ID'] ?? '')) { + forbidEdit = true; + } + } }); } catch (e, st) { print('加载单条数据失败: $e\n$st'); @@ -80,7 +88,6 @@ class _CheckPersonDetailState extends State { } } - Future _openDrawer(Map hiddenForm, int index) async { try { final result = await openCustomDrawer( @@ -151,25 +158,56 @@ class _CheckPersonDetailState extends State { }).toList(); } - - - // ------------ 提交入口 ------------ - Future _submit() async { Future _sign() async { - final path = await Navigator.push( - context, - MaterialPageRoute(builder: (context) => MineSignPage()), - ); - if (path != null) { - final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now()); - - setState(() { - signImages.add(path); - signTimes.add(now); - FocusHelper.clearFocus(context); - }); + Future _submit() async { + if (forbidEdit) { + Navigator.of(context).pop(); + return; } - } + for (var rule in inspectorRules) { + if ((rule['name'] as String).isEmpty && !FormUtils.hasValue(inspectorForm, rule['name'])) { + ToastUtil.showNormal(context, rule['message']); + return; + } + } + if (inspectorForm['INSPECTION_STATUS']?.toString() == '-1' && + (inspectorForm['INSPECTION_USER_OPINION']?.toString().trim().isEmpty ?? true)) { + ToastUtil.showNormal(context, '核实结果有异议时必填'); + return; + } + + // 签字必填 + if (signImages.isEmpty) { + ToastUtil.showNormal(context, '请签字'); + return; + } + + // 显示加载 + LoadingDialogHelper.show(); + + inspectorForm['OPERATOR'] = SessionService.instance.loginUserId; + inspectorForm['ACTION_USER'] = SessionService.instance.username; + + try { + // 准备上传文件路径(兼容多种 signImgList 存法) + String filePath = signImages.first; + final resp = await ApiService.getSafePersonCheck(inspectorForm, filePath); + if (resp['result'] == 'success') { + Navigator.of(context).pop(); // 关闭 loading + }else { + ToastUtil.showNormal(context, '提交失败'); + } + LoadingDialogHelper.hide(); + + + } catch (e) { + LoadingDialogHelper.hide(); + + ToastUtil.showNormal(context, '请求失败:${e.toString()}'); + } + + + } // ========== 罚单提交方法 @@ -228,115 +266,157 @@ class _CheckPersonDetailState extends State { final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now()); setState(() { + signImages = []; + signTimes = []; signImages.add(path); signTimes.add(now); FocusHelper.clearFocus(context); }); } } + Widget _signListWidget() { return Column( children: - signImages.map((path) { - return Column( - children: [ - const SizedBox(height: 10), - const Divider(), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + signImages.map((path) { + return Column( children: [ - GestureDetector( - child: // 用一个 ConstrainedBox 限制最大尺寸,并改为 BoxFit.contain - ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 200, - maxHeight: 150, - ), - child: Image.file( - File(path), - // 改为完整显示 - fit: BoxFit.contain, - ), - ), - onTap: () { - presentOpaque( - SingleImageViewer(imageUrl: path), - context, - ); - }, - ), - Column( + const SizedBox(height: 10), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Container( - padding: const EdgeInsets.only(right: 5), - child: CustomButton( - text: 'X', - height: 30, - padding: const EdgeInsets.symmetric(horizontal: 10), - backgroundColor: Colors.red, - onPressed: () { - setState(() { - signImages.remove(path); - }); - }, + GestureDetector( + child: // 用一个 ConstrainedBox 限制最大尺寸,并改为 BoxFit.contain + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 200, + maxHeight: 150, + ), + child: Image.file( + File(path), + // 改为完整显示 + fit: BoxFit.contain, + ), ), + onTap: () { + presentOpaque( + SingleImageViewer(imageUrl: path), + context, + ); + }, + ), + Column( + children: [ + Container( + padding: const EdgeInsets.only(right: 5), + child: CustomButton( + text: 'X', + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 10), + backgroundColor: Colors.red, + onPressed: () { + setState(() { + signImages.remove(path); + }); + }, + ), + ), + const SizedBox(height: 80), + ], ), - const SizedBox(height: 80), ], ), ], - ), - ], - ); - }).toList(), + ); + }).toList(), ); } + Widget _mainWidget() { return ListView( children: [ Column( children: [ - SafeCheckFormView(form: form, isEdit: false, onHiddenShow: (item, index) { + SafeCheckFormView( + form: form, + isEdit: false, + onHiddenShow: (item, index) { + _openDrawer(item, index); - }), - ItemListWidget.itemContainer( - horizontal: 0, - Column( - children: [ - - - - - if (signImages.isNotEmpty) _signListWidget(), - - ], - ), + }, ), - SizedBox(height: 20), + + if (!forbidEdit) + ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ListItemFactory.createYesNoSection( + title: '核实结果:', + groupValue: inspectorForm['INSPECTION_STATUS'] == '1' ? true : false, + yesLabel: '同意', + noLabel: '不同意', + isEdit: true, + isRequired: false, + horizontalPadding: 5, + verticalPadding: 0, + onChanged: (val) { + // 如果需要把选择写回 form,可以在这里 setState 更新 widget.form + setState(() { + inspectorForm['INSPECTION_STATUS'] = val ? '1' : '-1'; + }); + }, + ), + if (inspectorForm['INSPECTION_STATUS'] == '-1') + Column( + children: [ + const Divider(), + ItemListWidget.multiLineTitleTextField( + label: '核实意见', + isEditable: true, + isRequired: false, + hintText: '检查人意见(有异议时必填)', + onChanged: (val) { + inspectorForm['INSPECTION_USER_OPINION'] = val; + }, + ), + ], + ), + + const Divider(), + Container( + padding: EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ListItemFactory.headerTitle('签字:'), + CustomButton( + text: '手写签字', + height: 36, + backgroundColor: Colors.green, + onPressed: _sign, + ), + ], + ), + ), + if (signImages.isNotEmpty) + ItemListWidget.itemContainer( + horizontal: 0, + Column(children: [if (signImages.isNotEmpty) _signListWidget()]), + ), + ], + ), + ), + SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (_isEdit) - SizedBox( - width: 150, - child: CustomButton( - text: '返回', - textStyle: TextStyle( - color: Colors.white, - fontSize: 17, - ), - backgroundColor: Colors.black38, - onPressed: () => Navigator.pop(context), - ), - ), SizedBox( width: 150, child: CustomButton( - text: _isEdit ? '提交' : '返回', - textStyle: TextStyle( - color: Colors.white, - fontSize: 17, - ), + text: !forbidEdit ? '提交' : '返回', + textStyle: TextStyle(color: Colors.white, fontSize: 17), backgroundColor: Colors.blue, onPressed: _submit, ), @@ -348,18 +428,16 @@ class _CheckPersonDetailState extends State { ], ); } + @override Widget build(BuildContext context) { return Scaffold( - appBar: MyAppbar(title: "安全检查发起", actions: []), + appBar: MyAppbar(title: "安全检查确认", actions: []), body: SafeArea( child: Padding( padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), - child: - form.isNotEmpty - ? _mainWidget() - : SizedBox(), + child: form.isNotEmpty ? _mainWidget() : SizedBox(), ), ), ); diff --git a/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart b/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart index 6f3238a..74ca354 100644 --- a/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart +++ b/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart @@ -82,6 +82,7 @@ class _CheckPersonListPageState extends State { try { final data = { 'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '', + 'INSPECTION_USER_ID': SessionService.instance.loginUserId, 'KEYWORDS': searchKeywords, }; final url = @@ -111,39 +112,9 @@ class _CheckPersonListPageState extends State { _fetchData(); } - /// 申请 - void _handleApply() { - // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context); - } - - /// 打开流程图 - Future _openFlowDrawer(String ID) async { - try { - final response = await ApiService.safeCheckFlowList(ID); - final List? newFlow = response['varList']; - if (newFlow == null || newFlow.isEmpty) { - ToastUtil.showNormal(context, '暂无流程图数据'); - return; - } - - setState(() { - flowList = List>.from(newFlow); - }); - Future.microtask(() { - _scaffoldKey.currentState?.openEndDrawer(); - }); - } catch (e) { - print('Error fetching flow data: $e'); - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); - } - } - void _goToDetail(Map item) async { - pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context); + await pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'],isEdit: false), context); setState(() { _fetchData(); @@ -244,7 +215,7 @@ class _CheckPersonListPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"), + Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis), ], ), const SizedBox(height: 8), @@ -370,16 +341,7 @@ class _CheckPersonListPageState extends State { key: _scaffoldKey, appBar: MyAppbar( title: '${widget.flow}', - actions: [ - TextButton( - onPressed: _handleApply, - child: const Text( - '发起', - style: TextStyle(color: Colors.white, fontSize: 17), - ), - ), - - ], + actions: [], ), endDrawer: Drawer( child: SafeArea( diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart new file mode 100644 index 0000000..bc2672e --- /dev/null +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; + +class SafecheckAssignmentDetailPage extends StatefulWidget { + const SafecheckAssignmentDetailPage({super.key}); + + @override + State createState() => _SafecheckAssignmentDetailPageState(); +} + +class _SafecheckAssignmentDetailPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: '安全检查指派'), + body: SafeArea(child: SizedBox()), + ); + } +} diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart new file mode 100644 index 0000000..9d2978d --- /dev/null +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart @@ -0,0 +1,357 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart'; +import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; + +class SafecheckAssignmentList extends StatefulWidget { + final String INSPECTION_ID; + + const SafecheckAssignmentList({Key? key, required this.INSPECTION_ID}) + : super(key: key); + + @override + _SafecheckAssignmentListState createState() => _SafecheckAssignmentListState(); +} + +class _SafecheckAssignmentListState extends State { + // Data and state variables + List list = []; + int currentPage = 1; + int rows = 10; + int totalPage = 1; + bool isLoading = false; + final List> hiddenStatusList = [ + {'ID': '', 'NAME': '请选择'}, + {'ID': '1', 'NAME': '待整改'}, + {'ID': '2', 'NAME': '待验收'}, + {'ID': '3', 'NAME': '已整改'}, + {'ID': '4', 'NAME': '已验收'}, + {'ID': '5', 'NAME': '忽略隐患'}, + {'ID': '6', 'NAME': '重大隐患'}, + {'ID': '7', 'NAME': '待处理的特殊申请隐患'}, + {'ID': '8', 'NAME': '已处理的特殊隐患'}, + {'ID': '10', 'NAME': '验收打回'}, + {'ID': '11', 'NAME': '分公司安委会办公室副主任核定'}, + {'ID': '12', 'NAME': '分公司安委会办公室副主任核定'}, + {'ID': '13', 'NAME': '港股分公司安委会办公室副主任核定、重大隐患待整改'}, + {'ID': '13', 'NAME': '重大隐患待验收'}, + {'ID': '15', 'NAME': '重大隐患已归档'}, + {'ID': '16', 'NAME': '确认打回'}, + {'ID': '100','NAME': '安全检查暂存的隐患'}, + {'ID': '100','NAME': '检查已归档,待指派'}, + {'ID': '101','NAME': '待指派整改人'}, + {'ID': '-1', 'NAME': '已过期'}, + {'ID': '-2', 'NAME': '待确认'}, + ]; + + List> flowList = []; + final GlobalKey _scaffoldKey = GlobalKey(); + + final ScrollController _scrollController = ScrollController(); + + @override + void initState() { + super.initState(); + _fetchData(); + _scrollController.addListener(_onScroll); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + void _onScroll() { + if (_scrollController.position.pixels >= + _scrollController.position.maxScrollExtent && + !isLoading) { + if (currentPage < totalPage) { + currentPage++; + _fetchData(); + } + } + } + String? translateHidden(String id) { + final match = hiddenStatusList.firstWhere( + (item) => item['ID'] == id, + orElse: () => {}, + ); + return match['NAME']; // 如果 orElse 返回 {},这里会是 null(安全) + } + Future _fetchData() async { + if (isLoading) return; + setState(() => isLoading = true); + + try { + + final response = await ApiService.getSafeCheckDangerList(widget.INSPECTION_ID); + + setState(() { + if (currentPage == 1) { + list = response['varList']; + } else { + list.addAll(response['varList']); + } + Map page = response['page']; + totalPage = page['totalPage'] ?? 1; + isLoading = false; + }); + } catch (e) { + print('Error fetching data: $e'); + setState(() => isLoading = false); + } + } + + +//查看 + void _goToDetail(Map item) async { + + // await pushPage(CheckPersonDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'],isEdit: false), context); + // + // setState(() { + // _fetchData(); + // }); + + } + /// 指派 + void _goToAssign(Map item) async { + + // await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); + _fetchData(); + + + } + /// 验收 + void _goAccept(Map item) async { + + // await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); + _fetchData(); + + + } + + Widget _buildFlowStepItem({ + required Map item, + required bool isFirst, + required bool isLast, + }) { + bool status = item['active'] == item['order']; + // 依据状态设色 + final Color dotColor = status ? Colors.blue :Colors.grey; + final Color textColor = status ? Colors.blue :Colors.black54; + + return ListTile( + visualDensity: VisualDensity(vertical: -4), + + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + leading: Container( + width: 24, + alignment: Alignment.center, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + // 上方线段或占位 + isFirst + ? SizedBox(height: 6 + 5) + : Expanded(child: Container(width: 1, color: Colors.grey[300])), + // 圆点 + CircleAvatar(radius: 6, backgroundColor: dotColor), + // 下方线段或占位 + isLast + ? SizedBox(height: 6 + 5) + : Expanded(child: Container(width: 1, color: Colors.grey[300])), + ], + ), + ), + title: Text( + item['title'] ?? '', + style: TextStyle(color: textColor, fontSize: 15), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (item['desc'] != null) + Text( + item['desc'], + style: TextStyle(color: textColor, fontSize: 13), + ), + ], + ), + ); + } + + + Widget _buildListItem(Map item) { + return Card( + color: Colors.white, + margin: const EdgeInsets.all(8.0), + child: InkWell( + onTap: () => _goToDetail(item), + child: Padding( + padding: const EdgeInsets.all(12.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + item['HIDDENDESCR'] ?? '', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), + ), + ], + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("隐患状态: ${translateHidden(item['HIDDEN_STATUS'] ?? '')}"), + ], + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("隐患描述: ${item['HIDDENDESCR'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis), + ], + ), + const SizedBox(height: 8), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(), + Row( + spacing: 5, + children: [ + CustomButton( + text: '查看', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.green, + onPressed: () => _goToDetail(item), + ), + if (item['INSPECTED_SITEUSER_ID'] == SessionService.instance.loginUserId && item['HIDDEN_STATUS'] == '101') + CustomButton( + text: '指派', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.blue, + onPressed: () => _goToAssign(item), + ), + if (item['CREATOR'] == SessionService.instance.loginUserId && + (item['HIDDEN_STATUS'] == '4' || item['HIDDEN_STATUS'] == '8') && + (item['HIDDEN_STATUS'] == '4' || item['HIDDEN_STATUS'] == '8') && + FormUtils.hasValue(item, 'FINAL_CHECK')) + CustomButton( + text: '验收', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.blue, + onPressed: () => _goAccept(item), + ), + ], + ) + + ], + ), + + ], + ), + ), + ), + ); + } + + Widget _buildListContent() { + if (isLoading && list.isEmpty) { + // 初始加载时显示居中的加载指示器 + return Center(child: CircularProgressIndicator()); + } else if (list.isEmpty) { + // 没有数据 + return NoDataWidget.show(); + } else { + // 有数据或加载更多 + return ListView.builder( + padding: EdgeInsets.zero, + + controller: _scrollController, + itemCount: list.length + (isLoading ? 1 : 0), + itemBuilder: (context, index) { + if (index >= list.length) { + // 加载更多时在列表底部显示加载指示器 + return Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0), + child: Center(child: CircularProgressIndicator()), + ); + } + return _buildListItem(list[index]); + }, + ); + } + } + + @override + Widget build(BuildContext context) { + final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1); + + return Scaffold( + key: _scaffoldKey, + appBar: MyAppbar( + title: '发现问题', + actions: [], + ), + endDrawer: Drawer( + child: SafeArea( + child: + flowList.isEmpty + ? Center(child: Text('暂无流程图数据')) + : ListView.builder( + padding: const EdgeInsets.symmetric(vertical: 16), + itemCount: flowList.length + 1, // +1 用来放标题 + itemBuilder: (context, i) { + if (i == 0) { + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + child: Text( + '查看流程图', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + ); + } + final idx = i - 1; + final item = flowList[idx]; + final bool isFirst = idx == 0; + final bool isLast = idx == flowList.length - 1; + + return _buildFlowStepItem( + item: item, + isFirst: isFirst, + isLast: isLast, + ); + }, + ), + ), + ), + + body: SafeArea(child: Expanded(child: _buildListContent()),), + ); + } +} diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_start_list_page.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_danger_list_page.dart similarity index 78% rename from lib/pages/home/SafeCheck/DangeCheck/safeCheck_start_list_page.dart rename to lib/pages/home/SafeCheck/DangeCheck/safeCheck_danger_list_page.dart index 85fdf8a..1f385ac 100644 --- a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_start_list_page.dart +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_danger_list_page.dart @@ -1,5 +1,9 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safecheck_sign_detail.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_detail.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -9,17 +13,17 @@ import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; import 'package:qhd_prevention/http/ApiService.dart'; -class SafecheckStartListPage extends StatefulWidget { +class SafecheckDangerListPage extends StatefulWidget { final String flow; - const SafecheckStartListPage({Key? key, required this.flow}) + const SafecheckDangerListPage({Key? key, required this.flow}) : super(key: key); @override - _SafecheckStartListPageState createState() => _SafecheckStartListPageState(); + _SafecheckDangerListPageState createState() => _SafecheckDangerListPageState(); } -class _SafecheckStartListPageState extends State { +class _SafecheckDangerListPageState extends State { // Data and state variables List list = []; int currentPage = 1; @@ -27,18 +31,14 @@ class _SafecheckStartListPageState extends State { int totalPage = 1; bool isLoading = false; List stepList = [ - {'id': '', 'name': '请选择'}, - {'id': '0', 'name': '待检查人核实'}, - {'id': '1', 'name': '检查人核实中'}, - {'id': '2', 'name': '待被检查人确认'}, + {'id': '3-7', 'name': '请选择'}, {'id': '3', 'name': '待指派'}, {'id': '4', 'name': '指派中'}, {'id': '5', 'name': '指派完成'}, {'id': '6', 'name': '检查待验收'}, {'id': '7', 'name': '检查已验收'}, {'id': '8', 'name': '已归档'}, - {'id': '-1', 'name': '检查人核实打回'}, - {'id': '-2', 'name': '被检查人申辩'}, + ]; final TextEditingController _searchController = TextEditingController(); @@ -81,10 +81,11 @@ class _SafecheckStartListPageState extends State { try { final data = { 'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '', + 'ARCHIVE_USER_ID': SessionService.instance.loginUserId, 'KEYWORDS': searchKeywords, }; final url = - '/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage'; + '/app/safetyenvironmental/checkList?showCount=-1¤tPage=$currentPage'; final response = await ApiService.getSafeCheckSearchList(data, url); setState(() { @@ -109,44 +110,28 @@ class _SafecheckStartListPageState extends State { list.clear(); _fetchData(); } - - /// 申请 - void _handleApply() { - // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context); - } - - /// 打开流程图 - Future _openFlowDrawer(String ID) async { - try { - final response = await ApiService.safeCheckFlowList(ID); - final List? newFlow = response['varList']; - if (newFlow == null || newFlow.isEmpty) { - ToastUtil.showNormal(context, '暂无流程图数据'); - return; - } - - setState(() { - flowList = List>.from(newFlow); - }); - Future.microtask(() { - _scaffoldKey.currentState?.openEndDrawer(); - }); - } catch (e) { - print('Error fetching flow data: $e'); - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); - } - } - + /// 查看 void _goToDetail(Map item) async { - pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context); + await pushPage(SafecheckDangerDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); + _fetchData(); + + + } + /// 指派 + void _goToAssign(Map item) async { + + await pushPage(SafecheckAssignmentList(INSPECTION_ID: item['INSPECTION_ID'] ?? ''), context); + _fetchData(); + + + } + /// 验收 + void _goAccept(Map item) async { + + // await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); + _fetchData(); - setState(() { - _fetchData(); - }); } @@ -243,7 +228,7 @@ class _SafecheckStartListPageState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"), + Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}", maxLines: 5, overflow: TextOverflow.ellipsis), ], ), const SizedBox(height: 8), @@ -274,19 +259,43 @@ class _SafecheckStartListPageState extends State { ], ), const SizedBox(height: 8), - Row( - children: [ - CustomButton( - text: '流程图', - height: 35, - padding: EdgeInsets.symmetric(horizontal: 12), - margin: EdgeInsets.only(left: 0), - backgroundColor: Colors.blue, - onPressed: () => _openFlowDrawer(item['INSPECTION_ID']), - ), - SizedBox(width: 1), - ], - ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + SizedBox(), + Row( + spacing: 5, + children: [ + CustomButton( + text: '查看', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.green, + onPressed: () => _goToDetail(item), + ), + if ((item['INSPECTION_STATUS'] == '3' || item['INSPECTION_STATUS'] == '4') && item['INSPECTED_SITEUSER_ID'] == SessionService.instance.loginUserId) + CustomButton( + text: '指派', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.blue, + onPressed: () => _goToAssign(item), + ), + if ((item['INSPECTION_STATUS'] == '5' || item['INSPECTION_STATUS'] == '6' || item['INSPECTION_STATUS'] == '7') && item['checkout'].toString() == '1') + CustomButton( + text: '验收', + height: 32, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.blue, + onPressed: () => _goAccept(item), + ), + ], + ) + ], + ), ], ), ), @@ -367,16 +376,7 @@ class _SafecheckStartListPageState extends State { key: _scaffoldKey, appBar: MyAppbar( title: '${widget.flow}', - actions: [ - TextButton( - onPressed: _handleApply, - child: const Text( - '发起', - style: TextStyle(color: Colors.white, fontSize: 17), - ), - ), - - ], + actions: [], ), endDrawer: Drawer( child: SafeArea( diff --git a/lib/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart b/lib/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart new file mode 100644 index 0000000..569bf38 --- /dev/null +++ b/lib/pages/home/SafeCheck/DangeCheck/safecheck_danger_detail.dart @@ -0,0 +1,311 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker.dart'; +import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/dotted_border_box.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart'; +import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safe_drawer_page.dart'; +import 'package:qhd_prevention/pages/app/Danger_paicha/quick_report_page.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/SafeCheckFormView.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart'; +import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; +import 'package:qhd_prevention/pages/mine/mine_sign_page.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; + +class SafecheckDangerDetail extends StatefulWidget { + const SafecheckDangerDetail({ + super.key, + required this.INSPECTION_ID, + required this.INSPECTION_INSPECTOR_ID, + required this.isEdit, + }); + + final String INSPECTION_ID; + final String INSPECTION_INSPECTOR_ID; + final bool isEdit; + + @override + State createState() => _SafecheckDangerDetailState(); +} + +class _SafecheckDangerDetailState extends State { + String msg = 'add'; + bool _isEdit = false; + List signImages = []; + List signTimes = []; // 签字时间列表 + Map inspectedForm = {}; + List> inspectorRules = [ + {'name': 'INSPECTION_STATUS', 'message': '核实结果不能为空'}, + {'name': 'INSPECTION_ID', 'message': '安全检查ID不能为空'}, + {'name': 'INSPECTION_USER_ID', 'message': '检查人不能为空'}, + ]; + Map form = {}; + + @override + void initState() { + super.initState(); + _isEdit = widget.isEdit; + + WidgetsBinding.instance.addPostFrameCallback((_) { + _getData(); + }); + } + + Future _getData() async { + try { + final result = await ApiService.getSafeCheckSureList( + widget.INSPECTION_ID, + ); + // 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错 + if (!mounted) return; + setState(() { + form = result['pd'] ?? {}; + inspectedForm = { + 'INSPECTION_EXPLAIN_ID': '', // 安全检查人员主键ID + 'INSPECTION_STATUS': '3', + 'INSPECTION_ID': widget.INSPECTION_ID, // 安全检查ID + 'INSPECTED_EXPLAIN': '', // 申辩内容 + 'INSPECTED_EXPLAIN_FILENAME': '', // 申辩附件名称 + 'INSPECTED_SITEUSER_SIGN_IMG': '', // 被检查单位现场负责人签字 + 'INSPECTED_SITEUSER_SIGN_TIME': '', + }; + + }); + } catch (e, st) { + print('加载单条数据失败: $e\n$st'); + if (mounted) { + ToastUtil.showNormal(context, '加载数据失败:$e'); + } + } + } + + Future _openDrawer(Map hiddenForm, int index) async { + try { + final result = await openCustomDrawer( + context, + SafeCheckDrawerPage( + initialHidden: hiddenForm, + editType: + _isEdit + ? (index < 0 ? SafeCheckEditType.add : SafeCheckEditType.edit) + : SafeCheckEditType.see, + toCheckUnitList: [], + ), + ); + + if (result != null && mounted) { + setState(() { + if (index < 0) { + // 新增 + form['hiddenList'].add(result); + print(form); + } else { + // 修改 + form['hiddenList'][index] = result; + } + }); + } + } catch (e) { + print("打开抽屉失败: $e"); + ToastUtil.showNormal(context, "打开抽屉失败"); + } + } + + Future openCustomDrawer(BuildContext context, Widget child) { + return Navigator.of(context).push( + PageRouteBuilder( + opaque: false, + barrierDismissible: true, + barrierColor: Colors.black54, + pageBuilder: (_, __, ___) { + return Align( + alignment: Alignment.centerRight, + child: FractionallySizedBox( + widthFactor: 4 / 5, + child: Material(color: Colors.white, child: child), + ), + ); + }, + transitionsBuilder: (_, anim, __, child) { + return SlideTransition( + position: Tween( + begin: const Offset(1, 0), + end: Offset.zero, + ).animate(CurvedAnimation(parent: anim, curve: Curves.easeOut)), + child: child, + ); + }, + ), + ); + } + + /// 将 form['situationList'](若存在)转换为 List + List _situationListToStrings() { + final List cur = List.from(form['situationList'] ?? []); + if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致 + return cur.map((e) { + if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString(); + return ''; + }).toList(); + } + + Widget _signListWidget() { + return Column( + children: + signImages.map((path) { + return Column( + children: [ + const SizedBox(height: 10), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + child: // 用一个 ConstrainedBox 限制最大尺寸,并改为 BoxFit.contain + ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: 200, + maxHeight: 150, + ), + child: Image.file( + File(path), + // 改为完整显示 + fit: BoxFit.contain, + ), + ), + onTap: () { + presentOpaque( + SingleImageViewer(imageUrl: path), + context, + ); + }, + ), + Column( + children: [ + Container( + padding: const EdgeInsets.only(right: 5), + child: CustomButton( + text: 'X', + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 10), + backgroundColor: Colors.red, + onPressed: () { + setState(() { + signImages.remove(path); + }); + }, + ), + ), + const SizedBox(height: 80), + ], + ), + ], + ), + ], + ); + }).toList(), + ); + } + + Widget _mainWidget() { + return ListView( + children: [ + Column( + children: [ + SafeCheckFormView( + form: form, + isEdit: false, + onHiddenShow: (item, index) { + _openDrawer(item, index); + }, + ), + + Column( + children: [ + SizedBox(height: 10), + ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ItemListWidget.singleLineTitleText( + label: '被检查单位现场负责人意见:', + isEditable: false, + text: FormUtils.hasValue(form, 'INSPECTED_EXPLAIN') ? '申辩' : '同意', + ), + const Divider(), + if (FormUtils.hasValue(form, 'INSPECTED_EXPLAIN')) + Column( + children: [ + ItemListWidget.multiLineTitleTextField( + label: '申辩说明', + isEditable: false, + text: form['INSPECTED_EXPLAIN'] ?? '', + ), + const Divider(), + + ], + ), + ItemListWidget.OneRowImageTitle( + label: '被检查单位现场负责人签字', + text: form['INSPECTED_SITEUSER_SIGN_TIME'], + onTapCallBack: (path) { + presentOpaque(SingleImageViewer(imageUrl: path), context); + }, + imgPath: form['INSPECTED_SITEUSER_SIGN_IMG'], + ), + ], + ), + ), + ], + ), + SizedBox(height: 10), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 150, + child: CustomButton( + text: '返回', + textStyle: TextStyle(color: Colors.white, fontSize: 17), + backgroundColor: Colors.blue, + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ), + ], + ), + ], + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: "安全检查详情", actions: []), + + body: SafeArea( + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 12), + child: form.isNotEmpty ? _mainWidget() : SizedBox(), + ), + ), + ); + } +} diff --git a/lib/pages/home/SafeCheck/Record/safeCheck_start_list_page.dart b/lib/pages/home/SafeCheck/Record/safeCheck_start_list_page.dart deleted file mode 100644 index 85fdf8a..0000000 --- a/lib/pages/home/SafeCheck/Record/safeCheck_start_list_page.dart +++ /dev/null @@ -1,473 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:qhd_prevention/customWidget/toast_util.dart'; -import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart'; -import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; -import 'package:qhd_prevention/pages/my_appbar.dart'; -import 'package:qhd_prevention/tools/tools.dart'; -import 'package:qhd_prevention/customWidget/bottom_picker.dart'; -import 'package:qhd_prevention/customWidget/custom_button.dart'; -import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; -import 'package:qhd_prevention/http/ApiService.dart'; - -class SafecheckStartListPage extends StatefulWidget { - final String flow; - - const SafecheckStartListPage({Key? key, required this.flow}) - : super(key: key); - - @override - _SafecheckStartListPageState createState() => _SafecheckStartListPageState(); -} - -class _SafecheckStartListPageState extends State { - // Data and state variables - List list = []; - int currentPage = 1; - int rows = 10; - int totalPage = 1; - bool isLoading = false; - List stepList = [ - {'id': '', 'name': '请选择'}, - {'id': '0', 'name': '待检查人核实'}, - {'id': '1', 'name': '检查人核实中'}, - {'id': '2', 'name': '待被检查人确认'}, - {'id': '3', 'name': '待指派'}, - {'id': '4', 'name': '指派中'}, - {'id': '5', 'name': '指派完成'}, - {'id': '6', 'name': '检查待验收'}, - {'id': '7', 'name': '检查已验收'}, - {'id': '8', 'name': '已归档'}, - {'id': '-1', 'name': '检查人核实打回'}, - {'id': '-2', 'name': '被检查人申辩'}, - ]; - final TextEditingController _searchController = TextEditingController(); - - int sindex = 0; - String searchKeywords = ''; - - List> flowList = []; - final GlobalKey _scaffoldKey = GlobalKey(); - - final ScrollController _scrollController = ScrollController(); - - @override - void initState() { - super.initState(); - _fetchData(); - _scrollController.addListener(_onScroll); - } - - @override - void dispose() { - _scrollController.dispose(); - super.dispose(); - } - - void _onScroll() { - if (_scrollController.position.pixels >= - _scrollController.position.maxScrollExtent && - !isLoading) { - if (currentPage < totalPage) { - currentPage++; - _fetchData(); - } - } - } - - Future _fetchData() async { - if (isLoading) return; - setState(() => isLoading = true); - - try { - final data = { - 'INSPECTION_STATUS': sindex > 0 ? stepList[sindex]['id'] : '', - 'KEYWORDS': searchKeywords, - }; - final url = - '/app/safetyenvironmental/list?showCount=-1¤tPage=$currentPage'; - final response = await ApiService.getSafeCheckSearchList(data, url); - - setState(() { - if (currentPage == 1) { - list = response['varList']; - } else { - list.addAll(response['varList']); - } - Map page = response['page']; - totalPage = page['totalPage'] ?? 1; - isLoading = false; - }); - } catch (e) { - print('Error fetching data: $e'); - setState(() => isLoading = false); - } - } - - void _search() { - searchKeywords = _searchController.text.trim(); - currentPage = 1; - list.clear(); - _fetchData(); - } - - /// 申请 - void _handleApply() { - // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context); - } - - /// 打开流程图 - Future _openFlowDrawer(String ID) async { - try { - final response = await ApiService.safeCheckFlowList(ID); - final List? newFlow = response['varList']; - if (newFlow == null || newFlow.isEmpty) { - ToastUtil.showNormal(context, '暂无流程图数据'); - return; - } - - setState(() { - flowList = List>.from(newFlow); - }); - Future.microtask(() { - _scaffoldKey.currentState?.openEndDrawer(); - }); - } catch (e) { - print('Error fetching flow data: $e'); - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); - } - } - - void _goToDetail(Map item) async { - - pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context); - - setState(() { - _fetchData(); - }); - - } - - Widget _buildFlowStepItem({ - required Map item, - required bool isFirst, - required bool isLast, - }) { - bool status = item['active'] == item['order']; - // 依据状态设色 - final Color dotColor = status ? Colors.blue :Colors.grey; - final Color textColor = status ? Colors.blue :Colors.black54; - - return ListTile( - visualDensity: VisualDensity(vertical: -4), - - contentPadding: const EdgeInsets.symmetric(horizontal: 16), - leading: Container( - width: 24, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - // 上方线段或占位 - isFirst - ? SizedBox(height: 6 + 5) - : Expanded(child: Container(width: 1, color: Colors.grey[300])), - // 圆点 - CircleAvatar(radius: 6, backgroundColor: dotColor), - // 下方线段或占位 - isLast - ? SizedBox(height: 6 + 5) - : Expanded(child: Container(width: 1, color: Colors.grey[300])), - ], - ), - ), - title: Text( - item['title'] ?? '', - style: TextStyle(color: textColor, fontSize: 15), - ), - subtitle: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (item['desc'] != null) - Text( - item['desc'], - style: TextStyle(color: textColor, fontSize: 13), - ), - ], - ), - ); - } - - String _checkStatusWithId(String id) { - for (Map item in stepList) { - if (item['id'] == id) { - return item['name']; - } - } - return ''; - } - - Widget _buildListItem(Map item) { - return Card( - color: Colors.white, - margin: const EdgeInsets.all(8.0), - child: InkWell( - onTap: () => _goToDetail(item), - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "安全检查记录", - style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), - ), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "检查状态: ${_checkStatusWithId(item['INSPECTION_STATUS'].toString())}", - ), - Text("检查类型: ${item['INSPECTION_TYPE_NAME'] ?? ''}"), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("检查人: ${item['INSPECTION_USER_NAME'] ?? ''}"), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "检查发起人: ${item['INSPECTION_ORIGINATOR_NAME'] ?? ''}", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("被检查人: ${item['INSPECTED_SITEUSER_NAME'] ?? ''}"), - ], - ), - const SizedBox(height: 8), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - "检查时间: ${item['INSPECTION_TIME_START'] ?? ''}至${item['INSPECTION_TIME_END'] ?? ''}", - ), - ], - ), - const SizedBox(height: 8), - Row( - children: [ - CustomButton( - text: '流程图', - height: 35, - padding: EdgeInsets.symmetric(horizontal: 12), - margin: EdgeInsets.only(left: 0), - backgroundColor: Colors.blue, - onPressed: () => _openFlowDrawer(item['INSPECTION_ID']), - ), - SizedBox(width: 1), - ], - ), - ], - ), - ), - ), - ); - } - - // 显示底部选择器 - Future _showStepPicker() async { - if (stepList.isEmpty) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...'))); - if (stepList.isEmpty) { - ScaffoldMessenger.of( - context, - ).showSnackBar(SnackBar(content: Text('无法加载步骤数据'))); - return; - } - } - - // 创建选项列表 - final options = stepList.map((e) => e['name'] as String).toList(); - - // 显示底部选择器 - final choice = await BottomPicker.show( - context, - items: options, - itemBuilder: (item) => Text(item, textAlign: TextAlign.center), - initialIndex: sindex, - ); - - if (choice != null) { - // 找到选择的索引 - final newIndex = options.indexOf(choice); - if (newIndex != -1) { - setState(() { - sindex = newIndex; - }); - _search(); - } - } - } - - Widget _buildListContent() { - if (isLoading && list.isEmpty) { - // 初始加载时显示居中的加载指示器 - return Center(child: CircularProgressIndicator()); - } else if (list.isEmpty) { - // 没有数据 - return NoDataWidget.show(); - } else { - // 有数据或加载更多 - return ListView.builder( - padding: EdgeInsets.zero, - - controller: _scrollController, - itemCount: list.length + (isLoading ? 1 : 0), - itemBuilder: (context, index) { - if (index >= list.length) { - // 加载更多时在列表底部显示加载指示器 - return Padding( - padding: const EdgeInsets.symmetric(vertical: 16.0), - child: Center(child: CircularProgressIndicator()), - ); - } - return _buildListItem(list[index]); - }, - ); - } - } - - @override - Widget build(BuildContext context) { - final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1); - - return Scaffold( - key: _scaffoldKey, - appBar: MyAppbar( - title: '${widget.flow}', - actions: [ - TextButton( - onPressed: _handleApply, - child: const Text( - '发起', - style: TextStyle(color: Colors.white, fontSize: 17), - ), - ), - - ], - ), - endDrawer: Drawer( - child: SafeArea( - child: - flowList.isEmpty - ? Center(child: Text('暂无流程图数据')) - : ListView.builder( - padding: const EdgeInsets.symmetric(vertical: 16), - itemCount: flowList.length + 1, // +1 用来放标题 - itemBuilder: (context, i) { - if (i == 0) { - return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - child: Text( - '查看流程图', - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.bold, - ), - ), - ); - } - final idx = i - 1; - final item = flowList[idx]; - final bool isFirst = idx == 0; - final bool isLast = idx == flowList.length - 1; - - return _buildFlowStepItem( - item: item, - isFirst: isFirst, - isLast: isLast, - ); - }, - ), - ), - ), - - body: SafeArea(child: Column( - children: [ - // Filter bar - Container( - color: Colors.white, - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8), - child: Row( - children: [ - // 底部弹窗选择器 - SizedBox( - width: 65, - child: TextButton( - onPressed: _showStepPicker, - style: TextButton.styleFrom( - padding: EdgeInsets.symmetric( - vertical: 12, - horizontal: 5, - ), - ), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '筛选', - style: TextStyle(color: Colors.black87, fontSize: 16), - ), - Icon(Icons.arrow_drop_down, color: Colors.grey), - ], - ), - ), - ), - Expanded( - flex: 2, - child: SearchBarWidget( - showResetButton: false, - hintText: "请输入关键字", - // isClickableOnly: true, - onSearch: (text) { - _search(); - }, - controller: _searchController, - ), - ), - ], - ), - ), - const Divider(height: 1), - // List - Expanded(child: _buildListContent()), - ], - )), - ); - } -} diff --git a/lib/pages/home/SafeCheck/SafeCheckFormView.dart b/lib/pages/home/SafeCheck/SafeCheckFormView.dart index a695463..8b8f472 100644 --- a/lib/pages/home/SafeCheck/SafeCheckFormView.dart +++ b/lib/pages/home/SafeCheck/SafeCheckFormView.dart @@ -5,10 +5,12 @@ import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/dotted_border_box.dart'; +import 'package:qhd_prevention/customWidget/single_image_viewer.dart'; import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/MultiTextFieldWithTitle.dart'; import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/custom/safeCheck_table.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/tools/tools.dart'; class SafeCheckFormView extends StatefulWidget { const SafeCheckFormView({ @@ -32,7 +34,9 @@ class SafeCheckFormView extends StatefulWidget { class _SafeCheckFormViewState extends State { /// 将 widget.form['situationList'] 转为 MultiTextFieldWithTitle 需要的 List List _situationListToStrings() { - final List cur = List.from(widget.form['situationList'] ?? []); + final List cur = List.from( + widget.form['situationList'] ?? [], + ); if (cur.isEmpty) return ['']; // 保持至少一行,和 uni-app 行为一致 return cur.map((e) { if (e is Map && e['SITUATION'] != null) return e['SITUATION'].toString(); @@ -40,11 +44,12 @@ class _SafeCheckFormViewState extends State { return ''; }).toList(); } + Widget _personUnitItem(Map item, int index) { return Stack( children: [ Container( - padding: EdgeInsets.all(5), + padding: EdgeInsets.symmetric(vertical: 5), child: DottedBorderBox( child: SizedBox( child: Column( @@ -57,7 +62,6 @@ class _SafeCheckFormViewState extends State { setState(() {}); }, text: item['INSPECTION_DEPARTMENT_NAME'] ?? '请选择', - ), Divider(), ItemListWidget.selectableLineTitleTextRightButton( @@ -65,166 +69,209 @@ class _SafeCheckFormViewState extends State { label: '${index + 1}.检查人员:', isEditable: false, text: item['INSPECTION_USER_NAME'] ?? '请选择', - ), ], ), ), ), ), - ], ); // 删除按钮(叠加在左上角) } + Widget _checkItem(Map item, int index) { + return Column( + children: [ + const SizedBox(height: 10), + ItemListWidget.singleLineTitleText( + label: '检查人员核查结果:', + isEditable: false, + text: '', + ), + const Divider(), + ItemListWidget.multiLineTitleTextField( + label: '检查人意见', + isEditable: false, + text: item['INSPECTION_USER_OPINION'] ?? '', + ), + const Divider(), + ItemListWidget.OneRowImageTitle( + label: '检查人签字', + text: item['INSPECTION_USER_SIGN_TIME'], + onTapCallBack: (path) { + presentOpaque(SingleImageViewer(imageUrl: path), context); + }, + imgPath: item['INSPECTION_USER_SIGN_IMG'], + ), + ], + ); + } @override Widget build(BuildContext context) { final form = widget.form; final isEdit = widget.isEdit; - List inspectorList = widget.form['inspectorList']; + List inspectorList = widget.form['inspectorList'] ?? []; + List inspectorVerifyList = + widget.form['inspectorVerifyList'] ?? widget.form['inspectorList']; + return SizedBox( // padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 12), - child: - Column( - children: [ - // 顶部表单区容器 - ItemListWidget.itemContainer( - Column( - children: [ - // 检查题目选择(示例复用你项目的 ListItemFactory) - ListItemFactory.createYesNoSection( - title: '检查题目:', - groupValue: (form['INSPECTION_CATEGORY']?.toString() ?? '').toLowerCase() == '安全' - ? true - : (form['INSPECTION_CATEGORY']?.toString() ?? '').toLowerCase() == '综合' - ? false - : null, - yesLabel: '安全', - noLabel: '综合', - isEdit: isEdit, - isRequired: true, - horizontalPadding: 5, - verticalPadding: 0, - text:'${form['INSPECTION_SUBJECT'] ?? ''}现场检查记录', + child: Column( + children: [ + // 顶部表单区容器 + ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + // 检查题目选择(示例复用你项目的 ListItemFactory) + ListItemFactory.createYesNoSection( + title: '检查题目:', + groupValue: + (form['INSPECTION_CATEGORY']?.toString() ?? '') + .toLowerCase() == + '安全' + ? true + : (form['INSPECTION_CATEGORY']?.toString() ?? '') + .toLowerCase() == + '综合' + ? false + : null, + yesLabel: '安全', + noLabel: '综合', + isEdit: isEdit, + isRequired: true, + horizontalPadding: 5, + verticalPadding: 0, + text: '${form['INSPECTION_SUBJECT'] ?? ''}现场检查记录', - onChanged: (val) { - // 如果需要把选择写回 form,可以在这里 setState 更新 widget.form - // setState(() { widget.form['INSPECTION_CATEGORY'] = val ? '安全' : '综合'; }); - }, + onChanged: (val) { + // 如果需要把选择写回 form,可以在这里 setState 更新 widget.form + // setState(() { widget.form['INSPECTION_CATEGORY'] = val ? '安全' : '综合'; }); + }, + ), + + const Divider(), + ItemListWidget.singleLineTitleText( + label: '被检查单位:', + isEditable: false, + text: form['INSPECTED_DEPARTMENT_NAMES'] ?? '', + ), + const Divider(), + + ItemListWidget.selectableLineTitleTextRightButton( + label: '被检查单位现场负责人:', + isEditable: isEdit, + text: form['INSPECTED_SITEUSER_NAME'] ?? '', + ), + const Divider(), + + ItemListWidget.singleLineTitleText( + label: '检查场所:', + isEditable: isEdit, + text: form['INSPECTION_PLACE'], + hintText: '请输入检查场所', + onChanged: (val) { + // 可选择写回 form + // setState(() { widget.form['INSPECTION_PLACE'] = val; }); + }, + ), + const Divider(), + + ItemListWidget.selectableLineTitleTextRightButton( + label: '检查类型:', + isEditable: isEdit, + text: form['INSPECTION_TYPE_NAME'] ?? '', + ), + const Divider(), + + ItemListWidget.selectableLineTitleTextRightButton( + label: '检查开始时间:', + isEditable: isEdit, + text: form['INSPECTION_TIME_START'] ?? '', + onTap: () {}, + ), + const Divider(), + + ItemListWidget.selectableLineTitleTextRightButton( + label: '检查结束时间:', + isEditable: isEdit, + text: form['INSPECTION_TIME_END'] ?? '', + onTap: () {}, + ), + + const Divider(), + + // MultiTextFieldWithTitle(检查情况),外部通过 onMultiTextsChanged 更新 form['situationList'] + MultiTextFieldWithTitle( + label: "检查情况", + isEditable: isEdit, + hintText: "请输入检查情况...", + texts: _situationListToStrings(), + onTextsChanged: (val) {}, + ), + + const Divider(), + + ItemListWidget.itemContainer( + Column( + children: [ + ListItemFactory.headerTitle('检查人员'), + SizedBox(height: 5), + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: inspectorList.length, + itemBuilder: (context, index) { + return _personUnitItem(inspectorList[index], index); + }, + ), + ], ), + ), - const Divider(), - ItemListWidget.singleLineTitleText( - label: '被检查单位:', - isEditable: false, - text: form['INSPECTED_DEPARTMENT_NAMES'] ??'', + const Divider(), + + ItemListWidget.itemContainer( + horizontal: 12, + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ListItemFactory.headerTitle('发现问题')], ), - const Divider(), + ), - ItemListWidget.selectableLineTitleTextRightButton( - label: '被检查单位现场负责人:', - isEditable: isEdit, - text: form['INSPECTED_SITEUSER_NAME'] ?? '', - ), - const Divider(), - - ItemListWidget.singleLineTitleText( - label: '检查场所:', - isEditable: isEdit, - text: form['INSPECTION_PLACE'], - hintText: '请输入检查场所', - onChanged: (val) { - // 可选择写回 form - // setState(() { widget.form['INSPECTION_PLACE'] = val; }); - }, - ), - const Divider(), - - ItemListWidget.selectableLineTitleTextRightButton( - label: '检查类型:', - isEditable: isEdit, - text: form['INSPECTION_TYPE_NAME'] ?? '', - ), - const Divider(), - - ItemListWidget.selectableLineTitleTextRightButton( - label: '检查开始时间:', - isEditable: isEdit, - text: form['INSPECTION_TIME_START'] ?? '', - onTap: () { - }, - ), - const Divider(), - - ItemListWidget.selectableLineTitleTextRightButton( - label: '检查结束时间:', - isEditable: isEdit, - text: form['INSPECTION_TIME_END'] ?? '', - onTap: () { - }, - ), - - const Divider(), - - // MultiTextFieldWithTitle(检查情况),外部通过 onMultiTextsChanged 更新 form['situationList'] - MultiTextFieldWithTitle( - label: "检查情况", - isEditable: isEdit, - hintText: "请输入检查情况...", - texts: _situationListToStrings(), - onTextsChanged: (val) { - }, - ), - - const Divider(), - - ListItemFactory.headerTitle('检查人员'), - SizedBox(height: 10), - ListView.builder( - shrinkWrap: true, - physics: - const NeverScrollableScrollPhysics(), - itemCount: inspectorList.length, - itemBuilder: (context, index) { - return _personUnitItem( - inspectorList[index], - index, - ); - }, - ), - const Divider(), - - ItemListWidget.itemContainer( - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ListItemFactory.headerTitle('发现问题'), - ], - ), - ), - - // HiddenListTable:隐患列表展示(外部通过 onHiddenShow/onHiddenRemove 处理具体交互) - HiddenListTable( - hiddenList: (form['hiddenList'] as List?) ?? [], - forbidEdit: false, - baseImgPath: ApiService.baseImgPath, - personSignImg: '', - personSignTime: '', - showHidden: widget.onHiddenShow, - removeHidden: (item, index){}, - context: context, - ), - - ], - ), + // HiddenListTable:隐患列表展示(外部通过 onHiddenShow/onHiddenRemove 处理具体交互) + HiddenListTable( + hiddenList: (form['hiddenList'] as List?) ?? [], + forbidEdit: false, + baseImgPath: ApiService.baseImgPath, + personSignImg: '', + personSignTime: '', + showHidden: widget.onHiddenShow, + removeHidden: (item, index) {}, + context: context, + ), + ], ), - - const SizedBox(height: 20), - ], - ), - + ), + SizedBox(height: 10,), + ItemListWidget.itemContainer( + horizontal: 0, + inspectorVerifyList.isNotEmpty + ? ListView.builder( + padding: EdgeInsets.symmetric(horizontal: 0), + itemCount: inspectorVerifyList.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return _checkItem(inspectorVerifyList[index], index); + }, + ) + : SizedBox(), + ), + ], + ), ); } } diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart b/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart new file mode 100644 index 0000000..89dae9e --- /dev/null +++ b/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; + +class SafecheckDefendSetPage extends StatefulWidget { + const SafecheckDefendSetPage({super.key, required this.INSPECTION_ID}); + final String INSPECTION_ID; + + @override + State createState() => _SafecheckDefendSetPageState(); +} + +class _SafecheckDefendSetPageState extends State { + + late Map form = {}; + + Future _getData() async { + try { + final result = await ApiService.getSafeCheckStartGoEdit( + widget.INSPECTION_ID, + ); + // 在 await 之后检查 mounted,避免页面已经被 pop 导致 setState 报错 + if (!mounted) return; + setState(() { + form = result['pd'] ?? {}; + + }); + } catch (e, st) { + print('加载单条数据失败: $e\n$st'); + if (mounted) { + ToastUtil.showNormal(context, '加载数据失败:$e'); + } + } + } + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: '申辩处理'), + body: SafeArea(child: Padding( + padding: EdgeInsets.all(12), + child: ItemListWidget.itemContainer(Column(children: [ + + ],)))), + ); + } +} diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart b/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart index 3951cbf..4eb8890 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_drawer_page.dart @@ -352,7 +352,7 @@ class _SafeCheckDrawerPageState extends State { Expanded( child: CustomButton( onPressed: cancelHidden, - text: '取消', + text: '返回', textStyle: TextStyle(color: Colors.black87), backgroundColor: Colors.grey.shade300, ), diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart b/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart index d297969..ede94d3 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart @@ -29,11 +29,11 @@ class SafecheckStartDetail extends StatefulWidget { const SafecheckStartDetail({ super.key, required this.INSPECTION_ID, - required this.isEdit, + required this.type, }); final String INSPECTION_ID; - final bool isEdit; + final String type; @override State createState() => _SafecheckStartDetailState(); @@ -42,9 +42,11 @@ class SafecheckStartDetail extends StatefulWidget { class _SafecheckStartDetailState extends State { String msg = 'add'; - bool _isEdit = false; + bool _isEdit = false; // 禁止修改 /// 被检查单位负责人 late List personList = []; + /// 打回信息 + late List inspectorVerifyList = []; /// 检查类型 late List typeList = []; @@ -96,11 +98,15 @@ class _SafecheckStartDetailState extends State { @override void initState() { super.initState(); - _isEdit = widget.isEdit; form['INSPECTION_ID'] = widget.INSPECTION_ID; form['hiddenList'] = []; if (widget.INSPECTION_ID.isNotEmpty) { msg = 'edit'; + }else{ + _isEdit = true; + } + if (widget.type == 'look') { + _isEdit = false; } if (_isEdit) { inspectorList.add({ @@ -133,7 +139,12 @@ class _SafecheckStartDetailState extends State { FormUtils.hasValue(form, 'inspectorList') ? form['inspectorList'] : []; - if (FormUtils.hasValue(form, 'INSPECTION_STATUS') && int.parse(form['INSPECTION_STATUS']) < 1) { + inspectorVerifyList = + FormUtils.hasValue(form, 'inspectorVerifyList') + ? form['inspectorVerifyList'] + : []; + + if (FormUtils.hasValue(form, 'INSPECTION_STATUS') && int.parse(form['INSPECTION_STATUS']) < 1 && widget.type != 'look') { _isEdit = true; } chooseTitleType = form['INSPECTION_SUBJECT'] == '安全' ? true : false; @@ -693,20 +704,43 @@ class _SafecheckStartDetailState extends State { children: [ ItemListWidget.multiLineTitleTextField( label: '检查人意见:', - isEditable: _isEdit, + isEditable: false, text: item['opinion'], - hintText: '请输入作业负责人意见', ), const Divider(), - ItemListWidget.OneRowImageTitle( label: '检查人签字', - text: item['time'], + text: item['time'] ?? '', onTapCallBack: (path) { presentOpaque(SingleImageViewer(imageUrl: path), context); }, - imgPath: item['img'], + imgPath: item['img'] ?? '', ), + const Divider(), + Column( + children: [ + if (form['INSPECTION_STATUS'] == '3') + + ItemListWidget.multiLineTitleTextField( + label: '被检查单位现场负责人意见:', + isEditable: false, + text: item['INSPECTED_EXPLAIN'], + ), + if (FormUtils.hasValue(form, 'INSPECTED_EXPLAIN')) + ItemListWidget.multiLineTitleTextField(label: '申辩说明', isEditable: false,text: form['INSPECTED_EXPLAIN'] ?? ''), + if (form['INSPECTION_STATUS'] == '3') + ItemListWidget.OneRowImageTitle( + label: '检查人签字', + text: form['INSPECTED_SITEUSER_SIGN_TIME'], + onTapCallBack: (path) { + presentOpaque(SingleImageViewer(imageUrl: path), context); + }, + imgPath: item['INSPECTED_SITEUSER_SIGN_IMG'], + ), + + ], + ) + ], ), ); @@ -1113,35 +1147,53 @@ class _SafecheckStartDetailState extends State { }, context: context, ), - if (_isEdit) - ItemListWidget.multiLineTitleTextField( - label: '核实意见', - isEditable: _isEdit, - isRequired: false, - hintText: '检查人意见', - onChanged: (val) { - form['INSPECTION_USER_OPINION'] = val; - }, - text: form['INSPECTION_USER_OPINION'] ?? '', - ), - if (form['INSPECTION_USER_OPINION'].toString().isNotEmpty && _isEdit) - ItemListWidget.itemContainer(Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + if (widget.type == 'look' && inspectorVerifyList.isNotEmpty) + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + /// TODO —————————————————————————————————————————————— + + if (_isEdit && widget.type != 'detail') + Column( children: [ - ListItemFactory.headerTitle('签字'), - CustomButton( - text: '手写签字', - height: 36, - backgroundColor: Colors.green, - onPressed: () { - _sign(); + ItemListWidget.multiLineTitleTextField( + label: '核实意见', + isEditable: _isEdit, + isRequired: false, + hintText: '检查人意见', + onChanged: (val) { + form['INSPECTION_USER_OPINION'] = val; }, + text: form['INSPECTION_USER_OPINION'] ?? '', ), + if (form['INSPECTION_USER_OPINION'].toString().isNotEmpty && _isEdit) + ItemListWidget.itemContainer(Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ListItemFactory.headerTitle('签字'), + CustomButton( + text: '手写签字', + height: 36, + backgroundColor: Colors.green, + onPressed: () { + _sign(); + }, + ), + ], + ),), ], - ),), + ), if (signImages.isNotEmpty) _signListWidget(), - if (!_isEdit) + if (widget.type == 'detail') Column( children: [ const Divider(), @@ -1150,7 +1202,7 @@ class _SafecheckStartDetailState extends State { children: [ ItemListWidget.selectableLineTitleTextRightButton( label: '检查人员核实结果', - isEditable: _isEdit, + isEditable: false, text: ' ', ), SizedBox(height: 5,), @@ -1178,31 +1230,33 @@ class _SafecheckStartDetailState extends State { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - if (_isEdit) - SizedBox( - width: 150, - child: CustomButton( - text: '返回', - textStyle: TextStyle( - color: Colors.white, - fontSize: 17, - ), - backgroundColor: Colors.black38, - onPressed: () => Navigator.pop(context), - ), - ), - SizedBox( + if (_isEdit) ...[SizedBox( width: 150, child: CustomButton( - text: _isEdit ? '提交' : '返回', + text: '提交', textStyle: TextStyle( color: Colors.white, fontSize: 17, ), backgroundColor: Colors.blue, - onPressed: _submit, + onPressed: () => Navigator.pop(context), ), - ), + ),]else...[ + SizedBox( + width: 150, + child: CustomButton( + text:'返回', + textStyle: TextStyle( + color: Colors.white, + fontSize: 17, + ), + backgroundColor: Colors.blue, + onPressed: _submit, + ), + ), + ] + + ], ), ], diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart b/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart index 85fdf8a..ce60293 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_detail.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -113,7 +114,7 @@ class _SafecheckStartListPageState extends State { /// 申请 void _handleApply() { // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', isEdit: true), context); + pushPage(SafecheckStartDetail(INSPECTION_ID: '', type: 'add',), context); } /// 打开流程图 @@ -140,9 +141,9 @@ class _SafecheckStartListPageState extends State { } } - void _goToDetail(Map item) async { + void _goToDetail(Map item, String type) async { - pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', isEdit: false), context); + pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', type: type), context); setState(() { _fetchData(); @@ -154,11 +155,15 @@ class _SafecheckStartListPageState extends State { required Map item, required bool isFirst, required bool isLast, + required int status, // 1 = 完成, 0 = 进行中, -1 = 未到达 }) { - bool status = item['active'] == item['order']; // 依据状态设色 - final Color dotColor = status ? Colors.blue :Colors.grey; - final Color textColor = status ? Colors.blue :Colors.black54; + final Color dotColor = + status == 1 ? Colors.blue : (status == 0 ? Colors.blue : Colors.grey); + final Color textColor = + status == 1 + ? Colors.blue + : (status == 0 ? Colors.blue : Colors.black54); return ListTile( visualDensity: VisualDensity(vertical: -4), @@ -208,13 +213,19 @@ class _SafecheckStartListPageState extends State { } return ''; } + void _goToDefend(Map item) async { + await pushPage(SafecheckDefendSetPage(INSPECTION_ID: item['INSPECTION_ID'] ?? ''), context); + _fetchData(); + + + } Widget _buildListItem(Map item) { return Card( color: Colors.white, margin: const EdgeInsets.all(8.0), child: InkWell( - onTap: () => _goToDetail(item), + onTap: () => _goToDetail(item, 'detail'), child: Padding( padding: const EdgeInsets.all(12.0), child: Column( @@ -275,6 +286,8 @@ class _SafecheckStartListPageState extends State { ), const SizedBox(height: 8), Row( + spacing: 5, + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ CustomButton( text: '流程图', @@ -284,7 +297,41 @@ class _SafecheckStartListPageState extends State { backgroundColor: Colors.blue, onPressed: () => _openFlowDrawer(item['INSPECTION_ID']), ), - SizedBox(width: 1), + if (item['INSPECTION_STATUS'] == '0' || + item['INSPECTION_STATUS'] == '-1'|| + item['INSPECTION_STATUS'] == '-2') + Row( + spacing: 5, + children: [ + if (item['INSPECTION_STATUS'] == '-1') + CustomButton( + text: '编辑', + height: 35, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.green, + onPressed: () => _goToDetail(item, 'edit'), + ), + if (item['INSPECTION_STATUS'] == '-1') + CustomButton( + text: '查看', + height: 35, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.green, + onPressed: () => _goToDetail(item, 'look'), + ), + if (item['INSPECTION_STATUS'] == '-2' && item['INSPECTION_ORIGINATOR_ID'] == SessionService.instance.loginUserId) + CustomButton( + text: '申辩处理', + height: 35, + padding: EdgeInsets.symmetric(horizontal: 12), + margin: EdgeInsets.only(left: 0), + backgroundColor: Colors.green, + onPressed: () => _goToDefend(item), + ), + ], + ) ], ), ], @@ -407,10 +454,14 @@ class _SafecheckStartListPageState extends State { final bool isFirst = idx == 0; final bool isLast = idx == flowList.length - 1; + // 根据 lastDoneIndex 自动计算“进行中” + final int status = item['active'] == '1' ? 1 : -1; + return _buildFlowStepItem( item: item, isFirst: isFirst, isLast: isLast, + status: status, ); }, ), diff --git a/lib/pages/home/SafeCheck/safeCheck_tab_list.dart b/lib/pages/home/SafeCheck/safeCheck_tab_list.dart index 236ea44..6ee1342 100644 --- a/lib/pages/home/SafeCheck/safeCheck_tab_list.dart +++ b/lib/pages/home/SafeCheck/safeCheck_tab_list.dart @@ -4,7 +4,9 @@ import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/pages/KeyProjects/Danger/danger_list_page.dart'; import 'package:qhd_prevention/pages/KeyProjects/KeyProject/keyProject_list_page.dart'; import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/safeCheck_list_page.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSign/safeCheck_sign_list_page.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart'; +import 'package:qhd_prevention/pages/home/SafeCheck/DangeCheck/safeCheck_danger_list_page.dart'; import 'package:qhd_prevention/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/work_tab_icon_grid.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; @@ -106,10 +108,14 @@ class _SafecheckTabListState extends State { } break; case 2: { title = '安全检查确认'; - // await pushPage(DangerListPage(flow: title), context); + await pushPage(SafecheckSignListPage(flow: title), context); + + } break; + case 3: { + title = '隐患指派及验收'; + await pushPage(SafecheckDangerListPage(flow: title), context); } break; - case 3: title = '隐患指派及验收'; break; case 4: title = '申辩记录'; break; default: diff --git a/lib/pages/home/tap/item_list_widget.dart b/lib/pages/home/tap/item_list_widget.dart index b39b19b..1d8c08f 100644 --- a/lib/pages/home/tap/item_list_widget.dart +++ b/lib/pages/home/tap/item_list_widget.dart @@ -58,6 +58,7 @@ class ItemListWidget { keyboardType: keyboardType, style: TextStyle(fontSize: fontSize), maxLines: 1, + decoration: InputDecoration( isDense: true, hintText: hintText, @@ -65,11 +66,13 @@ class ItemListWidget { ), ), ) - : Text( - text ?? '', - style: TextStyle(fontSize: fontSize, color: detailtextColor), - overflow: TextOverflow.ellipsis, // 超出省略 - ), + : Expanded(child: Text( + text ?? '', + maxLines: 5, + style: TextStyle(fontSize: fontSize, color: detailtextColor), + textAlign: TextAlign.right, + overflow: TextOverflow.ellipsis, // 超出省略 + )), ], ), ); diff --git a/pubspec.lock b/pubspec.lock index 46b9322..f4c4347 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: args sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.7.0" asn1lib: @@ -14,7 +14,7 @@ packages: description: name: asn1lib sha256: "9a8f69025044eb466b9b60ef3bc3ac99b4dc6c158ae9c56d25eeccf5bc56d024" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.6.5" async: @@ -22,7 +22,7 @@ packages: description: name: async sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.13.0" boolean_selector: @@ -30,7 +30,7 @@ packages: description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" camera: @@ -38,7 +38,7 @@ packages: description: name: camera sha256: d6ec2cbdbe2fa8f5e0d07d8c06368fe4effa985a4a5ddade9cc58a8cd849557d - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.11.2" camera_android_camerax: @@ -46,7 +46,7 @@ packages: description: name: camera_android_camerax sha256: "58b8fe843a3c83fd1273c00cb35f5a8ae507f6cc9b2029bcf7e2abba499e28d8" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.6.19+1" camera_avfoundation: @@ -54,7 +54,7 @@ packages: description: name: camera_avfoundation sha256: e4aca5bccaf897b70cac87e5fdd789393310985202442837922fd40325e2733b - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.21+1" camera_platform_interface: @@ -62,7 +62,7 @@ packages: description: name: camera_platform_interface sha256: "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.10.0" camera_web: @@ -70,7 +70,7 @@ packages: description: name: camera_web sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.3.5" characters: @@ -78,7 +78,7 @@ packages: description: name: characters sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.4.0" clock: @@ -86,7 +86,7 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.2" collection: @@ -94,7 +94,7 @@ packages: description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.19.1" connectivity_plus: @@ -102,7 +102,7 @@ packages: description: name: connectivity_plus sha256: b5e72753cf63becce2c61fd04dfe0f1c430cc5278b53a1342dc5ad839eab29ec - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.5" connectivity_plus_platform_interface: @@ -110,7 +110,7 @@ packages: description: name: connectivity_plus_platform_interface sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.1" convert: @@ -118,7 +118,7 @@ packages: description: name: convert sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.2" cross_file: @@ -126,7 +126,7 @@ packages: description: name: cross_file sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.3.4+2" crypto: @@ -134,7 +134,7 @@ packages: description: name: crypto sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.6" csslib: @@ -142,7 +142,7 @@ packages: description: name: csslib sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.2" cupertino_icons: @@ -150,7 +150,7 @@ packages: description: name: cupertino_icons sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.8" dbus: @@ -158,7 +158,7 @@ packages: description: name: dbus sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.11" dio: @@ -166,7 +166,7 @@ packages: description: name: dio sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.9.0" dio_web_adapter: @@ -174,7 +174,7 @@ packages: description: name: dio_web_adapter sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" dotted_border: @@ -182,7 +182,7 @@ packages: description: name: dotted_border sha256: "99b091ec6891ba0c5331fdc2b502993c7c108f898995739a73c6845d71dad70c" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.0" encrypt: @@ -190,7 +190,7 @@ packages: description: name: encrypt sha256: "62d9aa4670cc2a8798bab89b39fc71b6dfbacf615de6cf5001fb39f7e4a996a2" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.3" extended_image: @@ -198,7 +198,7 @@ packages: description: name: extended_image sha256: f6cbb1d798f51262ed1a3d93b4f1f2aa0d76128df39af18ecb77fa740f88b2e0 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "10.0.1" extended_image_library: @@ -206,7 +206,7 @@ packages: description: name: extended_image_library sha256: "1f9a24d3a00c2633891c6a7b5cab2807999eb2d5b597e5133b63f49d113811fe" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.1" extension: @@ -214,7 +214,7 @@ packages: description: name: extension sha256: be3a6b7f8adad2f6e2e8c63c895d19811fcf203e23466c6296267941d0ff4f24 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.6.0" fake_async: @@ -222,7 +222,7 @@ packages: description: name: fake_async sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.3.3" ffi: @@ -230,7 +230,7 @@ packages: description: name: ffi sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.4" file: @@ -238,7 +238,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.1" file_selector_linux: @@ -246,7 +246,7 @@ packages: description: name: file_selector_linux sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.3+2" file_selector_macos: @@ -254,7 +254,7 @@ packages: description: name: file_selector_macos sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.4+3" file_selector_platform_interface: @@ -262,7 +262,7 @@ packages: description: name: file_selector_platform_interface sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.6.2" file_selector_windows: @@ -270,7 +270,7 @@ packages: description: name: file_selector_windows sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.9.3+4" fixnum: @@ -278,7 +278,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" flutter: @@ -291,7 +291,7 @@ packages: description: name: flutter_easyloading sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.5" flutter_html: @@ -299,7 +299,7 @@ packages: description: name: flutter_html sha256: "38a2fd702ffdf3243fb7441ab58aa1bc7e6922d95a50db76534de8260638558d" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.0" flutter_lints: @@ -307,7 +307,7 @@ packages: description: name: flutter_lints sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.0.0" flutter_new_badger: @@ -315,7 +315,7 @@ packages: description: name: flutter_new_badger sha256: d3742ace8009663db1ac6ba0377b092f479c35deb33e05514ba05cc0b0a5aaaa - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" flutter_plugin_android_lifecycle: @@ -323,7 +323,7 @@ packages: description: name: flutter_plugin_android_lifecycle sha256: "6382ce712ff69b0f719640ce957559dde459e55ecd433c767e06d139ddf16cab" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.29" flutter_spinkit: @@ -331,7 +331,7 @@ packages: description: name: flutter_spinkit sha256: "77850df57c00dc218bfe96071d576a8babec24cf58b2ed121c83cca4a2fdce7f" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.2.2" flutter_test: @@ -349,7 +349,7 @@ packages: description: name: fluttertoast sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "8.2.12" geolocator: @@ -357,7 +357,7 @@ packages: description: name: geolocator sha256: f4efb8d3c4cdcad2e226af9661eb1a0dd38c71a9494b22526f9da80ab79520e5 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "10.1.1" geolocator_android: @@ -365,7 +365,7 @@ packages: description: name: geolocator_android sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.6.2" geolocator_apple: @@ -373,7 +373,7 @@ packages: description: name: geolocator_apple sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.13" geolocator_platform_interface: @@ -381,7 +381,7 @@ packages: description: name: geolocator_platform_interface sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.2.6" geolocator_web: @@ -389,7 +389,7 @@ packages: description: name: geolocator_web sha256: "102e7da05b48ca6bf0a5bda0010f886b171d1a08059f01bfe02addd0175ebece" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.1" geolocator_windows: @@ -397,7 +397,7 @@ packages: description: name: geolocator_windows sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.5" html: @@ -405,7 +405,7 @@ packages: description: name: html sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.15.6" http: @@ -413,7 +413,7 @@ packages: description: name: http sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.5.0" http_client_helper: @@ -421,7 +421,7 @@ packages: description: name: http_client_helper sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.0" http_parser: @@ -429,7 +429,7 @@ packages: description: name: http_parser sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.1.2" image_picker: @@ -437,7 +437,7 @@ packages: description: name: image_picker sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.2" image_picker_android: @@ -445,7 +445,7 @@ packages: description: name: image_picker_android sha256: b08e9a04d0f8d91f4a6e767a745b9871bfbc585410205c311d0492de20a7ccd6 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.8.12+25" image_picker_for_web: @@ -453,7 +453,7 @@ packages: description: name: image_picker_for_web sha256: "717eb042ab08c40767684327be06a5d8dbb341fe791d514e4b92c7bbe1b7bb83" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.6" image_picker_ios: @@ -461,7 +461,7 @@ packages: description: name: image_picker_ios sha256: "05da758e67bc7839e886b3959848aa6b44ff123ab4b28f67891008afe8ef9100" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.8.12+2" image_picker_linux: @@ -469,7 +469,7 @@ packages: description: name: image_picker_linux sha256: "34a65f6740df08bbbeb0a1abd8e6d32107941fd4868f67a507b25601651022c9" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+2" image_picker_macos: @@ -477,23 +477,23 @@ packages: description: name: image_picker_macos sha256: "1b90ebbd9dcf98fb6c1d01427e49a55bd96b5d67b8c67cf955d60a5de74207c1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+2" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: "886d57f0be73c4b140004e78b9f28a8914a09e50c2d816bdd0520051a71236a0" - url: "https://pub.flutter-io.cn" + sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "2.10.1" + version: "2.11.0" image_picker_windows: dependency: transitive description: name: image_picker_windows sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1+1" intl: @@ -501,7 +501,7 @@ packages: description: name: intl sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.20.2" js: @@ -509,7 +509,7 @@ packages: description: name: js sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.2" leak_tracker: @@ -517,7 +517,7 @@ packages: description: name: leak_tracker sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "10.0.9" leak_tracker_flutter_testing: @@ -525,7 +525,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.9" leak_tracker_testing: @@ -533,7 +533,7 @@ packages: description: name: leak_tracker_testing sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.0.1" lints: @@ -541,7 +541,7 @@ packages: description: name: lints sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.1.1" list_counter: @@ -549,7 +549,7 @@ packages: description: name: list_counter sha256: c447ae3dfcd1c55f0152867090e67e219d42fe6d4f2807db4bbe8b8d69912237 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.2" matcher: @@ -557,7 +557,7 @@ packages: description: name: matcher sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.12.17" material_color_utilities: @@ -565,7 +565,7 @@ packages: description: name: material_color_utilities sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.11.1" meta: @@ -573,7 +573,7 @@ packages: description: name: meta sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.16.0" mime: @@ -581,7 +581,7 @@ packages: description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.0.0" mobile_scanner: @@ -589,7 +589,7 @@ packages: description: name: mobile_scanner sha256: "54005bdea7052d792d35b4fef0f84ec5ddc3a844b250ecd48dc192fb9b4ebc95" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.1" ndef_record: @@ -597,7 +597,7 @@ packages: description: name: ndef_record sha256: "0c72dfac0d5c16fc264846d103ee5d8249cd3858261a5a537b455a24c1bd5857" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.1" nested: @@ -605,7 +605,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.0" nfc_manager: @@ -613,7 +613,7 @@ packages: description: name: nfc_manager sha256: "164cc0223dee528d4d05a542da921f0b3a31ca0312400701c93ebf4ce757f676" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.0.2" nfc_manager_ndef: @@ -621,7 +621,7 @@ packages: description: name: nfc_manager_ndef sha256: "676e741c42b63ab1fda5a981015cb706ab4fdb76e5d0eec6611993bb27d7e7bf" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.0.1" nm: @@ -629,7 +629,7 @@ packages: description: name: nm sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.5.0" package_info_plus: @@ -637,7 +637,7 @@ packages: description: name: package_info_plus sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "8.3.1" package_info_plus_platform_interface: @@ -645,7 +645,7 @@ packages: description: name: package_info_plus_platform_interface sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.2.1" path: @@ -653,7 +653,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.9.1" path_provider: @@ -661,7 +661,7 @@ packages: description: name: path_provider sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.5" path_provider_android: @@ -669,7 +669,7 @@ packages: description: name: path_provider_android sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.17" path_provider_foundation: @@ -677,7 +677,7 @@ packages: description: name: path_provider_foundation sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" path_provider_linux: @@ -685,7 +685,7 @@ packages: description: name: path_provider_linux sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.1" path_provider_platform_interface: @@ -693,7 +693,7 @@ packages: description: name: path_provider_platform_interface sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.2" path_provider_windows: @@ -701,7 +701,7 @@ packages: description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.0" pdfx: @@ -709,7 +709,7 @@ packages: description: name: pdfx sha256: "29db9b71d46bf2335e001f91693f2c3fbbf0760e4c2eb596bf4bafab211471c1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.9.2" petitparser: @@ -717,7 +717,7 @@ packages: description: name: petitparser sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.0" photo_manager: @@ -725,7 +725,7 @@ packages: description: name: photo_manager sha256: a0d9a7a9bc35eda02d33766412bde6d883a8b0acb86bbe37dac5f691a0894e8a - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.7.1" photo_manager_image_provider: @@ -733,7 +733,7 @@ packages: description: name: photo_manager_image_provider sha256: b6015b67b32f345f57cf32c126f871bced2501236c405aafaefa885f7c821e4f - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.2.0" photo_view: @@ -741,7 +741,7 @@ packages: description: name: photo_view sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.15.0" platform: @@ -749,7 +749,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.6" plugin_platform_interface: @@ -757,7 +757,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.8" pointycastle: @@ -765,7 +765,7 @@ packages: description: name: pointycastle sha256: "4be0097fcf3fd3e8449e53730c631200ebc7b88016acecab2b0da2f0149222fe" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.9.1" provider: @@ -773,7 +773,7 @@ packages: description: name: provider sha256: "4abbd070a04e9ddc287673bf5a030c7ca8b685ff70218720abab8b092f53dd84" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.1.5" shared_preferences: @@ -781,7 +781,7 @@ packages: description: name: shared_preferences sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.5.3" shared_preferences_android: @@ -789,7 +789,7 @@ packages: description: name: shared_preferences_android sha256: "5bcf0772a761b04f8c6bf814721713de6f3e5d9d89caf8d3fe031b02a342379e" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.11" shared_preferences_foundation: @@ -797,7 +797,7 @@ packages: description: name: shared_preferences_foundation sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.5.4" shared_preferences_linux: @@ -805,7 +805,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -813,7 +813,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" shared_preferences_web: @@ -821,7 +821,7 @@ packages: description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.3" shared_preferences_windows: @@ -829,7 +829,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" simple_gesture_detector: @@ -837,7 +837,7 @@ packages: description: name: simple_gesture_detector sha256: ba2cd5af24ff20a0b8d609cec3f40e5b0744d2a71804a2616ae086b9c19d19a3 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.2.1" sky_engine: @@ -850,7 +850,7 @@ packages: description: name: source_span sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.10.1" sprintf: @@ -858,7 +858,7 @@ packages: description: name: sprintf sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "7.0.0" stack_trace: @@ -866,7 +866,7 @@ packages: description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.12.1" stream_channel: @@ -874,7 +874,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.4" stream_transform: @@ -882,7 +882,7 @@ packages: description: name: stream_transform sha256: ad47125e588cfd37a9a7f86c7d6356dde8dfe89d071d293f80ca9e9273a33871 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.1" string_scanner: @@ -890,7 +890,7 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.4.1" synchronized: @@ -898,7 +898,7 @@ packages: description: name: synchronized sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.4.0" table_calendar: @@ -906,7 +906,7 @@ packages: description: name: table_calendar sha256: "0c0c6219878b363a2d5f40c7afb159d845f253d061dc3c822aa0d5fe0f721982" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.2.0" term_glyph: @@ -914,7 +914,7 @@ packages: description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.2.2" test_api: @@ -922,7 +922,7 @@ packages: description: name: test_api sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.7.4" typed_data: @@ -930,7 +930,7 @@ packages: description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.4.0" universal_platform: @@ -938,7 +938,7 @@ packages: description: name: universal_platform sha256: "64e16458a0ea9b99260ceb5467a214c1f298d647c659af1bff6d3bf82536b1ec" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" url_launcher: @@ -946,7 +946,7 @@ packages: description: name: url_launcher sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.3.2" url_launcher_android: @@ -954,7 +954,7 @@ packages: description: name: url_launcher_android sha256: "0aedad096a85b49df2e4725fa32118f9fa580f3b14af7a2d2221896a02cd5656" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.3.17" url_launcher_ios: @@ -962,7 +962,7 @@ packages: description: name: url_launcher_ios sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.3.3" url_launcher_linux: @@ -970,7 +970,7 @@ packages: description: name: url_launcher_linux sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.2.1" url_launcher_macos: @@ -978,7 +978,7 @@ packages: description: name: url_launcher_macos sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.2.2" url_launcher_platform_interface: @@ -986,7 +986,7 @@ packages: description: name: url_launcher_platform_interface sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.3.2" url_launcher_web: @@ -994,7 +994,7 @@ packages: description: name: url_launcher_web sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.1" url_launcher_windows: @@ -1002,7 +1002,7 @@ packages: description: name: url_launcher_windows sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.1.4" uuid: @@ -1010,7 +1010,7 @@ packages: description: name: uuid sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.5.1" vector_math: @@ -1018,7 +1018,7 @@ packages: description: name: vector_math sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.1.4" video_player: @@ -1026,31 +1026,31 @@ packages: description: name: video_player sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.10.0" video_player_android: dependency: transitive description: name: video_player_android - sha256: d26f8791c8f670825cc227e2cad4319d2ac02b71b2ad5c2b67786bb873ac43b1 - url: "https://pub.flutter-io.cn" + sha256: "53f3b57c7ac88c18e6074d0f94c7146e128c515f0a4503c3061b8e71dea3a0f2" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "2.8.11" + version: "2.8.12" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: f52261d11f97bf14c43e8ed5714f71d8ce4538552b8cc87f45e5d87d3c205e41 - url: "https://pub.flutter-io.cn" + sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "2.8.3" + version: "2.8.4" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.4.0" video_player_web: @@ -1058,7 +1058,7 @@ packages: description: name: video_player_web sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.4.0" visibility_detector: @@ -1066,7 +1066,7 @@ packages: description: name: visibility_detector sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "0.4.0+2" vm_service: @@ -1074,7 +1074,7 @@ packages: description: name: vm_service sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "15.0.0" web: @@ -1082,7 +1082,7 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.1" webview_flutter: @@ -1090,23 +1090,23 @@ packages: description: name: webview_flutter sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "4.13.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "414174cacd339046a1a6dbf93cac62422194c676fed11119ccf228b81640e887" - url: "https://pub.flutter-io.cn" + sha256: "0a42444056b24ed832bdf3442d65c5194f6416f7e782152384944053c2ecc9a3" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "4.9.1" + version: "4.10.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "2.14.0" webview_flutter_wkwebview: @@ -1114,31 +1114,31 @@ packages: description: name: webview_flutter_wkwebview sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "3.23.0" wechat_assets_picker: dependency: "direct main" description: name: wechat_assets_picker - sha256: "8bffdf50d250e802fa6ac8a557594c9bfbb0080fc52220513aeb7a5040729fcd" - url: "https://pub.flutter-io.cn" + sha256: c307e50394c1e6dfcd5c4701e84efb549fce71444fedcf2e671c50d809b3e2a1 + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "9.6.0" + version: "9.8.0" wechat_picker_library: dependency: transitive description: name: wechat_picker_library - sha256: a42e09cb85b15fc9410f6a69671371cc60aa99c4a1f7967f6593a7f665f6f47a - url: "https://pub.flutter-io.cn" + sha256: "5cb61b9aa935b60da5b043f8446fbb9c5077419f20ccc4856bf444aec4f44bc1" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted - version: "1.0.5" + version: "1.0.7" win32: dependency: transitive description: name: win32 sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "5.14.0" xdg_directories: @@ -1146,7 +1146,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "1.1.0" xml: @@ -1154,7 +1154,7 @@ packages: description: name: xml sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 - url: "https://pub.flutter-io.cn" + url: "https://mirrors.tuna.tsinghua.edu.cn/dart-pub/" source: hosted version: "6.5.0" sdks: