diff --git a/assets/image/upload.png b/assets/image/upload.png new file mode 100644 index 0000000..fcb982b Binary files /dev/null and b/assets/image/upload.png differ diff --git a/lib/customWidget/department_picker_hidden.dart b/lib/customWidget/department_picker_hidden.dart new file mode 100644 index 0000000..b144712 --- /dev/null +++ b/lib/customWidget/department_picker_hidden.dart @@ -0,0 +1,296 @@ +import 'dart:convert'; +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/services/SessionService.dart'; +import '../tools/tools.dart'; // 包含 SessionService + +// 数据模型 +class Category { + final String id; + final String name; + final Map extValues; + final String departmentId; + final String parentId; + final String corpinfoId; // 新增:和 departmentId 同层级 + final List childrenList; + + Category({ + required this.id, + required this.name, + required this.childrenList, + required this.extValues, + required this.departmentId, + required this.parentId, + required this.corpinfoId, + }); + + factory Category.fromJson(Map json) { + // 安全读取并兼容字符串或数字类型的 id + String parseString(dynamic v) { + if (v == null) return ''; + if (v is String) return v; + return v.toString(); + } + + final rawChildren = json['childrenList']; + List children = []; + if (rawChildren is List) { + try { + children = rawChildren + .where((e) => e != null) + .map((e) => Category.fromJson(Map.from(e as Map))) + .toList(); + } catch (e) { + // 如果内部解析出错,保持 children 为空并继续 + children = []; + } + } + + // extValues 有可能为 null 或不是 Map + final extRaw = json['extValues']; + Map extMap = {}; + if (extRaw is Map) { + extMap = Map.from(extRaw); + } + + return Category( + id: parseString(json['id']), + name: parseString(json['name']), + childrenList: children, + extValues: extMap, + departmentId: parseString(json['departmentId']), + parentId: parseString(json['parentId']), + corpinfoId: parseString(json['corpinfoId']), // 从 JSON 同层级读取 + ); + } +} + +/// 弹窗回调签名:返回选中项的 id 和 name (保持原样,兼容旧代码) +typedef DeptSelectCallback = void Function(String id, String name); + +class DepartmentPickerHidden extends StatefulWidget { + /// 原回调,返回选中部门 id 与 name(保持不变) + final DeptSelectCallback onSelected; + + /// 新增可选扩展回调:当需要 corpinfoId 时使用(不影响原有调用) + final void Function(String id, String name, String? corpinfoId)? onSelectedWithCorp; + + /// 是否包含所有公司 + final bool includeAllFirm; + final Map? data; + + const DepartmentPickerHidden({ + Key? key, + required this.onSelected, + this.onSelectedWithCorp, + this.includeAllFirm = false, + this.data, + }) : super(key: key); + + @override + _DepartmentPickerHiddenState createState() => _DepartmentPickerHiddenState(); +} + +class _DepartmentPickerHiddenState extends State { + String selectedId = ''; + String selectedName = ''; + String? selectedCorpinfoId; // 记录选中项的 corpinfoId(可为 null) + Set expandedSet = {}; + + List original = []; + List filtered = []; + bool loading = true; + + final TextEditingController _searchController = TextEditingController(); + + @override + void initState() { + super.initState(); + // 初始均为空 + selectedId = ''; + selectedName = ''; + selectedCorpinfoId = null; + expandedSet = {}; + _searchController.addListener(_onSearchChanged); + _loadData(); + } + + @override + void dispose() { + _searchController.removeListener(_onSearchChanged); + _searchController.dispose(); + super.dispose(); + } + + Future _loadData() async { + try { + final result = await BasicInfoApi.getDeptFour(widget.includeAllFirm, data: widget.data); + final raw = result['data'] as List; + print(raw); + setState(() { + original = raw.map((e) => Category.fromJson(e as Map)).toList(); + filtered = original; + loading = false; + }); + } catch (e) { + setState(() => loading = false); + } + } + + void _onSearchChanged() { + final query = _searchController.text.toLowerCase().trim(); + setState(() { + filtered = query.isEmpty ? original : _filterCategories(original, query); + }); + } + + List _filterCategories(List list, String query) { + List result = []; + for (var cat in list) { + final children = _filterCategories(cat.childrenList, query); + if (cat.name.toLowerCase().contains(query) || children.isNotEmpty) { + result.add( + Category( + id: cat.id, + name: cat.name, + childrenList: children, + extValues: cat.extValues, + departmentId: cat.departmentId, + parentId: cat.parentId, + corpinfoId: cat.corpinfoId, // 保持 corpinfoId 传递 + ), + ); + } + } + return result; + } + + Widget _buildRow(Category cat, int indent) { + final hasChildren = cat.childrenList.isNotEmpty; + final isExpanded = expandedSet.contains(cat.id); + final isSelected = cat.id == selectedId; + return Column( + children: [ + InkWell( + onTap: () { + setState(() { + if (hasChildren) { + isExpanded + ? expandedSet.remove(cat.id) + : expandedSet.add(cat.id); + } + selectedId = cat.id; + selectedName = cat.name; + selectedCorpinfoId = cat.corpinfoId.isEmpty ? null : cat.corpinfoId; + }); + }, + child: Container( + color: Colors.white, + child: Row( + children: [ + SizedBox(width: 16.0 * indent), + SizedBox( + width: 24, + child: hasChildren + ? Icon( + isExpanded + ? Icons.arrow_drop_down_rounded + : Icons.arrow_right_rounded, + size: 35, + color: Colors.grey[600], + ) + : const SizedBox.shrink(), + ), + const SizedBox(width: 5), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 12), + child: Text(cat.name), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: Icon( + isSelected + ? Icons.radio_button_checked + : Icons.radio_button_unchecked, + color: Colors.blue, + ), + ), + ], + ), + ), + ), + if (hasChildren && isExpanded) + ...cat.childrenList.map((c) => _buildRow(c, indent + 1)), + ], + ); + } + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height * 0.7, + color: Colors.white, + child: Column( + children: [ + Container( + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + child: Row( + children: [ + GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: const Text('取消', style: TextStyle(fontSize: 16)), + ), + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: SearchBarWidget( + controller: _searchController, + isShowSearchButton: false, + onSearch: (keyboard) {}, + ), + ), + ), + GestureDetector( + onTap: () { + // 关闭弹窗并回调:优先调用扩展回调(带 corpinfoId),否则调用原回调 + Navigator.of(context).pop(); + if (widget.onSelectedWithCorp != null) { + widget.onSelectedWithCorp!( + selectedId, + selectedName, + selectedCorpinfoId, + ); + } else { + widget.onSelected(selectedId, selectedName); + } + }, + child: const Text( + '确定', + style: TextStyle(fontSize: 16, color: Colors.blue), + ), + ), + ], + ), + ), + Divider(), + Expanded( + child: loading + ? const Center(child: CircularProgressIndicator()) + : Container( + color: Colors.white, + child: ListView.builder( + itemCount: filtered.length, + itemBuilder: (ctx, idx) => _buildRow(filtered[idx], 0), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/http/modules/basic_info_api.dart b/lib/http/modules/basic_info_api.dart index 03df6e2..77ffdfa 100644 --- a/lib/http/modules/basic_info_api.dart +++ b/lib/http/modules/basic_info_api.dart @@ -153,6 +153,26 @@ class BasicInfoApi { ); } + /// 部门树状图 + static Future> getDeptFour(bool includeAllFirm, {Map? data}) async { + // var urlPath = includeAllFirm ? '/basicInfo/department/listAllTree' : '/basicInfo/department/listTree'; + var urlPath = '/basicInfo/department/listTree'; + + if (data != null) { + // inType 企业类型(0-普通企业,1-集团单位,2-股份单位,3-相关方企业,4-货主单位,5-驻港单位 6-物资中心) + // enterpriseType (企业类型1:监管 2:企业 3:相关方", name = "enterpriseType") + urlPath = '/basicInfo/department/listAllTreeByCorpType'; + } + return HttpManager().request( + ApiService.basePath, + urlPath, + method: Method.post, + data: { + ...?data, + }, + ); + } + /// 获取部门下所有用户 static Future> getDeptUsers(final departmentId, {int isMyCorp = 0, String corpinfoId = ''}) { final data = { diff --git a/lib/http/modules/hidden_danger_api.dart b/lib/http/modules/hidden_danger_api.dart index c3e1b78..34395e3 100644 --- a/lib/http/modules/hidden_danger_api.dart +++ b/lib/http/modules/hidden_danger_api.dart @@ -502,4 +502,25 @@ class HiddenDangerApi { + ///=====================隐患治理================== + + /// 获取过往记录详情 + static Future> getOldDangerDetail(String id) { + return HttpManager().request( + '${ApiService.basePath}/hidden', + '/hidden/history/$id', + method: Method.get, + data: {}, + ); + } + + + + + + + + + + } \ No newline at end of file diff --git a/lib/pages/home/Tap/special_header.dart b/lib/pages/home/Tap/special_header.dart index c3677f3..e229b42 100644 --- a/lib/pages/home/Tap/special_header.dart +++ b/lib/pages/home/Tap/special_header.dart @@ -139,4 +139,4 @@ class SpecialListInitData { } } -bool isKF = true; +bool isKF = false; diff --git a/lib/pages/home/hiddenDanger/danner_repair.dart b/lib/pages/home/hiddenDanger/danner_repair.dart new file mode 100644 index 0000000..d605dc7 --- /dev/null +++ b/lib/pages/home/hiddenDanger/danner_repair.dart @@ -0,0 +1,680 @@ +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/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker_hidden.dart'; +import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/item_list_widget.dart'; +import 'package:qhd_prevention/customWidget/photo_picker_row.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/services/SessionService.dart'; +import 'package:qhd_prevention/tools/h_colors.dart'; +import 'package:qhd_prevention/tools/tools.dart'; + + + + +class DepartmentEntry { + String department; + String responsible; + + String index; + String departmentId; + String responsibleId; + + DepartmentEntry({ + required this.department, + required this.responsible, + + required this.index, + required this.departmentId, + required this.responsibleId, + + + }); + + // 将对象转换为 Map + Map toJson() { + return { + 'deptId': departmentId, + 'userId': responsibleId, + 'deptName': department, + 'userName': responsible, + 'type': index, + }; + } + + // 将对象转换为 Map + Map toJsonTwo() { + return { + 'departmentId': departmentId, + 'userId': responsibleId, + 'departmentName': department, + 'userName': responsible, + 'listManagerId': index, + }; + } + +} + +/// 隐患整改 +class DannerRepair extends StatefulWidget { + DannerRepair(this.pd, {super.key}); + + final Map pd; + + @override + State createState() => DannerRepairState(); +} + +class DannerRepairState extends State { + + // 是否有整改方案 + bool acceptedPrepare = false; + + // 是否有整改计划 + bool acceptedPlan = false; + + final standardController = TextEditingController(); + final methodController = TextEditingController(); + final fundController = TextEditingController(); + final personController = TextEditingController(); + final workTimeController = TextEditingController(); + final timeController = TextEditingController(); + final workController = TextEditingController(); + final otherController = TextEditingController(); + final TextEditingController miaoShuController = TextEditingController(); + final TextEditingController linShiSZhengGaiController = TextEditingController(); + late var _selectData = DateTime.now(); + + + String investmentFunds=""; + String dataTime=""; + // 整改后图片 + List gaiHouImages = []; + //方案图片 + List fangAnImages = []; + //计划图片 + List jiHuaImages = []; + int yanShouAdd=1; + + // 是否是相关方 + bool _isStakeholder = false; + + + + final List departments = [ + DepartmentEntry(department: '请选择', responsible: '请选择',index:'300',departmentId: '',responsibleId:''), + ]; + + void _addDepartment() { + setState(() { + departments.add(DepartmentEntry(department: '请选择', responsible: '请选择',index:'300',departmentId: '',responsibleId:'')); + }); + } + + void _removeDepartment(int index) { + if (index == 0) return; // 防止删除第一行 + setState(() { + departments.removeAt(index); + }); + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + // _yanShouFuZeItem.add(_departmentItem(0)); + + setState(() { + // _isStakeholder=true; + _isStakeholder= widget.pd['isRelated']==1?true:false; + if(_isStakeholder){ + //部门 + departments[0].departmentId=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['deptId']??''; + departments[0].department=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['deptName']??''; + //人员 + departments[0].responsibleId=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['userId']??''; + departments[0].responsible=widget.pd['hiddenConfirmUserCO'][(widget.pd['hiddenConfirmUserCO'].length-1)]['userName']??''; + } + }); + + + } + + @override + void dispose() { + // 释放资源 + standardController.dispose(); + methodController.dispose(); + fundController.dispose(); + personController.dispose(); + workTimeController.dispose(); + timeController.dispose(); + workController.dispose(); + otherController.dispose(); + miaoShuController.dispose(); + linShiSZhengGaiController.dispose(); + + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.only(bottom: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: Column( + children: [ + // ListItemFactory.createBuildSimpleSection("隐患整改"), + // Divider(height: 1), + Container( + + padding: EdgeInsets.all(15), + child: Column( + children: [ + ListItemFactory.createBuildMultilineInput( + isRequired:true, + "整改描述", + "请对整改进行详细描述(必填项)", + miaoShuController, + ), + ], + ), + ), + Divider(height: 1), + GestureDetector( + onTap: () async { + DateTime? picked = await BottomDateTimePicker.showDate( + mode: BottomPickerMode.dateTimeWithSeconds, + context, + allowPast:false, + ); + if (picked != null) { + setState(() { + _selectData = picked; + dataTime= DateFormat('yyyy-MM-dd HH:mm:ss').format(picked); + }); + } + + }, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 15), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:true, + leftText: "整改日期", + rightText: dataTime.isEmpty?"请选择":dataTime, + isRight: true, + ), + ), + ), + + + Container( + padding: EdgeInsets.all(15), + child: Column( + children: [ + ListItemFactory.createBuildMultilineInput( + isRequired:true, + "临时整改措施", + "请填写临时整改措施", + linShiSZhengGaiController, + ), + ], + ), + ), + + ItemListWidget.singleLineTitleText( + label: '投入资金(元)', + isEditable: true, + text: '', + onChanged: (value) { + investmentFunds=value; + }, + ), + Divider(), + ItemListWidget.itemContainer( + RepairedPhotoSection( + isRequired:true, + title: "整改后照片", + maxCount: 4, + mediaType: MediaType.image, + onChanged: (files) { + // 上传 files 到服务器 + gaiHouImages.clear(); + for(int i=0;i _departmentItem( + departments[index], + index, + showLabel: index == 0, + ), + ), + ), + ], + + if(_isStakeholder)...[ + Column( + children: [ + GestureDetector( + onTap: () {}, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:true, + leftText: "验收部门", + rightText: departments[0].department.isNotEmpty ? departments[0].department : "", + isRight: false, + ), + ), + ), + + Divider(), + + GestureDetector( + onTap: () {}, + child:Container( + padding: EdgeInsets.symmetric(horizontal: 15), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:true, + leftText: "验收人", + rightText: departments[0].responsible.isNotEmpty?departments[0].responsible:"", + isRight: false, + ), + ), + ), + ], + ), + ], + + // for(int m=0;m<_yanShouFuZeItem.length;m++) + // _yanShouFuZeItem[m], + // _departmentItem(m), + // _departmentItem(2), + Divider(), + ListItemFactory.createYesNoSection( + title: "是否有整改方案", + yesLabel: "是", + noLabel: "否", + groupValue: acceptedPrepare, + onChanged: (val) { + setState(() { + acceptedPrepare = val; + }); + }, + ), + acceptedPrepare ? _acceptPrepare() : SizedBox(height: 1), + + + Divider(), + // 图片上传 + // const SizedBox(height: 16), + if(acceptedPrepare) + RepairedPhotoSection( + horizontalPadding: 15, + isRequired:true, + title: "方案图片", + maxCount: 4, + mediaType: MediaType.image, + onChanged: (files) { + // 上传 files 到服务器 + fangAnImages.clear(); + for(int i=0;i const Divider(height: 1, color: Colors.black12), + itemBuilder: + (_, index) => Padding( + padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 8), + child: fields[index], + ), + ); + } + + Widget _buildSectionContainer({required Widget child}) { + return Container( + margin: const EdgeInsets.only(top: 1), + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), + child: child, + ); + } + + Widget _buildReadOnlyRow(String left, String right) { + return ListItemFactory.createRowSpaceBetweenItem( + leftText: left, + rightText: right, + ); + } + + + /// 验收部门和负责人选择的item + Widget _departmentItem( + DepartmentEntry entry, + int index, { + required bool showLabel, + }) { + return Padding( + padding: const EdgeInsets.all(10), + child: Stack( + clipBehavior: Clip.none, + children: [ + Container( + decoration: BoxDecoration( + border: Border.all(color: Colors.black12, width: 1), + ), + child: _noAccepet_repair(false,index), + ), + + // 当 num > 1 时,左上角显示删除按钮 + if (index > 0) + Positioned( + top: -20, + left: -20, + child: IconButton( + padding: EdgeInsets.zero, + constraints: const BoxConstraints(), + icon: const Icon(Icons.cancel, color: Colors.red, size: 25), + onPressed: () { + _removeDepartment(index); + // 这里处理删除逻辑,比如: + // setState(() => _items.removeAt(num)); + }, + ), + ), + ], + ), + ); + } + + + // 存储各单位的人员列表 + final Map>> _personCache = {}; + // #region 不整改 + Widget _noAccepet_repair(bool _accept,int index, ) { + + return Column( + children: [ + GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: (ctx) => DepartmentPickerHidden(onSelected: (id, name) async { + + setState(() { + // buMenId=id; + // buMenName=name; + // + // // 清空已选人员 + // renYuanId=""; + // renYuanName=""; + departments[index].department=name; + departments[index].departmentId=id; + + departments[index].responsible=""; + departments[index].responsibleId=""; + + }); + + // // 拉取该单位的人员列表并缓存 + // final result = await HiddenDangerApi.getListTreePersonList(id); + // _personCache=List>.from( + // result['userList'] as List, + // ); + // 拉该单位人员并缓存 + await _getPersonListForUnitId(id); + + }), + ); + }, + child: Container( + padding: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:true, + leftText: "验收部门", + rightText: departments[index].department.isNotEmpty?departments[index].department:"请选择", + isRight: true, + ), + ), + ), + + Divider( + height: 10, + color: _accept ? h_backGroundColor() : Colors.transparent, + ), + + GestureDetector( + onTap: () { + if ( departments[index].departmentId.isEmpty) { + ToastUtil.showNormal(context, '请先选择部门'); + return; + } + final unitId = (departments[index].departmentId ?? '').toString(); + choosePersonHandle(unitId,index); + // DepartmentPersonPicker.show( + // context, + // personsData: _personCache, + // onSelected: (userId, name) { + // setState(() { + // // renYuanId = userId; + // // renYuanName = name; + // + // departments[index].responsible=name; + // departments[index].responsibleId=userId; + // departments[index].index=(index-1).toString(); + // }); + // + // }, + // ); + }, + child:Container( + padding: EdgeInsets.symmetric(horizontal: 10), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:true, + leftText: "验收人", + rightText: departments[index].responsible.isNotEmpty?departments[index].responsible:"请选择", + isRight: true, + ), + ), + ), + ], + ); + } + + /// 整改计划 + Widget _acceptPlan() { + return Padding( + padding: EdgeInsets.symmetric(horizontal: 15), + child: MediaPickerRow( + maxCount: 4, + onChanged: (List files) { + // images 列表更新 + // 上传 files 到服务器 + jiHuaImages.clear(); + for(int i=0;i _getPersonListForUnitId(String id) async { + if (id.isEmpty) return; + LoadingDialogHelper.show(); + try { + final result = await BasicInfoApi.getDeptUsers(id); + LoadingDialogHelper.hide(); + // 兼容 result['data'] / result['userList'] 等常见字段 + dynamic raw = result['data']; + List> list = []; + if (raw is List) { + list = raw.map>((e) { + if (e is Map) return e; + if (e is Map) return Map.from(e); + return {}; + }).toList(); + } else { + list = []; + } + setState(() { + _personCache[id] = list; + }); + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showError(context, '获取人员失败:$e'); + setState(() { + _personCache[id] = []; + }); + } + } + + /// 弹出人员选择 + void choosePersonHandle(final unitId, int index) async { + + List> personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + // 先拉取一次 + await _getPersonListForUnitId(unitId); + personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位'); + return; + } + } + + // 显示人员选择器(假设 DepartmentPersonPicker.show 接口存在) + DepartmentPersonPicker.show( + context, + personsData: personList, + onSelected: (userId, name) { + if(SessionService.instance.accountId==userId){ + ToastUtil.showNormal(context, '整改人和验收人不能是一个人'); + return; + } + setState(() { + departments[index].responsible=name; + departments[index].responsibleId=userId; + departments[index].index=(index-1).toString(); + }); + }, + ).then((_) { + //FocusHelper.clearFocus(context); + }); + } + + + +} diff --git a/lib/pages/home/hiddenDanger/hidden_danger_acceptance.dart b/lib/pages/home/hiddenDanger/hidden_danger_acceptance.dart new file mode 100644 index 0000000..e8d2672 --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_danger_acceptance.dart @@ -0,0 +1,752 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_record_detail_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'; +import 'dart:async'; + +enum DangerType { + detailsHiddenInvestigationRecord("排查隐患记录", "排查隐患记录-详情"), + ristRecord("隐患记录", "隐患记录详情"), + waitAcceptance("隐患验收", "隐患验收详情"), + acceptance("已验收隐患", "已验收隐患"), + acceptanced("已验收隐患", "已验收隐患-详情"), + hiddenIdentification("隐患确认", "隐患确认详情"), + wait("隐患整改", "隐患整改详情"), + expired("特殊处置审核", "特殊处置审核详情"), + delayReview("延期审核", "延期审核详情"), + ignoreHiddenDangers("忽略隐患", "忽略隐患详情"), + // 安全环保检查 + safeCheckHiddenAssign("隐患指派", "指派"), + safeCheckHiddenAccept("隐患验收", "验收"); + // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ + + final String displayName; + final String detailTitle; + + const DangerType(this.displayName, this.detailTitle); +} + +class HiddenDangerAcceptance extends StatefulWidget { + const HiddenDangerAcceptance(this.dangerType, this.appItem, {super.key}); + + final DangerType dangerType; + final int appItem; + + @override + State createState() => _HiddenDangerAcceptanceState(); +} + +class _HiddenDangerAcceptanceState extends State { + int _page = 1; + String searchKey = ""; + int _totalPage = 1; + late List _list = []; + bool _isLoading = false; + bool _hasMore = true; + Timer? _debounceTimer; + String buttonTextOne = '查看'; + String buttonTextTwo = '确认'; + + final TextEditingController _searchController = TextEditingController(); + + + + @override + void initState() { + super.initState(); + // 初始均为空 + + _searchController.addListener(_onSearchChanged); + + switch (widget.appItem) { + case 1: + buttonTextTwo = '确认'; + break; + case 2: + buttonTextTwo = '查看'; + break; + case 3: + buttonTextOne = '延期申请'; + buttonTextTwo = '整改'; + break; + case 4: + buttonTextTwo = '特殊处理审核'; + break; + case 5: + buttonTextTwo = '延期审核'; + break; + case 6: + buttonTextTwo = '验收'; + break; + } + + + _getListData(false); + } + + @override + void dispose() { + _debounceTimer?.cancel(); + _searchController.removeListener(_onSearchChanged); + _searchController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + // 取屏幕宽度 + final double screenWidth = MediaQuery.of(context).size.width; + + return Scaffold( + appBar: MyAppbar(title: widget.dangerType.displayName), + + body: SafeArea( + child: NotificationListener( + onNotification: _onScroll, + child: _vcDetailWidget(), + ), + ), + backgroundColor: Colors.white, + ); + } + + Widget _vcDetailWidget() { + return Column( + children: [ + Padding( + padding: EdgeInsets.all(10), + child: SearchBarWidget( + controller: _searchController, + isShowSearchButton: false, + hintText: '请输入隐患描述', + onTextChanged: (value) { + if (_debounceTimer?.isActive ?? false) { + _debounceTimer!.cancel(); + } + + _debounceTimer = Timer(const Duration(milliseconds: 500), () { + print('搜索关键词: ${_searchController.text}'); + _performSearch(_searchController.text); + }); + }, + onSearch: (keyboard) { + // _performSearch(_searchController.text); + }, + ), + ), + Container(height: 5, color: h_backGroundColor()), + Expanded( + child: + _list.isEmpty + ? NoDataWidget.show() + : ListView.builder( + itemCount: _list.length, + itemBuilder: (context, index) { + final item = _list[index]; + return _fxitemCell(item); + }, + ), + ), + ], + ); + } + + Widget _fxitemCell(pageData) { + // 使用GestureDetector包裹整个列表项以添加点击事件 + return GestureDetector( + onTap: () {}, + + child: Container( + margin: EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.3), + spreadRadius: 2, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, // 添加这一行 + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 10, top: 15, right: 8), + child: Text( + '隐患描述: ${pageData['hiddenDesc'] ?? ''}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + maxLines: 1, // 只显示一行 + overflow: TextOverflow.ellipsis, // 超出部分显示省略号 + ), + ), + ), + + // 状态标签 + Container( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: _getLevelColor(pageData), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(12), + topRight: Radius.circular(12), // 改为右上角 + ), + ), + child: Text( + pageData['hiddenLevelName'] ?? '', + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + + SizedBox(height: 16), + + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 来源 + Expanded( + child: Text( + _getSourceDangers(pageData), + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + ), + // 隐患状态 + // Expanded( + // child: Text( + // '隐患状态: ${_getState(pageData)}', + // style: TextStyle(fontSize: 14, color: Colors.black87), + // ), + // ), + ], + ), + ), + + SizedBox(height: 8), + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 来源 + // Expanded( + // child: Text( + // _getSourceDangers(pageData), + // style: TextStyle(fontSize: 14, color: Colors.black87), + // ), + // ), + // 隐患状态 + Expanded( + child: Text( + '隐患状态: ${_getState(pageData)}', + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + ), + ], + ), + ), + + SizedBox(height: 8), + + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 隐患发现人 - 使用 Expanded 包裹 + Expanded( + child: Text( + '发现人:${truncateString(pageData['createName'] ?? '')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + // 隐患发现时间 - 使用 Expanded 包裹 + Expanded( + child: Text( + '发现时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}', + + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (widget.appItem != 1) SizedBox(height: 8), + + if (widget.appItem != 1) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 隐患确认人 + Expanded( + child: Text( + '确认人:${pageData['confirmUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + Expanded( + child: Text( + '确认时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}', + + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (widget.appItem == 6) SizedBox(height: 8), + + if (widget.appItem == 6) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 整改人 + Expanded( + child: Text( + '整改人:${pageData['rectifyUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + Expanded( + child: Text( + '整改时间:${_changeTime(pageData['rectificationTime'] ?? '')}', + + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (pageData['hiddenYUserName'] != null && + pageData['hiddenYUserName'].isNotEmpty) + SizedBox(height: 8), + + if (pageData['hiddenYUserName'] != null && + pageData['hiddenYUserName'].isNotEmpty) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 整改人 + Text( + '验收人: ${pageData['hiddenYUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + + // Text( + // '隐患验收时间: ${_changeTime(pageData['hiddenYTime']??'')}', + // style: TextStyle( + // fontSize: 14, + // color: Colors.black87, + // ), + // ), + ], + ), + ), + + SizedBox(height: 8), + + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 验收按钮 + if (widget.appItem != 2 && (widget.appItem != 3 || pageData['noReviewExtensionNum'] == 0)) + Expanded( + child: CustomButton( + height: 35, + onPressed: () async { + // print('查看: ${pageData['title']}'); + if (widget.appItem == 3) { + await pushPage( + HiddenRecordDetailPage( + widget.dangerType, + 8, + pageData['id'], + pageData['hiddenId'], + true, + ), + context, + ); + _page=1; + _getListData(false); + } else { + pushPage( + HiddenRecordDetailPage( + widget.dangerType, + widget.appItem, + pageData['id'], + pageData['hiddenId'], + false, + ), + context, + ); + + } + }, + backgroundColor: h_backGroundColor(), + textStyle: const TextStyle(color: Colors.black), + buttonStyle: ButtonStyleType.secondary, + text: buttonTextOne, + ), + ), + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 10, right: 5), // 调整间距 + // decoration: BoxDecoration( + // border: Border.all(color: Colors.blue, width: 1.0), + // borderRadius: BorderRadius.circular(8), + // ), + // child: ElevatedButton( + // onPressed: () { + // // print('查看: ${pageData['title']}'); + // if (widget.appItem == 3) { + // pushPage( + // HiddenRecordDetailPage( + // widget.dangerType, + // 8, + // pageData['id'], + // pageData['hiddenId'], + // true, + // ), + // context, + // ); + // } else { + // pushPage( + // HiddenRecordDetailPage( + // widget.dangerType, + // widget.appItem, + // pageData['id'], + // pageData['hiddenId'], + // false, + // ), + // context, + // ); + // } + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.white, + // foregroundColor: Colors.blue, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // elevation: 0, + // ), + // child: Text(buttonTextOne), + // ), + // ), + // ), + SizedBox(width: 10), // 使用width而不是height + // 查看详情按钮 + Expanded( + child: CustomButton( + height: 35, + onPressed: () async { + // print('查看详情: ${pageData['title']}'); + String text = await pushPage( + HiddenRecordDetailPage( + widget.dangerType, + widget.appItem, + pageData['id'], + pageData['hiddenId'], + widget.appItem != 2, + ), + context, + ); + if (text == '1') { + _page = 1; + _getListData(false); + } + }, + backgroundColor: h_AppBarColor(), + textStyle: const TextStyle(color: Colors.white), + buttonStyle: ButtonStyleType.primary, + text: buttonTextTwo, + ), + ), + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 5, right: 10), + // child: ElevatedButton( + // onPressed: () async { + // // print('查看详情: ${pageData['title']}'); + // String text = await pushPage( + // HiddenRecordDetailPage( + // widget.dangerType, + // widget.appItem, + // pageData['id'], + // pageData['hiddenId'], + // widget.appItem != 2, + // ), + // context, + // ); + // if (text == '1') { + // _page = 1; + // _getListData(false); + // } + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.blue, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text(buttonTextTwo), + // ), + // ), + // ), + ], + ), + + SizedBox(height: 10), + ], + ), + ), + ); + } + + void _performSearch(String keyword) { + // 执行搜索逻辑 + // if (keyword.isNotEmpty) { + // print('执行搜索: $keyword'); + // 调用API或其他搜索操作 + // 输入请求接口 + _page = 1; + searchKey = keyword; + _getListData(false); + // } + } + + bool _onScroll(ScrollNotification n) { + if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 && + _hasMore && + !_isLoading) { + _page++; + _getListData(true); + } + return false; + } + + void _onSearchChanged() { + final query = _searchController.text.toLowerCase().trim(); + setState(() { + print("=====>" + query); + // filtered = query.isEmpty ? original : _filterCategories(original, query); + }); + } + + + + + Future _getListData(bool loadMore) async { + try { + if (_isLoading) return; + _isLoading = true; + + LoadingDialogHelper.show(); + + final Map result; + if (widget.appItem == 2) { + result = await HiddenDangerApi.getIgnoreList(_page, searchKey); + } else if (widget.appItem == 3) { + result = await HiddenDangerApi.getRectificationList(_page, searchKey); + } else if (widget.appItem == 4) { + result = await HiddenDangerApi.getSpecialHandlingList( + _page, + searchKey, + // isJGD ? '1' : '2', + ); + } else if (widget.appItem == 5) { + result = await HiddenDangerApi.getDelayReviewList( + _page, + searchKey, + // isJGD ? '1' : '2', + ); + } else if (widget.appItem == 6) { + result = await HiddenDangerApi.getHiddenDangerAcceptanceList( + _page, + searchKey, + ); + } else { + result = await HiddenDangerApi.getConfirmationList(_page, searchKey); + } + + LoadingDialogHelper.hide(); + if (result['success']) { + _totalPage = result['totalPages'] ?? 1; + final List newList = result['data'] ?? []; + // setState(() { + // _list.addAll(newList); + // }); + + setState(() { + if (loadMore) { + _list.addAll(newList); + } else { + _list = newList; + } + _hasMore = _page < _totalPage; + // if (_hasMore) _page++; + }); + } else { + ToastUtil.showNormal(context, "加载数据失败"); + // _showMessage('加载数据失败'); + } + } catch (e) { + LoadingDialogHelper.hide(); + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } finally { + // if (!loadMore) LoadingDialogHelper.hide(); + _isLoading = false; + } + } + + String _getSourceDangers(final item) { + int type = item["source"] ?? 0; + if (1 == type) { + return "隐患来源:隐患快报"; + } else if (2 == type) { + return "隐患来源:清单排查"; + } else if (3 == type) { + return "隐患来源:标准排查"; + } else if (4 == type) { + return "隐患来源:安全环保检查(监管端)"; + } else if (5 == type) { + return "隐患来源:安全环保检查(企业端)"; + } else if (6 == type) { + return "隐患来源:消防点检"; + } else if (7 == type) { + return "隐患来源:视频巡屏"; + } else { + return "隐患来源:"; + } + } + + // 隐患等级颜色 + Color _getLevelColor(final item) { + String type = item["hiddenLevelName"] ?? ''; + if ("重大隐患" == type) { + return Colors.red; + } else if ("较大隐患" == type) { + return Color(0xFFFF6A4D); + } else if ("一般隐患" == type) { + return Colors.orange; + } else if ("轻微隐患" == type) { + return h_AppBarColor(); + } else { + return Colors.green; + } + } + + String _getState(final item) { + int type = item["state"]; + if(100==type){ + return "待确认"; + }else if(200==type){ + return "未整改"; + }else if(201==type){ + return "确认打回"; + }else if(202==type){ + return "待处理特殊隐患"; + }else if(300==type){ + return "待验收"; + }else if(301==type){ + return "已验收"; + }else if(302==type){ + return "验收打回"; + }else if(303==type){ + return "验收打回"; + }else if(400==type){ + return "已处理特殊隐患"; + }else if(99==type){ + return "强制关闭(人员变动)"; + }else if(98==type){ + return "安全环保检查/清单排查暂存"; + }else if(102==type){ + return "安全环保检查,隐患待指派"; + }else if(97==type){ + return "已过期"; + }else if(101==type){ + return "忽略隐患"; + }else{ + return "已过期"; + } + } + + String _changeTime(String time) { + try { + // 解析 ISO 8601 格式的时间字符串 + DateTime dateTime = DateTime.parse(time); + // 格式化为年月日 + return DateFormat('yyyy-MM-dd').format(dateTime); + } catch (e) { + // 如果解析失败,返回原字符串或默认值 + return ' '; + } + } + + String truncateString(String input) { + if (input.length > 10) { + return '${input.substring(0, 10)}...'; + } + return input; + } +} diff --git a/lib/pages/home/hiddenDanger/hidden_danger_deawer.dart b/lib/pages/home/hiddenDanger/hidden_danger_deawer.dart new file mode 100644 index 0000000..3787ff4 --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_danger_deawer.dart @@ -0,0 +1,613 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker_two.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker_three.dart'; +import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/item_list_widget.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; + +import 'package:webview_flutter/webview_flutter.dart'; +import '../../../customWidget/bottom_picker.dart'; +import '../../../tools/h_colors.dart'; +import '/customWidget/custom_button.dart'; +import '../../../tools/tools.dart'; + + + + +/// 自定义抽屉 +class HiddenDangerDeawer extends StatefulWidget { + const HiddenDangerDeawer(this.searchData, {super.key,required this.onClose}); + + final Function(Map) onClose; // 回调函数 + final Map searchData; + // final DangerWaitBean waitBean; + + @override + _HiddenDangerDeawerState createState() => _HiddenDangerDeawerState(); +} + +class _HiddenDangerDeawerState extends State { + + Map allData={}; + + DateTime? _startDate; + DateTime? _endDate; + + // 存储各单位的人员列表 + List> _personCache = []; + + + // 转换为List> + late List> departmentList ; + late List _HazardPersonlist = []; + dynamic _hazardLeve; + + + // final List investigationMethod = ["隐患快报", "隐患排查", "标准排查", "专项检查", "安全检查"]; + final List investigationMethod = ["风险排查隐患", "隐患排查隐患"]; + final List hazardLevel = [" 一般风险 ", " 重大风险 "]; + final List dangerStatus = ["未整改", "已整改", "已验收", "已过期"]; + final List laiYuanStatus = ["隐患快报", "隐患排查", "标准排查", "专项检查", "安全检查", "NFC设备巡检"]; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + setState(() { + allData=widget.searchData; + if(allData['beginTIme']!=''){ + _startDate= DateTime.parse(allData['beginTIme']); + } + if(allData['endTime']!='') { + _endDate = DateTime.parse(allData['endTime']); + } + }); + + // if(allData['findUserName']==''){ + // _getUserData(); + // } + + } + + + + + @override + Widget build(BuildContext context) { + + return SafeArea( + child: + // SingleChildScrollView( // 添加这一行 + // child: + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 15), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + const Text( + "高级查询", + style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), + ), + + const Divider(height: 20, color: Colors.grey), + + // 开始时间 - 结束时间 —— // + Column( + children: [ + _buildDatePickerBox( + label: "隐患发现开始时间", + date: _startDate, + onTap: _pickStartDate, + ), + + const SizedBox(height: 10), + + _buildDatePickerBox( + label: "隐患发现结束时间", + date: _endDate, + onTap: _pickEndDate, + ), + ], + ), + + const SizedBox(height: 10), + + Column( + children: [ + GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (ctx) => DepartmentPickerTwo( + onSelected: (id, name,pdId) async { + setState(() { + + allData['buMenId']= id; + allData['buMenName']= name; + + allData['findUserId']= ""; + allData['findUserName']= ""; + + + }); + // 拉取该单位的人员列表并缓存 + final result = await HiddenDangerApi.getListTreePersonList(id); + _personCache=List>.from( + result['data'] as List, + ); + }, + ), + ); + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:false, + leftText: "隐患发现部门", + rightText: allData['buMenName'].isNotEmpty ? allData['buMenName'] : "请选择", + isRight: true, + ), + ), + ), + + + const SizedBox(height: 10), + + // GestureDetector( + // onTap: () async { + // if(_personCache.isEmpty){ + // // 拉取该单位的人员列表并缓存 + // final result = await HiddenDangerApi.getListTreePersonList(allData['buMenId']); + // _personCache=List>.from( + // result['data'] as List, + // ); + // } + // if ( allData['buMenName'].isEmpty) { + // ToastUtil.showNormal(context, '请先选择部门'); + // return; + // } + // DepartmentPersonPicker.show( + // context, + // personsData: _personCache, + // onSelected: (userId, name) { + // setState(() { + // + // allData['findUserId']= userId; + // allData['findUserName']= name; + // + // }); + // + // }, + // ); + // }, + // child:Container( + // padding: EdgeInsets.symmetric(horizontal: 0), + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(4), + // border: Border.all(color: Colors.grey.shade400), + // color: Colors.white, + // ), + // child: ListItemFactory.createRowSpaceBetweenItem( + // isRequired:false, + // leftText: "隐患发现人", + // rightText: allData['findUserName'].isNotEmpty?allData['findUserName']:"请选择", + // isRight: true, + // ), + // ), + // ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all(color: Colors.grey.shade400), + color: Colors.white, + ), + child: ItemListWidget.singleLineTitleText( + label: '隐患发现人', + isEditable: true, + isRequired:false, + isTextFont:false, + hintText: '', + text: allData['confirmUserName'] ?? '', + onChanged: (value) { + setState(() { + allData['confirmUserName'] = value; + + }); + }, + ), + ), + + + + + ], + ), + + + + const SizedBox(height: 10), + GestureDetector( + onTap: () async { + + if(_HazardPersonlist.isEmpty){ + await _getHazardPersonlist(); + } + String choice = await BottomPickerTwo.show( + context, + items: _HazardPersonlist, + itemName: "name", + itemBuilder: (item) => Text(item["name"], textAlign: TextAlign.center), + initialIndex: 0, + ); + if (choice != null) { + for(int i=0;i<_HazardPersonlist.length;i++){ + if(choice==_HazardPersonlist[i]["name"]){ + _hazardLeve = _HazardPersonlist[i]; + } + } + + setState(() { + allData['trueUserId']=_hazardLeve["userId"]; + allData['trueUserName']=_hazardLeve["name"]; + + // addData['confirmDeptId']=_hazardLeve["deptId"]; + // addData['confirmDeptName']=_hazardLeve["deptName"]; + + }); + } + }, + child:Container( + padding: EdgeInsets.symmetric(horizontal: 0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all(color: Colors.grey.shade400), + color: Colors.white, + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:false, + leftText: "隐患确认人", + rightText: allData['trueUserName'].isNotEmpty?allData['trueUserName']:"请选择", + isRight: true, + ), + ), + ), + + + const SizedBox(height: 10), + GestureDetector( + onTap: () { + _getHiddenDangerType(); + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired:false, + leftText: "隐患类型", + rightText: allData['hiddenTypeName'].isNotEmpty?allData['hiddenTypeName']:"请选择", + isRight: true, + ), + ), + ), + + + + Expanded(child: SizedBox(height: 20),), + Row( + children: [ + Flexible( + flex: 1, + child: CustomButton( + text: "重置", + buttonStyle:ButtonStyleType.secondary, + backgroundColor: h_backGroundColor(), + textStyle: const TextStyle(color: Colors.black45), + onPressed: () { + setState(() { + + + _startDate = null; + _endDate = null; + + allData={ + "beginTIme": "", + "endTime": "", + "buMenId": "", + "buMenName": "", + "findUserId": "", + "findUserName": "", + "trueUserId": "", + "trueUserName": "", + "type": "", + 'hiddenTypeName': "", + 'confirmUserName': "", + }; + + setResult(); + // widget.onClose("","","","","","",""); + + }); + }, + ), + ), + const SizedBox(width: 12), + Flexible( + flex: 2, + child: CustomButton( + text: "完成", + backgroundColor: Colors.blue, + onPressed: () { + setResult(); + // TODO: 提交筛选条件 + Navigator.pop(context); // 关闭加载对话框 + }, + ), + ), + ], + ), + ], + ), + ), + // ), + ); + } + + + Widget _buildSectionContainer({required Widget child}) { + return Container( + margin: const EdgeInsets.only(top: 1), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all(color: Colors.grey.shade400), + color: Colors.white, + ), + // color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0), + child: child, + ); + } + + + + + Future _pickStartDate() async { + final now = DateTime.now(); + final picked = await showDatePicker( + context: context, + initialDate: _startDate ?? now, + firstDate: DateTime(now.year - 5), + lastDate: DateTime(now.year + 5), + ); + if (picked != null) { + setState(() { + + _startDate = picked; + final dateFormat = DateFormat('yyyy-MM-dd'); + allData['beginTIme']=dateFormat.format(picked); + + // 保证开始 <= 结束 + if (_endDate != null && _endDate!.isBefore(picked)) { + _endDate = null; + } + + + // setResult(); + + }); + } + } + + Future _pickEndDate() async { + final now = DateTime.now(); + final initial = _endDate ?? + (_startDate != null && _startDate!.isAfter(now) + ? _startDate! + : now); + final picked = await showDatePicker( + context: context, + initialDate: initial, + firstDate: _startDate ?? DateTime(now.year - 5), + lastDate: DateTime(now.year + 5), + ); + if (picked != null) { + setState(() { + _endDate = picked; + + final dateFormat = DateFormat('yyyy-MM-dd'); + allData['endTime']=dateFormat.format(picked); + + // setResult(); + + }); + } + } + + Widget _buildDatePickerBox({ + required String label, + DateTime? date, + required VoidCallback onTap, + }) { + final display = date != null + ? "${date.year.toString().padLeft(4, '0')}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, '0')}" + : label; + return GestureDetector( + onTap: onTap, + child: Container( + height: 35, + padding: const EdgeInsets.symmetric(horizontal: 5), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(4), + border: Border.all(color: Colors.grey.shade400), + color: Colors.white, + ), + child: Row( + children: [ + const Icon(Icons.calendar_today, size: 18, color: Colors.grey), + const SizedBox(width: 6), + Text(display, style: const TextStyle(fontSize: 14, color: Colors.black38)), + ], + ), + ), + + ); + } + + Future _getHiddenDangerType() async { + + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => MultiDictValuesPicker( + title: '隐患类型', + dictType: 'hiddenType', + allowSelectParent: false, + onSelected: (id, name, extraData) { + setState(() { + allData['type'] = extraData?['dictValue']; + allData['hiddenTypeName'] = name; + + //顶层 + // allData['hiddenType2'] = extraData?['dingValue']; + // allData['hiddenType2Name'] = extraData?['dingName']; + + }); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + // try { + // LoadingDialogHelper.show(); + // final raw = await HiddenDangerApi.getHiddenDangerType( ); + // if (raw['success'] ) { + // final newList = raw['data'] ?? []; + // LoadingDialogHelper.hide(); + // + // for(int i=0;i DepartmentPickerThree( + // listdata: newList, + // onSelected: (id, name,pdId) async { + // setState(() { + // allData['type']=id; + // allData['hiddenTypeName']=name; + // + // }); + // + // }, + // ), + // ); + // + // }else{ + // ToastUtil.showNormal(context, "获取列表失败"); + // LoadingDialogHelper.hide(); + // } + // + // } catch (e) { + // // 出错时可以 Toast 或者在页面上显示错误状态 + // print('加载首页数据失败:$e'); + // LoadingDialogHelper.hide(); + // } + } + + + Future _getUserData() async { + try { + + final raw = await AuthApi.getUserData( ); + if (raw['success'] ) { + + setState(() { + allData['findUserId']=raw['data']['id']; + allData['findUserName']=raw['data']['name']; + allData['buMenId']=raw['data']['departmentId']; + allData['buMenName']=raw['data']['departmentName']; + + }); + + }else{ + ToastUtil.showNormal(context, "获取个人信息失败"); + + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + + } + } + + + Future _getHazardPersonlist() async { + try { + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.getHazardPersonlist( ); + if (raw['success'] ) { + _HazardPersonlist = raw['data'] ?? []; + LoadingDialogHelper.hide(); + + + }else{ + ToastUtil.showNormal(context, "获取列表失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + + + void setResult(){ + widget.onClose( + allData + ); // 触发回调 + } + + + +} + + diff --git a/lib/pages/home/hiddenDanger/hidden_danger_record_two.dart b/lib/pages/home/hiddenDanger/hidden_danger_record_two.dart new file mode 100644 index 0000000..dea4394 --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_danger_record_two.dart @@ -0,0 +1,874 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/constants/app_enums.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/ApiService.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_deawer.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_record_detail_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'; +import 'dart:async'; + +import 'package:shared_preferences/shared_preferences.dart'; + +class HiddenDangerRecordTwo extends StatefulWidget { + const HiddenDangerRecordTwo( + this.dangerType, + this.appItem, + this.corpId, { + super.key, + }); + + final DangerType dangerType; + final int appItem; + final String corpId; + + @override + State createState() => _HiddenDangerRecordTwoState(); +} + +class _HiddenDangerRecordTwoState extends State { + int _page = 1; + String searchKey = ""; + int _totalPage = 1; + late List _list = []; + bool _isLoading = false; + bool _hasMore = true; + Timer? _debounceTimer; + bool _isShowDelete = true; + + final TextEditingController _searchController = TextEditingController(); + Map searchData = { + "beginTIme": "", + "endTime": "", + "buMenId": "", + "buMenName": "", + "findUserId": "", + "findUserName": "", + "trueUserId": "", + "trueUserName": "", + "type": "", + 'hiddenTypeName': "", + 'confirmUserName': "", + }; + + @override + void initState() { + super.initState(); + // 初始均为空 + + _searchController.addListener(_onSearchChanged); + + _initializeVisibility(); + _getListData(false); + } + + Future _initializeVisibility() async { + _isShowDelete = false; + } + + @override + void dispose() { + _debounceTimer?.cancel(); + _searchController.removeListener(_onSearchChanged); + _searchController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + // 取屏幕宽度 + final double screenWidth = MediaQuery.of(context).size.width; + + return Scaffold( + appBar: MyAppbar( + title: widget.dangerType.displayName, + actions: [ + Builder( + builder: (innerContext) { + return TextButton( + onPressed: () { + // 通过 innerContext 拿到 ScaffoldState,打开右侧抽屉 + Scaffold.of(innerContext).openEndDrawer(); + }, + child: Text( + "查询", + style: TextStyle(color: Colors.white, fontSize: 16), + ), + ); + }, + ), + ], + ), + + //弹窗 + endDrawer: Drawer( + // 用 Container 限制宽度为屏幕的 3/5 + child: Container( + width: screenWidth * 3 / 5, + color: Colors.white, + child: HiddenDangerDeawer( + searchData, + onClose: (closeData) { + searchData = closeData; + _page = 1; + _getListData(false); + }, + ), + ), + ), + + body: SafeArea( + child: NotificationListener( + onNotification: _onScroll, + child: _vcDetailWidget(), + ), + ), + backgroundColor: Colors.white, + ); + } + + Widget _vcDetailWidget() { + return Column( + children: [ + Padding( + padding: EdgeInsets.all(10), + child: SearchBarWidget( + controller: _searchController, + hintText: '请输入隐患描述', + isShowSearchButton: false, + onTextChanged: (value) { + if (_debounceTimer?.isActive ?? false) { + _debounceTimer!.cancel(); + } + + _debounceTimer = Timer(const Duration(milliseconds: 500), () { + print('搜索关键词: ${_searchController.text}'); + _performSearch(_searchController.text); + }); + }, + onSearch: (keyboard) {}, + ), + ), + Container(height: 5, color: h_backGroundColor()), + Expanded( + child: + _list.isEmpty + ? NoDataWidget.show() + : ListView.builder( + itemCount: _list.length, + itemBuilder: (context, index) { + final item = _list[index]; + return _fxitemCell(item, index); + }, + ), + ), + ], + ); + } + + Widget _fxitemCell(pageData, index) { + // 使用GestureDetector包裹整个列表项以添加点击事件 + return GestureDetector( + onTap: () {}, + + child: Container( + margin: EdgeInsets.all(6), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.3), + spreadRadius: 2, + blurRadius: 5, + offset: Offset(0, 3), + ), + ], + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题 + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, // 添加这一行 + children: [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 10, top: 15, right: 8), + child: Text( + '隐患描述: ${pageData['hiddenDesc']!}', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.black87, + ), + maxLines: 1, // 只显示一行 + overflow: TextOverflow.ellipsis, // 超出部分显示省略号 + ), + ), + ), + + // 状态标签 + Container( + padding: EdgeInsets.symmetric(horizontal: 12, vertical: 6), + decoration: BoxDecoration( + color: _getLevelColor(pageData), + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(12), + topRight: Radius.circular(12), // 改为右上角 + ), + ), + child: Text( + pageData['hiddenLevelName']!, + style: TextStyle( + color: Colors.white, + fontSize: 12, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ), + + SizedBox(height: 16), + + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 来源 + Expanded( + child: Text( + _getSourceDangers(pageData), + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + ), + // 隐患状态 + // Expanded( + // child: Text( + // '隐患状态:${_getState(pageData)}', + // style: TextStyle(fontSize: 14, color: Colors.black87), + // ), + // ), + ], + ), + ), + + SizedBox(height: 8), + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 来源 + // Expanded( + // child: Text( + // _getSourceDangers(pageData), + // style: TextStyle(fontSize: 14, color: Colors.black87), + // ), + // ), + // 隐患状态 + Expanded( + child: Text( + '隐患状态:${_getState(pageData)}', + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + ), + ], + ), + ), + + SizedBox(height: 8), + + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 隐患发现人 + Expanded( + child: Text( + '发现人:${truncateString(pageData['createName'] ?? '')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + ), + ), + + Expanded( + child: Text( + '发现时间:${_changeTime(pageData['hiddenFindTime']??'')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (widget.appItem != 1) SizedBox(height: 8), + + if (widget.appItem != 1) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 隐患确认人 + Expanded( + child: Text( + '确认人:${pageData['confirmUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + Expanded( + child: Text( + '确认时间:${_changeTime(pageData['hiddenFindTime'] ?? '')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (widget.appItem == 6) SizedBox(height: 8), + + if (widget.appItem == 6) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 整改人 + Expanded( + child: Text( + '整改人:${pageData['rectifyUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + Expanded( + child: Text( + '整改时间:${_changeTime(pageData['rectificationTime'] ?? '')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + if (pageData['hiddenYUserName'] != null && + pageData['hiddenYUserName'].isNotEmpty) + SizedBox(height: 8), + + if (pageData['hiddenYUserName'] != null && + pageData['hiddenYUserName'].isNotEmpty) + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 整改人 + Expanded( + child: Text( + '验收人:${pageData['hiddenYUserName'] ?? ''}', + style: TextStyle(fontSize: 14, color: Colors.black87), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + + Expanded( + child: Text( + '验收时间:${_changeTime(pageData['hiddenYTime'] ?? '')}', + style: TextStyle(fontSize: 14, color: Colors.black87), + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + ), + + SizedBox(height: 8), + + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // 查看详情按钮 + Expanded( + child: CustomButton( + height: 35, + onPressed: () { + // print('查看详情: ${pageData['title']}'); + pushPage( + HiddenRecordDetailPage( + widget.dangerType, + widget.appItem, + pageData['id'], + pageData['hiddenId'], + false, + ), + context, + ); + }, + backgroundColor: h_AppBarColor(), + textStyle: const TextStyle(color: Colors.white), + buttonStyle: ButtonStyleType.primary, + text: '查看', + ), + ), + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 5, right: 10), + // child: ElevatedButton( + // onPressed: () { + // // print('查看详情: ${pageData['title']}'); + // pushPage(HiddenRecordDetailPage(widget.dangerType,widget.appItem,pageData['id'],pageData['hiddenId'],false), context); + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.blue, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('查看'), + // ), + // ), + // ), + if (_isShowDelete && 201 == pageData["state"]) + SizedBox(width: 10), + + // 修改按钮 + if (_isShowDelete && 201 == pageData["state"]) + Expanded( + child: CustomButton( + height: 35, + onPressed: () { + // print('查看详情: ${pageData['title']}'); + // pushPage(HiddenDangerModificationPage(pageData['id'],pageData['hiddenId']), context); + _getTemporaryStorageOfHiddenYinHuan( + pageData, + pageData['hiddenId'], + index, + ); + }, + backgroundColor: h_AppBarColor(), + textStyle: const TextStyle(color: Colors.white), + buttonStyle: ButtonStyleType.primary, + text: '修改', + ), + ), + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 5, right: 10), + // child: ElevatedButton( + // onPressed: () { + // // print('查看详情: ${pageData['title']}'); + // // pushPage(HiddenDangerModificationPage(pageData['id'],pageData['hiddenId']), context); + // _getTemporaryStorageOfHiddenYinHuan(pageData,pageData['hiddenId'],index); + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.blue, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('修改'), + // ), + // ), + // ), + if (_isShowDelete && 100 == pageData["state"]) + SizedBox(width: 10), + + // 查看详情按钮 + if (_isShowDelete && 100 == pageData["state"]&&pageData["source"]!=4&&pageData["source"]!=5) + Expanded( + child: CustomButton( + height: 35, + onPressed: () { + // print('查看详情: ${pageData['title']}'); + _showLogoutConfirmation(pageData); + }, + backgroundColor: Colors.red, + textStyle: const TextStyle(color: Colors.white), + buttonStyle: ButtonStyleType.primary, + text: '删除', + ), + ), + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 5, right: 10), + // child: ElevatedButton( + // onPressed: () { + // // print('查看详情: ${pageData['title']}'); + // _showLogoutConfirmation(pageData); + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.red, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('删除'), + // ), + // ), + // ), + ], + ), + + SizedBox(height: 10), + ], + ), + ), + ); + } + + void _performSearch(String keyword) { + // 执行搜索逻辑 + // if (keyword.isNotEmpty) { + // print('执行搜索: $keyword'); + // 调用API或其他搜索操作 + // 输入请求接口 + _page = 1; + searchKey = keyword; + _getListData(false); + // } + } + + bool _onScroll(ScrollNotification n) { + if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 && + _hasMore && + !_isLoading) { + _page++; + _getListData(true); + } + return false; + } + + void _onSearchChanged() { + final query = _searchController.text.toLowerCase().trim(); + setState(() { + print("=====>" + query); + // filtered = query.isEmpty ? original : _filterCategories(original, query); + }); + } + + Future _getListData(bool loadMore) async { + try { + if (_isLoading) return; + _isLoading = true; + + LoadingDialogHelper.show(); + + final Map result; + result = await HiddenDangerApi.getGeneralHazardList( + _page, + searchKey, + searchData, + widget.corpId, + ); + + LoadingDialogHelper.hide(); + if (result['success']) { + _totalPage = result['totalPages'] ?? 1; + final List newList = result['data'] ?? []; + // setState(() { + // _list.addAll(newList); + // }); + + setState(() { + if (loadMore) { + _list.addAll(newList); + } else { + _list = newList; + } + _hasMore = _page < _totalPage; + // if (_hasMore) _page++; + }); + } else { + ToastUtil.showNormal(context, "加载数据失败"); + // _showMessage('加载数据失败'); + } + } catch (e) { + LoadingDialogHelper.hide(); + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载数据失败:$e'); + } finally { + // if (!loadMore) LoadingDialogHelper.hide(); + _isLoading = false; + } + } + + String _getSourceDangers(final item) { + int type = item["source"]; + if (1 == type) { + return "隐患来源:隐患快报"; + } else if (2 == type) { + return "隐患来源:清单排查"; + } else if (3 == type) { + return "隐患来源:标准排查"; + } else if (4 == type) { + return "隐患来源:安全环保检查(监管端)"; + } else if (5 == type) { + return "隐患来源:安全环保检查(企业端)"; + } else if (6 == type) { + return "隐患来源:消防点检"; + } else if (7 == type) { + return "隐患来源:视频巡屏"; + } else { + return "隐患来源:NFC设备巡检"; + } + } + + // 隐患等级颜色 + Color _getLevelColor(final item) { + String type = item["hiddenLevelName"]; + if ("重大隐患" == type) { + return Colors.red; + } else if ("较大隐患" == type) { + return Color(0xFFFF6A4D); + } else if ("一般隐患" == type) { + return Colors.orange; + } else if ("轻微隐患" == type) { + return h_AppBarColor(); + } else { + return Colors.green; + } + } + + String _getState(final item) { + int type = item["state"]; + if (100 == type) { + return "待确认"; + } else if (200 == type) { + return "未整改"; + } else if (201 == type) { + return "确认打回"; + } else if (202 == type) { + return "待处理特殊隐患"; + } else if (300 == type) { + return "已整改"; + } else if (301 == type) { + return "已验收"; + } else if (302 == type) { + return "验收打回"; + } else if (303 == type) { + return "验收打回"; + } else if (400 == type) { + return "已处理特殊隐患"; + } else if (99 == type) { + return "强制关闭(人员变动)"; + } else if (98 == type) { + return "安全环保检查/清单排查暂存"; + } else if (102 == type) { + return "安全环保检查,隐患带指派"; + } else if (97 == type) { + return "已过期"; + } else if (101 == type) { + return "忽略隐患"; + } else { + return "已过期"; + } + } + + String _changeTime(String time) { + try { + // 解析 ISO 8601 格式的时间字符串 + DateTime dateTime = DateTime.parse(time); + // 格式化为年月日 + return DateFormat('yyyy-MM-dd').format(dateTime); + } catch (e) { + // 如果解析失败,返回原字符串或默认值 + return ' '; + } + } + + void _showLogoutConfirmation(pageData) { + showDialog( + context: context, + builder: + (context) => AlertDialog( + title: const Text("删除隐患"), + content: const Text("确定要删除隐患吗??"), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[400], + foregroundColor: Colors.white, + ), + child: const Text("取消"), + ), + ElevatedButton( + onPressed: () { + // 执行删除操作 + Navigator.pop(context); + _deleteData(pageData); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue[700], + foregroundColor: Colors.white, + ), + child: const Text("确定"), + ), + ], + ), + ); + } + + Future _deleteData(pageData) async { + try { + LoadingDialogHelper.show(); + + final Map result; + result = await HiddenDangerApi.deleteHiddenDangers(pageData['id']); + + LoadingDialogHelper.hide(); + if (result['success']) { + setState(() { + ToastUtil.showNormal(context, "删除成功"); + _page = 1; + _getListData(false); + }); + } else { + ToastUtil.showNormal(context, "删除失败"); + // _showMessage('加载数据失败'); + } + } catch (e) { + LoadingDialogHelper.hide(); + // 出错时可以 Toast 或者在页面上显示错误状态 + print('删除失败:$e'); + } + } + + Future _getTemporaryStorageOfHiddenYinHuan( + Map item, + String hiddenId, + index, + ) async { + // try { + // LoadingDialogHelper.show(); + // final results = await Future.wait([ + // HiddenDangerApi.getDetailByHiddeNiD(hiddenId), + // // HiddenDangerApi.getImagePath(hiddenId, "3"), + // // HiddenDangerApi.getImagePath(hiddenId, "102"), + // // HiddenDangerApi.getImagePath(hiddenId, "4"), + // FileApi.getImagePath(hiddenId, UploadFileType.hiddenDangerPhoto), + // FileApi.getImagePath(hiddenId, UploadFileType.hiddenDangerVideo), + // // FileApi.getImagePath(item['hiddenUserId'] ?? '', UploadFileType.hiddenDangerRectificationPhoto), + // ]); + // + // LoadingDialogHelper.hide(); + // if (results[0]['success']) { + // Map pd = results[0]['data']; + // + // //隐患图片 + // List imgList = await _getImagePath( + // results[1]['data'], + // "3", + // ); + // List videos = await _getImagePath( + // results[2]['data'], + // "102", + // ); + // // 整改图片 + // List zgImgList = []; + // // List zgImgList = await _getImagePath(results[3]['data'],"4"); + // + // await pushPage( + // HiddenDangerModificationPage(pd, imgList, videos, zgImgList), + // context, + // ); + // _getListData(false); + // } else { + // ToastUtil.showNormal(context, "加载数据失败"); + // } + // } catch (e) { + // LoadingDialogHelper.hide(); + // print('加载数据失败:$e'); + // } + } + + // Future> _getImagePath( + // List images, + // String type, + // ) async { + // try { + // List dataList = []; + // for (int i = 0; i < images.length; i++) { + // String filePath = images[i]['filePath']; + // + // if ("3" == type) { + // dataList.add( + // // 直接创建实例 + // hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"), + // ); + // } else if ("102" == type) { + // dataList.add( + // // 直接创建实例 + // hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"), + // ); + // } else if ("4" == type) { + // dataList.add( + // // 直接创建实例 + // hiddenImgData(path: ApiService.baseImgPath + filePath, id: "1"), + // ); + // } + // } + // return dataList; + // } catch (e) { + // print('Error fetching data: $e'); + // return []; + // } + // } + + String truncateString(String input) { + if (input.length > 10) { + return '${input.substring(0, 10)}...'; + } + return input; + } + + Future _getString(String key) async { + final prefs = await SharedPreferences.getInstance(); + String text = prefs.getString(key) ?? ''; + return text; + } +} diff --git a/lib/pages/home/hiddenDanger/hidden_danger_tab_page.dart b/lib/pages/home/hiddenDanger/hidden_danger_tab_page.dart new file mode 100644 index 0000000..5176e1b --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_danger_tab_page.dart @@ -0,0 +1,330 @@ +// lib/pages/application_template.dart +import 'dart:ffi'; + +import 'package:flutter/material.dart'; +import 'package:qhd_prevention/common/route_service.dart'; +import 'package:qhd_prevention/http/modules/key_tasks_api.dart'; +import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_record_two.dart'; +import 'package:qhd_prevention/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart'; +import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_check_list_page.dart'; +import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_confirm_list_page.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/services/SessionService.dart'; +import 'package:qhd_prevention/tools/tools.dart'; + + + +class HiddenDangerTabPage extends StatefulWidget { + const HiddenDangerTabPage({super.key}); + + @override + State createState() => _HiddenDangerTabPageState(); +} + +class _HiddenDangerTabPageState extends State { + + final String bannerAsset = 'assets/images/key_tasks_banner.jpg'; + late List defaultSections; + + + @override + void initState() { + // TODO: implement initState + super.initState(); + + _initSections(); // 初始化 sections + _getDoorCarCount(); + } + + + // 初始化 sections 的方法 + void _initSections() { + defaultSections = [ + AppSection(title: '隐患治理', items: [ + AppSectionItem( + title: '隐患整改', + icon: 'assets/images/key_tasks_ico6.png', + menuPerms:'dashboard:Key-assignment:Hidden-danger-rectification', + badge: 0, + onTap: () async { + await pushPage(HiddenDangerAcceptance(DangerType.wait, 3), context); + _getDoorCarCount(); + }, + ), + AppSectionItem( + title: '隐患记录', + icon: 'assets/images/key_tasks_ico7.png', + menuPerms:'dashboard:Key-assignment:Hidden-Hazard-Record', + badge: 0, + onTap: () async { + await pushPage(HiddenDangerRecordTwo(DangerType.ristRecord, 7, ''), context); + _getDoorCarCount(); + }, + ), + + ]), + + ]; + } + + Future _getDoorCarCount() async { + // try { + // String userId= SessionService.instance.accountId??''; + // final result = await KeyTasksApi.getKeyTasksToDoCount(userId); + // if (result['success'] ) { + // dynamic data = result['data']?? {} ; + // + // setState(() { + // // 隐患治理 + // final gateSection = defaultSections[0]; + // + // // 隐患治理 + // gateSection.items[0].badge = int.parse(data['zdzysqCount']??0); + // // 确认 + // gateSection.items[1].badge = int.parse(data['bjcrqrCount']??0); + // // 整改 + // gateSection.items[2].badge = int.parse(data['yhdzgCount']??0); + // + // }); + // } + // // else { + // // ToastUtil.showNormal(context, result['errMessage'] ?? "加载数据失败"); + // // } + // } catch (e) { + // LoadingDialogHelper.hide(); + // print('加载数据失败:$e'); + // } + } + + @override + Widget build(BuildContext context) { + final double bannerHeight = (730.0 / 1125.0) * MediaQuery.of(context).size.width; + final double iconSectionHeight = + MediaQuery.of(context).size.height - bannerHeight - 30.0; + const double iconOverlapBanner = 30.0; + + // 过滤掉没有可见 items 的分组 + // final visibleSections = defaultSections + // .map((s) => AppSection( + // title: s.title, + // items: s.items.where((it) => it.visible).toList())) + // .where((s) => s.items.isNotEmpty) + // .toList(); + final routeService = RouteService(); + + return AnimatedBuilder( + animation: routeService, + builder: (context, _) + { + final rebuiltVisibleSections = defaultSections.map((section) { + final visibleItems = section.items.where((item) { + return item.visible && routeService.hasPerm(item.menuPerms); + }).toList(); + + return AppSection( + title: section.title, + items: visibleItems, + ); + }).where((section) => section.items.isNotEmpty).toList(); + + return Scaffold( + extendBodyBehindAppBar: true, + appBar: MyAppbar(title: '隐患治理', backgroundColor: Colors.transparent,), + body: ListView( + physics: const AlwaysScrollableScrollPhysics(), + padding: EdgeInsets.zero, + children: [ + SizedBox( + height: bannerHeight + iconSectionHeight, + child: Stack( + clipBehavior: Clip.none, + children: [ + Positioned( + top: 0, + left: 0, + right: 0, + height: bannerHeight, + child: _buildBannerSection(bannerHeight, context), + ), + Positioned( + left: 10, + right: 10, + top: bannerHeight - iconOverlapBanner, + height: iconSectionHeight, + child: _buildIconSection(context, rebuiltVisibleSections), + ), + ], + ), + ), + ], + ), + ); + }, + ); + } + + Widget _buildBannerSection(double bannerHeight, BuildContext context) { + return Stack( + children: [ + Image.asset( + bannerAsset, + width: MediaQuery.of(context).size.width, + height: bannerHeight, + fit: BoxFit.fitWidth, + errorBuilder: (c, e, s) { + return Container( + color: Colors.blueGrey, + height: bannerHeight, + alignment: Alignment.center, + child: const Text('Banner', style: TextStyle(color: Colors.white)), + ); + }, + ), + ], + ); + } + + Widget _buildIconSection(BuildContext context, List buttonInfos) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + boxShadow: const [ + BoxShadow(color: Colors.black12, blurRadius: 6, offset: Offset(0, 2)), + ], + ), + child: ListView.builder( + physics: const AlwaysScrollableScrollPhysics(), + padding: const EdgeInsets.all(0), + itemCount: buttonInfos.length, + itemBuilder: (context, index) { + final section = buttonInfos[index]; + final items = section.items; + if (items.isEmpty) return const SizedBox.shrink(); + + return Padding( + padding: const EdgeInsets.only(top: 10, left: 10, right: 10), + child: Container( + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 标题 + Padding( + padding: const EdgeInsets.fromLTRB(10, 10, 10, 5), + child: Row( + children: [ + Container(width: 2, height: 10, color: Colors.blue), + const SizedBox(width: 5), + Text(section.title, + style: const TextStyle( + fontSize: 14, fontWeight: FontWeight.bold)), + ], + ), + ), + // icons + Padding( + padding: const EdgeInsets.all(10), + child: LayoutBuilder( + builder: (context, constraints) { + const spacing = 20.0; + final totalWidth = constraints.maxWidth; + final itemWidth = (totalWidth - spacing * 2) / 3; + return Wrap( + spacing: spacing, + runSpacing: spacing, + children: items.map((item) { + return SizedBox( + width: itemWidth, + child: _buildItem( + item, + onTap: item.onTap ?? + () => debugPrint('Tapped ${item.title}'), + ), + ); + }).toList(), + ); + }, + ), + ), + ], + ), + ), + ); + }, + ), + ); + } + + Widget _buildItem(AppSectionItem item, {VoidCallback? onTap}) { + const double iconSize = 30; + final int badgeNum = item.badge; + final String title = item.title; + final String iconPath = item.icon; + + return InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(8), + child: SizedBox( + width: double.infinity, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Stack( + clipBehavior: Clip.none, + children: [ + SizedBox( + width: iconSize, + height: iconSize, + child: Image.asset( + iconPath, + fit: BoxFit.contain, + errorBuilder: (c, e, s) { + return Container( + color: Colors.grey.shade200, + child: const Center(child: Icon(Icons.image, size: 18)), + ); + }, + ), + ), + if (badgeNum > 0) + Positioned( + top: -6, + right: -6, + child: Container( + padding: + const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + decoration: + const BoxDecoration(color: Colors.red, shape: BoxShape.circle), + constraints: const BoxConstraints(minWidth: 16, minHeight: 16), + child: Center( + child: Text( + badgeNum > 99 ? '99+' : badgeNum.toString(), + style: const TextStyle(color: Colors.white, fontSize: 10, height: 1), + textAlign: TextAlign.center, + ), + ), + ), + ), + ], + ), + const SizedBox(height: 4), + Text( + title, + style: const TextStyle(fontSize: 13), + textAlign: TextAlign.center, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pages/home/hiddenDanger/hidden_record_detail_page.dart b/lib/pages/home/hiddenDanger/hidden_record_detail_page.dart new file mode 100644 index 0000000..73a0c95 --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_record_detail_page.dart @@ -0,0 +1,4080 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'package:open_file/open_file.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:qhd_prevention/constants/app_enums.dart'; +import 'package:qhd_prevention/customWidget/DocumentPicker.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart'; +import 'package:qhd_prevention/customWidget/big_video_viewer.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker_two.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker_hidden.dart'; +import 'package:qhd_prevention/customWidget/department_picker_three.dart'; +import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; +import 'package:qhd_prevention/customWidget/item_list_widget.dart'; +import 'package:qhd_prevention/customWidget/photo_picker_row.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/read_file_page.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/http/modules/auth_api.dart'; +import 'package:qhd_prevention/http/modules/file_api.dart'; +import 'package:qhd_prevention/http/modules/hidden_danger_api.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/danner_repair.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_record_detail_pastrecords_page.dart'; + + +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/services/SessionService.dart'; +import 'package:qhd_prevention/tools/h_colors.dart'; +import 'package:qhd_prevention/tools/tools.dart'; +import 'dart:convert'; +import 'package:video_player/video_player.dart'; + + +import 'package:qhd_prevention/http/modules/safety_check_api.dart'; + +class HiddenRecordDetailPage extends StatefulWidget { + const HiddenRecordDetailPage( + this.dangerType, + this.item, + this.itemId, + this.hiddenId, + this.canChange, { + Key? key, + this.inspectId, + this.inspectCodeId, + + }) : super(key: key); + + final DangerType dangerType; + final item; + final String itemId; + final String hiddenId; + final bool canChange; + final String? inspectId; + final String? inspectCodeId; + + @override + _HiddenRecordDetailPageState createState() => _HiddenRecordDetailPageState(); +} + +class _HiddenRecordDetailPageState extends State { + late Map pd = {}; + + List files = []; + List files2 = []; + List files4 = []; + List files5 = []; //验收图片 + List files6 = []; //安全环保检查验收图片 + List videoList = []; + List checkList = []; + List files7 = []; + + //隐患整改照片集合 + List> rectifiedPhotosList = []; + + //隐患验收照片集合 + List> acceptancePhotosList = []; + + bool modalShow = false; + VideoPlayerController? _videoController; + + ///隐患确认 + String buMenId = ""; + String buMenName = ""; + String responsibleId = ""; + String responsibleName = ""; + late bool _isDanger = false; + + // 存储各单位的人员列表缓存: key = deptId + final Map>> _personCache = {}; + + ///延期信息 + final TextEditingController _disposalPlanController = TextEditingController(); + String attachmentUp = '处置方案附件'; + + ///整改 + // 是否正常整改 + bool _accepted = true; + + // 是否有整改方案 + bool acceptedPrepare = false; + + // 是否有整改计划 + bool acceptedPlan = false; + late DannerRepair dannerRepair; + + // 在父组件中 + final GlobalKey dannerRepairKey = GlobalKey(); + final TextEditingController _reasonInabilityController = + TextEditingController(); + + ///特殊处置审核 + // 处置审核 + bool _disposalAudit = true; + + //是否更换整改负责人 + bool _replacePerson = false; + final TextEditingController _disposalPlanTwoController = + TextEditingController(); + + ///延期审核 + // 是否通过 + bool _agreePostpone = true; + + ///隐患验收 + // 是否合格 + bool _hazardAcceptanceQualified = true; + final TextEditingController _acceptanceDescriptionController = + TextEditingController(); + final TextEditingController _replyFeedbackController = + TextEditingController(); + List _acceptanceImages = []; + + // 查看过程记录 + bool _showAllData = false; + + //附件 + late SelectedFile? choosefile = null; + + // 是否是相关方 + bool _isStakeholder = false; + + /// 安全环保检查---------------------------- + // 安全环保检查指派人员列表 + late List _HazardPersonlist = []; + // 隐患确认人信息 + Map _hazarder = {}; + List safeCheckFiles = []; + // 验收信息 + Map acceptForm = {'finalCheck' : 1}; + /// ---------------------------- + + @override + void initState() { + super.initState(); + + if (widget.canChange) { + switch (widget.item) { + case 1: //确认 + hazardConfirmation['id'] = widget.itemId; + hazardConfirmation['hiddenId'] = widget.hiddenId; + hazardConfirmation['rectificationType'] = '2'; + break; + case 2: //忽略 + + break; + case 3: + hiddenDangerRectification['id'] = widget.itemId; + hiddenDangerRectification['hiddenId'] = widget.hiddenId; + // buttonText='整改'; + break; + case 4: + specialHandlingReview['id'] = widget.itemId; + specialHandlingReview['hiddenId'] = widget.hiddenId; + // buttonText='特殊处理审核'; + break; + case 5: + approvalExtensionApplication['id'] = widget.itemId; + approvalExtensionApplication['hiddenId'] = widget.hiddenId; + approvalExtensionApplication['state'] = 3; + // buttonText='延期审核'; + break; + case 6: + hiddenDangerAcceptance['id'] = widget.itemId; + hiddenDangerAcceptance['hiddenId'] = widget.hiddenId; + // buttonText='验收'; + break; + case 8: //延期 + requestExtension['hiddenId'] = widget.hiddenId; + break; + } + } + + _getUserData(); + _getAllData(); + } + + Future _getAllData() async { + await getData(); + _getImagePath( + widget.hiddenId, + UploadFileType.safetyEnvironmentalInspectionAcceptance, + ); + setState(() { + _getImagePath(widget.hiddenId, UploadFileType.hiddenDangerPhoto); + _getImagePath(widget.hiddenId, UploadFileType.hiddenDangerVideo); + + if(pd['hiddenRectifyUserCO'] != null && pd['hiddenRectifyUserCO'].isNotEmpty){ + _getImagePath( + pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length - + 1)]['hiddenUserId'], + UploadFileType.hiddenDangerRectificationPhoto, + ); + } + + + // _getImagePath(pd['hiddenAcceptUserCO'][(pd['hiddenAcceptUserCO'].length-1)]['hiddenUserId'],UploadFileType.hiddenDangerVerificationPhoto); + if (pd['hiddenAcceptUserCO'] != null) { + for (int i = 0; i < pd['hiddenAcceptUserCO'].length; i++) { + if((pd['hiddenAcceptUserCO'][i]['hiddenUserId']??'').isNotEmpty){ + _getImagePath( + pd['hiddenAcceptUserCO'][i]['hiddenUserId'], + UploadFileType.hiddenDangerVerificationPhoto, + ); + }else{ + acceptancePhotosList.add([]); + } + + } + } + + if (pd['hiddenRectifyUserCO'] != null &&pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length - + 1)]['hiddenSchemeCO'] != + null) { + _getImagePath( + pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length - + 1)]['hiddenSchemeCO']['hiddenSchemeId'], + UploadFileType.hiddenDangerRectificationPlan, + ); + } + + + }); + } + + Future _getHazardPersonlist() async { + try { + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.getHazardPersonlist(); + if (raw['success']) { + setState(() { + _HazardPersonlist = raw['data'] as List; + }); + LoadingDialogHelper.hide(); + } else { + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + @override + void dispose() { + _videoController?.dispose(); + super.dispose(); + } + + Future getData() async { + try { + final data = await HiddenDangerApi.getDangerDetail(widget.itemId); + if (data['success']) { + setState(() { + pd = data['data']; + // _isStakeholder=true; + _isStakeholder = pd['isRelated'] == 1 ? true : false; + if (widget.item == 1) { + hazardConfirmation['hiddenLevel'] = pd['hiddenLevel']; + hazardConfirmation['hiddenLevelName'] = pd['hiddenLevelName']; + hazardConfirmation['rectificationType'] = pd['rectificationType']; + _isDanger = pd['rectificationType'] == "1" ? true : false; + if (pd["hiddenUserPresetsCO"] != null) { + //整改 + hazardConfirmation['deptId'] = + pd["hiddenUserPresetsCO"]['rectifyDeptId'] ?? ''; + hazardConfirmation['deptName'] = + pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? ''; + hazardConfirmation['userId'] = + pd["hiddenUserPresetsCO"]['rectifyUserId'] ?? ''; + hazardConfirmation['userName'] = + pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? ''; + + //验收 + hazardConfirmation['checkDeptId'] = + pd["hiddenUserPresetsCO"]['checkDeptId'] ?? ''; + hazardConfirmation['checkDeptName'] = + pd["hiddenUserPresetsCO"]['checkDeptName'] ?? ''; + hazardConfirmation['checkUserId'] = + pd["hiddenUserPresetsCO"]['checkUserId'] ?? ''; + hazardConfirmation['checkUserName'] = + pd["hiddenUserPresetsCO"]['checkUserName'] ?? ''; + hazardConfirmation['rectificationDeadline'] = + pd["hiddenUserPresetsCO"]['rectifyDeadline'] ?? ''; + } + } + if ((pd['source'] == 5 || pd['source'] == 4) && pd['state'] == 102) { + _getHazardPersonlist(); + } + }); + } else { + ToastUtil.showNormal(context, "获取列表失败"); + } + } catch (e) { + print('Error fetching data: $e'); + } + } + + Future _getUserData() async { + try { + final raw = await AuthApi.getUserData(); + if (raw['success']) { + setState(() { + responsibleId = raw['data']['id']; + responsibleName = raw['data']['name']; + buMenId = raw['data']['departmentId']; + buMenName = raw['data']['departmentName']; + }); + } else { + ToastUtil.showNormal(context, "获取个人信息失败"); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + } + } + + Future _getImagePath(id, type) async { + try { + final data = await FileApi.getImagePath(id, type); + if (data['success']) { + setState(() { + List images = data['data'] ?? []; + if (UploadFileType.hiddenDangerPhoto == type) { + files.addAll(images); + } else if (UploadFileType.hiddenDangerVideo == type) { + videoList.addAll(images); + } else if (UploadFileType.hiddenDangerRectificationPhoto == type) { + files2.addAll(images); + List newList = []; + newList.addAll(images); + rectifiedPhotosList.add(newList); + } else if (UploadFileType.hiddenDangerRectificationPlan == type) { + files4.addAll(images); + } else if (UploadFileType.hiddenDangerVerificationPhoto == type) { + files5.addAll(images); + List newList = []; + newList.addAll(images); + acceptancePhotosList.add(newList); + } else if (UploadFileType.safetyEnvironmentalInspectionAcceptance == + type) { + files6.addAll(images); + } + }); + } else { + // ToastUtil.showNormal(context, "获取图片失败"); + } + } catch (e) { + print('Error fetching data: $e'); + } + } + + Future _getDiscoverPersonList() async { + String choice = await BottomPickerTwo.show( + context, + items: _HazardPersonlist, + itemName: "name", + itemBuilder: (item) => Text(item["name"], textAlign: TextAlign.center), + initialIndex: 0, + ); + if (choice != null) { + for (int i = 0; i < _HazardPersonlist.length; i++) { + if (choice == _HazardPersonlist[i]["name"]) { + setState(() { + _hazarder = _HazardPersonlist[i]; + }); + } + } + } + } + + Future _checkPersonSubmit() async { + if (!FormUtils.hasValue(acceptForm, 'finalCheckDesc')) { + ToastUtil.showNormal(context, '请输入验收描述'); + return; + } + if (!FormUtils.hasValue(acceptForm, 'finalCheckTime')) { + ToastUtil.showNormal(context, '请选择验收时间'); + return; + } + + LoadingDialogHelper.show(); + printLongString(jsonEncode(SessionService.instance.accountId)); + if (await _checkAcceptImages()) { + acceptForm['id'] = pd['id'] ?? ''; + try { + final result = await SafetyCheckApi.safeCheckAcceptance(acceptForm); + if (result['success']) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '提交成功'); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } else { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '提交失败:${result['errMessage']}'); + } + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '提交异常:$e'); + } + } + } + + /// 校验是否有验收图片需要上传 + Future _checkAcceptImages() async { + // 检查情况上传图片 + // text,images + var isSuccess = false; + if (safeCheckFiles.isNotEmpty) { + try { + await FileApi.uploadFiles( + safeCheckFiles, + UploadFileType.safetyEnvironmentalInspectionAcceptance, + pd['hiddenId'] ?? '', + ).then((result) { + if (result['success']) { + isSuccess = true; + } else { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, '图片上传失败'); + isSuccess = false; + } + }); + } catch (e) { + ToastUtil.showNormal(context, '图片上传失败'); + isSuccess = false; + } + } else { + isSuccess = true; + } + return isSuccess; + } + + /// 隐患指派确认 + Future _zpSubmit() async { + if (_hazarder.isEmpty) { + ToastUtil.showNormal(context, "请选择隐患确认人"); + return; + } + final data = { + "hiddenId": pd['id'] ?? '', + "hiddenBusinessId": pd['hiddenId'] ?? '', + "userId": _hazarder['userId'] ?? '', + "userName": _hazarder['name'] ?? '', + "deptId": _hazarder['deptId'] ?? '', + "deptName": _hazarder['deptName'] ?? '', + "inspectId": widget.inspectId, + }; + try { + LoadingDialogHelper.show(); + final result = await SafetyCheckApi.safeCheckHiddenAssign(data); + LoadingDialogHelper.dismiss(); + if (result['success'] == true) { + ToastUtil.showNormal(context, "指派成功"); + Navigator.pop(context); + } + } catch (e) { + LoadingDialogHelper.dismiss(); + print(e); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: widget.dangerType.detailTitle), + body: + pd.isEmpty + ? const Center(child: CircularProgressIndicator()) + : _listWidget(), + ); + } + + Widget _listWidget() { + List list = pd["hiddenAcceptUserCO"] ?? []; + + return LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints(minHeight: constraints.maxHeight), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + //隐患信息 + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem('隐患来源', _getSourceDangers(pd)), + + Divider(height: 1), + _buildInfoItem('隐患类型', pd['hiddenTypeName'] ?? ''), + + Divider(height: 1), + _buildInfoItem('隐患级别', pd['hiddenLevelName'] ?? ''), + + Divider(height: 1), + _buildInfoItem('隐患状态', _getState(pd)), + + Divider(height: 1), + _buildInfoItem('隐患描述', pd['hiddenDesc'] ?? ''), + + if (pd['hiddenPartName'] != null && + pd['hiddenPartName'].isNotEmpty) + Divider(height: 1), + if (pd['hiddenPartName'] != null && + pd['hiddenPartName'].isNotEmpty) + _buildInfoItem('隐患部位', pd['hiddenPartName'] ?? ''), + + // 条件渲染部分 + if (pd['source'] == 2 && + pd['hiddenCheckListCO'] != null) ...[ + Divider(height: 1), + _buildInfoItem( + '隐患清单', + pd['hiddenCheckListCO']['listName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '风险点(单元)', + pd['hiddenCheckListCO']['listRiskPoints'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '辨识部位', + pd['hiddenCheckListCO']['identifiedLocations'] ?? + '', + ), + Divider(height: 1), + _buildInfoItem( + '存在风险', + pd['hiddenCheckListCO']['existingRisks'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '风险分级', + pd['hiddenCheckListCO']['riskLevel'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '检查内容', + pd['hiddenCheckListCO']['inspectionContent'] ?? '', + ), + ], + + if ((pd['longitude'] ?? '').isNotEmpty) + Divider(height: 1), + if ((pd['longitude'] ?? '').isNotEmpty) + _buildInfoItem( + '隐患上报位置(经纬度)', + ((pd['longitude'] ?? '').isNotEmpty) + ? '${pd['longitude'] ?? ''},${pd['latitude'] ?? ''}' + : '', + ), + + if ((pd['positionDesc'] ?? '').isNotEmpty) + Divider(height: 1), + if ((pd['positionDesc'] ?? '').isNotEmpty) + _buildInfoItem('隐患位置描述', pd['positionDesc'] ?? ''), + + Divider(height: 1), + _buildInfoItem('隐患发现人', pd['creatorName'] ?? ''), + + Divider(height: 1), + _buildInfoItem( + '隐患发现时间', + _changeTime(pd['hiddenFindTime'] ?? ''), + ), + + Divider(height: 1), + _buildInfoItem( + '整改类型', + _getRectificationType(pd['rectificationType']), + ), + + Divider(height: 1), + _buildInfoItem('是否相关方', _getText(pd['isRelated'])), + + Divider(height: 1), + // 隐患照片 + // const Text('隐患照片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files, onTap: (index) => _showImageGallery(files, index)), + ListItemFactory.createTextImageItem( + text: "隐患照片", + imageUrls: + files + .map((item) => item['filePath'].toString()) + .toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: '', + imageUrls: + files + .map( + (item) => + ApiService.baseImgPath + + item['filePath'], + ) + .toList(), + initialIndex: index, + ), + context, + ); + }, + ), + + // 隐患视频 + if (videoList.isNotEmpty) ...[ + SizedBox(height: 10), + Padding( + padding: EdgeInsets.only(left: 10, right: 10), + child: Text( + '隐患视频', + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + + GestureDetector( + onTap: () { + showDialog( + context: context, + barrierColor: Colors.black54, + builder: + (_) => VideoPlayerPopup( + videoUrl: + ApiService.baseImgPath + + videoList[0]['filePath'], + ), + ); + }, + child: Image.asset( + 'assets/image/videostart.png', // 替换为你的视频占位图 + color: Colors.blue, + width: 120, + height: 120, + ), + ), + ], + ], + ), + ), + + + // 整改信息(发现人预填) + if (pd['hiddenUserPresetsCO'] != null) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "整改信息(发现人预填)", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem( + pd["isRelated"] == 0 ? '整改部门' : '整改单位(相关方项目)', + pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改人' : '整改人(相关方项目)', + pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? '', + ), + + if (pd["hiddenUserPresetsCO"]['rectifyDeadline'] != + null && + pd["hiddenUserPresetsCO"]['rectifyDeadline'] != + '') + Divider(height: 1), + if (pd["hiddenUserPresetsCO"]['rectifyDeadline'] != + null && + pd["hiddenUserPresetsCO"]['rectifyDeadline'] != + '') + _buildInfoItem( + '整改期限', + // _changeTime( pd["hiddenUserPresetsCO"]['rectifyDeadline'] ?? ''), + pd["hiddenUserPresetsCO"]['rectifyDeadline'] ?? + '', + ), + + if ((pd["hiddenUserPresetsCO"]['checkDeptName'] ?? + '') != + '') ...[ + Divider(height: 1), + _buildInfoItem( + '验收部门', + // pd["isRelated"]==0?'验收部门':'验收单位(相关方项目)', + pd["hiddenUserPresetsCO"]['checkDeptName'] ?? '', + ), + ], + + if ((pd["hiddenUserPresetsCO"]['checkUserName'] ?? + '') != + '') ...[ + Divider(height: 1), + _buildInfoItem( + '验收人', + // pd["isRelated"]==0?'验收人':'验收人(相关方项目)', + pd["hiddenUserPresetsCO"]['checkUserName'] ?? '', + ), + ], + ], + ), + ), + ], + + // 隐患确认 + if (pd['hiddenConfirmUserCO'] != null + // &&(pd["state"]!=100) + && + (widget.item == 1 || + widget.item == 2 || + widget.item == 3 || + widget.item == 4 || + widget.item == 5 || + widget.item == 6 || + widget.item == 7|| + widget.item == 8)) ...[ + // const Divider(height: 10,color: Colors.grey,), + SizedBox(height: 10), + + if (!_showAllData) + _hiddenDangerConfirmationItem( + pd["hiddenConfirmUserCO"][(pd["hiddenConfirmUserCO"].length - 1)], + pd["hiddenConfirmUserCO"].length - 1, + ), + + if (_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenConfirmUserCO"].length, + itemBuilder: + (ctx, idx) => _hiddenDangerConfirmationItem( + pd["hiddenConfirmUserCO"][idx], + idx, + ), + ), + ], + + + + //延期和特殊处置 + if (widget.item == 3 || + widget.item == 4 || + widget.item == 5 || + widget.item == 6 || + widget.item == 7 || + widget.item == 8) ...[ + if (pd["hiddenExtensionList"] != null && + pd["hiddenExtensionList"].isNotEmpty) ...[ + SizedBox(height: 10), + + if (!_showAllData && + (pd["hiddenExtensionList"][(pd["hiddenExtensionList"] + .length - + 1)]['updateName'] != + null)) + _delayInformationItem( + pd["hiddenExtensionList"][(pd["hiddenExtensionList"] + .length - + 1)], + 0, + ), + + if (_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenExtensionList"].length, + itemBuilder: + (ctx, idx) => _delayInformationItem( + pd["hiddenExtensionList"][idx], + idx, + ), + ), + ], + + if (pd["hiddenSpecialList"] != null && + pd["hiddenSpecialList"].isNotEmpty) ...[ + SizedBox(height: 10), + + if (!_showAllData && + pd["hiddenSpecialList"][(pd["hiddenSpecialList"] + .length - + 1)]['updateName'] != + null && + pd["hiddenSpecialList"][(pd["hiddenSpecialList"] + .length - + 1)]['updateName'] != + '') + _specialDisposalItem( + pd["hiddenSpecialList"][(pd["hiddenSpecialList"] + .length - + 1)], + 0, + ), + + if (_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenSpecialList"].length, + itemBuilder: + (ctx, idx) => _specialDisposalItem( + pd["hiddenSpecialList"][idx], + idx, + ), + ), + ], + ], + + // 整改信息 + if (pd['hiddenRectifyUserCO'] != null && + (pd["state"] != 100) && + (widget.item == 6 || widget.item == 7)) ...[ + SizedBox(height: 10), + + // const Divider(height: 10,color: Colors.grey,), + if (!_showAllData) + _ectificationInformationItem( + pd["hiddenRectifyUserCO"][(pd["hiddenRectifyUserCO"] + .length - + 1)], + 0, + ), + + if (_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenRectifyUserCO"].length, + itemBuilder: + (ctx, idx) => _ectificationInformationItem( + pd["hiddenRectifyUserCO"][idx], + idx, + ), + ), + ], + + // 验收信息 + if (pd['hiddenAcceptUserCO'] != null && + (pd["state"] != 100) && + ((widget.item == 7) || (widget.item == 3))) ...[ + SizedBox(height: 10), + + // const Divider(height: 10,color: Colors.grey,), + if (!_showAllData) + _acceptanceInformationItem(list.last, (list.length - 1)), + + if (_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenAcceptUserCO"].length, + itemBuilder: + (ctx, idx) => _acceptanceInformationItem( + pd["hiddenAcceptUserCO"][idx], + idx, + ), + ), + ], + + // 安全环保检查验收信息 + if (pd['hiddenInspecCO'] != null && (widget.item == 7)) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + _safetyEnvironmentalItem(pd["hiddenInspecCO"] ?? {}, 0), + ], + + ///=============以下是操作 + // 隐患确认操作 + if (widget.canChange && widget.item == 1) ...[ + SizedBox(height: 10), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患确认", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + if ((pd['source'] != 5 || pd['source'] == 4) && pd['source'] != 4 ) + GestureDetector( + onTap: () { + _getHazardLevel(); + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "隐患级别", + rightText: + hazardConfirmation['hiddenLevelName'] + .isNotEmpty + ? hazardConfirmation['hiddenLevelName'] + : "请选择", + isRight: true, + ), + ), + ), + + if ('忽略隐患' != + hazardConfirmation['hiddenLevelName']) ...[ + if (pd['rectificationType'] == 1) + Divider(height: 1), + if (pd['rectificationType'] == 1) + _buildSectionContainer( + child: ListItemFactory.createYesNoSectionTwo( + title: "是否立即整改", + horizontalPadding: 0, + verticalPadding: 0, + yesLabel: "是", + noLabel: "否", + groupValue: _isDanger, + canClick: true, + context: context, + onChanged: (val) { + setState(() { + _isDanger = val; + _isDanger ? hazardConfirmation['rectificationType'] = '1' : hazardConfirmation['rectificationType'] ='2'; + + if (_isDanger) { + //整改 + // hazardConfirmation['deptId'] = buMenId; + // hazardConfirmation['deptName'] = buMenName; + // hazardConfirmation['userId'] = responsibleId; + // hazardConfirmation['userName'] = responsibleName; + //验收 + hazardConfirmation['checkDeptId'] = + pd["hiddenUserPresetsCO"]['checkDeptId'] ?? + ''; + hazardConfirmation['checkDeptName'] = + pd["hiddenUserPresetsCO"]['checkDeptName'] ?? + ''; + hazardConfirmation['checkUserId'] = + pd["hiddenUserPresetsCO"]['checkUserId'] ?? + ''; + hazardConfirmation['checkUserName'] = + pd["hiddenUserPresetsCO"]['checkUserName'] ?? + ''; + } else { + //整改 + // hazardConfirmation['deptId'] = ''; + // hazardConfirmation['deptName'] = ''; + // hazardConfirmation['userId'] = ''; + // hazardConfirmation['userName'] = ''; + //验收 + hazardConfirmation['checkDeptId'] = ''; + hazardConfirmation['checkDeptName'] = + ''; + hazardConfirmation['checkUserId'] = ''; + hazardConfirmation['checkUserName'] = + ''; + } + + // if(_isStakeholder){ + // //整改 + // hazardConfirmation['deptId'] = pd["hiddenUserPresetsCO"]['rectifyDeptId'] ?? ''; + // hazardConfirmation['deptName'] = pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? ''; + // hazardConfirmation['userId'] = pd["hiddenUserPresetsCO"]['rectifyUserId'] ?? ''; + // hazardConfirmation['userName'] = pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? ''; + // // //验收 + // // hazardConfirmation['checkDeptId'] = pd["hiddenUserPresetsCO"]['rectifyDeptId'] ?? ''; + // // hazardConfirmation['checkDeptName'] = pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? ''; + // // hazardConfirmation['checkUserId'] = pd["hiddenUserPresetsCO"]['rectifyUserId'] ?? ''; + // // hazardConfirmation['checkUserName'] = pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? ''; + // } + }); + }, + ), + ), + + Column( + children: [ + Divider(height: 1), + GestureDetector( + onTap: () { + if (!_isStakeholder) { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => DepartmentPickerHidden( + onSelected: (id, name) async { + setState(() { + hazardConfirmation['deptId'] = + id; + hazardConfirmation['deptName'] = + name; + // 选单位后清空该组的人员选择 + hazardConfirmation['userId'] = + ''; + hazardConfirmation['userName'] = + ''; + }); + // 拉该单位人员并缓存 + await _getPersonListForUnitId( + id, + ); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + } + }, + child: _buildSectionContainer( + child: + ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: + _isStakeholder + ? '整改单位' + : "整改部门", + rightText: + hazardConfirmation['deptName'] + .isNotEmpty + ? hazardConfirmation['deptName'] + : "请选择", + isRight: !_isStakeholder, + ), + ), + ), + + Divider(height: 1), + + GestureDetector( + onTap: () { + if (!_isStakeholder) { + if (hazardConfirmation['deptName'] + .isEmpty) { + ToastUtil.showNormal(context, '请先选择部门'); + return; + } + final unitId = + (hazardConfirmation['deptId'] ?? '') + .toString(); + choosePersonHandle(unitId, 1); + } + }, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 15, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: + ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "整改人", + rightText: + hazardConfirmation['userName'] + .isNotEmpty + ? hazardConfirmation['userName'] + : "请选择", + isRight: !_isStakeholder, + ), + ), + ), + + Divider(height: 1), + + if (!_isDanger) + GestureDetector( + onTap: () async { + DateTime? picked = + await BottomDateTimePicker.showDate( + mode: BottomPickerMode.date, + context, + allowPast: false, + ); + if (picked != null) { + setState(() { + hazardConfirmation['rectificationDeadline'] = + DateFormat( + 'yyyy-MM-dd', + ).format(picked); + }); + //FocusHelper.clearFocus(context); + } + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "整改期限", + rightText: + hazardConfirmation['rectificationDeadline'] + .isNotEmpty + ? hazardConfirmation['rectificationDeadline'] + : "请选择", + isRight: true, + ), + ), + ), + ], + ), + + Divider(height: 1), + if (_isDanger) + Column( + children: [ + GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => DepartmentPickerHidden( + onSelected: (id, name) async { + setState(() { + hazardConfirmation['checkDeptId'] = + id; + hazardConfirmation['checkDeptName'] = + name; + // 选单位后清空该组的人员选择 + hazardConfirmation['checkUserId'] = + ''; + hazardConfirmation['checkUserName'] = + ''; + }); + // 拉该单位人员并缓存 + await _getPersonListForUnitId( + id, + ); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "验收部门", + rightText: + hazardConfirmation['checkDeptName'] + .isNotEmpty + ? hazardConfirmation['checkDeptName'] + : "请选择", + isRight: true, + ), + ), + ), + + Divider(height: 1), + + GestureDetector( + onTap: () { + if (hazardConfirmation['checkDeptName'] + .isEmpty) { + ToastUtil.showNormal(context, '请先选择部门'); + return; + } + final unitId = + (hazardConfirmation['checkDeptId'] ?? + '') + .toString(); + choosePersonHandle(unitId, 2); + }, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 15, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "验收人", + rightText: + hazardConfirmation['checkUserName'] + .isNotEmpty + ? hazardConfirmation['checkUserName'] + : "请选择", + isRight: true, + ), + ), + ), + ], + ), + ], + ], + ), + ), + ], + + //隐患整改操作 + if (widget.canChange && widget.item == 3) ...[ + SizedBox(height: 10), + + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患整改", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + ListItemFactory.createYesNoSection( + title: '是否正常整改', + yesLabel: '是', + noLabel: '否', + groupValue: _accepted, + onChanged: (val) { + setState(() { + _accepted = val; + }); + }, + ), + + // 整改选项 + _accepted + ? _getRepairState() + : _noAccepet_repair(_accepted), + ], + ), + ), + ], + + //特殊处理审核操作 + if (widget.canChange && widget.item == 4) ...[ + SizedBox(height: 10), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "特殊处理审核", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem( + '无法整改原因', + pd['hiddenSpecialList'][(pd['hiddenSpecialList'] + .length - + 1)]['examine'] ?? + '', + ), + + // Divider(height: 1), + // if((pd['hiddenSpecialList'][0]['disposalFile'])!=null&&(pd['hiddenSpecialList'][0]['disposalFile'])!='') + // GestureDetector( + // onTap: () { + // _downloadAndLoad(pd['hiddenSpecialList'][0]['disposalFile'] ); + // }, + // child: _buildSectionContainer( + // child: ListItemFactory.createRowSpaceBetweenItem( + // isRequired:true, + // leftText: "处置方案附件", + // rightText: "附件", + // isRight: true, + // ), + // ), + // ), + Divider(height: 1), + _buildInfoItem('特殊处置审核状态', '待审核'), + + Divider(height: 1), + ListItemFactory.createYesNoSection( + horizontalPadding: 0, + title: '处置审核', + yesLabel: '通过', + noLabel: '打回', + groupValue: _disposalAudit, + onChanged: (val) { + setState(() { + _disposalAudit = val; + }); + }, + ), + + Divider(height: 1), + if (_disposalAudit) ...[ + ItemListWidget.twoRowSelectableTitleText( + label: '处置方案', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller: _disposalPlanTwoController, + ), + Divider(height: 1), + SizedBox(height: 5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ItemListWidget.itemContainer( + ListItemFactory.headerTitle( + '处置方案附件:', + isRequired: true, + ), + ), + GestureDetector( + onTap: () async { + final List picked = + await DocumentPicker.showPickerModal( + context, + maxAssets: 1, + maxSizeInBytes: 20 * 1024 * 1024, + allowedExtensions: ['pdf'], + //, 'png', 'jpg', 'jpeg' + allowMultipleFiles: false, + showPhotoSelect: false, + ); + + if (picked.isNotEmpty && + picked.first.path != null) { + LoadingDialogHelper.show(); + final raw = await FileApi.uploadFile( + picked.first.path!, + UploadFileType.hiddenDangerPhoto, + specialHandlingReview['hiddenId'], + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + choosefile = picked.first; + specialHandlingReview['disposalFile'] = + raw['data']['filePath']; + attachmentUp = '已上传'; + ToastUtil.showNormal( + context, + "附件上传成功", + ); + }); + } else { + ToastUtil.showNormal(context, "附件上传失败"); + LoadingDialogHelper.hide(); + } + } + }, + child: Container( + width: choosefile != null ? 120 : 100, + margin: EdgeInsets.only(right: 10), + height: 35, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(4), + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/image/upload.png', + width: 15, + height: 15, + ), + const SizedBox(width: 5), + Text( + choosefile != null + ? '重新选择附件' + : '上传附件', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ), + ], + ), + SizedBox(height: 5), + if (choosefile != null) + Padding( + padding: EdgeInsetsGeometry.symmetric( + horizontal: 10, + ), + child: Column( + children: [ + SizedBox(height: 10), + GestureDetector( + onTap: () { + _onlySee(choosefile?.path ?? ''); + }, + child: Icon( + Icons.file_copy_outlined, + color: Colors.grey, + size: 50, + ), + ), + + SizedBox(height: 5), + Text(choosefile!.name), + SizedBox(height: 10), + ], + ), + ), + ], + + if (!_disposalAudit && !_isStakeholder) + ListItemFactory.createYesNoSection( + horizontalPadding: 0, + title: '是否更换整改负责人', + yesLabel: '是', + noLabel: '否', + groupValue: _replacePerson, + onChanged: (val) { + setState(() { + _replacePerson = val; + }); + }, + ), + + if (_replacePerson) + Column( + children: [ + GestureDetector( + onTap: () { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => DepartmentPickerHidden( + onSelected: (id, name) async { + setState(() { + specialHandlingReview['deptId'] = + id; + specialHandlingReview['deptName'] = + name; + // 选单位后清空该组的人员选择 + specialHandlingReview['rectifyPersonId'] = + ''; + specialHandlingReview['rectifyPersonName'] = + ''; + }); + // 拉该单位人员并缓存 + await _getPersonListForUnitId(id); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "整改部门", + rightText: + specialHandlingReview['deptName'] + .isNotEmpty + ? specialHandlingReview['deptName'] + : "请选择", + isRight: true, + ), + ), + ), + + Divider(height: 1), + + GestureDetector( + onTap: () { + if (specialHandlingReview['deptName'] + .isEmpty) { + ToastUtil.showNormal(context, '请先选择部门'); + return; + } + final unitId = + (specialHandlingReview['deptId'] ?? '') + .toString(); + choosePersonHandle(unitId, 1); + }, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 15, + ), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5), + ), + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "整改负责人", + rightText: + specialHandlingReview['rectifyPersonName'] + .isNotEmpty + ? specialHandlingReview['rectifyPersonName'] + : "请选择", + isRight: true, + ), + ), + ), + ], + ), + ], + ), + ), + ], + + //延期审核操作 + if (widget.canChange && widget.item == 5) ...[ + SizedBox(height: 10), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "延期审核", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem( + '申请延期日期', + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['createTime'] ?? + '', + ), + + Divider(height: 1), + _buildInfoItem( + '延期日期', + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['delayTime'] ?? + '', + ), + + if (pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['updateName'] != + null && + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['updateName'] != + '') ...[ + Divider(height: 1), + _buildInfoItem( + '审核人', + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['updateName'] ?? + '', + ), + ], + + Divider(height: 1), + _buildInfoItem( + '处置方案', + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['disposalPlan'] ?? + '', + ), + + if ((pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['disposalFile'] ?? + '') + .isNotEmpty) ...[ + Divider(height: 1), + ItemListWidget.OneRowButtonTitleText( + horizontalnum: 10, + label: '处置方案附件', + buttonText: '查看', + text: '', + onTap: () { + if ((pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['disposalFile'] ?? + '') + .isEmpty) { + ToastUtil.showNormal(context, '未上传文件'); + return; + } + _downloadAndLoad( + pd['hiddenExtensionList'][(pd['hiddenExtensionList'] + .length - + 1)]['disposalFile'] ?? + '', + ); + }, + ), + ], + + Divider(height: 1), + _buildInfoItem('延期审核状态', '待审核 '), + + ListItemFactory.createYesNoSection( + horizontalPadding: 0, + title: '是否通过', + yesLabel: '通过', + noLabel: '打回', + groupValue: _agreePostpone, + onChanged: (val) { + setState(() { + _agreePostpone = val; + approvalExtensionApplication['state'] = + _agreePostpone ? 3 : 4; + }); + }, + ), + ], + ), + ), + ], + + //隐患验收操作 + if (widget.canChange && widget.item == 6) ...[ + SizedBox(height: 10), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患验收", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + ListItemFactory.createYesNoSection( + horizontalPadding: 0, + title: '是否合格', + yesLabel: '是', + noLabel: '否', + groupValue: _hazardAcceptanceQualified, + onChanged: (val) { + setState(() { + _hazardAcceptanceQualified = val; + }); + }, + ), + + if (_hazardAcceptanceQualified) ...[ + Divider(height: 1), + ItemListWidget.twoRowSelectableTitleText( + label: '验收描述', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller: _acceptanceDescriptionController, + ), + + Divider(height: 1), + GestureDetector( + onTap: () async { + DateTime? picked = + await BottomDateTimePicker.showDate( + mode: + BottomPickerMode.dateTimeWithSeconds, + context, + allowPast: false, + ); + if (picked != null) { + setState(() { + hiddenDangerAcceptance['rectificationTime'] = + DateFormat( + 'yyyy-MM-dd HH:mm:ss', + ).format(picked); + }); + //FocusHelper.clearFocus(context); + } + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "验收日期", + rightText: + hiddenDangerAcceptance['rectificationTime'] + .isNotEmpty + ? hiddenDangerAcceptance['rectificationTime'] + : "请选择", + isRight: true, + ), + ), + ), + + Divider(height: 1), + _buildSectionContainer( + child: RepairedPhotoSection( + isRequired:false, + title: "验收图片", + maxCount: 4, + horizontalPadding: 0, + mediaType: MediaType.image, + isShowAI: false, + onChanged: (List files) { + // 上传图片 files + _acceptanceImages.clear(); + for (int i = 0; i < files.length; i++) { + _acceptanceImages.add(files[i].path); + } + }, + onAiIdentify: () {}, + ), + ), + ], + + Divider(height: 1), + if (!_hazardAcceptanceQualified) + ItemListWidget.twoRowSelectableTitleText( + label: '打回意见', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller: _replyFeedbackController, + ), + ], + ), + ), + ], + + //延期申请操作 + if (widget.canChange && widget.item == 8) ...[ + SizedBox(height: 10), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "延期信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + GestureDetector( + onTap: () async { + DateTime now = DateTime.now(); + String formattedDate = "${now.year}-${now.month.toString().padLeft(2, '0')}-${now.day.toString().padLeft(2, '0')}"; + if(pd["hiddenConfirmUserCO"]!=null&&pd["hiddenConfirmUserCO"].isNotEmpty&& + (pd["hiddenConfirmUserCO"][(pd["hiddenConfirmUserCO"].length - 1)]['rectificationDeadline']??'').isNotEmpty){ + formattedDate=pd["hiddenConfirmUserCO"][(pd["hiddenConfirmUserCO"].length - 1)]['rectificationDeadline']; + } + + if(pd["hiddenExtensionList"]!=null&&pd["hiddenExtensionList"].isNotEmpty&& + (pd["hiddenExtensionList"][(pd["hiddenExtensionList"].length - 1)]['delayTime']??'').isNotEmpty){ + formattedDate=pd["hiddenExtensionList"][(pd["hiddenExtensionList"].length - 1)]['delayTime']; + } + + DateTime? picked = + await BottomDateTimePicker.showDate( + mode: BottomPickerMode.date, + context, + allowPast: false, + minTimeStr: formattedDate, + ); + if (picked != null) { + setState(() { + requestExtension['delayTime'] = DateFormat( + 'yyyy-MM-dd', + ).format(picked); + }); + //FocusHelper.clearFocus(context); + } + }, + child: _buildSectionContainer( + child: ListItemFactory.createRowSpaceBetweenItem( + isRequired: true, + leftText: "延期日期", + rightText: + requestExtension['delayTime'].isNotEmpty + ? requestExtension['delayTime'] + : "请选择", + isRight: true, + ), + ), + ), + + ItemListWidget.twoRowSelectableTitleText( + label: '处置方案', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller: _disposalPlanController, + ), + + // ItemListWidget.OneRowButtonTitleText( + // horizontalnum: 25, + // label: '处置方案附件', + // buttonText: attachmentUp, + // text: '', + // onTap: () async { + // final List picked = await DocumentPicker.showPickerModal( + // context, + // maxAssets: 1, + // maxSizeInBytes: 20 * 1024 * 1024, + // allowedExtensions: ['pdf', 'png', 'jpg', 'jpeg'], + // allowMultipleFiles: false, + // ); + // + // if (picked.isNotEmpty && picked.first.path != null) { + // LoadingDialogHelper.show(); + // final raw = await FileApi.uploadFile(picked.first.path!,UploadFileType.hiddenDangerPhoto, requestExtension['hiddenId']); + // if (raw['success'] ) { + // LoadingDialogHelper.hide(); + // setState(() { + // requestExtension['disposalFile']=raw['data']['filePath']; + // attachmentUp='已上传'; + // ToastUtil.showNormal(context, "附件上传成功"); + // }); + // + // }else{ + // ToastUtil.showNormal(context, "附件上传失败"); + // LoadingDialogHelper.hide(); + // } + // } + // + // }, + // ), + SizedBox(height: 5), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ItemListWidget.itemContainer( + ListItemFactory.headerTitle( + '处置方案附件:', + isRequired: false, + ), + ), + GestureDetector( + onTap: () async { + final List picked = + await DocumentPicker.showPickerModal( + context, + maxAssets: 1, + maxSizeInBytes: 20 * 1024 * 1024, + allowedExtensions: ['pdf'], + //, 'png', 'jpg', 'jpeg' + allowMultipleFiles: false, + showPhotoSelect: false, + ); + + if (picked.isNotEmpty && + picked.first.path != null) { + LoadingDialogHelper.show(); + final raw = await FileApi.uploadFile( + picked.first.path!, + UploadFileType.hiddenDangerPhoto, + specialHandlingReview['hiddenId'], + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + choosefile = picked.first; + requestExtension['disposalFile'] = + raw['data']['filePath']; + attachmentUp = '已上传'; + ToastUtil.showNormal(context, "附件上传成功"); + }); + } else { + ToastUtil.showNormal(context, "附件上传失败"); + LoadingDialogHelper.hide(); + } + } + }, + child: Container( + width: choosefile != null ? 120 : 100, + margin: EdgeInsets.only(right: 10), + height: 35, + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(4), + ), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'assets/image/upload.png', + width: 15, + height: 15, + ), + const SizedBox(width: 5), + Flexible( + child: Text( + choosefile != null ? '重新选择附件' : '上传附件', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + ), + overflow: TextOverflow.ellipsis, // 文字过长时显示... + ), + ), + ], + ) + ), + ), + ], + ), + SizedBox(height: 5), + if (choosefile != null) + Padding( + padding: EdgeInsetsGeometry.symmetric( + horizontal: 10, + ), + child: Column( + children: [ + SizedBox(height: 10), + GestureDetector( + onTap: () { + _onlySee(choosefile?.path ?? ''); + }, + child: Icon( + Icons.file_copy_outlined, + color: Colors.grey, + size: 50, + ), + ), + + SizedBox(height: 5), + Text(choosefile!.name), + SizedBox(height: 10), + ], + ), + ), + ], + ), + ), + ], + + // 安全环保检查隐患指派 + if ((pd['source'] == 5 || pd['source'] == 4) && pd['state'] == 102 && widget.canChange) ...[ + Card( + color: Colors.white, + child: Padding( + padding: EdgeInsetsGeometry.symmetric(vertical: 5), + child: Column( + children: [ + ListItemFactory.createBuildSimpleSection( + '安全环保检查指派隐患确认人', + ), + ItemListWidget.selectableLineTitleTextRightButton( + isRequired: true, + label: "隐患确认人", + text: + _hazarder.isNotEmpty + ? _hazarder['name'] + : "请选择", + isEditable: true, + onTap: () { + _getDiscoverPersonList(); + }, + ), + const SizedBox(height: 5), + ], + ), + ), + ), + const SizedBox(height: 10), + + ], + + + //操作按钮 + if (widget.canChange) SizedBox(height: 12), + if (widget.canChange) ...[ + if (widget.item == 7 && + (pd['source'] == 5 || pd['source'] == 4) && + (pd['state'] == 301 || pd['state'] == 400) ) ...[ + Card(color: Colors.white, child: safeCheckWidget()), + const SizedBox(height: 10), + ], + ], + if (widget.canChange) + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // if (widget.item == 1)...[ + // if (pd['source'] != 5 && pd['source'] != 4&&pd["source"]!=7) + // Expanded( + // child: CustomButton( + // height: 35, + // onPressed: () { + // pushPage( + // RejectHiddenPage(hazardConfirmation), + // context, + // ); + // // _rejectHidden(); + // }, + // backgroundColor: Colors.red, + // textStyle: const TextStyle(color: Colors.white), + // buttonStyle: ButtonStyleType.primary, + // text: '打回', + // ), + // ), + // SizedBox(width: 10), + // ], + + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 10, right: 5), // 调整间距 + // child: ElevatedButton( + // onPressed: () { + // pushPage(RejectHiddenPage(hazardConfirmation), context); + // // _rejectHidden(); + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.red, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('打回'), + // ), + // ), + // ), + // 使用width而不是height + // 安全环保检查验收 + + // 查看详情按钮 + Expanded( + child: CustomButton( + height: 35, + onPressed: () { + // print('查看详情: ${pageData['title']}'); + switch (widget.item) { + case 1: + _setHazardConfirmation(); + break; + case 2: //忽略 + + break; + case 3: + _setHiddenDangerRectification(); + // buttonText='整改'; + break; + case 4: + _setApprovalSpecialDisposal(); + // buttonText='特殊处理审核'; + break; + case 5: + _setApprovalExtensionApplication(); + // buttonText='延期审核'; + break; + case 6: + // if (_hazardAcceptanceQualified) { + _setHiddenDangerAcceptance(); + // } else { + // _showConfirmation(); + // } + case 7: + if (pd['source'] == 5|| pd['source'] == 4) { + if (widget.dangerType == DangerType.safeCheckHiddenAccept) { + _checkPersonSubmit(); + } + if (widget.dangerType == DangerType.safeCheckHiddenAssign) { + _zpSubmit(); + } + } + case 6: + // if (_hazardAcceptanceQualified) { + _setHiddenDangerAcceptance(); + // } else { + // _showConfirmation(); + // } + case 7: + if (pd['source'] == 5 || pd['source'] == 4) { + if (widget.dangerType == DangerType.safeCheckHiddenAccept) { + _checkPersonSubmit(); + } + if (widget.dangerType == DangerType.safeCheckHiddenAssign) { + _zpSubmit(); + } + } + case 8: //延期 + _setRequestExtension(); + break; + } + }, + textStyle: const TextStyle(color: Colors.white), + buttonStyle: ButtonStyleType.primary, + text: '提交', + ), + ), + + // Expanded( + // child: Container( + // height: 35, + // margin: EdgeInsets.only(left: 5, right: 10), + // child: ElevatedButton( + // onPressed: () { + // // print('查看详情: ${pageData['title']}'); + // switch(widget.item){ + // case 1: + // _setHazardConfirmation(); + // break; + // case 2://忽略 + // + // break; + // case 3: + // _setHiddenDangerRectification(); + // // buttonText='整改'; + // break; + // case 4: + // _setApprovalSpecialDisposal(); + // // buttonText='特殊处理审核'; + // break; + // case 5: + // _setApprovalExtensionApplication(); + // // buttonText='延期审核'; + // break; + // case 6: + // if(_hazardAcceptanceQualified){ + // _setHiddenDangerAcceptance(); + // }else{ + // _showConfirmation(); + // } + // + // // buttonText='验收'; + // break; + // case 8://延期 + // _setRequestExtension(); + // break; + // } + // }, + // style: ElevatedButton.styleFrom( + // backgroundColor: Colors.blue, + // foregroundColor: Colors.white, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(8), + // ), + // ), + // child: Text('提交'), + // ), + // ), + // ), + ], + ), + + // 查看过程记录 + if (widget.item == 7 && widget.dangerType != DangerType.safeCheckHiddenAssign && widget.dangerType != DangerType.safeCheckHiddenAccept) ...[ + SizedBox(height: 12), + Container( + height: 35, + margin: EdgeInsets.only(left: 10, right: 10), + child: CustomButton( + text: _showAllData ? '收起过程记录' : '查看过程记录', + backgroundColor: Colors.blue, + borderRadius: 8, + onPressed: () { + setState(() { + pushPage( + HiddenRecordDetailPastrecordsPage( + widget.dangerType, + widget.item, + widget.itemId, + widget.hiddenId, + widget.canChange, + ), + context, + ); + // _showAllData=!_showAllData; + }); + }, + ), + ), + ], + + // 添加底部安全区域间距 + SizedBox(height: MediaQuery.of(context).padding.bottom + 20), + ], + ), + ), + ), + ); + }, + ); + } + + Widget safeCheckWidget() { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "安全环保检查验收", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + const SizedBox(height: 10), + ListItemFactory.createYesNoSection( + horizontalPadding: 0, + verticalPadding: 0, + title: '是否合格', + yesLabel: '是', + noLabel: '否', + isRequired: true, + groupValue: acceptForm['finalCheck'] == 1 ? true : false, + onChanged: (val) { + setState(() { + acceptForm['finalCheck'] = val ? 1 : 2; + }); + }, + ), + // const Text('整改信息', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), + const SizedBox(height: 5), + ItemListWidget.multiLineTitleTextField( + label: '验收描述', + isEditable: true, + hintText: '请输入验收描述', + text: acceptForm['finalCheckDesc'] ?? '', + onChanged: (v) { + setState(() { + acceptForm['finalCheckDesc'] = v; + }); + }, + ), + const SizedBox(height: 5), + ItemListWidget.selectableLineTitleTextRightButton( + label: '验收日期', + isEditable: true, + onTap: () async { + DateTime? picked = await BottomDateTimePicker.showDate( + mode: BottomPickerMode.date, + context, + allowPast: false, + ); + if (picked != null) { + setState(() { + acceptForm['finalCheckTime'] = DateFormat('yyyy-MM-dd HH:mm:ss').format(picked); + }); + } + }, + text: acceptForm['finalCheckTime'] ?? '', + ), + const SizedBox(height: 5), + // imageUrls: + // files4 + // .map((item) => item['filePath'].toString()) + // .toList(), + ItemListWidget.itemContainer( + horizontal: 6, + RepairedPhotoSection( + title: '验收图片', + initialMediaPaths: files6.map((item) => '${ApiService.baseImgPath}${item['filePath']}').toList(), + maxCount: 4, + isRequired: false, + mediaType: MediaType.image, + followInitialUpdates:true, + onChanged: + (files) => setState(() { + safeCheckFiles.clear(); + for (int i = 0; i < files.length; i++) { + safeCheckFiles.add(files[i].path); + } + }), + onAiIdentify: () {}, + ), + ), + ], + ); + } + + Widget _buildInfoItem(String title, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 120, + child: Text( + title, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + Expanded(child: Text(value, textAlign: TextAlign.right)), + ], + ), + ); + } + + //正常整改 + Widget _getRepairState() { + dannerRepair = DannerRepair(pd, key: dannerRepairKey); + return dannerRepair; + } + + //不是正常整改 + Widget _noAccepet_repair(bool _accept) { + return ItemListWidget.twoRowSelectableTitleText( + label: '无法整改原因', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller: _reasonInabilityController, + ); + } + + //隐患确认 + Future _setHazardConfirmation() async { + try { + + if (hazardConfirmation['hiddenLevelName'].isEmpty && (pd['source'] != 5 &&pd['source'] != 4)) { + ToastUtil.showNormal(context, "请选择隐患级别"); + return; + } + + if ('忽略隐患' != hazardConfirmation['hiddenLevelName']) { + if (hazardConfirmation['deptName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改责任部门"); + return; + } + + if (hazardConfirmation['userName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改人"); + return; + } + + if (_isDanger) { + if (hazardConfirmation['checkDeptName'].isEmpty) { + ToastUtil.showNormal(context, "请选择验收部门"); + return; + } + + if (hazardConfirmation['checkUserName'].isEmpty) { + ToastUtil.showNormal(context, "请选择验收改人"); + return; + } + } else { + if (hazardConfirmation['rectificationDeadline'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改期限"); + return; + } + } + } + + hazardConfirmation['status'] = '1'; + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setHazardConfirmation( + hazardConfirmation, + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //延期申请 + Future _setRequestExtension() async { + try { + if (requestExtension['delayTime'].isEmpty) { + ToastUtil.showNormal(context, "请选择延时审核延时间"); + return; + } + + // if(requestExtension['disposalFile'].isEmpty){ + // ToastUtil.showNormal(context, "请上传处置附件"); + // return; + // } + + String text = _disposalPlanController.text.trim(); + if (text.isEmpty) { + ToastUtil.showNormal(context, "请填写处置方案"); + return; + } + requestExtension['disposalPlan'] = text; + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setRequestExtension(requestExtension); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //隐患整改 + Future _setHiddenDangerRectification() async { + try { + if (_accepted) { + hiddenDangerRectification['status'] = 1; + String miaoShu = + dannerRepairKey.currentState!.miaoShuController.text.trim(); + if (miaoShu.isEmpty) { + ToastUtil.showNormal(context, "请填整改描述"); + return; + } + hiddenDangerRectification['descr'] = miaoShu; + + String dataTime = dannerRepairKey.currentState!.dataTime; + if (dataTime.isEmpty) { + ToastUtil.showNormal(context, "请选择整改时间"); + return; + } + hiddenDangerRectification['rectificationTime'] = dataTime; + + String linShiSZhengGai = dannerRepairKey.currentState!.linShiSZhengGaiController.text.trim(); + if (linShiSZhengGai.isEmpty) { + ToastUtil.showNormal(context, "请填临时整改措施"); + return; + } + hiddenDangerRectification['tempSafeMeasure'] = linShiSZhengGai; + + + String investmentFunds = dannerRepairKey.currentState!.investmentFunds; + if (investmentFunds.isEmpty) { + ToastUtil.showNormal(context, "请填写投入资金"); + return; + } + hiddenDangerRectification['investmentFunds'] = investmentFunds; + + List gaiHouImages = dannerRepairKey.currentState!.gaiHouImages; + if (gaiHouImages.isEmpty) { + ToastUtil.showNormal(context, "请上传整改后照片"); + return; + } + + List fangAnImages = []; + // 是否有整改方案 + bool acceptedPrepare = dannerRepairKey.currentState!.acceptedPrepare; + if (acceptedPrepare) { + hiddenDangerRectification['isRectificationScheme'] = 1; + + String standard = + dannerRepairKey.currentState!.standardController.text; + if (standard.isEmpty) { + ToastUtil.showNormal(context, "请输入治理标准要求"); + return; + } + hiddenDangerRectification['governStanDards'] = standard; + + String method = dannerRepairKey.currentState!.methodController.text; + if (method.isEmpty) { + ToastUtil.showNormal(context, "请输入治理方法"); + return; + } + hiddenDangerRectification['governMethod'] = method; + + String fund = dannerRepairKey.currentState!.fundController.text; + if (fund.isEmpty) { + ToastUtil.showNormal(context, "请输入经费和物资的落实"); + return; + } + hiddenDangerRectification['expenditure'] = fund; + + String person = dannerRepairKey.currentState!.personController.text; + if (person.isEmpty) { + ToastUtil.showNormal(context, "请输入负责治理人员"); + return; + } + hiddenDangerRectification['principal'] = person; + + String workTime = + dannerRepairKey.currentState!.workTimeController.text; + if (workTime.isEmpty) { + ToastUtil.showNormal(context, "请输入工时安排"); + return; + } + hiddenDangerRectification['programming'] = workTime; + + String time = dannerRepairKey.currentState!.timeController.text; + if (time.isEmpty) { + ToastUtil.showNormal(context, "请输入时限要求"); + return; + } + hiddenDangerRectification['timeLimitFor'] = time; + + String work = dannerRepairKey.currentState!.workController.text; + if (work.isEmpty) { + ToastUtil.showNormal(context, "请输入工作要求"); + return; + } + hiddenDangerRectification['jobRequireMent'] = work; + + String other = dannerRepairKey.currentState!.otherController.text; + if (other.isEmpty) { + ToastUtil.showNormal(context, "请输入其他事项"); + return; + } + hiddenDangerRectification['otherBusiness'] = other; + + fangAnImages = dannerRepairKey.currentState!.fangAnImages; + if (fangAnImages.isEmpty) { + ToastUtil.showNormal(context, "请上传方案照片"); + return; + } + } else { + hiddenDangerRectification['isRectificationScheme'] = 0; + } + + // String acceptedPlanType="0"; + // List jiHuaImages =[]; + // // 是否有整改计划 + // bool acceptedPlan= dannerRepairKey.currentState!.acceptedPlan; + // if(acceptedPlan){ + // acceptedPlanType="1"; + // jiHuaImages = dannerRepairKey.currentState!.jiHuaImages; + // if(jiHuaImages.isEmpty){ + // ToastUtil.showNormal(context, "请上传计划照片"); + // return; + // } + // } + + LoadingDialogHelper.show(); + + List departments = + dannerRepairKey.currentState!.departments; + bool departmentsAllInput = true; + bool departmentsSameMan = false; + for (int i = 0; i < departments.length; i++) { + if (departments[i].responsibleId.isEmpty) { + departmentsAllInput = false; + } else { + for (int m = i + 1; m < departments.length; m++) { + if (departments[i].responsibleId == + departments[m].responsibleId) { + departmentsSameMan = true; + } + } + } + } + + if (!departmentsAllInput) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, "请添加验收部门负责人"); + return; + } + + if (departmentsSameMan) { + LoadingDialogHelper.hide(); + ToastUtil.showNormal(context, "不能选择重复的验收部门负责人"); + return; + } + + // 转换为 JSON 字符串 + List> buMendata = _convertDepartmentsToJson( + departments, + ); + hiddenDangerRectification['hiddenUserAddCmds'] = buMendata; + + if (gaiHouImages.isNotEmpty) { + await _addImgFilesZhengGaiID( + gaiHouImages, + UploadFileType.hiddenDangerRectificationPhoto, + ); + } + + if (gaiHouImages.isNotEmpty) { + await _addImgFilesZhengGai( + fangAnImages, + UploadFileType.hiddenDangerRectificationPlan, + ); + } + + // for(int i=0;i raw; + // if(_accepted) { + raw = await HiddenDangerApi.setHiddenDangerRectification( + hiddenDangerRectification, + ); + // }else{ + // raw = await HiddenDangerApi.setReasonInability(hiddenDangerRectification); + // } + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //审批特殊处置审核 + Future _setApprovalSpecialDisposal() async { + try { + if (_disposalAudit) { + // 处置审核(通过,打回) + specialHandlingReview['state'] = 3; + + String text = _disposalPlanTwoController.text.trim(); + if (text.isEmpty) { + ToastUtil.showNormal(context, "请填写处置方案"); + return; + } + specialHandlingReview['disposalPlan'] = text; + + if (specialHandlingReview['disposalFile'].isEmpty) { + ToastUtil.showNormal(context, "请上传处置附件"); + return; + } + } else { + specialHandlingReview['state'] = 4; + if (_replacePerson) { + specialHandlingReview['modifyRectifyPerson'] = 1; + if (specialHandlingReview['deptName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改责任部门"); + return; + } + + if (specialHandlingReview['rectifyPersonName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改人"); + return; + } + } else { + specialHandlingReview['modifyRectifyPerson'] = 0; + } + } + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setApprovalSpecialDisposal( + specialHandlingReview, + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //审批延期申请 + Future _setApprovalExtensionApplication() async { + try { + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setApprovalExtensionApplication( + approvalExtensionApplication, + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //隐患验收 + Future _setHiddenDangerAcceptance() async { + try { + if (_hazardAcceptanceQualified) { + hiddenDangerAcceptance['status'] = 1; + String text = _acceptanceDescriptionController.text.trim(); + if (text.isEmpty) { + ToastUtil.showNormal(context, "请填写验收描述"); + return; + } + hiddenDangerAcceptance['descr'] = text; + + if (hiddenDangerAcceptance['rectificationTime'].isEmpty) { + ToastUtil.showNormal(context, "请选择验收日期"); + return; + } + + // if(_acceptanceImages.isEmpty){ + // ToastUtil.showNormal(context, "请选择验收图片"); + // return; + // } + + if (_acceptanceImages.isNotEmpty) { + await _addImgFiles( + _acceptanceImages, + UploadFileType.hiddenDangerVerificationPhoto, + hiddenDangerAcceptance['hiddenId'], + ); + } + } else { + hiddenDangerAcceptance['status'] = 0; + String text = _replyFeedbackController.text.trim(); + if (text.isEmpty) { + ToastUtil.showNormal(context, "请填写打回意见"); + return; + } + hiddenDangerAcceptance['repulseCause'] = text; + } + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setHiddenDangerAcceptance( + hiddenDangerAcceptance, + ); + if (raw['success']) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + } else { + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + Future _getHazardLevel() async { + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => MultiDictValuesPicker( + title: '隐患级别', + dictType: 'hiddenLevel', + allowSelectParent: false, + showIgnoreHidden: true, + onSelected: (id, name, extraData) { + setState(() { + hazardConfirmation['hiddenLevel'] = extraData?['dictValue']; + hazardConfirmation['hiddenLevelName'] = name; + }); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + + // try { + // LoadingDialogHelper.show(); + // final raw = await HiddenDangerApi.getHazardLevel( ); + // if (raw['success'] ) { + // final newList = raw['data'] ?? []; + // LoadingDialogHelper.hide(); + // + // for(int i=0;i DepartmentPickerThree( + // listdata: newList, + // onSelected: (id, name,pdId) async { + // setState(() { + // hazardConfirmation['hiddenLevel']=id; + // hazardConfirmation['hiddenLevelName']=name; + // }); + // + // }, + // ), + // ); + // + // }else{ + // ToastUtil.showNormal(context, "获取列表失败"); + // LoadingDialogHelper.hide(); + // } + // + // } catch (e) { + // // 出错时可以 Toast 或者在页面上显示错误状态 + // print('加载首页数据失败:$e'); + // LoadingDialogHelper.hide(); + // } + } + + /// 拉取某单位人员并缓存(兼容返回结构) + Future _getPersonListForUnitId(String id) async { + if (id.isEmpty) return; + LoadingDialogHelper.show(); + try { + final result = await BasicInfoApi.getDeptUsers(id); + LoadingDialogHelper.hide(); + // 兼容 result['data'] / result['userList'] 等常见字段 + dynamic raw = result['data']; + List> list = []; + if (raw is List) { + list = + raw.map>((e) { + if (e is Map) return e; + if (e is Map) return Map.from(e); + return {}; + }).toList(); + } else { + list = []; + } + setState(() { + _personCache[id] = list; + }); + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showError(context, '获取人员失败:$e'); + setState(() { + _personCache[id] = []; + }); + } + } + + /// 弹出人员选择 + void choosePersonHandle(final unitId, int num) async { + List> personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + // 先拉取一次 + await _getPersonListForUnitId(unitId); + personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位'); + return; + } + } + + // 显示人员选择器(假设 DepartmentPersonPicker.show 接口存在) + DepartmentPersonPicker.show( + context, + personsData: personList, + onSelected: (userId, name) { + setState(() { + switch (widget.item) { + case 1: + switch (num) { + case 1: + hazardConfirmation['userId'] = userId; + hazardConfirmation['userName'] = name; + break; + case 2: + hazardConfirmation['checkUserId'] = userId; + hazardConfirmation['checkUserName'] = name; + break; + } + break; + case 2: + // buttonText='忽略'; + break; + case 3: + // buttonText='整改'; + break; + case 4: + specialHandlingReview['rectifyPersonId'] = userId; + specialHandlingReview['rectifyPersonName'] = name; + // buttonText='特殊处理审核'; + break; + case 5: + // buttonText='延期审核'; + break; + case 6: + // buttonText='验收'; + break; + case 8: //延期 + // buttonText='验收'; + break; + } + }); + }, + ).then((_) { + //FocusHelper.clearFocus(context); + }); + } + + List> _convertDepartmentsToJson( + List departments, + ) { + // 1. 将列表中的每个对象转换为 Map + List> jsonList = + departments.map((dept) => dept.toJson()).toList(); + + // 2. 使用 jsonEncode 转换为 JSON 字符串 + // return jsonEncode(jsonList); + return jsonList; + } + + Widget _buildSectionContainer({required Widget child}) { + return Container( + margin: const EdgeInsets.only(top: 1), + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), + child: child, + ); + } + + String _getSourceDangers(final item) { + int type = item["source"]; + if (1 == type) { + return "隐患快报"; + } else if (2 == type) { + return "清单排查"; + } else if (3 == type) { + return "标准排查"; + } else if (4 == type) { + return "安全环保检查(监管端)"; + } else if (5 == type) { + return "安全环保检查(企业端)"; + } else if (6 == type) { + return "消防点检"; + }else if (7 == type) { + return "视频巡屏"; + } else { + return "NFC设备巡检"; + } + } + + String _getState(final item) { + int type = item["state"]; + if (100 == type) { + return "待确认"; + } else if (200 == type) { + return "未整改"; + } else if (201 == type) { + return "确认打回"; + } else if (202 == type) { + return "待处理特殊隐患"; + } else if (300 == type) { + return "已整改"; + } else if (301 == type) { + return "已验收"; + } else if (302 == type) { + return "验收打回"; + } else if (303 == type) { + return "验收打回"; + } else if (400 == type) { + return "已处理特殊隐患"; + } else if (99 == type) { + return "强制关闭(人员变动)"; + } else if (98 == type) { + return "安全环保检查/清单排查暂存"; + } else if (102 == type) { + return "安全环保检查,隐患待指派"; + } else if (97 == type) { + return "已过期"; + } else if (101 == type) { + return "忽略隐患"; + } else { + return "已过期"; + } + } + + String _changeTime(String time) { + try { + // 解析 ISO 8601 格式的时间字符串 + DateTime dateTime = DateTime.parse(time); + // 格式化为年月日 + return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); + } catch (e) { + // 如果解析失败,返回原字符串或默认值 + return ''; + } + } + + String _getRectificationType(int? type) { + switch (type) { + case 1: + return '立即整改'; + case 2: + return '限期整改'; + default: + return ''; + } + } + + Future _addImgFiles( + List imagePaths, + UploadFileType type, + String hiddenId, + ) async { + try { + final raw = await FileApi.uploadFiles(imagePaths, type, ''); + if (raw['success']) { + hiddenDangerAcceptance['hiddenUserId'] = raw['data']['foreignKey']; + return raw['data']; + } else { + // _showMessage('反馈提交失败'); + return ""; + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + Future _addImgFilesZhengGai( + List imagePaths, + UploadFileType type, + ) async { + try { + final raw = await FileApi.uploadFiles(imagePaths, type, ''); + if (raw['success']) { + hiddenDangerRectification['hiddenSchemeId'] = raw['data']['foreignKey']; + + return raw['data']; + } else { + // _showMessage('反馈提交失败'); + return ""; + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + Future _addImgFilesZhengGaiID( + List imagePaths, + UploadFileType type, + ) async { + try { + final raw = await FileApi.uploadFiles(imagePaths, type, ''); + if (raw['success']) { + hiddenDangerRectification['hiddenUserId'] = raw['data']['foreignKey']; + + return raw['data']; + } else { + // _showMessage('反馈提交失败'); + return ""; + } + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + Future _downloadAndLoad(String path) async { + try { + if (path.isEmpty) { + ToastUtil.showNormal(context, "文件地址错误"); + return; + } + pushPage(ReadFilePage(fileUrl: ApiService.baseImgPath + path), context); + // final url =ApiService.baseImgPath + path; + // final filename = url.split('/').last; + // final dir = await getTemporaryDirectory(); + // final filePath = '${dir.path}/$filename'; + // + // final dio = Dio(); + // final response = await dio.get>( + // url, + // options: Options(responseType: ResponseType.bytes), + // ); + // final file = File(filePath); + // await file.writeAsBytes(response.data!); + // + // final result = await OpenFile.open(filePath); + // if (result.type != ResultType.done) { + // ToastUtil.showNormal(context, "文件加载失败"); + // } + } catch (e) { + // 下载或加载失败 + ToastUtil.showNormal(context, "文件加载失败"); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('文件加载失败: \$e')), + // ); + } + } + + Future _onlySee(String path) async { + try { + if (path.isEmpty) { + ToastUtil.showNormal(context, "文件地址错误"); + return; + } + + final result = await OpenFile.open(path); + if (result.type != ResultType.done) { + ToastUtil.showNormal(context, "文件加载失败"); + } + } catch (e) { + // 下载或加载失败 + ToastUtil.showNormal(context, "文件加载失败"); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('文件加载失败: \$e')), + // ); + } + } + + void _showConfirmation() { + showDialog( + context: context, + builder: + (context) => AlertDialog( + title: const Text("提示"), + content: const Text("打回会清空整改图片"), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[400], + foregroundColor: Colors.white, + ), + child: const Text(" 取消 "), + ), + ElevatedButton( + onPressed: () { + // 执行操作 + Navigator.pop(context); + _setHiddenDangerAcceptance(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue[700], + foregroundColor: Colors.white, + ), + child: const Text("确定"), + ), + ], + ), + ); + } + + String _getText(int source) { + if (source == 1) { + return "是"; + } else { + return "否"; + } + } + + String _delayInformationText(text) { + if (text != '') { + if (text == 1) { + return "通过"; + } else { + return "未通过"; + } + } else { + return ""; + } + } + + String _delayInformationTextTwo(text) { + if (text != '') { + if (text == 1) { + return "待审核"; + }else if(text == 2){ + return "审批中"; + }else if(text == 3){ + return "已通过"; + }else if(text == 4){ + return "已拒绝"; + } else if(text == 5){ + return "已撤回"; + } else { + return "未通过"; + } + } else { + return ""; + } + } + + //隐患确认 + Widget _hiddenDangerConfirmationItem(itemData, int idx) { + if ((itemData["rectificationTime"] == null)) { + return SizedBox(); + } else { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "隐患确认", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + if (itemData["status"] != 0) + _buildInfoItem('隐患级别', itemData['hiddenLevelName'] ?? ''), + + Divider(height: 1), + _buildInfoItem('隐患确认人', itemData['userName'] ?? ''), + + Divider(height: 1), + _buildInfoItem( + '隐患确认时间', + _changeTime(itemData['rectificationTime'] ?? ''), + ), + + if (widget.item != 2 && itemData["status"] != 0) ...[ + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改部门' : '整改单位(相关方项目)', + itemData['rectifyDeptName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改人' : '整改人(相关方项目)', + itemData['rectifyUserName'] ?? '', + ), + + Divider(height: 1), + if ((itemData['rectificationDeadline'] ?? '').isNotEmpty) + _buildInfoItem( + '整改完成期限', + // _changeTime( itemData['rectificationDeadline'] ?? ''), + itemData['rectificationDeadline'] ?? '', + ), + ], + + if (itemData["status"] == 0) ...[ + Divider(height: 1), + _buildInfoItem('打回意见', itemData['repulseCause'] ?? ''), + + Divider(height: 1), + _buildInfoItem('打回时间', itemData['rectificationTime'] ?? ''), + ], + ], + ), + ); + } + } + + //延期信息 + Widget _delayInformationItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "延期信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem('申请延期日期', itemData['createTime'] ?? ''), + + Divider(height: 1), + _buildInfoItem('延期日期', itemData['delayTime'] ?? ''), + + Divider(height: 1), + _buildInfoItem('审核人', itemData['updateName'] ?? ''), + + Divider(height: 1), + _buildInfoItem('处置方案', itemData['disposalPlan'] ?? ''), + + if ((itemData['disposalFile'] ?? '').isNotEmpty) ...[ + Divider(height: 1), + ItemListWidget.OneRowButtonTitleText( + horizontalnum: 10, + label: '处置方案附件', + buttonText: '查看', + text: '', + onTap: () { + if ((itemData['disposalFile'] ?? '').isEmpty) { + ToastUtil.showNormal(context, '未上传文件'); + return; + } + _downloadAndLoad(itemData['disposalFile'] ?? ''); + }, + ), + ], + + Divider(height: 1), + _buildInfoItem( + '延期审核状态', + _delayInformationTextTwo(itemData['state'] ?? ''), + ), + + Divider(height: 1), + if((_delayInformationTextTwo(itemData['state'] ?? '')).isNotEmpty && itemData['state'] !=5) + _buildInfoItem('延期审核时间', itemData['updateTime'] ?? ''), + ], + ), + ); + } + + //隐患特殊处置 + Widget _specialDisposalItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "特殊处置信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem('审核人', itemData['updateName'] ?? ''), + + Divider(height: 1), + _buildInfoItem('审核时间', itemData['updateTime'] ?? ''), + + Divider(height: 1), + _buildInfoItem('无法整改原因', itemData['examine'] ?? ''), + + if (itemData['state'] == 3) ...[ + Divider(height: 1), + _buildInfoItem('处置方案', itemData['disposalPlan'] ?? ''), + + if ((itemData['disposalFile'] ?? '').isNotEmpty) ...[ + Divider(height: 1), + ItemListWidget.OneRowButtonTitleText( + horizontalnum: 10, + label: '处置方案附件', + buttonText: '查看', + text: '', + onTap: () { + if ((itemData['disposalFile'] ?? '').isEmpty) { + ToastUtil.showNormal(context, '未上传文件'); + return; + } + _downloadAndLoad(itemData['disposalFile'] ?? ''); + }, + ), + ], + ], + + if (itemData['modifyRectifyPerson'] != null) ...[ + Divider(height: 1), + _buildInfoItem( + '是否更换整改负责人', + _getText(itemData['modifyRectifyPerson'] ?? 0), + ), + if (itemData['rectifyUserCO'] != null) ...[ + Divider(height: 1), + _buildInfoItem( + '整改负责人', + itemData['rectifyUserCO']['userName'] ?? '', + ), + ], + ], + + Divider(height: 1), + _buildInfoItem( + '特殊处置审核状态', + _delayInformationTextTwo(itemData['state'] ?? ''), + ), + ], + ), + ); + } + + //整改信息 + Widget _ectificationInformationItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "整改信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem( + pd["isRelated"] == 0 ? '整改部门' : '整改单位(相关方项目)', + itemData['deptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改人' : '整改人(相关方项目)', + itemData['userName'] ?? '', + ), + + if (itemData['status'] != 0) ...[ + Divider(height: 1), + _buildInfoItem( + '整改时间', + // _changeTime( itemData['rectificationTime'] ?? ''), + itemData['rectificationTime'] ?? '', + ), + Divider(height: 1), + _buildInfoItem('整改描述', itemData['descr'] ?? ''), + Divider(height: 1), + _buildInfoItem('临时整改措施', itemData['remarks'] ?? ''), + Divider(height: 1), + _buildInfoItem( + '投入资金', + '${itemData['investmentFunds'].toString() ?? ''}元', + ), + + Divider(height: 1), + // const Text('整改后图片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files2, onTap: (index) => _showImageGallery(files2, index)), + ListItemFactory.createTextImageItem( + text: "整改后图片", + imageUrls: + files2.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + files2[index]['filePath'], + ), + context, + ); + }, + ), + + Divider(height: 1), + _buildInfoItem( + '整改方案', + itemData['isRectificationScheme'] == 1 ? '有' : '无', + ), + Divider(height: 1), + if (itemData['isRectificationScheme'] == 1 && + itemData["hiddenSchemeCO"] != null) + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // _buildInfoItem( + // '排查日期', + // itemData["hiddenSchemeCO"]['screeningDate'] ?? '', + // ), + + // Divider(height: 1), + _buildInfoItem( + '治理标准', + itemData["hiddenSchemeCO"]['governStanDards'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '治理方法', + itemData["hiddenSchemeCO"]['governMethod'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '经费落实', + itemData["hiddenSchemeCO"]['expenditure'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '负责人员', + itemData["hiddenSchemeCO"]['principal'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '工时安排', + itemData["hiddenSchemeCO"]['programming'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '时限要求', + itemData["hiddenSchemeCO"]['timeLimitFor'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '工作要求', + itemData["hiddenSchemeCO"]['jobRequireMent'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '其他事项', + itemData["hiddenSchemeCO"]['otherBusiness'] ?? '', + ), + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "方案图片", + imageUrls: + files4 + .map((item) => item['filePath'].toString()) + .toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + files4[index]['filePath'], + ), + context, + ); + }, + ), + ], + ), + ], + + if (itemData['status'] == 0) ...[ + Divider(height: 1), + _buildInfoItem('是否正常整改', '否'), + Divider(height: 1), + _buildInfoItem('无法整改原因', itemData['repulseCause'] ?? ''), + ], + ], + ), + ); + } + + //验收信息 + Widget _acceptanceInformationItem(itemData, int idx) { + // if(!_showAllData&&itemData['status']!=null&&itemData['status']==0){ + // return SizedBox(); + // }else{ + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "验收信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem( + '验收部门', + // pd["isRelated"]==0?'验收部门':'验收单位(相关方项目)', + itemData['deptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '验收人', + // pd["isRelated"]==0?'验收人':'验收人(相关方项目)', + itemData['userName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '验收时间', + _changeTime(itemData['rectificationTime'] ?? ''), + ), + + if (itemData['status'] != null && itemData['status'] == 0) ...[ + Divider(height: 1), + _buildInfoItem('是否合格', '不合格'), + Divider(height: 1), + _buildInfoItem('验收打回意见', itemData['repulseCause'] ?? ''), + ], + + if (itemData['status'] != 0) ...[ + Divider(height: 1), + _buildInfoItem('是否合格', '合格'), + + if ((itemData['descr'] ?? '').isNotEmpty) ...[ + Divider(height: 1), + _buildInfoItem( + '验收描述', + itemData['descr'] ?? '', + // itemData['repulseCause'] ?? '', + ), + ], + + if (acceptancePhotosList.isNotEmpty && + getFilePathList(acceptancePhotosList, idx).isNotEmpty) ...[ + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "验收图片", + // imageUrls: files5.map((item) => item['filePath'].toString()).toList(), + imageUrls: getFilePathList(acceptancePhotosList, idx), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + // files5[index]['filePath'], + acceptancePhotosList[idx][index]['filePath'], + ), + context, + ); + }, + ), + ], + ], + ], + ), + ); + // } + } + + //安全环保检查验收信息 + Widget _safetyEnvironmentalItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only(top: 10, left: 10, right: 10), + child: Row( + children: [ + Container(width: 3, height: 15, color: Colors.blue), + const SizedBox(width: 8), + Text( + "安全环保检查验收信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + _buildInfoItem('验收人', itemData['finalCheckOr'] ?? ''), + Divider(height: 1), + _buildInfoItem( + '验收时间', + itemData['finalCheckTime'] ?? '', + // _changeTime( itemData['finalCheckTime'] ?? ''), + ), + + Divider(height: 1), + _buildInfoItem('是否合格', itemData['finalCheck'] == 1 ? "合格" : "不合格"), + Divider(height: 1), + _buildInfoItem('验收描述', itemData['finalCheckDesc'] ?? ''), + + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "验收图片", + imageUrls: + files6.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: ApiService.baseImgPath + files6[index]['filePath'], + ), + context, + ); + }, + ), + ], + ), + ); + } + + List getFilePathList(List list, int idx) { + // List list= oldList.reversed.toList(); + if (list.isEmpty || idx < 0 || idx >= list.length || list[idx] == null) { + return []; // 返回空列表作为默认值 + } + + final items = list[idx]; + if (items == null || items.isEmpty) { + return []; + } + + // 方法1:使用 cast() + return (items as List) + .map( + (item) => + (item as Map)['filePath']?.toString() ?? '', + ) + .toList(); + } + + //隐患确认 + Map hazardConfirmation = { + "id": "", + "hiddenId": "", + "status": "", + "rectificationType": "", + "hiddenLevel": "", + "hiddenLevelName": "", + "rectificationDeadline": "", + "deptId": "", + "deptName": "", + "userId": "", + "userName": "", + "checkUserId": "", + "checkUserName": "", + "checkDeptId": "", + "checkDeptName": "", + "repulseCause": "", + }; + + //申请延期 + Map requestExtension = { + "hiddenId": "", + "delayTime": "", + "disposalFile": "", + "disposalPlan": "", + }; + + //隐患整改 + Map hiddenDangerRectification = { + "id": "", + "hiddenId": "", + "status": "", + "descr": "", + "investmentFunds": "", + "rectificationTime": "", + "tempSafeMeasure": "", + "isRectificationScheme": "", + "repulseCause": "", + "hiddenSchemeId": "", //整改方案id + "screeningDate": "", + "governStanDards": "", + "governMethod": "", + "expenditure": "", + "principal": "", + "programming": "", + "timeLimitFor": "", + "filePath": "", + "jobRequireMent": "", + "otherBusiness": "", + "examine": "", + "hiddenUserAddCmds": [ + // { + // "type": "300", + // "deptId": "", + // "deptName": "", + // "userId": "", + // "userName": "", + // } + ], + }; + + //特殊处理审核 + Map specialHandlingReview = { + "id": "", + "hiddenId": "", + "state": "", + "disposalPlan": "", + "modifyRectifyPerson": "", + "deptId": "", + "deptName": "", + "rectifyPersonId": "", + "rectifyPersonName": "", + "disposalFile": "", + "examine": "", + }; + + //审批延期申请 + Map approvalExtensionApplication = { + "id": "", + "hiddenId": "", + "state": "", + "examine": "", + }; + + //隐患验收 + Map hiddenDangerAcceptance = { + "id": "", + "hiddenId": "", + "hiddenUserId": "", + "status": "", + "descr": "", + "rectificationTime": "", + "repulseCause": "", + "checkUserId": "", + }; +} diff --git a/lib/pages/home/hiddenDanger/hidden_record_detail_pastrecords_page.dart b/lib/pages/home/hiddenDanger/hidden_record_detail_pastrecords_page.dart new file mode 100644 index 0000000..f65edf4 --- /dev/null +++ b/lib/pages/home/hiddenDanger/hidden_record_detail_pastrecords_page.dart @@ -0,0 +1,2534 @@ +import 'dart:io'; + +import 'package:dio/dio.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; +import 'package:open_file/open_file.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:qhd_prevention/constants/app_enums.dart'; +import 'package:qhd_prevention/customWidget/DocumentPicker.dart'; +import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; +import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart'; +import 'package:qhd_prevention/customWidget/big_video_viewer.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/department_person_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker.dart'; +import 'package:qhd_prevention/customWidget/department_picker_three.dart'; +import 'package:qhd_prevention/customWidget/department_picker_two.dart'; +import 'package:qhd_prevention/customWidget/full_screen_video_page.dart'; +import 'package:qhd_prevention/customWidget/item_list_widget.dart'; +import 'package:qhd_prevention/customWidget/photo_picker_row.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/read_file_page.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/http/modules/hidden_danger_api.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/danner_repair.dart'; + +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_acceptance.dart'; + +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/h_colors.dart'; +import 'package:qhd_prevention/tools/tools.dart'; +import 'dart:convert'; +import 'package:video_player/video_player.dart'; + + + +class HiddenRecordDetailPastrecordsPage extends StatefulWidget { + const HiddenRecordDetailPastrecordsPage(this.dangerType, this.item, this.itemId, this.hiddenId, this.canChange, {Key? key}) + : super(key: key); + + final DangerType dangerType; + final item; + final String itemId; + final String hiddenId; + final bool canChange; + + @override + _HiddenRecordDetailPastrecordsPageState createState() => _HiddenRecordDetailPastrecordsPageState(); +} + +class _HiddenRecordDetailPastrecordsPageState extends State { + + + + late Map pd = {}; + + List files = []; + List files2 = []; + List files4 = []; + List files5 = [];//验收图片 + List files6 = [];//安全环保检查验收图片 + List videoList = []; + List checkList = []; + List files7 = []; + + bool modalShow = false; + VideoPlayerController? _videoController; + + + ///隐患确认 + String buMenId = ""; + String buMenName = ""; + String responsibleId=""; + String responsibleName=""; + late bool _isDanger = false; + // 存储各单位的人员列表缓存: key = deptId + final Map>> _personCache = {}; + + + ///延期信息 + final TextEditingController _disposalPlanController=TextEditingController(); + String attachmentUp='处置方案附件'; + + ///整改 + // 是否正常整改 + bool _accepted = true; + // 是否有整改方案 + bool acceptedPrepare = false; + // 是否有整改计划 + bool acceptedPlan = false; + late DannerRepair dannerRepair; + // 在父组件中 + final GlobalKey dannerRepairKey = GlobalKey(); + final TextEditingController _reasonInabilityController=TextEditingController(); + + ///特殊处置审核 + // 处置审核 + bool _disposalAudit = true; + //是否更换整改负责人 + bool _replacePerson = false; + final TextEditingController _disposalPlanTwoController=TextEditingController(); + + ///延期审核 + // 是否通过 + bool _agreePostpone = true; + + ///隐患验收 + // 是否合格 + bool _hazardAcceptanceQualified = true; + final TextEditingController _acceptanceDescriptionController=TextEditingController(); + final TextEditingController _replyFeedbackController=TextEditingController(); + List _acceptanceImages = []; + + // 查看过程记录 + bool _showAllData = true; + + //附件 + late SelectedFile? choosefile = null; + // 是否是相关方 + bool _isStakeholder = false; + + //隐患整改照片集合 + List> rectifiedPhotosList=[]; + //隐患验收照片集合 + List> acceptancePhotosList=[]; + + @override + void initState() { + super.initState(); + + if(widget.canChange) { + switch (widget.item) { + case 1://确认 + hazardConfirmation['id'] = widget.itemId; + hazardConfirmation['hiddenId'] = widget.hiddenId; + hazardConfirmation['rectificationType'] = '2'; + break; + case 2://忽略 + + break; + case 3: + hiddenDangerRectification['id'] = widget.itemId; + hiddenDangerRectification['hiddenId'] = widget.hiddenId; + // buttonText='整改'; + break; + case 4: + specialHandlingReview['id'] = widget.itemId; + specialHandlingReview['hiddenId'] = widget.hiddenId; + // buttonText='特殊处理审核'; + break; + case 5: + approvalExtensionApplication['id'] = widget.itemId; + approvalExtensionApplication['hiddenId'] = widget.hiddenId; + approvalExtensionApplication['state']=3; + // buttonText='延期审核'; + break; + case 6: + hiddenDangerAcceptance['id'] = widget.itemId; + hiddenDangerAcceptance['hiddenId'] = widget.hiddenId; + // buttonText='验收'; + break; + case 8: //延期 + requestExtension['hiddenId'] = widget.hiddenId; + break; + } + } + + + _getUserData(); + _getAllData(); + + + } + + Future _getAllData() async { + await getData(); + setState(() { + _getImagePath(widget.hiddenId,UploadFileType.hiddenDangerPhoto); + _getImagePath(widget.hiddenId,UploadFileType.hiddenDangerVideo); + + if(pd['hiddenRectifyUserCO'] != null && pd['hiddenRectifyUserCO'].isNotEmpty) { + _getImagePath( + pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length - + 1)]['hiddenUserId'], + UploadFileType.hiddenDangerRectificationPhoto); + } + + // _getImagePath(pd['hiddenAcceptUserCO'][(pd['hiddenAcceptUserCO'].length-1)]['hiddenUserId'],UploadFileType.hiddenDangerVerificationPhoto); + if (pd['hiddenAcceptUserCO'] != null) { + for (int i = 0; i < pd['hiddenAcceptUserCO'].length; i++) { + if((pd['hiddenAcceptUserCO'][i]['hiddenUserId']??'').isNotEmpty){ + _getImagePath( + pd['hiddenAcceptUserCO'][i]['hiddenUserId'], + UploadFileType.hiddenDangerVerificationPhoto, + ); + }else{ + acceptancePhotosList.add([]); + } + + } + } + + if(pd['hiddenRectifyUserCO'] != null &&pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length-1)]['hiddenSchemeCO']!=null){ + _getImagePath(pd['hiddenRectifyUserCO'][(pd['hiddenRectifyUserCO'].length-1)]['hiddenSchemeCO']['hiddenSchemeId'],UploadFileType.hiddenDangerRectificationPlan); + } + + _getImagePath(widget.hiddenId,UploadFileType.safetyEnvironmentalInspectionAcceptance); + }); + + } + + + + + @override + void dispose() { + _videoController?.dispose(); + super.dispose(); + } + + Future getData() async { + try { + final data = await HiddenDangerApi.getOldDangerDetail(widget.itemId); + if (data['success']) { + setState(() { + pd = data['data']; + // _isStakeholder=true; + _isStakeholder= pd['isRelated']==1?true:false; + if(widget.item==1){ + hazardConfirmation['hiddenLevel'] = pd['hiddenLevel']; + hazardConfirmation['hiddenLevelName'] = pd['hiddenLevelName']; + hazardConfirmation['rectificationType'] =pd['rectificationType']; + _isDanger=pd['rectificationType']=="1"?true:false; + if(pd["hiddenUserPresetsCO"]!=null){ + //整改 + hazardConfirmation['deptId'] = pd["hiddenUserPresetsCO"]['rectifyDeptId'] ?? ''; + hazardConfirmation['deptName'] = pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? ''; + hazardConfirmation['userId'] = pd["hiddenUserPresetsCO"]['rectifyUserId'] ?? ''; + hazardConfirmation['userName'] = pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? ''; + + //验收 + hazardConfirmation['checkDeptId'] = pd["hiddenUserPresetsCO"]['checkDeptId'] ?? ''; + hazardConfirmation['checkDeptName'] = pd["hiddenUserPresetsCO"]['checkDeptName'] ?? ''; + hazardConfirmation['checkUserId'] = pd["hiddenUserPresetsCO"]['checkUserId'] ?? ''; + hazardConfirmation['checkUserName'] = pd["hiddenUserPresetsCO"]['checkUserName'] ?? ''; + hazardConfirmation['rectificationDeadline']=pd["hiddenUserPresetsCO"]['rectifyDeadline']?? ''; + } + + } + + }); + } else { + ToastUtil.showNormal(context, "获取列表失败"); + } + } catch (e) { + print('Error fetching data: $e'); + } + } + + + Future _getUserData() async { + try { + + final raw = await AuthApi.getUserData( ); + if (raw['success'] ) { + + setState(() { + + responsibleId=raw['data']['id']; + responsibleName=raw['data']['name']; + buMenId = raw['data']['departmentId']; + buMenName = raw['data']['departmentName']; + + }); + + }else{ + ToastUtil.showNormal(context, "获取个人信息失败"); + + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + + } + } + + + Future _getImagePath(id, type) async { + try { + final data = await FileApi.getImagePath(id,type); + if (data['success']) { + setState(() { + List images = data['data']??[]; + if(UploadFileType.hiddenDangerPhoto==type){ + files.addAll(images); + }else if(UploadFileType.hiddenDangerVideo==type){ + videoList.addAll(images); + }else if(UploadFileType.hiddenDangerRectificationPhoto==type){ + files2.addAll(images); + List newList = []; + newList.addAll(images); + rectifiedPhotosList.add(newList); + }else if(UploadFileType.hiddenDangerRectificationPlan==type){ + files4.addAll(images); + }else if(UploadFileType.hiddenDangerVerificationPhoto==type){ + files5.addAll(images); + List newList = []; + newList.addAll(images); + acceptancePhotosList.add(newList); + } else if(UploadFileType.safetyEnvironmentalInspectionAcceptance==type){ + files6.addAll(images); + } + + }); + } else { + + // ToastUtil.showNormal(context, "获取图片失败"); + } + } catch (e) { + print('Error fetching data: $e'); + + } + } + + + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: MyAppbar(title: '过程记录'), + body: + pd.isEmpty + ? const Center(child: CircularProgressIndicator()) + : _listWidget(), + ); + } + Widget _listWidget() { + List list = pd["hiddenAcceptUserCO"] ?? []; + + return LayoutBuilder( + builder: (context, constraints) { + return SingleChildScrollView( + child: ConstrainedBox( + constraints: BoxConstraints( + minHeight: constraints.maxHeight, + ), + child: Padding( + padding: const EdgeInsets.all(10), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + //隐患信息 + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + _buildInfoItem( + '隐患来源', + _getSourceDangers(pd), + ), + + Divider(height: 1), + _buildInfoItem( + '隐患类型', + pd['hiddenTypeName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患级别', + pd['hiddenLevelName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患状态', + _getState(pd), + ), + + Divider(height: 1), + _buildInfoItem( + '隐患描述', + pd['hiddenDesc'] ?? '', + ), + + if(pd['hiddenPartName']!=null&&pd['hiddenPartName'].isNotEmpty) + Divider(height: 1), + if(pd['hiddenPartName']!=null&&pd['hiddenPartName'].isNotEmpty) + _buildInfoItem( + '隐患部位', + pd['hiddenPartName'] ?? '', + ), + + + + // 条件渲染部分 + if (pd['source'] == 2&&pd['hiddenCheckListCO']!=null) ...[ + + Divider(height: 1), + _buildInfoItem( + '隐患清单', + pd['hiddenCheckListCO']['listName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '风险点(单元)', + pd['hiddenCheckListCO']['listRiskPoints'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '辨识部位', + pd['hiddenCheckListCO']['identifiedLocations'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '存在风险', + pd['hiddenCheckListCO']['existingRisks'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '风险分级', + pd['hiddenCheckListCO']['riskLevel'] ?? '' + ), + Divider(height: 1), + _buildInfoItem( + '检查内容', + pd['hiddenCheckListCO']['inspectionContent'] ?? '', + ), + + ], + + + if((pd['longitude'] ?? '').isNotEmpty) + Divider(height: 1), + if((pd['longitude'] ?? '').isNotEmpty) + _buildInfoItem( + '隐患上报位置(经纬度)', + ((pd['longitude'] ?? '').isNotEmpty)? '${pd['longitude'] ?? ''},${pd['latitude'] ?? ''}':'', + ), + + if((pd['positionDesc'] ?? '').isNotEmpty) + Divider(height: 1), + if((pd['positionDesc'] ?? '').isNotEmpty) + _buildInfoItem( + '隐患位置描述', + pd['positionDesc'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患发现人', + pd['creatorName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患发现时间', + _changeTime(pd['hiddenFindTime'] ?? ''), + ), + + Divider(height: 1), + _buildInfoItem( + '整改类型', + _getRectificationType( + pd['rectificationType'], + ), + ), + + Divider(height: 1), + _buildInfoItem( + '是否相关方', + _getText( + pd['isRelated'], + ), + ), + + + Divider(height: 1), + // 隐患照片 + // const Text('隐患照片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files, onTap: (index) => _showImageGallery(files, index)), + ListItemFactory.createTextImageItem( + text: "隐患照片", + imageUrls: files.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl:'', + imageUrls: files.map((item) => ApiService.baseImgPath + item['filePath']).toList(), + initialIndex: index, + ), + context, + ); + }, + ), + + // 隐患视频 + if (videoList.isNotEmpty) ...[ + SizedBox(height: 10), + Padding( + padding: EdgeInsets.only( + left: 10, + right: 10, + ), + child: Text( + '隐患视频', + style: TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + + GestureDetector( + onTap: () { + showDialog( + context: context, + barrierColor: Colors.black54, + builder: + (_) => VideoPlayerPopup( + videoUrl: + ApiService.baseImgPath + + videoList[0]['filePath'], + ), + ); + }, + child: Image.asset( + 'assets/image/videostart.png', // 替换为你的视频占位图 + color: Colors.blue, + width: 120, + height: 120, + ), + ), + ], + ], + ), + ), + + + // 整改信息(发现人预填) + if (pd['hiddenUserPresetsCO'] != null ) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "整改信息(发现人预填)", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + + _buildInfoItem( + pd["isRelated"]==0?'整改部门':'整改单位(相关方项目)', + pd["hiddenUserPresetsCO"]['rectifyDeptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + pd["isRelated"]==0?'整改人':'整改人(相关方项目)', + pd["hiddenUserPresetsCO"]['rectifyUserName'] ?? '', + ), + + + if(pd["hiddenUserPresetsCO"]['rectifyDeadline']!=null&&pd["hiddenUserPresetsCO"]['rectifyDeadline']!='') + Divider(height: 1), + if(pd["hiddenUserPresetsCO"]['rectifyDeadline']!=null&&pd["hiddenUserPresetsCO"]['rectifyDeadline']!='') + _buildInfoItem( + '整改期限', + // _changeTime( pd["hiddenUserPresetsCO"]['rectifyDeadline'] ?? ''), + pd["hiddenUserPresetsCO"]['rectifyDeadline'] ?? '', + ), + + if((pd["hiddenUserPresetsCO"]['checkDeptName'] ?? '')!='')...[ + Divider(height: 1), + _buildInfoItem( + '验收部门', + // pd["isRelated"]==0?'验收部门':'验收单位(相关方项目)', + pd["hiddenUserPresetsCO"]['checkDeptName'] ?? '', + ), + ], + + + if((pd["hiddenUserPresetsCO"]['checkUserName'] ?? '')!='')...[ + Divider(height: 1), + _buildInfoItem( + '验收人', + // pd["isRelated"]==0?'验收人':'验收人(相关方项目)', + pd["hiddenUserPresetsCO"]['checkUserName'] ?? '', + ), + ], + + + ], + ), + ), + + ], + + + // 隐患确认 + if (pd['hiddenConfirmUserCO']!=null + // &&(pd["state"]!=100)&&(widget.item==2||widget.item==3 + // ||widget.item==4||widget.item==5 + // ||widget.item==6||widget.item==7) + ) ...[ + // const Divider(height: 10,color: Colors.grey,), + SizedBox(height: 10), + + if(!_showAllData) + _hiddenDangerConfirmationItem(pd["hiddenConfirmUserCO"][pd["hiddenConfirmUserCO"].length-1],0), + + if(_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenConfirmUserCO"].length, + itemBuilder: (ctx, idx) => _hiddenDangerConfirmationItem(pd["hiddenConfirmUserCO"][idx],idx), + ), + + ], + + + //延期和特殊处置 + if (widget.item==3 + ||widget.item==4||widget.item==5|| + widget.item==6||widget.item==7)...[ + if(pd["hiddenExtensionList"]!=null&&pd["hiddenExtensionList"].isNotEmpty)...[ + SizedBox(height: 10), + + if(!_showAllData&&(pd["hiddenExtensionList"][(pd["hiddenExtensionList"].length-1)]['updateName']!=null)) + _delayInformationItem(pd["hiddenExtensionList"][(pd["hiddenExtensionList"].length-1)],0), + + if(_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenExtensionList"].length, + itemBuilder: (ctx, idx) => _delayInformationItem(pd["hiddenExtensionList"][idx],idx), + ), + ], + + if(pd["hiddenSpecialList"]!=null&&pd["hiddenSpecialList"].isNotEmpty)...[ + SizedBox(height: 10), + + if(!_showAllData&&pd["hiddenSpecialList"][(pd["hiddenSpecialList"].length-1)]['updateName']!=null&&pd["hiddenSpecialList"][(pd["hiddenSpecialList"].length-1)]['updateName']!='') + _specialDisposalItem(pd["hiddenSpecialList"][(pd["hiddenSpecialList"].length-1)],0), + + if(_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenSpecialList"].length, + itemBuilder: (ctx, idx) => _specialDisposalItem(pd["hiddenSpecialList"][idx],idx), + ), + ] + ], + + + // 整改信息 + if (pd['hiddenRectifyUserCO'] != null + // && (pd["state"]!=100)&&(widget.item==6||widget.item==7) + ) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + + if(!_showAllData) + _ectificationInformationItem(pd["hiddenRectifyUserCO"][(pd["hiddenRectifyUserCO"].length-1)],0), + + if(_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenRectifyUserCO"].length, + itemBuilder: (ctx, idx) => _ectificationInformationItem(pd["hiddenRectifyUserCO"][idx],idx), + ), + + ], + + + // 验收信息 + if (pd['hiddenAcceptUserCO'] != null + // && (pd["state"]!=100)&&((widget.item==7)||(widget.item==3)) + ) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + + if(!_showAllData) + _acceptanceInformationItem(list.last,(list.length-1)), + + if(_showAllData) + ListView.builder( + shrinkWrap: true, // 自适应内容高度 + physics: const NeverScrollableScrollPhysics(), + itemCount: pd["hiddenAcceptUserCO"].length, + itemBuilder: (ctx, idx) => _acceptanceInformationItem(pd["hiddenAcceptUserCO"][idx],idx), + ), + + ], + + + // 安全环保检查验收信息 + if (pd['hiddenInspecCO'] != null + // && (widget.item==7) + ) ...[ + SizedBox(height: 10), + // const Divider(height: 10,color: Colors.grey,), + _safetyEnvironmentalItem(pd["hiddenInspecCO"],0), + + ], + + + + + // 添加底部安全区域间距 + SizedBox( + height: + MediaQuery.of(context).padding.bottom + 20, + ), + ], + ), + ), + ), + ); + }, + ); + } + + Widget _buildInfoItem(String title, String value) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 10), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 120, + child: Text( + title, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + ), + Expanded(child: Text(value, textAlign: TextAlign.right)), + ], + ), + ); + } + + // //正常整改 + // Widget _getRepairState() { + // dannerRepair= DannerRepair(pd,key: dannerRepairKey, ); + // return dannerRepair; + // } + + //不是正常整改 + Widget _noAccepet_repair(bool _accept) { + return ItemListWidget.twoRowSelectableTitleText( + label: '无法整改原因', + isEditable: true, + text: '请输入', + isRequired: true, + showSelect: false, + controller:_reasonInabilityController, + ); + } + + //隐患确认 + Future _setHazardConfirmation() async { + try { + + if(hazardConfirmation['hiddenLevelName'].isEmpty){ + ToastUtil.showNormal(context, "请选择隐患级别"); + return; + } + + if('忽略隐患'!=hazardConfirmation['hiddenLevelName']) { + if (hazardConfirmation['deptName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改责任部门"); + return; + } + + if (hazardConfirmation['userName'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改人"); + return; + } + + if(_isDanger){ + if (hazardConfirmation['checkDeptName'].isEmpty) { + ToastUtil.showNormal(context, "请选择验收部门"); + return; + } + + if (hazardConfirmation['checkUserName'].isEmpty) { + ToastUtil.showNormal(context, "请选择验收改人"); + return; + } + }else{ + if (hazardConfirmation['rectificationDeadline'].isEmpty) { + ToastUtil.showNormal(context, "请选择整改期限"); + return; + } + } + } + + + + + hazardConfirmation['status']='1'; + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setHazardConfirmation( hazardConfirmation); + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //延期申请 + Future _setRequestExtension() async { + try { + + if(requestExtension['delayTime'].isEmpty){ + ToastUtil.showNormal(context, "请选择延时审核延时间"); + return; + } + + // if(requestExtension['disposalFile'].isEmpty){ + // ToastUtil.showNormal(context, "请上传处置附件"); + // return; + // } + + String text= _disposalPlanController.text.trim(); + if(text.isEmpty){ + ToastUtil.showNormal(context, "请填写处置方案"); + return; + } + requestExtension['disposalPlan']=text; + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setRequestExtension( requestExtension); + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //隐患整改 + Future _setHiddenDangerRectification() async { + try { + + if(_accepted){ + hiddenDangerRectification['status']=1; + String miaoShu= dannerRepairKey.currentState!.miaoShuController.text.trim(); + if(miaoShu.isEmpty){ + ToastUtil.showNormal(context, "请填整改描述"); + return; + } + hiddenDangerRectification['descr']=miaoShu; + + String dataTime= dannerRepairKey.currentState!.dataTime; + if(dataTime.isEmpty){ + ToastUtil.showNormal(context, "请选择整改时间"); + return; + } + hiddenDangerRectification['rectificationTime']=dataTime; + + String investmentFunds= dannerRepairKey.currentState!.investmentFunds; + if(investmentFunds.isEmpty){ + ToastUtil.showNormal(context, "请填写投入资金"); + return; + } + hiddenDangerRectification['investmentFunds']=investmentFunds; + + + + List gaiHouImages = dannerRepairKey.currentState!.gaiHouImages; + if(gaiHouImages.isEmpty){ + ToastUtil.showNormal(context, "请上传整改后照片"); + return; + } + + + List fangAnImages =[]; + // 是否有整改方案 + bool acceptedPrepare= dannerRepairKey.currentState!.acceptedPrepare; + if(acceptedPrepare){ + + hiddenDangerRectification['isRectificationScheme']=1; + + String standard= dannerRepairKey.currentState!.standardController.text; + if(standard.isEmpty){ + ToastUtil.showNormal(context, "请输入治理标准要求"); + return; + } + hiddenDangerRectification['governStanDards']=standard; + + String method= dannerRepairKey.currentState!.methodController.text; + if(method.isEmpty){ + ToastUtil.showNormal(context, "请输入治理方法"); + return; + } + hiddenDangerRectification['governMethod']=method; + + String fund= dannerRepairKey.currentState!.fundController.text; + if(fund.isEmpty){ + ToastUtil.showNormal(context, "请输入经费和物资的落实"); + return; + } + hiddenDangerRectification['expenditure']=fund; + + String person= dannerRepairKey.currentState!.personController.text; + if(person.isEmpty){ + ToastUtil.showNormal(context, "请输入负责治理人员"); + return; + } + hiddenDangerRectification['principal']=person; + + String workTime= dannerRepairKey.currentState!.workTimeController.text; + if(workTime.isEmpty){ + ToastUtil.showNormal(context, "请输入工时安排"); + return; + } + hiddenDangerRectification['programming']=workTime; + + String time= dannerRepairKey.currentState!.timeController.text; + if(time.isEmpty){ + ToastUtil.showNormal(context, "请输入时限要求"); + return; + } + hiddenDangerRectification['timeLimitFor']=time; + + String work= dannerRepairKey.currentState!.workController.text; + if(work.isEmpty){ + ToastUtil.showNormal(context, "请输入工作要求"); + return; + } + hiddenDangerRectification['jobRequireMent']=work; + + String other= dannerRepairKey.currentState!.otherController.text; + if(other.isEmpty){ + ToastUtil.showNormal(context, "请输入其他事项"); + return; + } + hiddenDangerRectification['otherBusiness']=other; + + fangAnImages = dannerRepairKey.currentState!.fangAnImages; + if(fangAnImages.isEmpty){ + ToastUtil.showNormal(context, "请上传方案照片"); + return; + } + + }else{ + hiddenDangerRectification['isRectificationScheme']=0; + } + + + + // String acceptedPlanType="0"; + // List jiHuaImages =[]; + // // 是否有整改计划 + // bool acceptedPlan= dannerRepairKey.currentState!.acceptedPlan; + // if(acceptedPlan){ + // acceptedPlanType="1"; + // jiHuaImages = dannerRepairKey.currentState!.jiHuaImages; + // if(jiHuaImages.isEmpty){ + // ToastUtil.showNormal(context, "请上传计划照片"); + // return; + // } + // } + + + LoadingDialogHelper.show(); + + + List departments = dannerRepairKey.currentState!.departments; + bool departmentsAllInput=true; + bool departmentsSameMan=false; + for(int i=0;i> buMendata = _convertDepartmentsToJson(departments); + hiddenDangerRectification['hiddenUserAddCmds']=buMendata; + + if(gaiHouImages.isNotEmpty){ + await _addImgFilesZhengGaiID(gaiHouImages,UploadFileType.hiddenDangerRectificationPhoto,) ; + } + + if(gaiHouImages.isNotEmpty){ + await _addImgFilesZhengGai(fangAnImages,UploadFileType.hiddenDangerRectificationPlan) ; + } + + // for(int i=0;i raw; + // if(_accepted) { + raw = await HiddenDangerApi.setHiddenDangerRectification(hiddenDangerRectification); + // }else{ + // raw = await HiddenDangerApi.setReasonInability(hiddenDangerRectification); + // } + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //审批特殊处置审核 + Future _setApprovalSpecialDisposal() async { + try { + + if(_disposalAudit){// 处置审核(通过,打回) + specialHandlingReview['state']=3; + + String text= _disposalPlanTwoController.text.trim(); + if(text.isEmpty){ + ToastUtil.showNormal(context, "请填写处置方案"); + return; + } + specialHandlingReview['disposalPlan']=text; + + if(specialHandlingReview['disposalFile'].isEmpty){ + ToastUtil.showNormal(context, "请上传处置附件"); + return; + } + + }else{ + specialHandlingReview['state']=4; + if(_replacePerson){ + specialHandlingReview['modifyRectifyPerson']=1; + if(specialHandlingReview['deptName'].isEmpty){ + ToastUtil.showNormal(context, "请选择整改责任部门"); + return; + } + + if(specialHandlingReview['rectifyPersonName'].isEmpty){ + ToastUtil.showNormal(context, "请选择整改人"); + return; + } + + }else{ + specialHandlingReview['modifyRectifyPerson']=0; + + } + + } + + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setApprovalSpecialDisposal( specialHandlingReview); + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //审批延期申请 + Future _setApprovalExtensionApplication() async { + try { + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setApprovalExtensionApplication( approvalExtensionApplication); + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + //隐患验收 + Future _setHiddenDangerAcceptance() async { + try { + + if(_hazardAcceptanceQualified){ + hiddenDangerAcceptance['status']=1; + String text= _acceptanceDescriptionController.text.trim(); + if(text.isEmpty){ + ToastUtil.showNormal(context, "请填写验收描述"); + return; + } + hiddenDangerAcceptance['descr']=text; + + if(hiddenDangerAcceptance['rectificationTime'].isEmpty){ + ToastUtil.showNormal(context, "请选择验收日期"); + return; + } + + if(_acceptanceImages.isEmpty){ + ToastUtil.showNormal(context, "请选择验收图片"); + return; + } + + if(_acceptanceImages.isNotEmpty){ + await _addImgFiles(_acceptanceImages,UploadFileType.hiddenDangerVerificationPhoto,hiddenDangerAcceptance['hiddenId']) ; + } + + }else{ + hiddenDangerAcceptance['status']=0; + String text= _replyFeedbackController.text.trim(); + if(text.isEmpty){ + ToastUtil.showNormal(context, "请填写打回意见"); + return; + } + hiddenDangerAcceptance['repulseCause']=text; + + } + + LoadingDialogHelper.show(); + final raw = await HiddenDangerApi.setHiddenDangerAcceptance( hiddenDangerAcceptance); + if (raw['success'] ) { + LoadingDialogHelper.hide(); + setState(() { + ToastUtil.showNormal(context, "提交成功"); + Navigator.of(context).pop('1'); + }); + + }else{ + ToastUtil.showNormal(context, "提交失败"); + LoadingDialogHelper.hide(); + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + LoadingDialogHelper.hide(); + } + } + + + + Future _getHazardLevel() async { + + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (_) => MultiDictValuesPicker( + title: '隐患级别', + dictType: 'hiddenLevel', + allowSelectParent: false, + showIgnoreHidden:true, + onSelected: (id, name, extraData) { + setState(() { + hazardConfirmation['hiddenLevel'] = extraData?['dictValue']; + hazardConfirmation['hiddenLevelName'] = name; + + }); + }, + ), + ).then((_) { + // 可选:FocusHelper.clearFocus(context); + }); + + // try { + // LoadingDialogHelper.show(); + // final raw = await HiddenDangerApi.getHazardLevel( ); + // if (raw['success'] ) { + // final newList = raw['data'] ?? []; + // LoadingDialogHelper.hide(); + // + // for(int i=0;i DepartmentPickerThree( + // listdata: newList, + // onSelected: (id, name,pdId) async { + // setState(() { + // hazardConfirmation['hiddenLevel']=id; + // hazardConfirmation['hiddenLevelName']=name; + // }); + // + // }, + // ), + // ); + // + // }else{ + // ToastUtil.showNormal(context, "获取列表失败"); + // LoadingDialogHelper.hide(); + // } + // + // } catch (e) { + // // 出错时可以 Toast 或者在页面上显示错误状态 + // print('加载首页数据失败:$e'); + // LoadingDialogHelper.hide(); + // } + } + + /// 拉取某单位人员并缓存(兼容返回结构) + Future _getPersonListForUnitId(String id) async { + if (id.isEmpty) return; + LoadingDialogHelper.show(); + try { + final result = await BasicInfoApi.getDeptUsers(id); + LoadingDialogHelper.hide(); + // 兼容 result['data'] / result['userList'] 等常见字段 + dynamic raw = result['data']; + List> list = []; + if (raw is List) { + list = raw.map>((e) { + if (e is Map) return e; + if (e is Map) return Map.from(e); + return {}; + }).toList(); + } else { + list = []; + } + setState(() { + _personCache[id] = list; + }); + } catch (e) { + LoadingDialogHelper.hide(); + ToastUtil.showError(context, '获取人员失败:$e'); + setState(() { + _personCache[id] = []; + }); + } + } + + /// 弹出人员选择 + void choosePersonHandle(final unitId, int num) async { + + List> personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + // 先拉取一次 + await _getPersonListForUnitId(unitId); + personList = _personCache[unitId] ?? []; + if (personList.isEmpty) { + ToastUtil.showNormal(context, '暂无可选人员,请选择其他单位'); + return; + } + } + + // 显示人员选择器(假设 DepartmentPersonPicker.show 接口存在) + DepartmentPersonPicker.show( + context, + personsData: personList, + onSelected: (userId, name) { + setState(() { + switch(widget.item){ + case 1: + switch(num){ + case 1: + hazardConfirmation['userId'] = userId; + hazardConfirmation['userName'] = name; + break; + case 2: + hazardConfirmation['checkUserId'] = userId; + hazardConfirmation['checkUserName'] = name; + break; + } + break; + case 2: + // buttonText='忽略'; + break; + case 3: + // buttonText='整改'; + break; + case 4: + specialHandlingReview['rectifyPersonId'] = userId; + specialHandlingReview['rectifyPersonName'] = name; + // buttonText='特殊处理审核'; + break; + case 5: + // buttonText='延期审核'; + break; + case 6: + // buttonText='验收'; + break; + case 8://延期 + // buttonText='验收'; + break; + } + + }); + }, + ).then((_) { + //FocusHelper.clearFocus(context); + }); + } + + + + List> _convertDepartmentsToJson(List departments) { + // 1. 将列表中的每个对象转换为 Map + List> jsonList = departments + .map((dept) => dept.toJson()) + .toList(); + + // 2. 使用 jsonEncode 转换为 JSON 字符串 + // return jsonEncode(jsonList); + return jsonList; + } + + Widget _buildSectionContainer({required Widget child}) { + return Container( + margin: const EdgeInsets.only(top: 1), + color: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 5), + child: child, + ); + } + + String _getSourceDangers(final item) { + int type = item["source"]; + if(1==type){ + return "隐患快报"; + }else if(2==type){ + return "清单排查"; + }else if(3==type){ + return "标准排查"; + }else if(4==type){ + return "安全环保检查(监管端)"; + }else if(5==type){ + return "安全环保检查(企业端)"; + }else if(6==type){ + return "消防点检"; + }else if (7 == type) { + return "视频巡屏"; + } else{ + return "NFC设备巡检"; + } + } + + String _getState(final item) { + int type = item["state"]; + if(100==type){ + return "待确认"; + }else if(200==type){ + return "未整改"; + }else if(201==type){ + return "确认打回"; + }else if(202==type){ + return "待处理特殊隐患"; + }else if(300==type){ + return "待验收"; + }else if(301==type){ + return "已验收"; + }else if(302==type){ + return "验收打回"; + }else if(303==type){ + return "验收打回"; + }else if(400==type){ + return "已处理特殊隐患"; + }else if(99==type){ + return "强制关闭(人员变动)"; + }else if(98==type){ + return "安全环保检查/清单排查暂存"; + }else if(102==type){ + return "安全环保检查,隐患待指派"; + }else if(97==type){ + return "已过期"; + }else if(101==type){ + return "忽略隐患"; + }else{ + return "已过期"; + } + } + + String _changeTime(String time) { + try { + // 解析 ISO 8601 格式的时间字符串 + DateTime dateTime = DateTime.parse(time); + // 格式化为年月日 + return DateFormat('yyyy-MM-dd HH:mm:ss').format(dateTime); + } catch (e) { + // 如果解析失败,返回原字符串或默认值 + return ''; + } + } + + String _getRectificationType(int? type) { + switch (type) { + case 1: + return '立即整改'; + case 2: + return '限期整改'; + default: + return ''; + } + } + + Future _addImgFiles(List imagePaths,UploadFileType type,String hiddenId) async { + try { + + final raw = await FileApi.uploadFiles( imagePaths, type, ''); + if (raw['success'] ) { + + hiddenDangerAcceptance['hiddenUserId']=raw['data']['foreignKey']; + return raw['data']; + }else{ + // _showMessage('反馈提交失败'); + return ""; + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + Future _addImgFilesZhengGai(List imagePaths,UploadFileType type) async { + try { + + final raw = await FileApi.uploadFiles( imagePaths, type,''); + if (raw['success'] ) { + hiddenDangerRectification['hiddenSchemeId']=raw['data']['foreignKey']; + + return raw['data']; + }else{ + // _showMessage('反馈提交失败'); + return ""; + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + Future _addImgFilesZhengGaiID(List imagePaths,UploadFileType type) async { + try { + + final raw = await FileApi.uploadFiles( imagePaths, type,''); + if (raw['success'] ) { + hiddenDangerRectification['hiddenUserId']=raw['data']['foreignKey']; + + return raw['data']; + }else{ + // _showMessage('反馈提交失败'); + return ""; + } + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + return ""; + } + } + + + + Future _downloadAndLoad(String path) async { + try { + if(path.isEmpty){ + ToastUtil.showNormal(context, "文件地址错误"); + return; + } + + pushPage(ReadFilePage(fileUrl:ApiService.baseImgPath +path), context); + // final url =ApiService.baseImgPath + path; + // final filename = url.split('/').last; + // final dir = await getTemporaryDirectory(); + // final filePath = '${dir.path}/$filename'; + // + // final dio = Dio(); + // final response = await dio.get>( + // url, + // options: Options(responseType: ResponseType.bytes), + // ); + // final file = File(filePath); + // await file.writeAsBytes(response.data!); + // + // final result = await OpenFile.open(filePath); + // if (result.type != ResultType.done) { + // ToastUtil.showNormal(context, "文件加载失败"); + // } + } catch (e) { + // 下载或加载失败 + ToastUtil.showNormal(context, "文件加载失败"); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('文件加载失败: \$e')), + // ); + } + } + + + Future _onlySee(String path) async { + try { + if(path.isEmpty){ + ToastUtil.showNormal(context, "文件地址错误"); + return; + } + + final result = await OpenFile.open(path); + if (result.type != ResultType.done) { + ToastUtil.showNormal(context, "文件加载失败"); + } + } catch (e) { + // 下载或加载失败 + ToastUtil.showNormal(context, "文件加载失败"); + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text('文件加载失败: \$e')), + // ); + } + } + + + void _showConfirmation() { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: const Text("提示"), + content: const Text("打回会清空整改图片"), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), + actions: [ + ElevatedButton( + onPressed: () { + Navigator.pop(context); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.grey[400], + foregroundColor: Colors.white, + ), + child: const Text(" 取消 "), + ), + ElevatedButton( + onPressed: () { + // 执行操作 + Navigator.pop(context); + _setHiddenDangerAcceptance(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blue[700], + foregroundColor: Colors.white, + ), + child: const Text("确定"), + ), + ], + ), + ); + } + + + String _getText(int source) { + if (source == 1) { + return "是"; + } else { + return "否"; + } + } + + String _delayInformationText( text) { + if(text!=''){ + if (text == 1) { + return "通过"; + } else { + return "未通过"; + } + }else{ + return ""; + } + } + + String _delayInformationTextTwo( text) { + if(text!=''){ + if (text == 3) { + return "通过"; + } else { + return "未通过"; + } + }else{ + return ""; + } + } + + //隐患确认 + Widget _hiddenDangerConfirmationItem(itemData, int idx) { + if( (itemData["rectificationTime"]==null)){ + return SizedBox(); + }else { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "隐患确认", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + if(itemData["status"] != 0) + _buildInfoItem( + '隐患级别', + itemData['hiddenLevelName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患确认人', + itemData['userName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '隐患确认时间', + _changeTime(itemData['rectificationTime'] ?? ''), + ), + + if(widget.item != 2 && itemData["status"] != 0)...[ + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改部门' : '整改单位(相关方项目)', + itemData['rectifyDeptName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + pd["isRelated"] == 0 ? '整改人' : '整改人(相关方项目)', + itemData['rectifyUserName'] ?? '', + ), + + Divider(height: 1), + if((itemData['rectificationDeadline'] ?? '').isNotEmpty) + _buildInfoItem( + '整改完成期限', + // _changeTime(itemData['rectificationDeadline'] ?? ''), + itemData['rectificationDeadline'] ?? '', + ), + ], + + if(itemData["status"] == 0)...[ + Divider(height: 1), + _buildInfoItem( + '打回意见', + itemData['repulseCause'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '打回时间', + itemData['rectificationTime'] ?? '', + ), + + ], + + + ], + ), + ); + } + } + + //延期信息 + Widget _delayInformationItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "延期信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + _buildInfoItem( + '申请延期日期', + itemData['createTime'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '延期日期', + itemData['delayTime'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '审核人', + itemData['updateName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '处置方案', + itemData['disposalPlan'] ?? '', + ), + + if((itemData['disposalFile'] ?? '').isNotEmpty)...[ + Divider(height: 1), + ItemListWidget.OneRowButtonTitleText( + horizontalnum: 10, + label: '处置方案附件', + buttonText: '查看', + text: '', + onTap: () { + if((itemData['disposalFile'] ?? '').isEmpty){ + ToastUtil.showNormal(context, '未上传文件'); + return; + } + _downloadAndLoad(itemData['disposalFile'] ?? ''); + }, + ), + ], + + + Divider(height: 1), + _buildInfoItem( + '延期审核状态', + _delayInformationTextTwo(itemData['state'] ?? ''), + ), + + Divider(height: 1), + _buildInfoItem( + '延期审核时间', + itemData['updateTime'] ?? '', + ), + + + ], + ), + ); + } + + //隐患特殊处置 + Widget _specialDisposalItem(itemData, int idx) { + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "特殊处置信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + _buildInfoItem( + '审核人', + itemData['updateName'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '审核时间', + itemData['updateTime'] ?? '', + ), + + Divider(height: 1), + _buildInfoItem( + '无法整改原因', + itemData['examine'] ?? '', + ), + + if(itemData['state']==3)...[ + Divider(height: 1), + _buildInfoItem( + '处置方案', + itemData['disposalPlan'] ?? '', + ), + + if((itemData['disposalFile'] ?? '').isNotEmpty)...[ + Divider(height: 1), + ItemListWidget.OneRowButtonTitleText( + horizontalnum: 10, + label: '处置方案附件', + buttonText: '查看', + text: '', + onTap: () { + if((itemData['disposalFile'] ?? '').isEmpty){ + ToastUtil.showNormal(context, '未上传文件'); + return; + } + _downloadAndLoad(itemData['disposalFile'] ?? ''); + }, + ), + ], + + ], + + + if( itemData['modifyRectifyPerson']!=null)...[ + Divider(height: 1), + _buildInfoItem( + '是否更换整改负责人', + _getText( itemData['modifyRectifyPerson'] ?? 0), + ), + ], + + Divider(height: 1), + _buildInfoItem( + '特殊处置审核状态', + _delayInformationTextTwo(itemData['state'] ?? ''), + ), + + + ], + ), + ); + } + + //整改信息 + Widget _ectificationInformationItem(itemData, int idx){ + // if(( itemData['rectificationTime'] ?? '').isEmpty){ + // return SizedBox(height: 1,); + // }else{ + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "整改信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + + _buildInfoItem( + pd["isRelated"]==0?'整改部门':'整改单位(相关方项目)', + itemData['deptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + pd["isRelated"]==0?'整改人':'整改人(相关方项目)', + itemData['userName'] ?? '', + ), + + if(itemData['status']!=0)...[ + Divider(height: 1), + _buildInfoItem( + '整改时间', + // _changeTime( itemData['rectificationTime'] ?? ''), + itemData['rectificationTime'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '整改描述', + itemData['descr'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '投入资金', + '${itemData['investmentFunds'].toString() ?? ''}元', + ), + + Divider(height: 1), + // const Text('整改后图片', style: TextStyle(fontWeight: FontWeight.bold)), + // _buildImageGrid(files2, onTap: (index) => _showImageGallery(files2, index)), + ListItemFactory.createTextImageItem( + text: "整改后图片", + imageUrls: files2.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + files2[index]['filePath'], + ), + context, + ); + }, + ), + + Divider(height: 1), + _buildInfoItem( + '整改方案', + itemData['isRectificationScheme'] == 1 ? '有' : '无', + ), + Divider(height: 1), + if (itemData['isRectificationScheme'] == 1&&itemData["hiddenSchemeCO"]!=null) + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + // _buildInfoItem( + // '排查日期', + // itemData["hiddenSchemeCO"]['screeningDate'] ?? '', + // ), + + // Divider(height: 1), + _buildInfoItem( + '治理标准', + itemData["hiddenSchemeCO"]['governStanDards'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '治理方法', + itemData["hiddenSchemeCO"]['governMethod'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '经费落实', + itemData["hiddenSchemeCO"]['expenditure'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '负责人员', + itemData["hiddenSchemeCO"]['principal'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '工时安排', + itemData["hiddenSchemeCO"]['programming'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '时限要求', + itemData["hiddenSchemeCO"]['timeLimitFor'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '工作要求', + itemData["hiddenSchemeCO"]['jobRequireMent'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '其他事项', + itemData["hiddenSchemeCO"]['otherBusiness'] ?? '', + ), + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "方案图片", + imageUrls: files4.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + files4[index]['filePath'], + ), + context, + ); + }, + ), + ], + ), + ], + + if(itemData['status']==0)...[ + Divider(height: 1), + _buildInfoItem( + '是否正常整改', + '否', + ), + Divider(height: 1), + _buildInfoItem( + '无法整改原因', + itemData['repulseCause'] ??'', + ), + ], + + + + ], + ), + ); + // } + } + + //验收信息 + Widget _acceptanceInformationItem(itemData, int idx){ + // if(!_showAllData&&itemData['status']!=null&&itemData['status']==0){ + // return SizedBox(); + // }else{ + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "验收信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + + _buildInfoItem( + '验收部门', + // pd["isRelated"]==0?'验收部门':'验收单位(相关方项目)', + itemData['deptName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '验收人', + // pd["isRelated"]==0?'验收人':'验收人(相关方项目)', + itemData['userName'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '验收时间', + _changeTime( itemData['rectificationTime'] ?? ''), + ), + + + + if(itemData['status']!=null&&itemData['status']==0)...[ + Divider(height: 1), + _buildInfoItem( + '是否合格', + '不合格', + ), + Divider(height: 1), + _buildInfoItem( + '验收打回意见', + itemData['repulseCause'] ?? '', + ), + ], + + + if(itemData['status']!=0)...[ + Divider(height: 1), + _buildInfoItem( + '是否合格', + '合格', + ), + + + if((itemData['descr'] ?? '').isNotEmpty)...[ + Divider(height: 1), + _buildInfoItem( + '验收描述', + itemData['descr'] ?? '', + // itemData['repulseCause'] ?? '', + ), + ], + + if(acceptancePhotosList.isNotEmpty&&getFilePathList(acceptancePhotosList,idx).isNotEmpty)...[ + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "验收图片", + // imageUrls: files5.map((item) => item['filePath'].toString()).toList(), + imageUrls: getFilePathList(acceptancePhotosList,idx), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + // files5[index]['filePath'], + acceptancePhotosList[idx][index]['filePath'], + ), + context, + ); + }, + ), + ], + + + ], + + + + ], + ), + ); + // } + + } + + //安全环保检查验收信息 + Widget _safetyEnvironmentalItem(itemData, int idx){ + return Card( + color: Colors.white, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: EdgeInsets.only( + top: 10, + left: 10, + right: 10, + ), + child: Row( + children: [ + Container( + width: 3, + height: 15, + color: Colors.blue, + ), + const SizedBox(width: 8), + Text( + "安全环保检查验收信息", + style: const TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + + + + _buildInfoItem( + '验收人', + itemData['finalCheckOr'] ?? '', + ), + Divider(height: 1), + _buildInfoItem( + '验收时间', + itemData['finalCheckTime'] ?? '' + // _changeTime( itemData['finalCheckTime'] ?? ''), + ), + + + Divider(height: 1), + _buildInfoItem( + '是否合格', + itemData['finalCheck']??1?"合格":"不合格", + ), + Divider(height: 1), + _buildInfoItem( + '验收描述', + itemData['finalCheckDesc'] ?? '', + ), + + Divider(height: 1), + ListItemFactory.createTextImageItem( + text: "验收图片", + imageUrls: files6.map((item) => item['filePath'].toString()).toList(), + horizontalPadding: 10, + onImageTapped: (index) { + presentOpaque( + SingleImageViewer( + imageUrl: + ApiService.baseImgPath + + files6[index]['filePath'], + ), + context, + ); + }, + ), + + + ], + ), + ); + } + + List getFilePathList(List list, int idx) { + // List list= oldList.reversed.toList(); + if (list.isEmpty || + idx < 0 || + idx >= list.length || + list[idx] == null) { + return []; // 返回空列表作为默认值 + } + + final items = list[idx]; + if (items == null || items.isEmpty) { + return []; + } + + + // 方法1:使用 cast() + return (items as List) + .map((item) => (item as Map)['filePath']?.toString() ?? '') + .toList(); + } + + //隐患确认 + Map hazardConfirmation={ + "id": "", + "hiddenId": "", + "status": "", + "rectificationType": "", + "hiddenLevel": "", + "hiddenLevelName": "", + "rectificationDeadline": "", + "deptId": "", + "deptName": "", + "userId": "", + "userName": "", + "checkUserId": "", + "checkUserName": "", + "checkDeptId": "", + "checkDeptName": "", + "repulseCause": "", + }; + + //申请延期 + Map requestExtension={ + "hiddenId": "", + "delayTime": "", + "disposalFile": "", + "disposalPlan": "", + }; + + + //隐患整改 + Map hiddenDangerRectification={ + "id": "", + "hiddenId": "", + "status": "", + "descr": "", + "investmentFunds": "", + "rectificationTime": "", + "tempSafeMeasure": "", + "isRectificationScheme": "", + "repulseCause": "", + "hiddenSchemeId": "", //整改方案id + "screeningDate": "", + "governStanDards": "", + "governMethod": "", + "expenditure": "", + "principal": "", + "programming": "", + "timeLimitFor": "", + "filePath": "", + "jobRequireMent": "", + "otherBusiness": "", + "examine": "", + "hiddenUserAddCmds": [ + // { + // "type": "300", + // "deptId": "", + // "deptName": "", + // "userId": "", + // "userName": "", + // } + ], + + }; + + //特殊处理审核 + Map specialHandlingReview={ + "id": "", + "hiddenId": "", + "state": "", + "disposalPlan": "", + "modifyRectifyPerson": "", + "deptId": "", + "deptName": "", + "rectifyPersonId": "", + "rectifyPersonName": "", + "disposalFile": "", + "examine": "", + + }; + + //审批延期申请 + Map approvalExtensionApplication={ + "id": "", + "hiddenId": "", + "state": "", + "examine": "", + }; + + //隐患验收 + Map hiddenDangerAcceptance={ + "id": "", + "hiddenId": "", + "hiddenUserId": "", + "status": "", + "descr": "", + "rectificationTime": "", + "repulseCause": "", + "checkUserId": "", + }; + + + +} + + diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart index f9d4e5e..689d1dd 100644 --- a/lib/pages/home/home_page.dart +++ b/lib/pages/home/home_page.dart @@ -13,6 +13,7 @@ import 'package:qhd_prevention/http/modules/key_tasks_api.dart'; import 'package:qhd_prevention/pages/home/Study/study_tab_list_page.dart'; import 'package:qhd_prevention/pages/home/Tap/work_tab_list_page.dart'; import 'package:qhd_prevention/pages/home/doorAndCar/doorCar_tab_page.dart'; +import 'package:qhd_prevention/pages/home/hiddenDanger/hidden_danger_tab_page.dart'; import 'package:qhd_prevention/pages/home/keyTasks/key_tasks_tab_page.dart'; import 'package:qhd_prevention/pages/home/scan_page.dart'; import 'package:qhd_prevention/pages/home/unit/unit_tab_page.dart'; @@ -758,9 +759,12 @@ class HomePageState extends RouteAwareState case "重点作业": await pushPage(KeyTasksTabPage(), context); break; - case "危险作业": - await pushPage(WorkTabListPage(), context); - break; + case "危险作业": + await pushPage(WorkTabListPage(), context); + break; + case "隐患治理": + await pushPage(HiddenDangerTabPage(), context); + break; default: ToastUtil.showNormal(context, '功能开发中...'); break;