513 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			513 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Dart
		
	
	
| import 'dart:io';
 | |
| import 'package:flutter/material.dart';
 | |
| import 'package:intl/intl.dart';
 | |
| import 'package:qhd_prevention/customWidget/department_person_picker.dart';
 | |
| import 'package:qhd_prevention/customWidget/department_picker.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/pages/home/tap/item_list_widget.dart';
 | |
| import '../../customWidget/ItemWidgetFactory.dart';
 | |
| import '../../customWidget/custom_button.dart';
 | |
| import '../../customWidget/date_picker_dialog.dart';
 | |
| import '../../customWidget/photo_picker_row.dart';
 | |
| import '../../tools/h_colors.dart';
 | |
| import '../../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<String, dynamic> toJson() {
 | |
|     return {
 | |
|       'DEPARTMENT_ID': departmentId,
 | |
|       'USER_ID': responsibleId,
 | |
|       'DEPARTMENT_NAME': department,
 | |
|       'USER_NAME': responsible,
 | |
|       'index': index,
 | |
|     };
 | |
|   }
 | |
| }
 | |
| 
 | |
| /// 隐患整改
 | |
| class DannerRepair extends StatefulWidget {
 | |
|    DannerRepair(this.pd, {super.key});
 | |
| 
 | |
|   final Map<String, dynamic> pd;
 | |
| 
 | |
|   @override
 | |
|   State<DannerRepair> createState() => DannerRepairState();
 | |
| }
 | |
| 
 | |
| class DannerRepairState extends State<DannerRepair> {
 | |
| 
 | |
|   // 是否有整改方案
 | |
|   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();
 | |
|   late var _selectData = DateTime.now();
 | |
| 
 | |
| 
 | |
| 
 | |
|   String dataTime="";
 | |
|   // 整改后图片
 | |
|   List<String> gaiHouImages = [];
 | |
|   //方案图片
 | |
|   List<String> fangAnImages = [];
 | |
|   //计划图片
 | |
|   List<String> jiHuaImages = [];
 | |
|   int yanShouAdd=1;
 | |
| 
 | |
| 
 | |
| 
 | |
|   final List<DepartmentEntry> departments = [
 | |
|     DepartmentEntry(department: '请选择', responsible: '请选择',index:'',departmentId: '',responsibleId:''),
 | |
|   ];
 | |
| 
 | |
|   void _addDepartment() {
 | |
|     setState(() {
 | |
|       departments.add(DepartmentEntry(department: '请选择', responsible: '请选择',index:'',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));
 | |
|   }
 | |
| 
 | |
|   @override
 | |
|   void dispose() {
 | |
|     // 释放资源
 | |
|     standardController.dispose();
 | |
|     methodController.dispose();
 | |
|     fundController.dispose();
 | |
|     personController.dispose();
 | |
|     workTimeController.dispose();
 | |
|     timeController.dispose();
 | |
|     workController.dispose();
 | |
|     otherController.dispose();
 | |
|     miaoShuController.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(
 | |
|             height: 130,
 | |
|             padding: EdgeInsets.all(15),
 | |
|             child: Column(
 | |
|               children: [
 | |
|                 Row(
 | |
|                   children: [
 | |
|                     Text('* ', style: TextStyle(color: Colors.red)),
 | |
|                     HhTextStyleUtils.mainTitle("隐患描述", fontSize: 15)],
 | |
|                 ),
 | |
|                 TextField(
 | |
|                   controller: miaoShuController,
 | |
|                   keyboardType: TextInputType.multiline,
 | |
|                   maxLines: null, // 不限制行数,输入多少文字就撑开多少行
 | |
|                   style: TextStyle(fontSize: 15),
 | |
|                   decoration: InputDecoration(
 | |
|                     hintText: '请对隐患进行详细描述(必填项)',
 | |
|                     border: InputBorder.none,
 | |
|                   ),
 | |
|                 ),
 | |
|               ],
 | |
|             ),
 | |
|           ),
 | |
|           Divider(height: 1),
 | |
|           GestureDetector(
 | |
|             onTap: () async {
 | |
|               DateTime? picked = await BottomDateTimePicker.showDate(
 | |
|                 mode: BottomPickerMode.date,
 | |
|                 context,
 | |
|                 allowPast:false,
 | |
|               );
 | |
|               if (picked != null) {
 | |
|                 setState(() {
 | |
|                    _selectData = picked;
 | |
|                    dataTime= DateFormat('yyyy-MM-dd').format(picked);
 | |
|                 });
 | |
|                 //FocusHelper.clearFocus(context);
 | |
|               }
 | |
|               // showDialog(
 | |
|               //   context: context,
 | |
|               //   builder:
 | |
|               //       (_) => HDatePickerDialog(
 | |
|               //     initialDate: DateTime.now(),
 | |
|               //     onCancel: () => Navigator.of(context).pop(),
 | |
|               //     onConfirm: (selected) {
 | |
|               //       Navigator.of(context).pop();
 | |
|               //       setState(() {
 | |
|               //         _selectData = selected;
 | |
|               //         dataTime= DateFormat('yyyy-MM-dd').format(selected);
 | |
|               //
 | |
|               //       });
 | |
|               //     },
 | |
|               //   ),
 | |
|               // );
 | |
|             },
 | |
|             child: Padding(
 | |
|               padding: EdgeInsets.symmetric(horizontal: 15),
 | |
|               child: ListItemFactory.createRowSpaceBetweenItem(
 | |
|                 isRequired:true,
 | |
|                 leftText: "整改日期",
 | |
|                 rightText: dataTime.isEmpty?"请选择":dataTime,
 | |
|                 isRight: true,
 | |
|               ),
 | |
|             ),
 | |
|           ),
 | |
|           Divider(),
 | |
|           ItemListWidget.itemContainer(
 | |
|             RepairedPhotoSection(
 | |
|               isRequired:true,
 | |
|               title: "整改后照片",
 | |
|               maxCount: 4,
 | |
|               mediaType: MediaType.image,
 | |
|               onChanged: (files) {
 | |
|                 // 上传 files 到服务器
 | |
|                 gaiHouImages.clear();
 | |
|                 for(int i=0;i<files.length;i++){
 | |
|                   gaiHouImages.add(files[i].path);
 | |
|                 }
 | |
|               },
 | |
|               onAiIdentify: () {
 | |
| 
 | |
|               },
 | |
|             ),
 | |
|           ),
 | |
| 
 | |
|           Divider(),
 | |
|           Row(
 | |
|             mainAxisAlignment: MainAxisAlignment.end,
 | |
|             children: [
 | |
|               CustomButton(
 | |
|                 onPressed: () {
 | |
|                   _addDepartment();
 | |
|                 },
 | |
|                 text: "添加",
 | |
|                 backgroundColor: Colors.blue,
 | |
|                 borderRadius: 17,
 | |
|                 height: 34,
 | |
|                 padding: EdgeInsets.symmetric(horizontal: 20),
 | |
|               ),
 | |
|             ],
 | |
|           ),
 | |
| 
 | |
| 
 | |
|           Column(
 | |
|             children: List.generate(
 | |
|               departments.length,
 | |
|                   (index) => _departmentItem(
 | |
|                 departments[index],
 | |
|                 index,
 | |
|                 showLabel: index == 0,
 | |
|               ),
 | |
|             ),
 | |
|           ),
 | |
| 
 | |
| 
 | |
|           // 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,
 | |
|             title: "方案图片",
 | |
|             maxCount: 4,
 | |
|             mediaType: MediaType.image,
 | |
|             onChanged: (files) {
 | |
|               // 上传 files 到服务器
 | |
|               fangAnImages.clear();
 | |
|               for(int i=0;i<files.length;i++){
 | |
|                 fangAnImages.add(files[i].path);
 | |
|               }
 | |
| 
 | |
|             },
 | |
|             onAiIdentify: () {
 | |
| 
 | |
|             },
 | |
|           ),
 | |
| 
 | |
|           Divider(),
 | |
|           ListItemFactory.createYesNoSection(
 | |
|             title: "是否有整改计划",
 | |
|             yesLabel: "是",
 | |
|             noLabel: "否",
 | |
|             groupValue: acceptedPlan,
 | |
|             onChanged: (val) {
 | |
|               setState(() {
 | |
|                 acceptedPlan = val;
 | |
|               });
 | |
|             },
 | |
|           ),
 | |
|           acceptedPlan ? _acceptPlan() : SizedBox(height: 1),
 | |
|         ],
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
|   /// 整改方案
 | |
|   Widget _acceptPrepare() {
 | |
|     final fields = [
 | |
|       _buildReadOnlyRow("排查日期", widget.pd["CREATTIME"]),
 | |
|       if(FormUtils.hasValue(widget.pd, "LIST_NAME"))
 | |
|       _buildReadOnlyRow("隐患清单", widget.pd["LIST_NAME"]),
 | |
|       ListItemFactory.createBuildMultilineInput("治理标准", "请输入治理标准", standardController),
 | |
|       ListItemFactory.createBuildMultilineInput("治理方法", "请输入治理方法", methodController),
 | |
|       ListItemFactory.createBuildMultilineInput("经费落实", "请输入经费落实", fundController),
 | |
|       ListItemFactory.createBuildMultilineInput("负责人员", "请输入负责人员", personController),
 | |
|       ListItemFactory.createBuildMultilineInput("工时安排", "请输入工时安排", workTimeController),
 | |
|       ListItemFactory.createBuildMultilineInput("时限要求", "请输入时限要求", timeController),
 | |
|       ListItemFactory.createBuildMultilineInput("工作要求", "请输入工作要求", workController),
 | |
|       ListItemFactory.createBuildMultilineInput("其他事项", "请输入其他事项", otherController),
 | |
|     ];
 | |
| 
 | |
|     return ListView.separated(
 | |
|       shrinkWrap: true,
 | |
|       physics: const NeverScrollableScrollPhysics(),
 | |
|       itemCount: fields.length,
 | |
|       separatorBuilder:
 | |
|           (_, __) => const Divider(height: 1, color: Colors.black12),
 | |
|       itemBuilder:
 | |
|           (_, index) => Padding(
 | |
|         padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
 | |
|         child: fields[index],
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   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));
 | |
|                 },
 | |
|               ),
 | |
|             ),
 | |
|         ],
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
| 
 | |
|   // 存储各单位的人员列表
 | |
|   List<Map<String, dynamic>> _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) => DepartmentPicker(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 ApiService.getListTreePersonList(id);
 | |
|               _personCache=List<Map<String, dynamic>>.from(
 | |
|                 result['userList'] as List,
 | |
|               );
 | |
| 
 | |
| 
 | |
|             }),
 | |
|           );
 | |
|         },
 | |
|         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;
 | |
|             }
 | |
|             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<File> files) {
 | |
|           // images 列表更新
 | |
|           // 上传 files 到服务器
 | |
|           jiHuaImages.clear();
 | |
|           for(int i=0;i<files.length;i++){
 | |
|             jiHuaImages.add(files[i].path);
 | |
|           }
 | |
|         },
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| }
 |