qhd-prevention-flutter/lib/pages/app/hidden_danger_management/danger_wait_deawer.dart

641 lines
19 KiB
Dart
Raw Normal View History

2025-08-20 09:56:31 +08:00
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:qhd_prevention/customWidget/department_picker.dart';
import 'package:qhd_prevention/pages/home/work/wait_list_picker.dart';
import '../../../customWidget/bottom_picker.dart';
import '../../../tools/h_colors.dart';
import '/customWidget/custom_button.dart';
import '../../../tools/tools.dart';
class DangerWaitBean {
final String? selectedCategoryId;
final String? selectedDepartmentId;
// 排查方式
final int investigationMethodOption;
final int investigationMethodId;
//隐患级别
final int hazardLevelOption ;
//风险等级
final int dangerStatusOption ;
// 新增:开始/结束时间
final String startTime;
final String endTime;
final String itemNameOne;
final String itemNameTwo;
DangerWaitBean({
required this.selectedCategoryId,
required this.selectedDepartmentId,
required this.investigationMethodOption,
required this.investigationMethodId,
required this.hazardLevelOption,
required this.dangerStatusOption,
required this.startTime,
required this.endTime,
required this.itemNameOne,
required this.itemNameTwo,
});
factory DangerWaitBean.fromJson(String selectedCategoryId,String selectedDepartmentId,
int investigationMethodOption, int investigationMethodId,
int hazardLevelOption, int dangerStatusOption,
String startTime,String endTime,
String itemNameOne,String itemNameTwo,
) {
return DangerWaitBean(
selectedCategoryId:selectedCategoryId,
selectedDepartmentId:selectedDepartmentId,
investigationMethodOption:investigationMethodOption,
investigationMethodId:investigationMethodId,
hazardLevelOption:hazardLevelOption,
dangerStatusOption:dangerStatusOption,
startTime:startTime,
endTime:endTime,
itemNameOne:itemNameOne,
itemNameTwo:itemNameTwo,
);
}
Map<String, dynamic> toJson() {
return {"selectedCategoryId":selectedCategoryId,"selectedDepartmentId":selectedDepartmentId,
"investigationMethodOption":investigationMethodOption,"investigationMethodId":investigationMethodId,
"hazardLevelOption":hazardLevelOption,"dangerStatusOption":dangerStatusOption,
"startTime":startTime,"endTime":endTime,
"itemNameOne":itemNameOne,"itemNameTwo":itemNameTwo,};
}
}
/// 自定义抽屉
class DangerWaitDrawer extends StatefulWidget {
const DangerWaitDrawer(this.treeJson, {super.key,required this.onClose});
final Function(String,String,String,String,String,String,String) onClose; // 回调函数
final String treeJson;
// final DangerWaitBean waitBean;
@override
DangerWaitDrawerState createState() => DangerWaitDrawerState();
}
class DangerWaitDrawerState extends State<DangerWaitDrawer> {
// 检查部门分类 id
String? _selectedCategoryId;
// 整改部门分类 id
String? _selectedDepartmentId;
// 排查方式
int _investigationMethodOption = -1;
int investigationMethodId=-1;
//隐患级别
int _hazardLevelOption = -1;
// int hazardLevelId=-1;
List<String> hazardLevelId = ["hiddenLevel0001", "hiddenLevel0002"];
//风险等级
int _dangerStatusOption = -1;
// int dangerStatusId=-1;
List<String> dangerStatusId = ["1", "3", "4", "-1"];
// 新增:开始/结束时间
DateTime? _startDate;
DateTime? _endDate;
String startTime="";
String endTime="";
List<WaitListBean> jsonList =[];
String itemNameOne="请选择";
String itemNameTwo="请选择";
// 转换为List<Map<String, dynamic>>
late List<Map<String, dynamic>> departmentList ;
@override
void initState() {
// TODO: implement initState
super.initState();
setState(() {
try {
String? dangerJson = SessionService.instance.dangerJson;
if(null!=dangerJson&&dangerJson.isNotEmpty) {
Map<String, dynamic> dangerWaitBean = json.decode(dangerJson);
_selectedCategoryId= dangerWaitBean["selectedCategoryId"];
_selectedDepartmentId= dangerWaitBean["selectedDepartmentId"];
_investigationMethodOption= dangerWaitBean["investigationMethodOption"];
investigationMethodId= dangerWaitBean["investigationMethodId"];
_hazardLevelOption= dangerWaitBean["hazardLevelOption"];
_dangerStatusOption= dangerWaitBean["dangerStatusOption"];
startTime= dangerWaitBean["startTime"];
endTime= dangerWaitBean["endTime"];
itemNameOne= dangerWaitBean["itemNameOne"];
itemNameTwo= dangerWaitBean["itemNameTwo"];
}
jsonList = parseDepartments(widget.treeJson);
} catch (e) {
print("解析失败: $e");
}
// // 解析JSON字符串
// jsonList = json.decode(widget.treeJson);
// departmentList = List<Map<String, dynamic>>.from(jsonList);
});
}
List<WaitListBean> parseDepartments(String jsonString) {
// 1. 解码 JSON 字符串
final List<dynamic> jsonList = json.decode(jsonString);
// 2. 转换为部门对象列表
return jsonList
.map((jsonItem) => WaitListBean.fromJson(jsonItem))
.toList();
}
@override
Widget build(BuildContext context) {
final List<String> investigationMethod = ["风险排查隐患", "隐患排查隐患"];
final List<String> hazardLevel = [" 一般风险 ", " 重大风险 "];
final List<String> dangerStatus = ["未整改", "已整改", "已验收", "已过期"];
// final List<WaitListBean> data = [
// Category(
// id: '1',
// title: '分类一1',
// children: [
// Category(id: '1-1', title: '子项 1-1'),
// Category(id: '1-2', title: '子项 1-2'),
// ],
// ),
// Category(id: '2', title: '分类二'),
// Category(
// id: '3',
// title: '分类三',
// children: [
// Category(id: '3-1', title: '子项 3-1', children: [
// Category(id: '3-1-1', title: '子项 3-1-1'),
// ]),
// ],
// ),
// ];
// 显示分类选择器
void showCategoryPicker(String type) {
showModalBottomSheet(
context: context,
isScrollControlled: true,
barrierColor: Colors.black54,
backgroundColor: Colors.transparent,
builder: (ctx) => WaitListPicker(
data: jsonList,
onSelected: (item) {
setState(() {
if("1"==type){
_selectedCategoryId = item?.id;
itemNameOne= item!.name;
}else{
_selectedDepartmentId= item?.id;
itemNameTwo=item!.name;
}
setResult();
});
},
),
);
}
return SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 15),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: const [
Text(
"高级查询",
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
],
),
const Divider(height: 12, color: Colors.grey),
// 管控部门
_buildDropdownBox(
"检查部门",
display: itemNameOne ?? '请选择',
onTap: () {
showCategoryPicker("1");
}
),
const SizedBox(height: 6),
// 风险点(单元)
_buildDropdownBox(
"整改部门",
display: itemNameTwo ?? '请选择',
onTap: () {
showCategoryPicker("2");
}
// display: '请选择',
// onTap: () {
// final choice = BottomPicker.show<String>(
// context,
// items: ['未知'],
// itemBuilder: (item) => Text(item, textAlign: TextAlign.center),
// initialIndex: 0,
// );
// if (choice != null) {
// // 用户点击确定并选择了 choice
// setState(() {
//
// });
// }
// },
),
const SizedBox(height: 12),
const Text(
"排查方式",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
// 风险等级:一行两个
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(investigationMethod.length, (idx) {
final bool selected = _investigationMethodOption == idx;
return GestureDetector(
onTap: (){
setState(() {
_investigationMethodOption = idx;
investigationMethodId=idx+1;
setResult();
});
} ,
// => setState(() => _investigationMethodOption = idx),
child: Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 6),
decoration: BoxDecoration(
color: selected ? Colors.blue : Colors.transparent,
borderRadius: BorderRadius.circular(4),
border: Border.all(color: Colors.blue, width: 1),
),
child: Text(
investigationMethod[idx],
style: TextStyle(
fontSize: 14,
color: selected ? Colors.white : Colors.blue,
),
),
),
);
}),
),
const SizedBox(height: 12),
const Text(
"隐患级别",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
// 风险等级:一行两个
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: List.generate(hazardLevel.length, (idx) {
final bool selected = _hazardLevelOption == idx;
return GestureDetector(
onTap: (){
setState(() {
_hazardLevelOption = idx;
setResult();
});
} ,
// onTap: () => setState(() => _hazardLevelOption = idx),
child: Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 6),
decoration: BoxDecoration(
color: selected ? Colors.blue : Colors.transparent,
borderRadius: BorderRadius.circular(4),
border: Border.all(color: Colors.blue, width: 1),
),
child: Text(
hazardLevel[idx],
style: TextStyle(
fontSize: 14,
color: selected ? Colors.white : Colors.blue,
),
),
),
);
}),
),
const SizedBox(height: 12),
// 时间查询
const Text(
"时间查询",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
// 开始时间 - 结束时间 —— //
Row(
children: [
_buildDatePickerBox(
label: "开始时间",
date: _startDate,
onTap: _pickStartDate,
),
const SizedBox(width: 5),
const Text("", style: TextStyle(fontSize: 8)),
const SizedBox(width: 5),
_buildDatePickerBox(
label: "结束时间",
date: _endDate,
onTap: _pickEndDate,
),
],
),
const SizedBox(height: 12),
const Text(
"风险等级",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
),
const SizedBox(height: 6),
// 风险等级:一行一个
Column(
children: List.generate(dangerStatus.length, (idx) {
final bool selected = _dangerStatusOption == idx;
return GestureDetector(
onTap: (){
setState(() {
_dangerStatusOption = idx;
setResult();
});
} ,
// onTap: () => setState(() => _dangerStatusOption = idx),
child: Container(
width: double.infinity,
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
decoration: BoxDecoration(
color: selected ? Colors.blue : Colors.transparent,
borderRadius: BorderRadius.circular(4),
border: Border.all(color: Colors.blue, width: 1),
),
child: Text(
dangerStatus[idx],
style: TextStyle(
fontSize: 14,
color: selected ? Colors.white : Colors.blue,
),
),
),
);
}),
),
const Spacer(),
Row(
children: [
Expanded(
flex: 1,
child: CustomButton(
text: "重置",
backgroundColor: h_backGroundColor(),
textStyle: const TextStyle(color: Colors.black45),
onPressed: () {
setState(() {
_selectedCategoryId = null;
_selectedDepartmentId=null;
_investigationMethodOption = -1;
_hazardLevelOption = -1;
_dangerStatusOption = -1;
_startDate = null;
_endDate = null;
itemNameOne="请选择";
itemNameTwo="请选择";
setResult();
// widget.onClose("","","","","","","");
});
},
),
),
const SizedBox(width: 12),
Expanded(
flex: 2,
child: CustomButton(
text: "完成",
backgroundColor: Colors.blue,
onPressed: () {
// TODO: 提交筛选条件
Navigator.pop(context); // 关闭加载对话框
},
),
),
],
),
],
),
),
);
}
Widget _buildDropdownBox(String title,
{required String display, required VoidCallback onTap}) {
return GestureDetector(
onTap: onTap,
child: Container(
height: 36,
padding: const EdgeInsets.symmetric(horizontal: 12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
border: Border.all(color: Colors.grey.shade400),
color: Colors.white,
),
child: Row(
children: [
Text(title, style: const TextStyle(fontSize: 14)),
const Spacer(),
Row(
children: [
Text(_truncateText(display,9)),
const Icon(Icons.arrow_drop_down, color: Colors.grey),
],
),
],
),
),
);
}
// 文本截取函数
String _truncateText(String text, int maxLength) {
if (text.runes.length <= maxLength) {
return text;
}
return String.fromCharCodes(text.runes.take(maxLength)) + '...';
}
Future<void> _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');
startTime=dateFormat.format(picked);
// 保证开始 <= 结束
if (_endDate != null && _endDate!.isBefore(picked)) {
_endDate = null;
}
setResult();
});
}
}
Future<void> _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');
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 Expanded(
child: 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)),
],
),
),
),
);
}
void setResult(){
DangerWaitBean waitBean= DangerWaitBean.fromJson(
_selectedCategoryId ?? "", _selectedDepartmentId?? "",
_investigationMethodOption,investigationMethodId,
_hazardLevelOption, _dangerStatusOption,
startTime, endTime,itemNameOne, itemNameTwo);
String jsonString = jsonEncode(waitBean.toJson());
SessionService.instance.setDangerWaitInfo(jsonString);
widget.onClose(
_selectedCategoryId ?? "",
_selectedDepartmentId ?? "",
_investigationMethodOption!=-1?investigationMethodId.toString():"",
_hazardLevelOption!=-1?hazardLevelId[_hazardLevelOption]:"",
_dangerStatusOption!=-1?dangerStatusId[_dangerStatusOption]:"",
_startDate!=null?startTime:"",
_endDate!=null?endTime:"",
); // 触发回调
}
}