diff --git a/lib/customWidget/photo_picker_row.dart b/lib/customWidget/photo_picker_row.dart index 04a2f0d..e8e5d46 100644 --- a/lib/customWidget/photo_picker_row.dart +++ b/lib/customWidget/photo_picker_row.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; @@ -48,12 +49,31 @@ class _MediaPickerGridState extends State { ? widget.initialMediaPaths!.take(widget.maxCount).toList() : []; WidgetsBinding.instance.addPostFrameCallback((_) { + // 改动点:不要把网络地址换成 File(''),保持 File(path)(path 可能是本地也可能是 http) widget.onChanged( - _mediaPaths.map((p) => p.startsWith('http') ? File('') : File(p)).toList(), + _mediaPaths.map((p) => File(p)).toList(), ); }); } + @override + void didUpdateWidget(covariant MediaPickerRow oldWidget) { + super.didUpdateWidget(oldWidget); + // 当父组件传入的 initialMediaPaths 变化时,更新内部 _mediaPaths 并触发 onChanged + if (!listEquals(oldWidget.initialMediaPaths, widget.initialMediaPaths)) { + _mediaPaths = widget.initialMediaPaths != null + ? widget.initialMediaPaths!.take(widget.maxCount).toList() + : []; + setState(() {}); // 触发 rebuild + WidgetsBinding.instance.addPostFrameCallback((_) { + // 改动点:同上,保持 File(path) + widget.onChanged( + _mediaPaths.map((p) => File(p)).toList(), + ); + }); + } + } + Future _showPickerOptions() async { if (!widget.isEdit) return; // 不可编辑时直接返回 @@ -120,6 +140,7 @@ class _MediaPickerGridState extends State { if (picked != null) { final path = picked.path; setState(() => _mediaPaths.add(path)); + // 这里本来就是 File(p) widget.onChanged(_mediaPaths.map((p) => File(p)).toList()); widget.onMediaAdded?.call(path); } @@ -308,6 +329,19 @@ class _RepairedPhotoSectionState extends State { }); } + @override + void didUpdateWidget(covariant RepairedPhotoSection oldWidget) { + super.didUpdateWidget(oldWidget); + // 父组件传入 initialMediaPaths 变更时,同步内部 _mediaPaths 并触发 onChanged + if (!listEquals(oldWidget.initialMediaPaths, widget.initialMediaPaths)) { + _mediaPaths = widget.initialMediaPaths?.take(widget.maxCount).toList() ?? []; + setState(() {}); + WidgetsBinding.instance.addPostFrameCallback((_) { + widget.onChanged(_mediaPaths.map((p) => File(p)).toList()); + }); + } + } + @override Widget build(BuildContext context) { return Container( @@ -372,4 +406,4 @@ class _RepairedPhotoSectionState extends State { ), ); } -} \ No newline at end of file +} diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index 95b3b53..42c37c5 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -418,9 +418,6 @@ U6Hzm1ninpWeE+awIDAQAB ); } /// 人脸比对上传接口 - /// - /// [imagePath] 本地图片文件路径 - /// 返回后端完整 JSON static Future> getUserFace(String imagePath, String studentId) async { final file = File(imagePath); if (!await file.exists()) { @@ -1200,7 +1197,7 @@ U6Hzm1ninpWeE+awIDAQAB }, ); } - /// 安全检查列表 + /// 所以安全检查列表 static Future> getSafeCheckSearchList(Map data, String url) { return HttpManager().request( basePath, @@ -1239,9 +1236,6 @@ U6Hzm1ninpWeE+awIDAQAB }, ); } - - - // 安全检查操作 static Future> SafeCheckStartGoEditMsg( String imagePath, @@ -1332,6 +1326,59 @@ U6Hzm1ninpWeE+awIDAQAB }, ); } + // 安全检查申辩不成立理由提交 + static Future> safeCheckDefendSubmit(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/safetyenvironmental/explain', + fromData: { + ...formData, + 'FFILE': await MultipartFile.fromFile( + file.path, + filename: fileName + ), + } + ); + } + // 安全检查隐患指派 + static Future> safeCheckDangerConfirm(Map data) { + return HttpManager().request( + basePath, + '/app/hidden/confirm', + method: Method.post, + data: { + ...data, + "CORPINFO_ID":SessionService.instance.corpinfoId, + "USER_ID":SessionService.instance.loginUserId, + "OPERATOR" :SessionService.instance.loginUserId, + "NAME":SessionService.instance.loginUser?["USERNAME"]??"", + "USERNAME": SessionService.instance.loginUser?["USERNAME"]??"", + + }, + ); + } + // 安全检查申辩记录 + static Future> safeCheckDefendRecordList(String INSPECTION_ID) { + return HttpManager().request( + basePath, + '/app/safetyenvironmental/getExplain', + method: Method.post, + data: { + "CORPINFO_ID":SessionService.instance.corpinfoId, + "INSPECTION_ORIGINATOR_ID":SessionService.instance.loginUserId, + "INSPECTION_ID" :INSPECTION_ID, + 'tm': DateTime.now().millisecondsSinceEpoch.toString(), + }, + ); + } diff --git a/lib/pages/app/application_page.dart b/lib/pages/app/application_page.dart index 1029379..c8f27e9 100644 --- a/lib/pages/app/application_page.dart +++ b/lib/pages/app/application_page.dart @@ -9,7 +9,6 @@ import '../../tools/tools.dart'; import '../home/userInfo_page.dart'; import 'ai_alarm_page.dart'; import '../home/work/danger_page.dart'; -import '../home/work/danger_repair_page.dart'; enum AppItem { riskInspection, // 隐患排查 diff --git a/lib/pages/app/danger_wait_list_page.dart b/lib/pages/app/danger_wait_list_page.dart index c14822e..ef95ea4 100644 --- a/lib/pages/app/danger_wait_list_page.dart +++ b/lib/pages/app/danger_wait_list_page.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/app/pending_rectification_detail_page.dart'; import 'package:qhd_prevention/pages/home/work/custom_driver_drawer.dart'; import 'package:qhd_prevention/pages/home/risk/risk_detail_page.dart'; -import 'package:qhd_prevention/pages/home/work/danger_repair_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:qhd_prevention/tools/tools.dart'; 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 74ca354..063c454 100644 --- a/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart +++ b/lib/pages/home/SafeCheck/CheckPersonSure/check_person_list_page.dart @@ -246,7 +246,8 @@ class _CheckPersonListPageState extends State { ], ), const SizedBox(height: 8), - if (item['INSPECTION_STATUS'] == '0' || item['INSPECTION_STATUS'] == '1') + if ((item['INSPECTION_STATUS'] == '0' || item['INSPECTION_STATUS'] == '1') && + !FormUtils.hasValue(item, 'INSPECTION_USER_SIGN_TIME')) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart index bc2672e..5aa24a4 100644 --- a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_detail_page.dart @@ -1,19 +1,348 @@ import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/date_picker_dialog.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; +import 'package:qhd_prevention/customWidget/photo_picker_row.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/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; class SafecheckAssignmentDetailPage extends StatefulWidget { - const SafecheckAssignmentDetailPage({super.key}); + const SafecheckAssignmentDetailPage({ + super.key, + required this.HIDDEN_STATUS, + required this.INSPECTION_ID, + required this.HIDDEN_ID, + }); + + final String HIDDEN_STATUS; + final String INSPECTION_ID; + final String HIDDEN_ID; @override - State createState() => _SafecheckAssignmentDetailPageState(); + State createState() => + _SafecheckAssignmentDetailPageState(); } -class _SafecheckAssignmentDetailPageState extends State { +class _SafecheckAssignmentDetailPageState + extends State { + late bool _isEdit = false; + late Map form = {}; + late List files = []; + late List hiddenVideo = []; + late List hiddenExamineList = []; + final Map _danger_des = { + '1': '隐患快报', + '2': '清单排查', + '3': '清单排查', + '4': '安全检查', + '5': '安全检查', + '6': '消防检查', + }; + late List inspectorList = []; + + // 存储各单位的人员列表 + final Map>> _personCache = {}; + + final Map _rect_des = {'1': '立即整改', '2': '限期整改'}; + @override + void initState() { + // TODO: implement initState + super.initState(); + if (widget.HIDDEN_ID == '-2') { + _isEdit = true; + } + WidgetsBinding.instance.addPostFrameCallback((_) { + _getData(); + }); + } + + @override + Future _getData() async { + LoadingDialogHelper.show(); + final data = await ApiService.getDangerDetail(widget.HIDDEN_ID); + LoadingDialogHelper.hide(); + if (data['result'] == 'success') { + setState(() { + form = data['pd']; + final List videos = data['hiddenVideo'] ?? []; + hiddenVideo = + videos + .map((item) => '${ApiService.baseImgPath}${item['FILEPATH']}') + .toList(); + files = data['hImgs']; + }); + } + } + + /// 弹出单位选择 + void chooseUnitHandle(String typeStr) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => DepartmentPicker( + onSelected: (id, name) async { + setState(() { + form['RECTIFICATIONDEPT'] = id; + form['RECTIFICATIONDEPTNAME'] = name; + }); + FocusHelper.clearFocus(context); + _getPersonListForUnitId(typeStr); + }, + ), + ).then((_) {}); + } + + Future _getPersonListForUnitId(String typeStr) async { + String unitId = form['RECTIFICATIONDEPT'] ?? ''; + // 拉取该单位的人员列表并缓存 + final result = await ApiService.getListTreePersonList(unitId); + setState(() { + _personCache[typeStr] = List>.from( + result['userList'] as List, + ); + }); + FocusHelper.clearFocus(context); + } + + /// 弹出人员选择,需先选择单位 + void choosePersonHandle(String typeStr) async { + final personList = _personCache[typeStr]; + if (!FormUtils.hasValue(_personCache, typeStr)) { + ToastUtil.showNormal(context, '请先选择单位'); + return; + } + + DepartmentPersonPicker.show( + context, + personsData: personList!, + onSelectedWithIndex: (userId, name, index) { + setState(() { + form['RECTIFICATIONOR'] = userId; + form['RECTIFICATIONORNAME'] = name; + }); + FocusHelper.clearFocus(context); + }, + ).then((_) {}); + } + + Future _submit() async { + if (!_isEdit) { + Navigator.of(context).pop(); + return; + } + final textRules = >[ + {'value': form['RECTIFICATIONDEPT'], 'message': '整改负责人部门不能为空'}, + {'value': form['RECTIFICATIONOR'], 'message': '整改负责人不能为空'}, + {'value': form['RECTIFICATIONDEADLINE'], 'message': '整改期限不能为空'}, + ]; + for (var rule in textRules) { + if ((rule['value'] as String).isEmpty) { + ToastUtil.showNormal(context, rule['message']); + return; + } + } + Map data = { + 'HIDDEN_ID': form['HIDDEN_ID'], + 'HIDDENLEVEL': form['HIDDENLEVEL'], + 'RECTIFICATIONDEPT': form['RECTIFICATIONDEPT'], + 'RECTIFICATIONDEADLINE': form['RECTIFICATIONDEADLINE'], + 'RECTIFICATIONOR': form['RECTIFICATIONOR'], + 'HIDDEN_STATUS': widget.HIDDEN_STATUS, + 'INSPECTION_ID': widget.INSPECTION_ID, + 'HIDDENDESCR': form['HIDDENDESCR'], + }; + try { + LoadingDialogHelper.show(); + final result = await ApiService.safeCheckDangerConfirm(data); + if (result['result'] == 'success') { + ToastUtil.showNormal(context, '保存成功'); + Navigator.of(context).pop(); + }else{ + ToastUtil.showNormal(context, '保存失败'); + + } + LoadingDialogHelper.hide(); + } catch (e) { + LoadingDialogHelper.hide(); + } + } + Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: '安全检查指派'), - body: SafeArea(child: SizedBox()), + body: SafeArea( + child: ListView( + children: [ + Padding( + padding: EdgeInsetsGeometry.all(12), + child: ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ItemListWidget.singleLineTitleText( + label: '隐患描述', + isEditable: false, + text: form['HIDDENDESCR'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '隐患来源', + isEditable: false, + text: _danger_des[form['SOURCE'] ?? ''] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '隐患部位', + isEditable: false, + text: form['hregionName'] ?? form['HIDDENPART'], + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '隐患级别', + isEditable: false, + text: form['HIDDENLEVELNAME'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '隐患类型', + isEditable: false, + text: + _rect_des[form['RECTIFICATIONTYPE'].toString()] ?? '', + ), + const Divider(), + ItemListWidget.twoRowTitleAndImages( + title: '隐患图片', + imageUrls: files.map((item) => item['FILEPATH']).toList(), + onTapCallBack: (url) { + presentOpaque( + SingleImageViewer(imageUrl: url), + context, + ); + }, + ), + if (hiddenVideo.isNotEmpty) + Column( + children: [ + const Divider(), + ItemListWidget.itemContainer( + horizontal: 5, + RepairedPhotoSection( + title: '隐患视频', + maxCount: 1, + onMediaTapped: (p) { + showDialog( + context: context, + barrierColor: Colors.black54, + builder: (_) => VideoPlayerPopup(videoUrl: p), + ); + }, + isEdit: false, + mediaType: MediaType.video, + initialMediaPaths: hiddenVideo, + onChanged: (files) {}, + onAiIdentify: () {}, + ), + ), + ], + ), + + const Divider(), + ItemListWidget.singleLineTitleText( + label: '隐患发现人', + isEditable: false, + text: form['CREATORNAME'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '发现时间', + isEditable: false, + text: form['CREATTIME'] ?? '', + ), + ], + ), + ), + ), + // SizedBox(height: 12,), + Padding( + padding: EdgeInsetsGeometry.only(left: 12, right: 12), + child: ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ListItemFactory.createBuildSimpleSection('安全检查隐患指派整改人'), + const SizedBox(height: 10), + ItemListWidget.selectableLineTitleTextRightButton( + label: '整改负责人部门', + isEditable: _isEdit, + isRequired: false, + isClean: false, + onTapClean: () { + setState(() {}); + }, + text: form['RECTIFICATIONDEPTNAME'] ?? '请选择', + onTap: () => chooseUnitHandle('key'), + ), + const Divider(), + ItemListWidget.selectableLineTitleTextRightButton( + label: '整改负责人', + isRequired: false, + + isEditable: _isEdit, + text: form['RECTIFICATIONORNAME'] ?? '请选择', + onTap: () => choosePersonHandle('key'), + ), + const Divider(), + ItemListWidget.selectableLineTitleTextRightButton( + label: '整改期限', + isRequired: false, + isEditable: _isEdit, + text: form['RECTIFICATIONDEADLINE'] ?? '请选择', + onTap: () { + showDialog( + context: context, + builder: + (_) => HDatePickerDialog( + initialDate: DateTime.now(), + onCancel: () => Navigator.of(context).pop(), + onConfirm: (selected) { + Navigator.of(context).pop(); + setState(() { + form['RECTIFICATIONDEADLINE'] = DateFormat( + 'yyyy-MM-dd', + ).format(selected); + }); + }, + ), + ); + }, + ), + ], + ), + ), + ), + SizedBox(height: 15), + Padding(padding: EdgeInsets.symmetric(horizontal: 50, vertical: 10), child: CustomButton( + text: _isEdit ? '保存' : '返回', + backgroundColor: Colors.blue, + onPressed: () { + _submit(); + }, + ),) + ], + ), + ), ); } } diff --git a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart index 9d2978d..51dd8d4 100644 --- a/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart +++ b/lib/pages/home/SafeCheck/DangeCheck/safeCheck_assignment_list.dart @@ -2,6 +2,7 @@ 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/DangeCheck/safeCheck_assignment_detail_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'; @@ -112,25 +113,21 @@ class _SafecheckAssignmentListState extends State { } -//查看 + //查看 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(); - // }); + await pushPage(SafecheckAssignmentDetailPage(HIDDEN_STATUS: '0', INSPECTION_ID: item['INSPECTION_ID'], HIDDEN_ID:item['HIDDEN_ID']), context); + _fetchData(); } - /// 指派 + // 指派 void _goToAssign(Map item) async { - // await pushPage(SafecheckSignDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', INSPECTION_INSPECTOR_ID: item['INSPECTION_INSPECTOR_ID'] ?? '',isEdit: false), context); + await pushPage(SafecheckAssignmentDetailPage(HIDDEN_STATUS: '-2', INSPECTION_ID: item['INSPECTION_ID'], HIDDEN_ID:item['HIDDEN_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); diff --git a/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart b/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart new file mode 100644 index 0000000..5975932 --- /dev/null +++ b/lib/pages/home/SafeCheck/Record/defend_record_detail_page.dart @@ -0,0 +1,140 @@ +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.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/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class DefendRecordDetailPage extends StatefulWidget { + const DefendRecordDetailPage({super.key, required this.INSPECTION_ID}); + + final String INSPECTION_ID; + + @override + State createState() => _DefendRecordDetailPageState(); +} + +class _DefendRecordDetailPageState extends State { + late List _list = []; + + @override + void initState() { + // TODO: implement initState + super.initState(); + _getData(); + } + + Future _getData() async { + LoadingDialogHelper.show(); + try { + final result = await ApiService.safeCheckDefendRecordList( + widget.INSPECTION_ID, + ); + if (result['result'] == 'success') { + _list = result['list']; + } + LoadingDialogHelper.hide(); + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '接口请求失败'); + } + } + + Widget _itemWidget(Map item) { + return Container( + color: Colors.white, + child: Column( + children: [ + ItemListWidget.itemContainer( + ListItemFactory.headerTitle( + '申辩意见:${item['INSPECTED_EXPLAIN'] ?? ''}', + ), + ), + ItemListWidget.singleLineTitleText( + label: '申辩时间', + isEditable: false, + text: item['CREATTIME'] ?? '', + ), + ItemListWidget.singleLineTitleText( + label: '申辩状态', + isEditable: false, + text: + item['ISPASS'] == '0' + ? '待审核' + : (item['ISPASS'] == '1' + ? '申辩成功' + : (item['ISPASS'] == '2' ? '申辩驳回' : '历史数据')), + ), + ItemListWidget.OneRowImageTitle( + label: '签字图片:', + imgPath: item['INSPECTED_SITEUSER_SIGN_IMG'] ?? '', + onTapCallBack: (imgUrl) { + presentOpaque(SingleImageViewer(imageUrl: imgUrl), context); + }, + ), + if (FormUtils.hasValue(item, 'INSPECTED_EXPLAIN_FILENAME')) + ItemListWidget.OneRowButtonTitleText( + label: '申辩附件名称', + buttonText: '申辩附件下载', + text: item['INSPECTED_EXPLAIN_FILENAME'] ?? '', + onTap: () { + launchUrl(Uri.parse(item['INSPECTED_EXPLAIN_FILENAME'] ?? '')); + }, + ), + + if (item['ISPASS'] == '2') + Column( + children: [ + ItemListWidget.OneRowImageTitle( + label: '检查人签字:', + imgPath: item['INSPECTION_ORIGINATOR_SIGN_IMG'] ?? '', + onTapCallBack: (imgUrl) { + presentOpaque(SingleImageViewer(imageUrl: imgUrl), context); + }, + ), + ItemListWidget.singleLineTitleText( + label: '检查人意见', + isEditable: false, + text: item['INSPECTED_EXPLAIN_REFUSE'] ?? '', + ), + ItemListWidget.singleLineTitleText( + label: '审批时间', + isEditable: false, + text: item['INSPECTION_ORIGINATOR_SIGN_TIME'] ?? '', + ), + ], + ), + if (item['ISPASS'] == '1') + ItemListWidget.singleLineTitleText( + label: '申辩时间', + isEditable: false, + text: item['OPERATTIME'] ?? '', + ), + SizedBox(height: 10), + const Divider(), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: '申辩记录'), + body: SafeArea( + child: Expanded( + child: ListView.builder( + itemCount: _list.length, + itemBuilder: (context, index) { + final item = _list[index]; + return _itemWidget(item); + }, + ), + ), + ), + ); + } +} diff --git a/lib/pages/home/SafeCheck/Record/defend_record_list_page.dart b/lib/pages/home/SafeCheck/Record/defend_record_list_page.dart new file mode 100644 index 0000000..a89a995 --- /dev/null +++ b/lib/pages/home/SafeCheck/Record/defend_record_list_page.dart @@ -0,0 +1,448 @@ +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/Record/defend_record_detail_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'; +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 DefendRecordListPage extends StatefulWidget { + final String flow; + + const DefendRecordListPage({Key? key, required this.flow}) : super(key: key); + + @override + _DefendRecordListPageState createState() => _DefendRecordListPageState(); +} + +class _DefendRecordListPageState 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'] : '', + 'roleLevel': SessionService.instance.loginUser?['roleLevel'] ?? '', + 'supDeparIds': SessionService.instance.loginUser?['supDeparIds'] ?? '', + 'KEYWORDS': searchKeywords, + }; + final url = + '/app/safetyenvironmental/pleadList?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 _goToDetail(Map item) async { + await pushPage( + DefendRecordDetailPage( + INSPECTION_ID: item['INSPECTION_ID'] ?? '', + ), + 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), + ), + ], + ), + ); + } + + 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'] ?? ''}", + maxLines: 5, + overflow: TextOverflow.ellipsis, + ), + ], + ), + 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( + 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), + ), + ], + ), + ], + ), + ), + ), + ); + } + + // 显示底部选择器 + 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: []), + 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/Start/safeCheck_defend_set_page.dart b/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart index 89dae9e..8ec9f68 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_defend_set_page.dart @@ -1,11 +1,22 @@ +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/custom_button.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/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/item_list_widget.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 SafecheckDefendSetPage extends StatefulWidget { const SafecheckDefendSetPage({super.key, required this.INSPECTION_ID}); + final String INSPECTION_ID; @override @@ -13,10 +24,20 @@ class SafecheckDefendSetPage extends StatefulWidget { } class _SafecheckDefendSetPageState extends State { - late Map form = {}; + late bool chooseType = true; + late String INSPECTION_STATUS = '-2'; + List signImages = []; + List signTimes = []; // 签字时间列表 + @override + void initState() { + // TODO: implement initState + super.initState(); + _getData(); + } Future _getData() async { + LoadingDialogHelper.show(); try { final result = await ApiService.getSafeCheckStartGoEdit( widget.INSPECTION_ID, @@ -25,24 +46,231 @@ class _SafecheckDefendSetPageState extends State { if (!mounted) return; setState(() { form = result['pd'] ?? {}; - }); + LoadingDialogHelper.hide(); } catch (e, st) { + LoadingDialogHelper.hide(); + print('加载单条数据失败: $e\n$st'); if (mounted) { ToastUtil.showNormal(context, '加载数据失败:$e'); } } } + + 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); + 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(), + ); + } + Future _submit() async{ + if (INSPECTION_STATUS == '-2') { + await pushPage(SafecheckStartDetail(INSPECTION_ID: form['INSPECTION_ID'] ?? '', type: 'edit'), context); + return; + } + if (INSPECTION_STATUS == '3' && form['INSPECTED_EXPLAIN_REFUSE'] == '') { + ToastUtil.showNormal(context, '请填写理由'); + return; + } + if (signImages.isEmpty) { + ToastUtil.showNormal(context, '请签字'); + return; + } + LoadingDialogHelper.show(); + form['OPERATOR'] = SessionService.instance.loginUserId; + form['ACTION_USER'] = SessionService.instance.username; + form['INSPECTION_STATUS'] = INSPECTION_STATUS; + final result = await ApiService.safeCheckDefendSubmit(form, signImages.first); + LoadingDialogHelper.hide(); + try{ + if (result['result'] == 'success') { + ToastUtil.showSuccess(context, '保存成功'); + }else{ + ToastUtil.showError(context, '保存失败'); + } + Navigator.of(context).pop(); + }catch(e){} + } + @override Widget build(BuildContext context) { return Scaffold( - appBar: MyAppbar(title: '申辩处理'), - body: SafeArea(child: Padding( - padding: EdgeInsets.all(12), - child: ItemListWidget.itemContainer(Column(children: [ - - ],)))), + appBar: MyAppbar(title: '申辩处理'), + body: SafeArea( + child: + form.isNotEmpty + ? ListView( + children: [ + Padding( + padding: EdgeInsets.all(12), + child: ItemListWidget.itemContainer( + horizontal: 0, + Column( + children: [ + ItemListWidget.OneRowImageTitle( + label: '申辩人签字', + text: form['INSPECTED_SITEUSER_SIGN_TIME'], + onTapCallBack: (path) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + form['INSPECTED_SITEUSER_SIGN_IMG'], + ), + context, + ); + }, + imgPath: + form['INSPECTED_SITEUSER_SIGN_IMG'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '申辩时间', + isEditable: false, + text: form['INSPECTED_SITEUSER_SIGN_TIME'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '申辩说明', + isEditable: false, + text: form['INSPECTED_EXPLAIN'] ?? '', + ), + const Divider(), + ListItemFactory.createYesNoSection( + title: '申辩是否成立:', + groupValue: chooseType, + isEdit: true, + isRequired: true, + horizontalPadding: 5, + verticalPadding: 0, + text: '${form['INSPECTION_SUBJECT'] ?? ''}现场检查记录', + onChanged: (val) { + setState(() { + chooseType = val; + INSPECTION_STATUS = val == true ? '-2' : '3'; + }); + }, + ), + if (INSPECTION_STATUS == '3') + Column( + children: [ + const Divider(), + ItemListWidget.multiLineTitleTextField( + label: '不成立理由', + isEditable: true, + hintText: '请输入理由', + onChanged: (val) { + setState(() { + form['INSPECTED_EXPLAIN_REFUSE'] = val; + }); + }, + ), + const Divider(), + ItemListWidget.itemContainer( + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + ListItemFactory.headerTitle('确认人'), + CustomButton( + text: '手写签字', + height: 36, + backgroundColor: Colors.green, + onPressed: () { + _sign(); + }, + ), + ], + ), + ), + if (signImages.isNotEmpty) _signListWidget(), + ], + ), + ], + ), + ), + ), + CustomButton( + text: INSPECTION_STATUS == '3' ? '提交' : '确认', + backgroundColor: Colors.blue, + onPressed: () { + _submit(); + }, + ), + ], + ) + : SizedBox(), + ), ); } } diff --git a/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart b/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart index ede94d3..39869d6 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_start_detail.dart @@ -1148,19 +1148,24 @@ class _SafecheckStartDetailState extends State { context: context, ), if (widget.type == 'look' && inspectorVerifyList.isNotEmpty) - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— - /// TODO —————————————————————————————————————————————— + Column(children: [ + const Divider(), + ItemListWidget.singleLineTitleText(label: '打回信息', isEditable: false,), + const Divider(), + ItemListWidget.singleLineTitleText(label: '打回人', isEditable: false, text: inspectorVerifyList.first['INSPECTION_USER_NAME']), + const Divider(), + ItemListWidget.singleLineTitleText(label: '打回信息', isEditable: false, text: inspectorVerifyList.first['INSPECTION_USER_OPINION']), + const Divider(), + ItemListWidget.OneRowImageTitle( + label: '检查人签字', + text: inspectorVerifyList.first['INSPECTION_USER_SIGN_TIME']?? '', + onTapCallBack: (path) { + presentOpaque(SingleImageViewer(imageUrl: path), context); + }, + imgPath: inspectorVerifyList.first['INSPECTION_USER_SIGN_IMG']?? '', + ), + ],), if (_isEdit && widget.type != 'detail') Column( children: [ @@ -1239,7 +1244,7 @@ class _SafecheckStartDetailState extends State { fontSize: 17, ), backgroundColor: Colors.blue, - onPressed: () => Navigator.pop(context), + onPressed: _submit, ), ),]else...[ SizedBox( @@ -1251,7 +1256,7 @@ class _SafecheckStartDetailState extends State { fontSize: 17, ), backgroundColor: Colors.blue, - onPressed: _submit, + onPressed:() => Navigator.pop(context), ), ), ] 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 ce60293..ef5d927 100644 --- a/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart +++ b/lib/pages/home/SafeCheck/Start/safeCheck_start_list_page.dart @@ -114,7 +114,7 @@ class _SafecheckStartListPageState extends State { /// 申请 void _handleApply() { // 处理申请按钮点击逻辑 - pushPage(SafecheckStartDetail(INSPECTION_ID: '', type: 'add',), context); + pushPage(SafecheckStartDetail(INSPECTION_ID: '', type: 'add',), context); } /// 打开流程图 @@ -143,7 +143,7 @@ class _SafecheckStartListPageState extends State { void _goToDetail(Map item, String type) async { - pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', type: type), context); + await pushPage(SafecheckStartDetail(INSPECTION_ID: item['INSPECTION_ID'] ?? '', type: type), context); setState(() { _fetchData(); diff --git a/lib/pages/home/SafeCheck/safeCheck_tab_list.dart b/lib/pages/home/SafeCheck/safeCheck_tab_list.dart index 6ee1342..db261cd 100644 --- a/lib/pages/home/SafeCheck/safeCheck_tab_list.dart +++ b/lib/pages/home/SafeCheck/safeCheck_tab_list.dart @@ -7,6 +7,7 @@ import 'package:qhd_prevention/pages/KeyProjects/SafeCheck/safeCheck_list_page.d 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/Record/defend_record_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'; @@ -116,7 +117,12 @@ class _SafecheckTabListState extends State { await pushPage(SafecheckDangerListPage(flow: title), context); } break; - case 4: title = '申辩记录'; break; + case 4: { + title = '申辩记录'; + await pushPage(DefendRecordListPage(flow: title), context); + + } break; + default: print("按钮 $index 被点击"); diff --git a/lib/pages/home/tap/item_list_widget.dart b/lib/pages/home/tap/item_list_widget.dart index 1d8c08f..6ad47eb 100644 --- a/lib/pages/home/tap/item_list_widget.dart +++ b/lib/pages/home/tap/item_list_widget.dart @@ -510,6 +510,7 @@ class ItemListWidget { required String text, // 显示内容或提示 required VoidCallback? onTap, // 第一行点击回调 double fontSize = 15, // 字体大小 + String buttonText = '分析详情' }) { return Container( padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 12), @@ -542,7 +543,7 @@ class ItemListWidget { ), ), CustomButton( - text: "分析详情", + text: buttonText, height: 30, padding: const EdgeInsets.symmetric(vertical: 2, horizontal: 5), backgroundColor: Colors.green, @@ -648,7 +649,7 @@ class ItemListWidget { /// 第二行:图片 static Widget twoRowTitleAndImages({ required String title, // 第一行标题 - required List? imageUrls, // 传入 pd['CONTENT_IMG_PATH'] + required List? imageUrls, double row2Height = 80, // 第二行高度 double fontSize = 15, // 字体大小 void Function(String)? onTapCallBack, diff --git a/lib/pages/home/work/dangerTypeItems/finish/danger_acceptance_finish.dart b/lib/pages/home/work/dangerTypeItems/finish/danger_acceptance_finish.dart deleted file mode 100644 index 20b7b82..0000000 --- a/lib/pages/home/work/dangerTypeItems/finish/danger_acceptance_finish.dart +++ /dev/null @@ -1,96 +0,0 @@ -import 'package:flutter/material.dart'; - -import '../../../../../customWidget/ItemWidgetFactory.dart'; -import '../../../../../customWidget/full_screen_video_page.dart'; -import '../../../../../customWidget/single_image_viewer.dart'; -import '../../../../../tools/tools.dart'; - -class DangerAcceptanceFinish extends StatefulWidget { - const DangerAcceptanceFinish({super.key}); - - @override - State createState() => _DangerAcceptanceFinishState(); -} - -class _DangerAcceptanceFinishState extends State { - final List imgUrls = [ - "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", - "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", - ]; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 0), - child: DecoratedBox( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // 标题 - ListItemFactory.createBuildSimpleSection("验收信息"), - const Divider(height: 1), - - // 修复信息 summary 区域 - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListItemFactory.createColumnTextItem( - topText: "验收描述", - bottomText: "这是一段整改描述", - ), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "是否合格", - rightText: "--", - ), - const Divider(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "验收部门", - rightText: "部门", - ), - const Divider(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "验收部门负责人", - rightText: "韩双", - ), - const Divider(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "验收时间", - rightText: "2020-01-01", - ), - ListItemFactory.createTextImageItem( - text: "验收图片", - imageUrls: imgUrls, - onImageTapped: (index) { - presentOpaque( - SingleImageViewer(imageUrl: imgUrls[index]), - context, - ); - }, - ), - ListItemFactory.createTextVideoItem( - text: "验收视频", - videoUrl: "https://www.w3school.com.cn/i/movie.mp4", - onVideoTapped: () { - showDialog( - context: context, - barrierColor: Colors.black54, - builder: (_) => VideoPlayerPopup(videoUrl: "https://www.w3school.com.cn/i/movie.mp4"), - ); - } - ), - SizedBox(height: 20), - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/lib/pages/home/work/dangerTypeItems/finish/danner_repair_finish.dart b/lib/pages/home/work/dangerTypeItems/finish/danner_repair_finish.dart deleted file mode 100644 index f2b95d4..0000000 --- a/lib/pages/home/work/dangerTypeItems/finish/danner_repair_finish.dart +++ /dev/null @@ -1,88 +0,0 @@ -import 'package:flutter/material.dart'; -import '../../../../../customWidget/ItemWidgetFactory.dart'; -import '../../../../../customWidget/single_image_viewer.dart'; -import '../../../../../tools/tools.dart'; - -class DannerRepairFinish extends StatefulWidget { - const DannerRepairFinish({super.key}); - - @override - State createState() => _DannerRepairFinishState(); -} - -class _DannerRepairFinishState extends State { - final List imgUrls = [ - "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", - "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", - ]; - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 0), - child: DecoratedBox( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // 标题 - ListItemFactory.createBuildSimpleSection("整改信息"), - const Divider(height: 1), - - // 修复信息 summary 区域 - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12,), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListItemFactory.createColumnTextItem( - topText: "整改描述", - bottomText: "这是一段整改描述", - ), - // const SizedBox(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改部门", - rightText: "部门", - ), - const Divider(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改人", - rightText: "韩双", - ), - const Divider(height: 10), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改时间", - rightText: "2020-01-01", - ), - ListItemFactory.createTextImageItem( - text: "整改后图片", - imageUrls: imgUrls, - onImageTapped: (index) { - presentOpaque( - SingleImageViewer(imageUrl: imgUrls[index]), - context, - ); - }, - ), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改方案", - rightText: "无", - ), - Divider(height: 10,), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改计划", - rightText: "无", - ), - ], - ), - ), - ], - ), - ), - ); - } -} - diff --git a/lib/pages/home/work/danger_repair_page.dart b/lib/pages/home/work/danger_repair_page.dart deleted file mode 100644 index 013baab..0000000 --- a/lib/pages/home/work/danger_repair_page.dart +++ /dev/null @@ -1,390 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:qhd_prevention/customWidget/custom_button.dart'; -import 'package:qhd_prevention/pages/home/work/dangerTypeItems/danger_detail.dart'; -import 'package:qhd_prevention/pages/home/work/dangerTypeItems/finish/danger_acceptance_finish.dart'; -import 'package:qhd_prevention/pages/home/work/dangerTypeItems/wait/danger_acceptance.dart'; -import 'package:qhd_prevention/pages/app/danner_repair.dart'; -import 'package:qhd_prevention/pages/app/danger_wait_list_page.dart'; -import 'package:qhd_prevention/pages/my_appbar.dart'; -import 'package:qhd_prevention/tools/h_colors.dart'; -import '../../../customWidget/ItemWidgetFactory.dart'; -import '../../../customWidget/single_image_viewer.dart'; -import '../../../http/ApiService.dart'; -import '../../../tools/tools.dart'; -import 'dangerTypeItems/finish/danner_repair_finish.dart'; - -class DangerRepairPage extends StatefulWidget { - const DangerRepairPage(this.dangerType, this.item, {Key? key}) : super(key: key); - - final DangerType dangerType; - final item; - - @override - State createState() => _DangerRepairPageState(); -} - -class _DangerRepairPageState extends State { - // 是否整改 - bool _accepted = false; - List hImgs = []; - List rImgs = []; - dynamic pd; - - @override - void initState() { - // TODO: implement initState - super.initState(); - if (widget.dangerType == DangerType.ristRecord){// 跳转到隐患记录页面 - _getDangerDetail(); - }else if (widget.dangerType == DangerType.wait){// 跳转到待整改隐患页面 - - }else if (widget.dangerType == DangerType.expired){// 跳转到超期未整改页面 - - }else if (widget.dangerType == DangerType.waitAcceptance){// 跳转到隐患验收页面 - - }else{// 跳转到已验收隐患页面 - - } - - } - - - - Widget build(BuildContext context) { - return Scaffold( - appBar: MyAppbar(title: widget.dangerType.detailTitle), - body: SafeArea( - child: Column( - children: [ - // 可滚动内容区域 - Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - // 隐患详情 - // DangerDetail(), - DangerPageDetail(), - - SizedBox(height: 15), - if (widget.dangerType == DangerType.wait) // 隐患整改 - _danner_type_wait() - else if (widget.dangerType == - DangerType.waitAcceptance) ...[ // 已整改、待验收 - DannerRepairFinish(), - SizedBox(height: 15), - DangerAcceptance(), - const SizedBox(height: 20), - CustomButton( - text: "提交", - backgroundColor: Colors.blue, - onPressed: () { - _submitToServer(); - }, - ), - ] else if (widget.dangerType == DangerType.acceptanced) ...[ - DannerRepairFinish(), - SizedBox(height: 15), - DangerAcceptanceFinish() - ] - else - SizedBox(), - ], - ), - ), - ), - // 底部警示文字,固定在页面底部 - if (widget.dangerType == DangerType.wait || - widget.dangerType == DangerType.waitAcceptance) - Container( - padding: const EdgeInsets.all(15), - color: Colors.white, - child: Text( - ' 严禁在本互联网非涉密平台处理、传输国家秘密和工作秘密,请确认扫描、传输的文件资料不涉及国家秘密和工作秘密', - style: TextStyle(fontSize: 14, color: Colors.red), - ), - ), - ], - ), - ), - ); - } - - /// 隐患整改 - Widget _danner_type_wait() { - return SizedBox( - child: Column( - children: [ - ListItemFactory.createYesNoSection( - horizontalPadding: 0, - - title: '是否正常整改', - yesLabel: '是', - noLabel: '否', - groupValue: _accepted, - onChanged: (val) { - setState(() { - _accepted = val; - }); - }, - ), - // 整改选项 - // _accepted ? DannerRepair() : _noAccepet_repair(_accepted), - - const SizedBox(height: 20), - CustomButton( - text: "提交", - backgroundColor: Colors.blue, - onPressed: () { - _submitToServer(); - }, - ), - ], - ), - ); - } - - void _submitToServer() { - // Todo 发送给接口... - } - - // #region 不整改 - Widget _noAccepet_repair(bool _accept) { - return Column( - children: [ - Container( - padding: EdgeInsets.symmetric(horizontal: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改部门", - rightText: "测试啊", - isRight: true, - ), - ), - Divider( - height: 10, - color: _accept ? h_backGroundColor() : Colors.transparent, - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改负责人", - rightText: "测试啊", - isRight: true, - ), - ), - ], - ); - } - - - Future _getDangerDetail() async { - try { - - final result = await ApiService.getDangerDetail(widget.item['HIDDEN_ID']); - if (result['result'] == 'success') { - setState(() { - hImgs= result['hImgs']; - rImgs= result['rImgs']; - pd= result['pd']; - - }); - }else{ - _showMessage('加载数据失败'); - } - } catch (e) { - // 出错时可以 Toast 或者在页面上显示错误状态 - print('加载数据失败:$e'); - } - } - - void _showMessage(String msg) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); - } - - - final List imgUrls = [ - "https://picsum.photos/id/237/200/300", - "https://pic.rmb.bdstatic.com/bjh/news/100b8b78cbd136ede03249d9f3b3f5c42221.jpeg", - ]; - Widget DangerPageDetail() { - return Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ListView( - shrinkWrap: true, - physics: NeverScrollableScrollPhysics(), - children: [ - ListItemFactory.createRowSpaceBetweenItem( - leftText: "隐患描述", - rightText: "", - // rightText: pd["HIDDENDESCR"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "隐患来源", - rightText: "", - // rightText: _getSourceDangers(pd), - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "风险点(单元)", - rightText: "", - // rightText: pd["RISK_UNIT"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "辨识部位", - rightText: "", - // rightText: pd["IDENTIFICATION"]??"", - ), - Divider(height: 1), - ListItemFactory.createColumnTextItem( - topText: "存在风险", - bottomText: "", - // bottomText: pd["RISK_DESCR"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "风险分级", - rightText: "", - // rightText: pd["LEVEL"]??"", - ), - Divider(height: 1), - - ListItemFactory.createColumnTextItem( - topText: "检测内容", - bottomText: "", - // bottomText: pd["CHECK_CONTENT"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "隐患部位", - rightText: "", - // rightText: pd["HIDDENPART"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "发现人", - rightText: "", - // rightText: pd["CREATORNAME"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "发现时间", - rightText: "", - // rightText: pd["CREATTIME"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "隐患类型", - rightText: "", - // rightText: pd["HIDDENTYPE_NAME"]??"", - ), - Divider(height: 1), - ListItemFactory.createRowSpaceBetweenItem( - leftText: "整改类型", - rightText: "", - // rightText: _getZhengGaiType(pd), - ), - Divider(height: 1), - - - ], - - - - - - - - // itemCount: 16, - // separatorBuilder: (_, __) => const Divider(height: 1), - // itemBuilder: (context, index) { - // Widget item; - // // if (index == 0) { - // // item = ListItemFactory.createAloneTextItem( - // // text: "地坪漆漆未分配全皮肤期漆未分配全皮肤期漆未分配全皮肤期未分配全皮肤期间哦飞机哦脾气金佛怕", - // // ); - // // } else - // if ((index == 0 && index < 4) || - // index == 5 || - // (index > 6 && index < 15)) { - // item = ListItemFactory.createRowSpaceBetweenItem( - // leftText: "隐患来源", - // rightText: "隐患排查", - // ); - // } else if (index == 4 || index == 6) { - // item = ListItemFactory.createColumnTextItem( - // topText: "存在风险", - // bottomText: "哦IQ好然后前后hi前后哦i", - // ); - // } else { - // item = ListItemFactory.createTextImageItem( - // text: "隐患照片", - // imageUrls: imgUrls, - // onImageTapped: (index) { - // present( - // SingleImageViewer(imageUrl: imgUrls[index]), - // context, - // ); - // }, - // ); - // } - // - // // 给每个 item 单独加左右内边距 - // return Padding( - // padding: const EdgeInsets.symmetric( - // horizontal: 12, - // vertical: 8, - // ), - // child: item, - // ); - // }, - ), - ], - ), - ); - -} - - String _getSourceDangers(final item) { - String type = item["SOURCE"]; - if("1"==type){ - return "隐患来源:隐患快报"; - }else if("2"==type){ - return "隐患来源:隐患排查清单检查"; - }else if("3"==type){ - return "隐患来源:标准排查清单检查"; - }else if("4"==type){ - return "隐患来源:专项检查"; - }else{ - return "隐患来源:安全检查"; - } - } - - String _getZhengGaiType(final item) { - String type = item["RECTIFICATIONTYPE"]; - if("1"==type){ - return "立即整改"; - }else { - return "限期整改"; - } - } - -} - - diff --git a/pubspec.yaml b/pubspec.yaml index e24e667..4cf613b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -79,6 +79,7 @@ dependencies: flutter_new_badger: ^1.1.1 #loading flutter_easyloading: ^3.0.5 + dev_dependencies: flutter_test: sdk: flutter