From 3a00844a573fb1444e627e326052b7279c73356f Mon Sep 17 00:00:00 2001 From: hs <873121290@qq.com> Date: Wed, 30 Jul 2025 17:08:46 +0800 Subject: [PATCH] 1 --- lib/customWidget/photo_picker_row.dart | 218 ++++++++------- lib/http/ApiService.dart | 56 +++- lib/main.dart | 2 +- lib/pages/home/tap/item_list_widget.dart | 10 +- .../special_wrok/WorkDetailFormWidget.dart | 250 +++++++++-------- .../dangerous_options_page.dart | 264 ++++++++++++++++++ .../hotwork_safe_func_sure.dart | 190 ++++++++----- .../dh_work_detai/MeasuresListWidget.dart | 142 +++++++--- .../dh_work_detai/hotwork_apply_detail.dart | 115 ++++---- .../hotwork_set_safe_detail.dart | 36 +-- lib/tools/h_colors.dart | 2 +- 11 files changed, 879 insertions(+), 406 deletions(-) create mode 100644 lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/dangerous_options_page.dart diff --git a/lib/customWidget/photo_picker_row.dart b/lib/customWidget/photo_picker_row.dart index 62e62d6..6f0a007 100644 --- a/lib/customWidget/photo_picker_row.dart +++ b/lib/customWidget/photo_picker_row.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:wechat_assets_picker/wechat_assets_picker.dart'; import 'package:photo_manager/photo_manager.dart'; @@ -10,25 +9,32 @@ import 'ItemWidgetFactory.dart'; /// 媒体选择类型 enum MediaType { image, video } -/// 横向一行最多四个媒体的添加组件,支持拍摄和全屏相册多选 +/// 横向一行最多四个媒体的添加组件,支持拍摄、全屏相册多选,以及初始地址列表展示 /// 使用示例: /// MediaPickerRow( /// maxCount: 4, /// mediaType: MediaType.video, -/// onChanged: (List medias) { -/// // medias 列表更新 -/// }, +/// initialMediaPaths: ['https://...', '/local/path.png'], +/// onChanged: (List medias) {}, +/// onMediaAdded: (String path) {}, +/// onMediaRemoved: (String path) {}, /// ), class MediaPickerRow extends StatefulWidget { final int maxCount; final MediaType mediaType; + final List? initialMediaPaths; final ValueChanged> onChanged; + final ValueChanged? onMediaAdded; + final ValueChanged? onMediaRemoved; const MediaPickerRow({ Key? key, this.maxCount = 4, this.mediaType = MediaType.image, + this.initialMediaPaths, required this.onChanged, + this.onMediaAdded, + this.onMediaRemoved, }) : super(key: key); @override @@ -37,56 +43,69 @@ class MediaPickerRow extends StatefulWidget { class _MediaPickerRowState extends State { final ImagePicker _picker = ImagePicker(); - final List _files = []; + late List _mediaPaths; + + @override + void initState() { + super.initState(); + _mediaPaths = widget.initialMediaPaths != null + ? widget.initialMediaPaths!.take(widget.maxCount).toList() + : []; + WidgetsBinding.instance.addPostFrameCallback((_) { + // 初始回调,转换为 File 列表 + widget.onChanged(_mediaPaths.map((p) => p.startsWith('http') ? File('') : File(p)).toList()); + }); + } Future _showPickerOptions() async { showModalBottomSheet( context: context, - builder: - (_) => SafeArea( - child: Wrap( - children: [ - ListTile( - leading: Icon( - widget.mediaType == MediaType.image - ? Icons.camera_alt - : Icons.videocam, - ), - title: Text( - widget.mediaType == MediaType.image ? '拍照' : '拍摄视频', - ), - onTap: () { - Navigator.of(context).pop(); - _pickCamera(); - }, - ), - ListTile( - leading: Icon( - widget.mediaType == MediaType.image - ? Icons.photo_library - : Icons.video_library, - ), - title: Text( - widget.mediaType == MediaType.image ? '从相册选择' : '从相册选择视频', - ), - onTap: () { - Navigator.of(context).pop(); - _pickGallery(); - }, - ), - ListTile( - leading: const Icon(Icons.close), - title: const Text('取消'), - onTap: () => Navigator.of(context).pop(), - ), - ], + builder: (_) => SafeArea( + child: Wrap( + children: [ + ListTile( + leading: Icon( + widget.mediaType == MediaType.image + ? Icons.camera_alt + : Icons.videocam, + ), + title: Text( + widget.mediaType == MediaType.image ? '拍照' : '拍摄视频', + ), + onTap: () { + Navigator.of(context).pop(); + _pickCamera(); + }, ), - ), + ListTile( + leading: Icon( + widget.mediaType == MediaType.image + ? Icons.photo_library + : Icons.video_library, + ), + title: Text( + widget.mediaType == MediaType.image + ? '从相册选择' + : '从相册选择视频', + ), + onTap: () { + Navigator.of(context).pop(); + _pickGallery(); + }, + ), + ListTile( + leading: const Icon(Icons.close), + title: const Text('取消'), + onTap: () => Navigator.of(context).pop(), + ), + ], + ), + ), ); } Future _pickCamera() async { - if (_files.length >= widget.maxCount) return; + if (_mediaPaths.length >= widget.maxCount) return; try { XFile? picked; if (widget.mediaType == MediaType.image) { @@ -95,10 +114,10 @@ class _MediaPickerRowState extends State { picked = await _picker.pickVideo(source: ImageSource.camera); } if (picked != null) { - setState(() { - _files.add(File(picked!.path)); - }); - widget.onChanged(_files); + final path = picked.path; + setState(() => _mediaPaths.add(path)); + widget.onChanged(_mediaPaths.map((p) => File(p)).toList()); + widget.onMediaAdded?.call(path); } } catch (e) { debugPrint('拍摄失败: $e'); @@ -106,49 +125,50 @@ class _MediaPickerRowState extends State { } Future _pickGallery() async { - if (_files.length >= widget.maxCount) return; + if (_mediaPaths.length >= widget.maxCount) return; final permission = await PhotoManager.requestPermissionExtend(); if (permission != PermissionState.authorized && permission != PermissionState.limited) { - ScaffoldMessenger.of( - context, - ).showSnackBar(const SnackBar(content: Text('请到设置中开启相册访问权限'))); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar(content: Text('请到设置中开启相册访问权限')), + ); return; } try { - final remaining = widget.maxCount - _files.length; + final remaining = widget.maxCount - _mediaPaths.length; final List? assets = await AssetPicker.pickAssets( context, pickerConfig: AssetPickerConfig( - requestType: - widget.mediaType == MediaType.image - ? RequestType.image - : RequestType.video, + requestType: widget.mediaType == MediaType.image + ? RequestType.image + : RequestType.video, maxAssets: remaining, gridCount: 4, ), ); if (assets != null) { for (final asset in assets) { - if (_files.length >= widget.maxCount) break; + if (_mediaPaths.length >= widget.maxCount) break; final file = await asset.file; if (file != null) { - _files.add(file); + final path = file.path; + _mediaPaths.add(path); + widget.onMediaAdded?.call(path); } } setState(() {}); - widget.onChanged(_files); + widget.onChanged(_mediaPaths.map((p) => File(p)).toList()); } } catch (e) { debugPrint('相册选择失败: $e'); } } - void _removeFile(int index) { - setState(() { - _files.removeAt(index); - }); - widget.onChanged(_files); + void _removeMedia(int index) { + final removed = _mediaPaths[index]; + setState(() => _mediaPaths.removeAt(index)); + widget.onChanged(_mediaPaths.map((p) => File(p)).toList()); + widget.onMediaRemoved?.call(removed); } @override @@ -157,43 +177,42 @@ class _MediaPickerRowState extends State { height: 80, child: ListView.separated( scrollDirection: Axis.horizontal, - itemCount: - _files.length < widget.maxCount - ? _files.length + 1 - : widget.maxCount, + itemCount: _mediaPaths.length < widget.maxCount + ? _mediaPaths.length + 1 + : widget.maxCount, separatorBuilder: (_, __) => const SizedBox(width: 8), itemBuilder: (context, index) { - if (index < _files.length) { + if (index < _mediaPaths.length) { + final path = _mediaPaths[index]; + final isNetwork = path.startsWith('http'); return Stack( children: [ ClipRRect( borderRadius: BorderRadius.circular(5), - child: - widget.mediaType == MediaType.image - ? Image.file( - _files[index], - width: 80, - height: 80, - fit: BoxFit.cover, - ) - : Container( - width: 80, - height: 80, - color: Colors.black12, - child: const Center( - child: Icon( - Icons.videocam, - color: Colors.white70, - ), - ), - ), + child: widget.mediaType == MediaType.image + ? (isNetwork + ? Image.network(path, + width: 80, height: 80, fit: BoxFit.cover) + : Image.file(File(path), + width: 80, height: 80, fit: BoxFit.cover)) + : Container( + width: 80, + height: 80, + color: Colors.black12, + child: const Center( + child: Icon( + Icons.videocam, + color: Colors.white70, + ), + ), + ), ), Positioned( - top: -6, - right: -6, + top: -15, + right: -15, child: IconButton( icon: const Icon(Icons.cancel, size: 20, color: Colors.red), - onPressed: () => _removeFile(index), + onPressed: () => _removeMedia(index), ), ), ], @@ -230,7 +249,10 @@ class RepairedPhotoSection extends StatelessWidget { final int maxCount; final MediaType mediaType; final String title; + final List? initialMediaPaths; final ValueChanged> onChanged; + final ValueChanged? onMediaAdded; + final ValueChanged? onMediaRemoved; final VoidCallback onAiIdentify; final bool isShowAI; final double horizontalPadding; @@ -240,10 +262,13 @@ class RepairedPhotoSection extends StatelessWidget { this.maxCount = 4, this.mediaType = MediaType.image, required this.title, + this.initialMediaPaths, this.isShowAI = false, required this.onChanged, required this.onAiIdentify, this.horizontalPadding = 10, + this.onMediaAdded, + this.onMediaRemoved, }) : super(key: key); @override @@ -257,7 +282,7 @@ class RepairedPhotoSection extends StatelessWidget { padding: EdgeInsets.symmetric(horizontal: horizontalPadding), child: ListItemFactory.createRowSpaceBetweenItem( leftText: title, - rightText: '0/$maxCount', + rightText: '${initialMediaPaths?.length ?? 0}/$maxCount', ), ), Padding( @@ -265,7 +290,10 @@ class RepairedPhotoSection extends StatelessWidget { child: MediaPickerRow( maxCount: maxCount, mediaType: mediaType, + initialMediaPaths: initialMediaPaths, onChanged: onChanged, + onMediaAdded: onMediaAdded, + onMediaRemoved: onMediaRemoved, ), ), const SizedBox(height: 20), diff --git a/lib/http/ApiService.dart b/lib/http/ApiService.dart index cef8921..49515b1 100644 --- a/lib/http/ApiService.dart +++ b/lib/http/ApiService.dart @@ -714,7 +714,7 @@ U6Hzm1ninpWeE+awIDAQAB data: { "CORPINFO_ID":SessionService.instance.corpinfoId, "HOTWORK_ID": homeWorkId, - "USER_ID":SessionService.instance.loginUserId, + "CONFIRM_ID":SessionService.instance.loginUserId, }, ); } @@ -801,6 +801,60 @@ U6Hzm1ninpWeE+awIDAQAB ); } + /// 上传图片 + static Future> uploadSaveFile ( + String filePath, + ) async { + final Map data = { + "CORPINFO_ID":SessionService.instance.corpinfoId, + }; + // 把文件路径填成 MultipartFile + final path = filePath; + data['file'] = await MultipartFile.fromFile( + path, + filename: path.split(Platform.pathSeparator).last, + ); + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/eightwork/saveFile', + fromData: data, + ); + } + ///删除图片 + static Future> deleteSaveFile(String FILE_PATH) { + return HttpManager().request( + basePath, + '/app/eightwork/deleteFile', + method: Method.post, + data: { + "FILE_PATH": FILE_PATH, + }, + ); + } + /// 安全措施个项保存 + static Future> saveDangerousOptionsFile ( + List filePaths, + ) async { + // 复制一份 formData + final Map data = { + "CORPINFO_ID":SessionService.instance.corpinfoId, + }; + // 把文件路径填成 MultipartFile + for (var i = 0; i < filePaths.length; i++) { + final path = filePaths[i]; + data['file$i'] = await MultipartFile.fromFile( + path, + filename: path.split(Platform.pathSeparator).last, + ); + } + return HttpManager().uploadFaceImage( + baseUrl: basePath, + path: '/app/eightwork/saveDangerousOptionsFile', + fromData: data, + ); + } + + ///TODO -------------–-------------------- 我的 -------------–-------------------- diff --git a/lib/main.dart b/lib/main.dart index 6dadfbd..782ac09 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -87,7 +87,7 @@ class MyApp extends StatelessWidget { ), primarySwatch: Colors.blue, // 统一设置页面背景颜色 - scaffoldBackgroundColor: const Color(0xFFF5F7FA), // 浅灰色背景 + scaffoldBackgroundColor: const Color(0xFFF1F1F1), // 浅灰色背景 colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), inputDecorationTheme: const InputDecorationTheme( border: InputBorder.none, diff --git a/lib/pages/home/tap/item_list_widget.dart b/lib/pages/home/tap/item_list_widget.dart index abbaf30..40be6f4 100644 --- a/lib/pages/home/tap/item_list_widget.dart +++ b/lib/pages/home/tap/item_list_widget.dart @@ -1,13 +1,17 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; +import '../../../customWidget/single_image_viewer.dart'; +import '../../../tools/tools.dart'; + class ItemListWidget { + + static const Color detailtextColor = Colors.black54; /// 单行水平排列: /// - 可编辑时:标题 + TextField /// - 不可编辑时:标题 + 带省略号的文本 - - static const Color detailtextColor = Colors.black54; - static Widget singleLineTitleText({ required String label, // 标题文本 required bool isEditable, // 是否可编辑 diff --git a/lib/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart b/lib/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart index f104d59..c5e8a35 100644 --- a/lib/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart +++ b/lib/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart @@ -35,129 +35,147 @@ class WorkDetailFormWidget extends StatelessWidget { this.relatedController, this.riskController, }) : assert( - !isEditable || (contentController != null && locationController != null && methodController != null && hotworkPersonController != null && relatedController != null && riskController != null), - 'Editable mode requires all TextEditingController parameters', - ), - super(key: key); + !isEditable || + (contentController != null && + locationController != null && + methodController != null && + hotworkPersonController != null && + relatedController != null && + riskController != null), + 'Editable mode requires all TextEditingController parameters', + ), + super(key: key); @override Widget build(BuildContext context) { final pd = this.pd; - return Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - ItemListWidget.singleLineTitleText( - label: '申请单位:', - isEditable: false, - text: pd['APPLY_DEPARTMENT_NAME'] ?? '', + return + Container( + padding: EdgeInsets.symmetric(vertical: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), ), - const Divider(), - ItemListWidget.singleLineTitleText( - label: '申请人:', - isEditable: false, - text: pd['APPLY_USER_NAME'] ?? '', - ), - if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[ - const Divider(), - ItemListWidget.singleLineTitleText( - label: '编号:', - isEditable: false, - text: pd['CHECK_NO'] ?? '', - ), - ], - const Divider(), - ItemListWidget.multiLineTitleTextField( - label: '作业内容:', - isEditable: isEditable, - controller: contentController, - text: pd['WORK_CONTENT'] ?? '', - ), - const Divider(), - ItemListWidget.singleLineTitleText( - label: '动火地点及动火部位:', - isEditable: isEditable, - controller: locationController, - text: pd['WORK_PLACE'] ?? '', - ), - const Divider(), - ItemListWidget.selectableLineTitleTextField( - label: '动火作业级别:', - isEditable: isEditable, - onTap: onChooseLevel, - text: pd['WORK_LEVEL'] ?? '', - ), - const Divider(), - ItemListWidget.singleLineTitleText( - label: '动火方式:', - isEditable: isEditable, - controller: methodController, - text: pd['WORK_FUNCTION'] ?? '', - ), - if (pd['WORK_START_DATE']?.toString().isNotEmpty == true) ...[ - const Divider(), - ItemListWidget.singleLineTitleText( - label: '动火作业实施时间:', - isEditable: isEditable, - text: '${pd['WORK_START_DATE']} 至 ${pd['WORK_END_DATE'] ?? '--'}', - ), - ], - const Divider(), - ItemListWidget.twoRowSelectableTitleText( - label: '动火人及证书编号:', - isEditable: isEditable, - onTap: onChooseHotworkUser, - text: pd['WORK_USER'] ?? '', - controller: hotworkPersonController, - ), - const Divider(), - ItemListWidget.twoRowButtonTitleText( - label: '关联其他特殊作业及安全作业票:', - isEditable: isEditable, - onTap: () async { - final val = await showDialog( - context: context, - builder: (_) => SelectionPopup( - type: 'assignments', - initialValue: pd['SPECIAL_WORK'] ?? '', - onConfirm: (v) => Navigator.of(context).pop(v), + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ItemListWidget.singleLineTitleText( + label: '申请单位:', + isEditable: false, + text: pd['APPLY_DEPARTMENT_NAME'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '申请人:', + isEditable: false, + text: pd['APPLY_USER_NAME'] ?? '', + ), + if (FormUtils.hasValue(pd, 'CHECK_NO')) ...[ + const Divider(), + ItemListWidget.singleLineTitleText( + label: '编号:', + isEditable: false, + text: pd['CHECK_NO'] ?? '', ), - ); - if (val != null) pd['SPECIAL_WORK'] = val; - FocusHelper.clearFocus(context); - }, - hintText: '请输入关联的其他特殊作业及安全作业票编号', - controller: relatedController, - text: pd['SPECIAL_WORK'] ?? '', - ), - const Divider(), - ItemListWidget.twoRowButtonTitleText( - label: '风险辨识结果:', - isEditable: isEditable, - onTap: () async { - final val = await showDialog( - context: context, - builder: (_) => SelectionPopup( - type: 'identification', - initialValue: pd['RISK_IDENTIFICATION'] ?? '', - onConfirm: (v) => Navigator.of(context).pop(v), + ], + const Divider(), + ItemListWidget.multiLineTitleTextField( + label: '作业内容:', + isEditable: isEditable, + controller: contentController, + text: pd['WORK_CONTENT'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '动火地点及动火部位:', + isEditable: isEditable, + controller: locationController, + text: pd['WORK_PLACE'] ?? '', + ), + const Divider(), + ItemListWidget.selectableLineTitleTextField( + label: '动火作业级别:', + isEditable: isEditable, + onTap: onChooseLevel, + text: pd['WORK_LEVEL'] ?? '', + ), + const Divider(), + ItemListWidget.singleLineTitleText( + label: '动火方式:', + isEditable: isEditable, + controller: methodController, + text: pd['WORK_FUNCTION'] ?? '', + ), + if (pd['WORK_START_DATE']?.toString().isNotEmpty == true) ...[ + const Divider(), + ItemListWidget.singleLineTitleText( + label: '动火作业实施时间:', + isEditable: isEditable, + text: '${pd['WORK_START_DATE']} 至 ${pd['WORK_END_DATE'] ?? '--'}', ), - ); - if (val != null) pd['RISK_IDENTIFICATION'] = val; - FocusHelper.clearFocus(context); - }, - hintText: '请输入风险辨识结果', - controller: riskController, - text: pd['RISK_IDENTIFICATION'] ?? '', + ], + const Divider(), + ItemListWidget.twoRowSelectableTitleText( + label: '动火人及证书编号:', + isEditable: isEditable, + onTap: onChooseHotworkUser, + text: pd['WORK_USER'] ?? '', + controller: hotworkPersonController, + ), + const Divider(), + ItemListWidget.twoRowButtonTitleText( + label: '关联其他特殊作业及安全作业票:', + isEditable: isEditable, + onTap: () async { + final val = await showDialog( + context: context, + builder: + (_) => SelectionPopup( + type: 'assignments', + initialValue: pd['SPECIAL_WORK'] ?? '', + onConfirm: (v) => Navigator.of(context).pop(v), + ), + ); + if (val != null) pd['SPECIAL_WORK'] = val; + FocusHelper.clearFocus(context); + }, + hintText: '请输入关联的其他特殊作业及安全作业票编号', + controller: relatedController, + text: pd['SPECIAL_WORK'] ?? '', + ), + const Divider(), + ItemListWidget.twoRowButtonTitleText( + label: '风险辨识结果:', + isEditable: isEditable, + onTap: () async { + final val = await showDialog( + context: context, + builder: + (_) => SelectionPopup( + type: 'identification', + initialValue: pd['RISK_IDENTIFICATION'] ?? '', + onConfirm: (v) => Navigator.of(context).pop(v), + ), + ); + if (val != null) pd['RISK_IDENTIFICATION'] = val; + FocusHelper.clearFocus(context); + }, + hintText: '请输入风险辨识结果', + controller: riskController, + text: pd['RISK_IDENTIFICATION'] ?? '', + ), + if (FormUtils.hasValue(pd, 'ANALYZE_TIME')) ...[ + const Divider(), + ItemListWidget.OneRowButtonTitleText( + label: '分析人:', + text: pd['ANALYZE_USER_NAME'] ?? '', + onTap: onAnalyzeTap, + ), + ], + ], ), - if (FormUtils.hasValue(pd, 'ANALYZE_TIME')) ...[ - const Divider(), - ItemListWidget.OneRowButtonTitleText( - label: '分析人:', - text: pd['ANALYZE_USER_NAME'] ?? '', - onTap: onAnalyzeTap, - ), - ], - ], - ); + ); + + } } diff --git a/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/dangerous_options_page.dart b/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/dangerous_options_page.dart new file mode 100644 index 0000000..ad5cda6 --- /dev/null +++ b/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/dangerous_options_page.dart @@ -0,0 +1,264 @@ +import 'dart:io'; +import 'dart:ui'; +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/http/HttpManager.dart'; +import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; + +import '../../../../../../customWidget/custom_button.dart'; +import '../../../../../../customWidget/photo_picker_row.dart'; +import '../../../../../../customWidget/single_image_viewer.dart'; +import '../../../../../../tools/tools.dart'; +import '../../../../../mine/mine_sign_page.dart'; + +/// 本地路径 + 线上路径模型 +class ImageData { + String localPath; + String? serverPath; + ImageData({required this.localPath, this.serverPath}); +} + +class DangerousOptionsPage extends StatefulWidget { + final int index; + final int status; + final String measures; + final List imgList; + final List signImgList; + + const DangerousOptionsPage({ + Key? key, + required this.index, + this.status = 1, + this.measures = '', + this.imgList = const [], + this.signImgList = const [], + }) : super(key: key); + + @override + _DangerousOptionsPageState createState() => _DangerousOptionsPageState(); +} + +class _DangerousOptionsPageState extends State { + late int index; + late int status; + late String measures; + late List imgList; + late List signImgList; + List signTimes = []; + + bool buttonLoading = false; + final Dio _dio = Dio(); + final _picker = ImagePicker(); + + @override + void initState() { + super.initState(); + index = widget.index; + status = widget.status; + measures = widget.measures; + imgList = List.from(widget.imgList); + signImgList = List.from(widget.signImgList); + } + + /// 拍照或选图后的回调 + Future _onImageAdded(String localPath) async { + // 上传到服务器 + final res = await ApiService.uploadSaveFile(localPath); + final url = res['FILE_PATH'] as String; + setState(() { + imgList.add(ImageData(localPath: localPath, serverPath: url)); + }); + } + + /// 删除图片处理:调用删除接口并更新列表 + Future _onImageRemoved(ImageData item) async { + if (item.serverPath != null) { + await ApiService.deleteSaveFile(item.serverPath!); + } + setState(() { + imgList.remove(item); + }); + } + + Future _submit() async { + if (signImgList.isEmpty) { + ScaffoldMessenger.of(context) + .showSnackBar(SnackBar(content: Text('请签字'))); + return; + } + await ApiService.saveDangerousOptionsFile(signImgList); + setState(() => buttonLoading = true); + Navigator.pop(context, { + 'imgList': imgList.map((e) => {'local': e.localPath, 'remote': e.serverPath}).toList(), + 'signImgList': signImgList, + 'index': index, + 'status': status, + }); + } + + Future _sign() async { + final path = await Navigator.push( + context, + MaterialPageRoute(builder: (c) => MineSignPage()), + ); + if (path != null) { + final now = DateFormat('yyyy-MM-dd HH:mm').format(DateTime.now()); + setState(() { + signImgList.add(path); + signTimes.add(now); + }); + FocusHelper.clearFocus(context); + } + } + + Widget _signListWidget() { + return Column( + children: signImgList.map((path) { + final idx = signImgList.indexOf(path); + return Column( + children: [ + const SizedBox(height: 10), + const Divider(), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + GestureDetector( + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 200, maxHeight: 150), + child: Image.file(File(path), fit: BoxFit.contain), + ), + onTap: () => presentOpaque(SingleImageViewer(imageUrl: path), context), + ), + Column( + children: [ + CustomButton( + text: '删除', + height: 30, + padding: const EdgeInsets.symmetric(horizontal: 10), + backgroundColor: Colors.red, + onPressed: () { + setState(() => signImgList.removeAt(idx)); + }, + ), + const SizedBox(height: 80), + ], + ), + ], + ), + ], + ); + }).toList(), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: '安全措施'), + body: Padding( + padding: const EdgeInsets.all(12.0), + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10, vertical: 10), + color: Colors.white, + child: ListView( + children: [ + Table( + border: TableBorder.all(color: Colors.grey.shade300), + columnWidths: {0: FlexColumnWidth(3), 1: FlexColumnWidth(2)}, + children: [ + TableRow( + decoration: BoxDecoration(color: Colors.grey.shade200), + children: [ + Padding( + padding: EdgeInsets.all(10), + child: Center( + child: Text('主要安全措施', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ), + Padding( + padding: EdgeInsets.all(10), + child: Center( + child: Text('操作', style: TextStyle(fontWeight: FontWeight.bold)), + ), + ), + ], + ), + TableRow( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 5), + child: Text(measures), + ), + Padding( + padding: const EdgeInsets.all(0), + child: Column( + children: [ + RadioListTile( + value: -1, + groupValue: status, + title: Text('不涉及'), + contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 8.0), + visualDensity: VisualDensity(vertical: -4, horizontal: 0), + onChanged: (v) => setState(() => status = v!), + ), + RadioListTile( + value: 1, + groupValue: status, + title: Text('涉及'), + contentPadding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 8.0), + visualDensity: VisualDensity(vertical: -4, horizontal: 0), + onChanged: (v) => setState(() => status = v!), + ), + ], + ), + ), + ], + ), + ], + ), + const SizedBox(height: 20), + RepairedPhotoSection( + title: '上传图片', + maxCount: 2, + mediaType: MediaType.image, + initialMediaPaths: imgList.map((e) => e.localPath).toList(), + onChanged: (paths) {}, + onMediaAdded: _onImageAdded, + onMediaRemoved: (path) { + final item = imgList.firstWhere((e) => e.localPath == path); + _onImageRemoved(item); + }, + onAiIdentify: () {}, + ), + const SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text('签字:', style: TextStyle(fontSize: 16)), + CustomButton( + text: '新增手写签字', + height: 36, + backgroundColor: Colors.green, + onPressed: _sign, + ), + ], + ), + if (signImgList.isNotEmpty) _signListWidget(), + const SizedBox(height: 30), + CustomButton( + text: '保存', + backgroundColor: Colors.blue, + onPressed: buttonLoading ? null : _submit, + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/hotwork_safe_func_sure.dart b/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/hotwork_safe_func_sure.dart index 0e459ad..1a38d7d 100644 --- a/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/hotwork_safe_func_sure.dart +++ b/lib/pages/home/tap/tabList/special_wrok/aqcs_work_detail/hotwork_safe_func_sure.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'dart:io'; import 'dart:math'; - import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; @@ -10,8 +9,8 @@ import 'package:qhd_prevention/customWidget/department_person_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; +import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/aqcs_work_detail/dangerous_options_page.dart'; import 'package:qhd_prevention/tools/tools.dart'; -import '../../../../../../customWidget/bottom_picker.dart'; import '../../../../../../customWidget/custom_alert_dialog.dart'; import '../../../../../../customWidget/single_image_viewer.dart'; import '../../../../../../http/ApiService.dart'; @@ -20,6 +19,7 @@ import '../../../../../my_appbar.dart'; import '../../special_Wrok/dh_work_detai/MeasuresListWidget.dart'; import '../../special_Wrok/qtfx_work_detail/hotwork_gas_list.dart'; import '../WorkDetailFormWidget.dart'; + /// 安全措施确认 class HotworkSafeFuncSure extends StatefulWidget { const HotworkSafeFuncSure({ @@ -45,6 +45,8 @@ class _HotworkSafeFuncSureState extends State { /// 详情 late Map pd = {}; late List> measuresList = []; + /// 其他安全措施 + final TextEditingController _otherController = TextEditingController(); /// 动火人及证书编号 late List workUserList = []; @@ -67,18 +69,6 @@ class _HotworkSafeFuncSureState extends State { return jsonEncode(jsonList); } - Widget _card(Widget child) { - return Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: child, - ); - } - - - /// 弹出单位选择 void chooseUnitHandle(MeasureItem item) { showModalBottomSheet( @@ -87,15 +77,16 @@ class _HotworkSafeFuncSureState extends State { barrierColor: Colors.black54, backgroundColor: Colors.transparent, builder: - (_) => DepartmentPicker( - onSelected: (id, name) async { - setState(() { - item.DEPARTMENT_ID = id; - item.DEPARTMENT_NAME = name; - }); - _getPersonListForUnitId(item); - }, - ), + (_) => + DepartmentPicker( + onSelected: (id, name) async { + setState(() { + item.DEPARTMENT_ID = id; + item.DEPARTMENT_NAME = name; + }); + _getPersonListForUnitId(item); + }, + ), ).then((_) {}); } @@ -265,16 +256,17 @@ class _HotworkSafeFuncSureState extends State { await showDialog( context: context, builder: - (_) => CustomAlertDialog( - title: '作废原因', - mode: DialogMode.input, - hintText: '请输入作废原因', - cancelText: '取消', - confirmText: '确定', - onInputConfirm: (text) { - reasonText = text; - }, - ), + (_) => + CustomAlertDialog( + title: '作废原因', + mode: DialogMode.input, + hintText: '请输入作废原因', + cancelText: '取消', + confirmText: '确定', + onInputConfirm: (text) { + reasonText = text; + }, + ), ); if (reasonText.isEmpty) { ToastUtil.showNormal(context, '请填写作废原因'); @@ -294,32 +286,33 @@ class _HotworkSafeFuncSureState extends State { await showDialog( context: context, builder: - (_) => CustomAlertDialog( - title: '提示', - content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?', - cancelText: '取消', - confirmText: '确定', - onConfirm: () async { - LoadingDialogHelper.show(context); - try { - final result = await ApiService.saveSafeFunctionSure( - formData, - imagePaths, - ); - LoadingDialogHelper.hide(context); - if (result['result'] == 'success') { - ToastUtil.showSuccess( - context, - status == '1' ? '提交成功' : '已暂存', - ); - Navigator.pop(context); - } - } catch (e) { - LoadingDialogHelper.hide(context); - ToastUtil.showNormal(context, '操作失败:$e'); - } - }, - ), + (_) => + CustomAlertDialog( + title: '提示', + content: '请确认' + (status == '1' ? "通过" : "作废") + '本作业票?', + cancelText: '取消', + confirmText: '确定', + onConfirm: () async { + LoadingDialogHelper.show(context); + try { + final result = await ApiService.saveSafeFunctionSure( + formData, + imagePaths, + ); + LoadingDialogHelper.hide(context); + if (result['result'] == 'success') { + ToastUtil.showSuccess( + context, + status == '1' ? '提交成功' : '已暂存', + ); + Navigator.pop(context); + } + } catch (e) { + LoadingDialogHelper.hide(context); + ToastUtil.showNormal(context, '操作失败:$e'); + } + }, + ), ); } @@ -380,6 +373,44 @@ class _HotworkSafeFuncSureState extends State { }); } + Future _itemToSign(Map measures, int index) async { + // 签名图片列表 + final List signImgList = measures['SIGN_ITEM'] ?? []; + + // 操作图片路径列表 + final List imgList = []; + if ((measures['IMG_PATH'] as String?)?.isNotEmpty ?? false) { + for (var path in (measures['IMG_PATH'] as String).split(',')) { + + imgList.add(ImageData(localPath: path)); + } + } + final result = await pushPage(DangerousOptionsPage(index: index,status: measures['STATUS'] ?? 1, + measures: measures['PROTECTIVE_MEASURES'] ?? '', + imgList: imgList, + signImgList: signImgList), context); + if (result != null) { + setState(() { + // 更新返回的图片列表(local + remote) + final returned = result['imgList'] as List; + measures['IMG_PATH'] = returned.map((m) { + return ImageData( + localPath: m['local'] as String, + serverPath: m['remote'] as String?, + ); + }).toList(); + + // 更新签字列表 + measures['SIGN_ITEM'] = List.from(result['signImgList'] as List); + + // 更新状态、序号等 + measures['STATUS'] = result['status']; + index = result['index'] as int; + }); + } + + } + /// 安全防护措施 Widget _setSafeDetailWidget() { return Container( @@ -390,10 +421,10 @@ class _HotworkSafeFuncSureState extends State { padding: EdgeInsets.symmetric(horizontal: 5), child: Column( children: [ - if (measuresList.length > 0) + if (measuresList.isNotEmpty) Column( children: [ - SizedBox(height: 20), + SizedBox(height: 5), ListItemFactory.createBuildSimpleSection('安全防护措施'), Container( color: Colors.white, @@ -401,10 +432,19 @@ class _HotworkSafeFuncSureState extends State { measuresList: measuresList, // List> baseImgPath: ApiService.baseImgPath, + isAllowEdit: true, + onSign: (item) { + _itemToSign(item, measuresList.indexOf(item)); + }, ), ), ], ), + ItemListWidget.singleLineTitleText(label: '其他安全措施:', + isEditable: true, + hintText: '请输入其他安全措施', + controller + :_otherController), SizedBox(height: 20), Row( @@ -468,20 +508,17 @@ class _HotworkSafeFuncSureState extends State { padding: EdgeInsets.all(12), child: Column( children: [ - // _card(_defaultDetail()), - _card( - WorkDetailFormWidget( - pd: pd, - isEditable: false, - onChooseLevel: (){}, - onChooseHotworkUser: (){}, - onAnalyzeTap: () { - pushPage( - HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID), - context, - ); - }, - ), + WorkDetailFormWidget( + pd: pd, + isEditable: false, + onChooseLevel: () {}, + onChooseHotworkUser: () {}, + onAnalyzeTap: () { + pushPage( + HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID), + context, + ); + }, ), SizedBox(height: 20), _setSafeDetailWidget(), @@ -514,7 +551,8 @@ class MeasureItem { List>? userList, this.userIndex = -1, List>? selectMeasures, - }) : userList = userList ?? [], + }) + : userList = userList ?? [], selectMeasures = selectMeasures ?? []; Map toJson() { diff --git a/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/MeasuresListWidget.dart b/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/MeasuresListWidget.dart index e1af6dd..d9c95d9 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/MeasuresListWidget.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/MeasuresListWidget.dart @@ -11,18 +11,31 @@ import '../../../../../../tools/tools.dart'; import 'hotwork_apply_detail.dart'; /// 表格组件,用于展示“安全防护措施”列表 +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +/// 主安全措施列表组件,支持编辑与只读模式 class MeasuresListWidget extends StatelessWidget { + const MeasuresListWidget({ + super.key, + required this.measuresList, + required this.baseImgPath, + required this.isAllowEdit, + this.onSign, + }); /// 接口返回的原始 Map 列表 final List> measuresList; /// 图片的基础路径 final String baseImgPath; - const MeasuresListWidget({ - Key? key, - required this.measuresList, - required this.baseImgPath, - }) : super(key: key); + /// 是否允许编辑(输入答案 & 签字按钮) + final bool isAllowEdit; + + /// 签字按钮回调,回调当前行 item + final void Function(Map item)? onSign; + + @override Widget build(BuildContext context) { @@ -98,32 +111,46 @@ class MeasuresListWidget extends StatelessWidget { item['SIGN_TIME'] as String? ?? '', ), - // 问题1~4 + 答案 + // 问题1~4 + 答案(可编辑或只读) for (var i = 1; i <= 4; i++) - if (item.containsKey('QUESTION$i')) - _buildQnA( - item['QUESTION$i'] as String? ?? '', - item['ANSWER$i'] as String? ?? '0', - ), + if ((item['QUESTION$i'] as String?)?.isNotEmpty ?? false) + _buildQnA(item, i), ], ), ), - // 第二列:状态 + 图片 + // 第二列:状态文字/按钮 + 操作图片 Padding( padding: const EdgeInsets.all(8), child: Column( children: [ - // 状态 - Text( + // 签字或状态 + isAllowEdit + ? TextButton( + onPressed: () { + if ((item['STATUS'] as String?) != '-1') { + onSign?.call(item); + } + }, + child: Text( + (item['SIGN_ITEM'] ?? '').toString().isNotEmpty + ? '已签字' + : '签字', + style: TextStyle( + color: (item['STATUS'] as String?) == '-1' + ? Colors.grey + : Colors.blue, + ), + ), + ) + : Text( (item['STATUS'] as String?) == '-1' ? '不涉及' : '涉及', style: TextStyle( - color: - (item['STATUS'] as String?) == '-1' - ? Colors.grey - : Colors.black, + color: (item['STATUS'] as String?) == '-1' + ? Colors.grey + : Colors.black, ), ), @@ -148,27 +175,71 @@ class MeasuresListWidget extends StatelessWidget { ); } - /// 构造“问题 + 答案”行 - Widget _buildQnA(String question, String answer) { + /// 构造“问题 + 答案”行,编辑模式下显示数字输入框 + Widget _buildQnA(Map item, int index) { + final question = item['QUESTION$index'] as String? ?? ''; + final key = 'ANSWER$index'; + final answer = item[key]?.toString() ?? ''; + + if (isAllowEdit) { + return Padding( + padding: const EdgeInsets.only(top: 8), + child: Row( + children: [ + Expanded( + flex: 2, + child: Text( + '$question:', + style: const TextStyle(fontWeight: FontWeight.w800), + ), + ), + Expanded( + flex: 1, + child: TextFormField( + initialValue: answer, + textAlign: TextAlign.center, // 输入文字居中对齐 + keyboardType: TextInputType.number, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], + decoration: InputDecoration( + isDense: true, + contentPadding: const EdgeInsets.symmetric(vertical: 8, horizontal: 4), + // 自定义边框颜色 + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey.shade300), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.grey.shade300), + ), + ), + onChanged: (val) { + item[key] = val; + }, + ), + ), + ], + ), + ); + } + + // 只读模式 return Padding( padding: const EdgeInsets.only(top: 8), child: Column( children: [ Padding( - padding: EdgeInsets.symmetric(horizontal: 12), + padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( - crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - '$question: ', + '$question:', style: const TextStyle(fontWeight: FontWeight.w800), ), Text(answer.isNotEmpty ? answer : '0'), ], ), ), - Divider(), + const Divider(), ], ), ); @@ -176,10 +247,10 @@ class MeasuresListWidget extends StatelessWidget { /// 构造一组图片 + 可选时间文本行 List _buildImageRows( - BuildContext context, - List paths, - String time, - ) { + BuildContext context, + List paths, + String time, + ) { return paths.map((p) { return Padding( padding: const EdgeInsets.only(top: 8), @@ -190,13 +261,12 @@ class MeasuresListWidget extends StatelessWidget { Navigator.of(context).push( PageRouteBuilder( opaque: false, - pageBuilder: - (_, __, ___) => - SingleImageViewer(imageUrl: '$baseImgPath$p'), + pageBuilder: (_, __, ___) => + SingleImageViewer(imageUrl: '$baseImgPath\$p'), ), ); }, - child: Image.network('$baseImgPath$p', width: 80, height: 80), + child: Image.network('$baseImgPath\$p', width: 80, height: 80), ), if (time.isNotEmpty) ...[const SizedBox(width: 8), Text(time)], ], @@ -206,6 +276,7 @@ class MeasuresListWidget extends StatelessWidget { } } + /// 其他安全防护措施表格组件 class OtherMeasuresWidget extends StatelessWidget { /// 其他安全防护措施数据列表 @@ -744,15 +815,16 @@ class _SelectionPopupState extends State { void _reset() { setState(() { // 回到下拉列表的初始选项(第 0 项) - selectedWorkType = workList[0]['WORK_TYPE']!; - selectedWorkName = workList[0]['WORK_NAME']!; + selectedWorkType = workList[0]['WORK_TYPE']!; + selectedWorkName = workList[0]['WORK_NAME']!; - selectedDate = null; + selectedDate = null; list.clear(); selectValue.clear(); }); _getData(); } + void _determine() { // 合并选中 final result = selectValue.join(','); diff --git a/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/hotwork_apply_detail.dart b/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/hotwork_apply_detail.dart index a81cf5c..73ff3f2 100644 --- a/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/hotwork_apply_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/dh_work_detai/hotwork_apply_detail.dart @@ -8,6 +8,7 @@ import 'package:qhd_prevention/customWidget/department_picker.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/home/tap/item_list_widget.dart'; import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/WorkDetailFormWidget.dart'; +import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:qhd_prevention/tools/tools.dart'; import '../../../../../../customWidget/bottom_picker.dart'; import '../../../../../../http/ApiService.dart'; @@ -188,6 +189,7 @@ class _HotworkApplyDetailState extends State { Widget _card(Widget child) { return Container( + padding: EdgeInsets.symmetric(vertical: 5), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), @@ -283,22 +285,23 @@ class _HotworkApplyDetailState extends State { ToastUtil.showNormal(context, '请先选择$unitName'); return; } + + if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口 + await _getPersonListForUnitId(unitId, type); + final list = _personCache[type] ?? []; + + if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人 + ToastUtil.showNormal(context, '暂无数据,请选择其他单位'); + }else{ + choosePersonHandle(type); + } + return; + } if (personList.isEmpty) { // 如果还是没数据,说明该部门没有可选的人 ToastUtil.showNormal(context, '请先选择' + type.displayName); return; } - // if (personList.isEmpty) { // 一般这种情况是因为重新编辑没有缓存对应部门的负责人,所以先拉取一下接口 - // await _getPersonListForUnitId(unitId, type); - // final list = _personCache[type] ?? []; - // - // if (list.isEmpty) { // 如果还是没数据,说明该部门没有可选的人 - // ToastUtil.showNormal(context, '暂无数据,请选择其他单位'); - // }else{ - // choosePersonHandle(type); - // } - // return; - // } DepartmentPersonPicker.show( context, personsData: personList, @@ -481,6 +484,7 @@ class _HotworkApplyDetailState extends State { @override Widget build(BuildContext context) { return Scaffold( + backgroundColor: h_backGroundColor(), appBar: MyAppbar(title: '动火安全作业申请'), body: SafeArea( child: SingleChildScrollView( @@ -582,8 +586,9 @@ class _HotworkApplyDetailState extends State { color: Colors.white, child: MeasuresListWidget( measuresList: - measuresList, // List> + measuresList, // List> baseImgPath: ApiService.baseImgPath, + isAllowEdit: false, ), ), ], @@ -609,9 +614,45 @@ class _HotworkApplyDetailState extends State { ), isEditable ? Row( - spacing: 10, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + spacing: 10, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: CustomButton( + height: 45, + textStyle: TextStyle( + fontSize: 16, + color: Colors.white, + ), + text: '提交', + backgroundColor: Colors.blue, + onPressed: () { + _submit('1'); + }, + ), + ), + + Expanded( + child: CustomButton( + textStyle: TextStyle( + fontSize: 16, + color: Colors.white, + ), + text: '暂存', + backgroundColor: Colors.green, + onPressed: () { + _submit('0'); + }, + ), + ), + ], + ) + : Column( + children: [ + SizedBox(height: 20), + Row( children: [ + SizedBox(width: 50), Expanded( child: CustomButton( height: 45, @@ -619,54 +660,18 @@ class _HotworkApplyDetailState extends State { fontSize: 16, color: Colors.white, ), - text: '提交', - backgroundColor: Colors.blue, - onPressed: () { - _submit('1'); - }, - ), - ), - - Expanded( - child: CustomButton( - textStyle: TextStyle( - fontSize: 16, - color: Colors.white, - ), - text: '暂存', + text: '返回', backgroundColor: Colors.green, onPressed: () { - _submit('0'); + Navigator.pop(context); }, ), ), - ], - ) - : Column( - children: [ - SizedBox(height: 20), - Row( - children: [ - SizedBox(width: 50), - Expanded( - child: CustomButton( - height: 45, - textStyle: TextStyle( - fontSize: 16, - color: Colors.white, - ), - text: '返回', - backgroundColor: Colors.green, - onPressed: () { - Navigator.pop(context); - }, - ), - ), - SizedBox(width: 50), - ], - ), + SizedBox(width: 50), ], ), + ], + ), ], ), ), diff --git a/lib/pages/home/tap/tabList/special_wrok/szaq_work_detail/hotwork_set_safe_detail.dart b/lib/pages/home/tap/tabList/special_wrok/szaq_work_detail/hotwork_set_safe_detail.dart index 96d0f1e..50dbbf5 100644 --- a/lib/pages/home/tap/tabList/special_wrok/szaq_work_detail/hotwork_set_safe_detail.dart +++ b/lib/pages/home/tap/tabList/special_wrok/szaq_work_detail/hotwork_set_safe_detail.dart @@ -68,15 +68,7 @@ class _HotworkSetSafeDetailState extends State { return jsonEncode(jsonList); } - Widget _card(Widget child) { - return Container( - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - ), - child: child, - ); - } + Widget _chooseItem(MeasureItem item) { return Column( @@ -255,7 +247,7 @@ class _HotworkSetSafeDetailState extends State { ); } - /// 提交 1 提交 0暂存 + /// 作废 -1 通过 1 Future _submit(String status) async { if (imagePaths.isEmpty) { ToastUtil.showNormal(context, '请签字'); @@ -572,19 +564,17 @@ class _HotworkSetSafeDetailState extends State { child: Column( children: [ // _card(_defaultDetail()), - _card( - WorkDetailFormWidget( - pd: pd, - isEditable: false, - onChooseLevel: (){}, - onChooseHotworkUser: (){}, - onAnalyzeTap: () { - pushPage( - HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID), - context, - ); - }, - ), + WorkDetailFormWidget( + pd: pd, + isEditable: false, + onChooseLevel: (){}, + onChooseHotworkUser: (){}, + onAnalyzeTap: () { + pushPage( + HotworkGasList(HOTWORK_ID: widget.HOTWORK_ID), + context, + ); + }, ), SizedBox(height: 20), _setSafeDetailWidget(), diff --git a/lib/tools/h_colors.dart b/lib/tools/h_colors.dart index bcc298d..5553432 100644 --- a/lib/tools/h_colors.dart +++ b/lib/tools/h_colors.dart @@ -1,7 +1,7 @@ import 'dart:ffi'; import 'dart:ui'; -Color h_backGroundColor() => Color(0xFFF5F7FA); +Color h_backGroundColor() => Color(0xFFF1F1F1); List riskLevelTextColors() { return [Color(0xFFE54D42),Color(0xFFF37B1D),Color(0xFFF9BD08),Color(0xFF3281FF)]; }