2025-08-20 09:56:31 +08:00
|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
2025-07-03 09:45:15 +08:00
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
import 'package:qhd_prevention/customWidget/department_picker.dart';
|
2025-08-20 09:56:31 +08:00
|
|
|
|
import 'package:qhd_prevention/customWidget/toast_util.dart';
|
|
|
|
|
import 'package:qhd_prevention/pages/home/work/risk_list_picker.dart';
|
|
|
|
|
import 'package:qhd_prevention/pages/home/work/wait_list_picker.dart';
|
|
|
|
|
import 'package:qhd_prevention/pages/http/ApiService.dart';
|
|
|
|
|
|
2025-07-07 16:49:05 +08:00
|
|
|
|
import '../../../tools/h_colors.dart';
|
2025-08-20 09:56:31 +08:00
|
|
|
|
import '../../../customWidget/custom_button.dart';
|
2025-07-07 16:49:05 +08:00
|
|
|
|
import '../../../tools/tools.dart';
|
2025-07-03 09:45:15 +08:00
|
|
|
|
|
|
|
|
|
/// 自定义抽屉
|
|
|
|
|
class CustomDriverDrawer extends StatefulWidget {
|
2025-08-20 09:56:31 +08:00
|
|
|
|
const CustomDriverDrawer(this.treeData, {super.key,required this.onClose});
|
|
|
|
|
|
|
|
|
|
final Function(String,String,String) onClose; // 回调函数
|
|
|
|
|
final List<WaitListBean> treeData;
|
2025-07-03 09:45:15 +08:00
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
_CustomDriverDrawerState createState() => _CustomDriverDrawerState();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class _CustomDriverDrawerState extends State<CustomDriverDrawer> {
|
2025-08-20 09:56:31 +08:00
|
|
|
|
|
|
|
|
|
// 管控部门 id
|
|
|
|
|
String? riskId;
|
|
|
|
|
// 风险点(单元)id
|
|
|
|
|
String? dept;
|
|
|
|
|
|
|
|
|
|
//风险等级
|
|
|
|
|
int _levelOption = -1;
|
|
|
|
|
List<String> dangerStatusId = ["levelA", "levelB", "levelC", "levelD"];
|
|
|
|
|
|
|
|
|
|
List<WaitListBean> jsonList =[];
|
|
|
|
|
String itemNameOne="请选择";
|
|
|
|
|
String itemNameTwo="请选择";
|
|
|
|
|
late List<RiskListBean> _list = [];
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
void initState() {
|
|
|
|
|
// TODO: implement initState
|
|
|
|
|
super.initState();
|
|
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
String? dangerJson = SessionService.instance.riskJson;
|
|
|
|
|
if(null!=dangerJson&&dangerJson.isNotEmpty) {
|
|
|
|
|
Map<String, dynamic> dangerWaitBean = json.decode(dangerJson);
|
|
|
|
|
riskId= dangerWaitBean["riskId"];
|
|
|
|
|
dept= dangerWaitBean["dept"];
|
|
|
|
|
_levelOption= dangerWaitBean["levelOption"];
|
|
|
|
|
|
|
|
|
|
itemNameOne= dangerWaitBean["itemNameOne"];
|
|
|
|
|
itemNameTwo= dangerWaitBean["itemNameTwo"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// jsonList = parseDepartments(widget.treeJson);
|
|
|
|
|
jsonList.addAll(widget.treeData);
|
|
|
|
|
} 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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<RiskListBean> parseRiskListBean(List<dynamic> jsonList) {
|
|
|
|
|
|
|
|
|
|
// 2. 转换为部门对象列表
|
|
|
|
|
return jsonList
|
|
|
|
|
.map((jsonItem) => RiskListBean.fromJson(jsonItem))
|
|
|
|
|
.toList();
|
|
|
|
|
}
|
2025-07-03 09:45:15 +08:00
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
Widget build(BuildContext context) {
|
2025-08-20 09:56:31 +08:00
|
|
|
|
final List<String> dangerStatus = ["重大风险", "较大风险", "一般风险", "低风险"];
|
|
|
|
|
|
2025-07-03 09:45:15 +08:00
|
|
|
|
|
|
|
|
|
// 显示分类选择器
|
2025-08-20 09:56:31 +08:00
|
|
|
|
void showCategoryPicker(String type) {
|
2025-07-03 09:45:15 +08:00
|
|
|
|
showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
isScrollControlled: true,
|
|
|
|
|
barrierColor: Colors.black54,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
2025-08-20 09:56:31 +08:00
|
|
|
|
builder: (ctx) => WaitListPicker(
|
|
|
|
|
data: jsonList,
|
|
|
|
|
onSelected: (item) {
|
2025-07-03 09:45:15 +08:00
|
|
|
|
setState(() {
|
2025-08-20 09:56:31 +08:00
|
|
|
|
// if("1"==type){
|
|
|
|
|
riskId = item?.id;
|
|
|
|
|
itemNameOne= item!.name;
|
|
|
|
|
// }else{
|
|
|
|
|
dept= null;
|
|
|
|
|
itemNameTwo="";
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
setResult();
|
2025-07-03 09:45:15 +08:00
|
|
|
|
});
|
2025-08-20 09:56:31 +08:00
|
|
|
|
_getTreeListUnit();
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 显示分类选择器
|
|
|
|
|
void showCategoryPickerTwo(String type) {
|
|
|
|
|
if("2"==type&&riskId==null){
|
|
|
|
|
ToastUtil.showNormal(context, "请先选择部门");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
showModalBottomSheet(
|
|
|
|
|
context: context,
|
|
|
|
|
isScrollControlled: true,
|
|
|
|
|
barrierColor: Colors.black54,
|
|
|
|
|
backgroundColor: Colors.transparent,
|
|
|
|
|
builder: (ctx) => RiskListPicker(
|
|
|
|
|
data: _list,
|
|
|
|
|
onSelected: (item) {
|
|
|
|
|
setState(() {
|
|
|
|
|
// if("1"==type){
|
|
|
|
|
// dept= item?.id;
|
|
|
|
|
// itemNameOne= item!.name;
|
|
|
|
|
// }else{
|
|
|
|
|
riskId = item?.id;
|
|
|
|
|
itemNameTwo=item!.name;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
setResult();
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-03 09:45:15 +08:00
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SafeArea(
|
|
|
|
|
child: Padding(
|
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20),
|
|
|
|
|
child: Column(
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
children: [
|
|
|
|
|
Row(
|
|
|
|
|
children: const [
|
|
|
|
|
Text(
|
|
|
|
|
"高级查询",
|
|
|
|
|
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
const Divider(height: 24, color: Colors.grey),
|
|
|
|
|
|
2025-08-20 09:56:31 +08:00
|
|
|
|
|
2025-07-03 09:45:15 +08:00
|
|
|
|
// 管控部门
|
|
|
|
|
_buildDropdownBox(
|
2025-08-20 09:56:31 +08:00
|
|
|
|
"管控部门",
|
|
|
|
|
display: itemNameOne ?? '请选择',
|
|
|
|
|
onTap: () {
|
|
|
|
|
showCategoryPicker("1");
|
|
|
|
|
}
|
2025-07-03 09:45:15 +08:00
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 12),
|
|
|
|
|
|
|
|
|
|
// 风险点(单元)
|
|
|
|
|
_buildDropdownBox(
|
2025-08-20 09:56:31 +08:00
|
|
|
|
"风险点(单元)",
|
|
|
|
|
display: itemNameTwo ?? '请选择',
|
|
|
|
|
onTap: () {
|
|
|
|
|
showCategoryPickerTwo("2");
|
2025-07-07 16:49:05 +08:00
|
|
|
|
}
|
2025-07-03 09:45:15 +08:00
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
const SizedBox(height: 24),
|
|
|
|
|
const Text(
|
|
|
|
|
"风险等级",
|
|
|
|
|
style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(height: 12),
|
|
|
|
|
|
|
|
|
|
// 风险等级:一行一个
|
|
|
|
|
Column(
|
2025-08-20 09:56:31 +08:00
|
|
|
|
children: List.generate(dangerStatus.length, (idx) {
|
|
|
|
|
final bool selected = _levelOption == idx;
|
2025-07-03 09:45:15 +08:00
|
|
|
|
return GestureDetector(
|
2025-08-20 09:56:31 +08:00
|
|
|
|
onTap: (){
|
|
|
|
|
setState(() {
|
|
|
|
|
_levelOption = idx;
|
|
|
|
|
|
|
|
|
|
setResult();
|
|
|
|
|
});
|
|
|
|
|
} ,
|
|
|
|
|
// onTap: () => setState(() => _dangerStatusOption = idx),
|
2025-07-03 09:45:15 +08:00
|
|
|
|
child: Container(
|
|
|
|
|
width: double.infinity,
|
|
|
|
|
margin: const EdgeInsets.only(bottom: 8),
|
2025-08-20 09:56:31 +08:00
|
|
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 6),
|
2025-07-03 09:45:15 +08:00
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
color: selected ? Colors.blue : Colors.transparent,
|
|
|
|
|
borderRadius: BorderRadius.circular(4),
|
|
|
|
|
border: Border.all(color: Colors.blue, width: 1),
|
|
|
|
|
),
|
|
|
|
|
child: Text(
|
2025-08-20 09:56:31 +08:00
|
|
|
|
dangerStatus[idx],
|
2025-07-03 09:45:15 +08:00
|
|
|
|
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(() {
|
2025-08-20 09:56:31 +08:00
|
|
|
|
|
|
|
|
|
riskId = null;
|
|
|
|
|
dept=null;
|
|
|
|
|
_levelOption = -1;
|
|
|
|
|
itemNameOne="请选择";
|
|
|
|
|
itemNameTwo="请选择";
|
|
|
|
|
// widget.onClose("","","",);
|
|
|
|
|
setResult();
|
2025-07-03 09:45:15 +08:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
const SizedBox(width: 12),
|
|
|
|
|
Expanded(
|
|
|
|
|
flex: 2,
|
|
|
|
|
child: CustomButton(
|
|
|
|
|
text: "完成",
|
|
|
|
|
backgroundColor: Colors.blue,
|
|
|
|
|
onPressed: () {
|
|
|
|
|
// TODO: 提交筛选条件
|
2025-08-20 09:56:31 +08:00
|
|
|
|
Navigator.pop(context); // 关闭加载对话框
|
2025-07-03 09:45:15 +08:00
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Widget _buildDropdownBox(String title,
|
|
|
|
|
{required String display, required VoidCallback onTap}) {
|
|
|
|
|
return GestureDetector(
|
|
|
|
|
onTap: onTap,
|
|
|
|
|
child: Container(
|
|
|
|
|
height: 48,
|
|
|
|
|
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: [
|
2025-08-20 09:56:31 +08:00
|
|
|
|
Text(_truncateText(display,9)),
|
2025-07-03 09:45:15 +08:00
|
|
|
|
const Icon(Icons.arrow_drop_down, color: Colors.grey),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
],
|
|
|
|
|
),
|
|
|
|
|
),
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-08-20 09:56:31 +08:00
|
|
|
|
|
|
|
|
|
// 文本截取函数
|
|
|
|
|
String _truncateText(String text, int maxLength) {
|
|
|
|
|
if (text.runes.length <= maxLength) {
|
|
|
|
|
return text;
|
|
|
|
|
}
|
|
|
|
|
return String.fromCharCodes(text.runes.take(maxLength)) + '...';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setResult(){
|
|
|
|
|
|
|
|
|
|
DangerRiskBean waitBean= DangerRiskBean.fromJson(
|
|
|
|
|
riskId ?? "", dept?? "",
|
|
|
|
|
_levelOption,itemNameOne, itemNameTwo);
|
|
|
|
|
|
|
|
|
|
String jsonString = jsonEncode(waitBean.toJson());
|
|
|
|
|
SessionService.instance.setRiskWaitInfo(jsonString);
|
|
|
|
|
|
|
|
|
|
widget.onClose(
|
|
|
|
|
riskId ?? "",
|
|
|
|
|
dept ?? "",
|
|
|
|
|
_levelOption!=-1?dangerStatusId[_levelOption]:"",
|
|
|
|
|
); // 触发回调
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Future<void> _getTreeListUnit( ) async {
|
|
|
|
|
try {
|
|
|
|
|
_list.clear();
|
|
|
|
|
final result = await ApiService.getTreeListUnit( riskId!);
|
|
|
|
|
|
|
|
|
|
if (result['result'] == 'success') {
|
|
|
|
|
final List<dynamic> newList = result['list'] ?? [];
|
|
|
|
|
|
|
|
|
|
setState(() {
|
|
|
|
|
_list.addAll(parseRiskListBean(newList));
|
|
|
|
|
// _list.addAll(newList);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
_showMessage('加载数据失败');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// 出错时可以 Toast 或者在页面上显示错误状态
|
|
|
|
|
print('加载数据失败:$e');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void _showMessage(String msg) {
|
|
|
|
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-03 09:45:15 +08:00
|
|
|
|
}
|
2025-08-20 09:56:31 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DangerRiskBean {
|
|
|
|
|
|
|
|
|
|
final String? riskId;
|
|
|
|
|
final String? dept;
|
|
|
|
|
|
|
|
|
|
//风险等级
|
|
|
|
|
final int levelOption;
|
|
|
|
|
|
|
|
|
|
final String itemNameOne;
|
|
|
|
|
final String itemNameTwo;
|
|
|
|
|
|
|
|
|
|
DangerRiskBean({
|
|
|
|
|
required this.riskId,
|
|
|
|
|
required this.dept,
|
|
|
|
|
required this.levelOption,
|
|
|
|
|
required this.itemNameOne,
|
|
|
|
|
required this.itemNameTwo,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
factory DangerRiskBean.fromJson(String riskId, String dept,
|
|
|
|
|
int levelOption,
|
|
|
|
|
String itemNameOne, String itemNameTwo,) {
|
|
|
|
|
return DangerRiskBean(
|
|
|
|
|
riskId: riskId,
|
|
|
|
|
dept: dept,
|
|
|
|
|
levelOption: levelOption,
|
|
|
|
|
itemNameOne: itemNameOne,
|
|
|
|
|
itemNameTwo: itemNameTwo,
|
|
|
|
|
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Map<String, dynamic> toJson() {
|
|
|
|
|
return {"riskId": riskId, "dept": dept,
|
|
|
|
|
"levelOption": levelOption,
|
|
|
|
|
"itemNameOne": itemNameOne, "itemNameTwo": itemNameTwo,};
|
|
|
|
|
}
|
|
|
|
|
}
|