681 lines
21 KiB
Dart
681 lines
21 KiB
Dart
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);
|
|
});
|
|
}
|
|
|
|
|
|
|
|
}
|