QinGang_interested/lib/pages/home/hiddenDanger/danner_repair.dart

681 lines
21 KiB
Dart
Raw Normal View History

2026-05-19 17:39:46 +08:00
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<String, dynamic> toJson() {
return {
'deptId': departmentId,
'userId': responsibleId,
'deptName': department,
'userName': responsible,
'type': index,
};
}
// 将对象转换为 Map
Map<String, dynamic> toJsonTwo() {
return {
'departmentId': departmentId,
'userId': responsibleId,
'departmentName': department,
'userName': responsible,
'listManagerId': 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();
final TextEditingController linShiSZhengGaiController = TextEditingController();
late var _selectData = DateTime.now();
String investmentFunds="";
String dataTime="";
// 整改后图片
List<String> gaiHouImages = [];
//方案图片
List<String> fangAnImages = [];
//计划图片
List<String> jiHuaImages = [];
int yanShouAdd=1;
// 是否是相关方
bool _isStakeholder = false;
final List<DepartmentEntry> 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<files.length;i++){
gaiHouImages.add(files[i].path);
}
},
onAiIdentify: () {
},
),
),
Divider(),
if(!_isStakeholder)...[
Padding(
padding: EdgeInsets.only(left: 20,right: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'验收人',
style: TextStyle(
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
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,
),
),
),
],
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<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,isRequired:true),
ListItemFactory.createBuildMultilineInput("治理方法", "请输入治理方法", methodController,isRequired:true),
ListItemFactory.createBuildMultilineInput("经费落实", "请输入经费落实", fundController,isRequired:true),
ListItemFactory.createBuildMultilineInput("负责人员", "请输入负责人员", personController,isRequired:true),
ListItemFactory.createBuildMultilineInput("工时安排", "请输入工时安排", workTimeController,isRequired:true),
ListItemFactory.createBuildMultilineInput("时限要求", "请输入时限要求", timeController,isRequired:true),
ListItemFactory.createBuildMultilineInput("工作要求", "请输入工作要求", workController,isRequired:true),
ListItemFactory.createBuildMultilineInput("其他事项", "请输入其他事项", otherController,isRequired:true),
];
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: 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<String, 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) => 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<Map<String, dynamic>>.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<File> files) {
// images 列表更新
// 上传 files 到服务器
jiHuaImages.clear();
for(int i=0;i<files.length;i++){
jiHuaImages.add(files[i].path);
}
},
),
);
}
/// 拉取某单位人员并缓存(兼容返回结构)
Future<void> _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<Map<String, dynamic>> list = [];
if (raw is List) {
list = raw.map<Map<String, dynamic>>((e) {
if (e is Map<String, dynamic>) return e;
if (e is Map) return Map<String, dynamic>.from(e);
return <String, dynamic>{};
}).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<Map<String, dynamic>> 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);
});
}
}