From 43958103032d0898d55a96a8e43d32ef9ae15a0b Mon Sep 17 00:00:00 2001 From: xufei <727302827@qq.com> Date: Thu, 16 Apr 2026 17:36:16 +0800 Subject: [PATCH] =?UTF-8?q?2026.4.16=20=E9=87=8D=E7=82=B9=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../key_tasks_hidden_danger_list.dart | 39 +- .../key_tasks_hidden_filter_page.dart | 486 ++++++++++++++++++ 2 files changed, 506 insertions(+), 19 deletions(-) create mode 100644 lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_filter_page.dart diff --git a/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart b/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart index 57d64b7..2f02d30 100644 --- a/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart +++ b/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_list.dart @@ -7,6 +7,7 @@ import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/modules/key_tasks_api.dart'; import 'package:qhd_prevention/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_danger_detail.dart'; +import 'package:qhd_prevention/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_filter_page.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/h_colors.dart'; import 'package:qhd_prevention/tools/tools.dart'; @@ -26,7 +27,7 @@ class KeyTasksHiddenDangerList extends StatefulWidget { class _KeyTasksHiddenDangerListState extends State { int _page = 1; - String searchKey = ""; + // String searchKey = ""; int _totalPage = 1; late List _list = []; bool _isLoading = false; @@ -103,7 +104,8 @@ class _KeyTasksHiddenDangerListState extends State { hintText: '请输入隐患描述', onTextChanged: (value) {}, onSearch: (keyboard) { - _performSearch(_searchController.text); + keyTasksHiddenDangerListData['hiddenDesc']=keyboard; + _performSearch(); }, ), ), @@ -112,46 +114,45 @@ class _KeyTasksHiddenDangerListState extends State { RangeFilterBar( initial: RangeOption.none, onRangeChanged: (range) { - String searchData=''; + switch (range) { case RangeOption.oneWeek: final data = DateTime.now().subtract( const Duration(days: 7), ); final time = DateFormat('yyyy-MM-dd').format(data); - searchData = time; + keyTasksHiddenDangerListData['startTime'] = time; break; case RangeOption.oneMonth: final data = DateTime.now().subtract( const Duration(days: 30), ); final time = DateFormat('yyyy-MM-dd').format(data); - searchData = time; + keyTasksHiddenDangerListData['startTime'] = time; break; case RangeOption.threeMonths: final data = DateTime.now().subtract( const Duration(days: 90), ); final time = DateFormat('yyyy-MM-dd').format(data); - searchData = time; + keyTasksHiddenDangerListData['startTime'] = time; case RangeOption.none: break; case RangeOption.oneDay: break; } - _performSearch(searchData); + _performSearch(); }, onFilterPressed: () async { // 弹出筛选对话框或跳转到筛选页面 - String searchData=''; - // searchData = await pushPage( - // SafecheckListfilterPage( - // searchData: searchData, - // mode: widget.mode, - // ), - // context, - // ); - _performSearch(searchData); + // String searchData=''; + keyTasksHiddenDangerListData = await pushPage( + KeyTasksHiddenFilterPage( + searchData: keyTasksHiddenDangerListData, + ), + context, + ); + _performSearch(); }, ), @@ -449,14 +450,14 @@ class _KeyTasksHiddenDangerListState extends State { ); } - void _performSearch(String keyword) { + void _performSearch() { // 执行搜索逻辑 // if (keyword.isNotEmpty) { // print('执行搜索: $keyword'); // 调用API或其他搜索操作 // 输入请求接口 _page = 1; - searchKey = keyword; + // searchKey = keyword; _getListData(false); // } } @@ -486,7 +487,7 @@ class _KeyTasksHiddenDangerListState extends State { _isLoading = true; keyTasksHiddenDangerListData['pageIndex']=_page; - keyTasksHiddenDangerListData['hiddenDesc']=searchKey; + // keyTasksHiddenDangerListData['hiddenDesc']=searchKey; LoadingDialogHelper.show(); final Map result = await KeyTasksApi.setKeyTasksHiddenDangerList(keyTasksHiddenDangerListData); diff --git a/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_filter_page.dart b/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_filter_page.dart new file mode 100644 index 0000000..564706c --- /dev/null +++ b/lib/pages/home/keyTasks/keyTasksDetail/keyTasksHiddenDanger/key_tasks_hidden_filter_page.dart @@ -0,0 +1,486 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart'; +import 'package:qhd_prevention/customWidget/bottom_picker.dart'; +import 'package:qhd_prevention/customWidget/custom_button.dart'; +import 'package:qhd_prevention/customWidget/date_picker_dialog.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_three.dart'; +import 'package:qhd_prevention/customWidget/item_list_widget.dart'; +import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; +import 'package:qhd_prevention/customWidget/toast_util.dart'; +import 'package:qhd_prevention/http/modules/basic_info_api.dart'; +import 'package:qhd_prevention/pages/my_appbar.dart'; +import 'package:qhd_prevention/tools/tools.dart'; + +class KeyTasksHiddenFilterPage extends StatefulWidget { + const KeyTasksHiddenFilterPage({ + super.key, + required this.searchData, + + }); + + final Map searchData; + + @override + State createState() => _KeyTasksHiddenFilterPageState(); +} + +class _KeyTasksHiddenFilterPageState extends State { + + // controllers / state + + /// 检查场所 + TextEditingController _inspectionSiteController = TextEditingController(); + /// 检查发起人 + TextEditingController _initiatorInspectionController = TextEditingController(); + /// 检查人 + TextEditingController _inspectorController = TextEditingController(); + + + // 存储各单位的人员列表 + final Map>> _personCache = {}; + + DateTime? _startDate; + DateTime? _endDate; + Map searchData = {}; + + final DateFormat _dateFmt = DateFormat('yyyy-MM-dd'); + + + @override + void initState() { + // TODO: implement initState + super.initState(); + _fetchData(); + } + + Future _fetchData() async { + setState(() { + searchData=widget.searchData; + _inspectionSiteController.text = searchData['hiddenDesc']; + _initiatorInspectionController.text = searchData['hiddenFindUserName']; + _inspectorController.text = searchData['projectName']; + + }); + } + + + // ========== 页面构建 ========== + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: const MyAppbar(title: '筛选'), + backgroundColor: Colors.white, + body: SafeArea( + child: Column( + children: [ + Expanded( + child: ListView( + children: [ + Container( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + + buildTextFieldRow( + labelText: '隐患描述', + controller: _inspectionSiteController, + hintText: '请输入隐患描述', + onChanged: (value) { + searchData['hiddenDesc'] = value; + }, + ), + + const SizedBox(height: 10), + buildChooseRow( + labelText: '隐患来源', + valueText: searchData['sourceName'], + onTap: () => _getApproverList(), + hintText: '选择隐患来源', + ), + + + const SizedBox(height: 10), + buildTextFieldRow( + labelText: '隐患发现人', + controller: _initiatorInspectionController, + hintText: '请输入隐患发现人', + onChanged: (value) { + searchData['hiddenFindUserName'] = value; + }, + ), + + + + const SizedBox(height: 10), + buildChooseRow( + labelText: '检查开始时间', + valueText: searchData['startTime'], + onTap: () => _pickDate(isStart: true), + hintText: '选择开始时间', + ), + const SizedBox(height: 10), + buildChooseRow( + labelText: '检查结束时间', + valueText: searchData['endTime'], + onTap: () => _pickDate(isStart: false), + hintText: '选择结束时间', + ), + + + const SizedBox(height: 10), + buildTextFieldRow( + labelText: '重点作业名称', + controller: _inspectorController, + hintText: '请输入重点作业名称', + onChanged: (value) { + searchData['projectName'] = value; + }, + ), + + + ], + ), + ), + ], + ), + ), + ItemListWidget.itemContainer( + Row( + children: [ + CustomButton( + text: '重置', + padding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 30, + ), + buttonStyle: ButtonStyleType.secondary, + onPressed: _resetAll, + ), + const SizedBox(width: 12), + Expanded( + child: CustomButton(text: '确定', onPressed: _confirm), + ), + ], + ), + ), + ], + ), + ), + ); + } + + + + + + @override + void dispose() { + _inspectionSiteController.dispose(); + _initiatorInspectionController.dispose(); + _inspectorController.dispose(); + super.dispose(); + } + + Widget buildTextFieldRow({ + required String labelText, + required TextEditingController controller, + required String hintText, + ValueChanged? onChanged, + }) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + labelText, + style: const TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + color: Colors.black, + ), + ), + const SizedBox(height: 8), + Container( + height: 45, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(5), + ), + padding: const EdgeInsets.symmetric(horizontal: 8), + alignment: Alignment.centerLeft, + child: TextFormField( + controller: controller, + decoration: InputDecoration( + hintText: hintText, + hintStyle: const TextStyle(color: Colors.grey), + border: InputBorder.none, + isDense: true, + ), + maxLines: 1, + onChanged: onChanged, + ), + ), + ], + ); + } + + Widget buildChooseRow({ + required String labelText, + required String hintText, + required String valueText, + required VoidCallback onTap, + bool showArrow = true, + }) { + final bool hasValue = valueText.trim().isNotEmpty; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + labelText, + style: TextStyle( + fontSize: 15, + fontWeight: FontWeight.w500, + color: Colors.black, + ), + ), + const SizedBox(height: 8), + Container( + height: 45, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(5), + ), + child: InkWell( + onTap: onTap, + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Row( + children: [ + Expanded( + child: Text( + hasValue ? valueText : hintText, + style: TextStyle( + color: hasValue ? Colors.black87 : Colors.black54, + fontSize: 15, + ), + overflow: TextOverflow.ellipsis, + ), + ), + if (showArrow) + const Icon(Icons.arrow_drop_down, color: Colors.black54), + ], + ), + ), + ), + ), + ], + ); + } + + // Future _chooseDepartment({required String typeStr}) async { + // showModalBottomSheet( + // context: context, + // isScrollControlled: true, + // barrierColor: Colors.black54, + // backgroundColor: Colors.transparent, + // builder: + // (_) => DepartmentPicker( + // onSelected: (id, name) async { + // setState(() { + // searchData['inspectionDepartmentId']=id; + // searchData['inspectionDepartmentName']=name; + // // personUnderInspection['departmentId'] = id; + // // personUnderInspection['userName'] = name; + // // if (typeStr == '检查部门') { + // // _inspectionDeptName = name; + // // } else if (typeStr == '被检查单位') { + // // _inspectedDepartmentName = name; + // // } + // }); + // // 拉该单位人员并缓存 + // await _getPersonListForUnitId(typeStr); + // }, + // ), + // ).then((_) { + // // 可选:FocusHelper.clearFocus(context); + // }); + // } + + Future _getPersonListForUnitId(String typeStr) async { + String unitId = searchData['inspectionDepartmentId'] ?? ''; + // 拉取该单位的人员列表并缓存 + final result = await BasicInfoApi.getDeptUsers(unitId); + dynamic raw = result['data']; + List> list = []; + if (raw is List) { + list = + raw.map>((e) { + if (e is Map) return e; + if (e is Map) return Map.from(e); + return {}; + }).toList(); + } else { + list = []; + } + setState(() { + _personCache[typeStr] = list; + }); + //FocusHelper.clearFocus(context); + } + + + Future _getApproverList() async { + try { + + List newList = [ + {'dataId':'1','dataName':'安全环保检查(监管端)',}, + {'dataId':'2','dataName':'安全环保检查(企业端)',}, + {'dataId':'3','dataName':'视频监控',}, + ]; + showModalBottomSheet( + context: context, + isScrollControlled: true, + barrierColor: Colors.black54, + backgroundColor: Colors.transparent, + builder: + (ctx) => DepartmentPickerThree( + listdata: newList, + onSelected: (id, name,pdId) async { + setState(() { + searchData['source']=id; + searchData['sourceName']=name; + }); + + }, + ), + ); + + } catch (e) { + // 出错时可以 Toast 或者在页面上显示错误状态 + print('加载首页数据失败:$e'); + // return ""; + LoadingDialogHelper.hide(); + } + } + + /// 弹出人员选择,需先选择单位 + // void choosePersonHandle(String typeStr) async { + // final personList = _personCache[typeStr]; + // if (!FormUtils.hasValue(_personCache, typeStr)) { + // ToastUtil.showNormal(context, '请先选择单位'); + // return; + // } + // + // DepartmentPersonPicker.show( + // context, + // personsData: personList!, + // onSelectedWithIndex: (userId, name, index) { + // setState(() { + // if (typeStr == '检查人') { + // _inspectionUserName = name; + // } else { + // _inspectedUserName = name; + // } + // }); + // //FocusHelper.clearFocus(context); + // }, + // ).then((_) {}); + // } + + Future _pickDate({required bool isStart}) async { + DateTime? picked = await BottomDateTimePicker.showDate( + context, + minTimeStr: !isStart ? searchData['startTime'] : null, + mode: BottomPickerMode.dateTime, + ); + if (picked != null) { + setState(() { + final dateFormat = DateFormat('yyyy-MM-dd HH:mm'); + if (isStart) { + _startDate = picked; + searchData['startTime'] = dateFormat.format(picked); + } else { + _endDate = picked; + searchData['endTime'] = dateFormat.format(picked); + } + // 保证开始 <= 结束 + if (_endDate != null && _endDate!.isBefore(picked)) { + _endDate = null; + } + }); + } + } + + // // 选择检查状态 + // Future _pickCheckStatus() async { + // List> items = SafeCheckListItem.getStepList(); + // final choice = await BottomPicker.show( + // context, + // items: items.map((item) => item['name'].toString()).toList(), + // itemBuilder: (item) => Text(item, textAlign: TextAlign.center), + // initialIndex: 0, + // ); + // if (choice != null) { + // setState(() { + // Map item = items[items.indexWhere((item) => item['name'] == choice)]; + // _checkStatus = item['id']; + // }); + // } + // } + + + // Future _pickYearDate() async { + // DateTime? picked = await BottomDateTimePicker.showDate( + // context, + // minTimeStr: null, + // mode: BottomPickerMode.year, + // ); + // if (picked != null) { + // setState(() { + // final dateFormat = DateFormat('yyyy'); + // searchData['year'] = dateFormat.format(picked); + // }); + // } + // } + + // ========== 重置 / 确定 ========== + void _resetAll() { + setState(() { + _inspectionSiteController.clear(); + _initiatorInspectionController.clear(); + _inspectorController.clear(); + + searchData['place']=''; + searchData['createName']=''; + searchData['inspectionDepartmentId']=''; + searchData['inspectionDepartmentName']=''; + searchData['timeStart']=''; + searchData['timeEnd']=''; + searchData['inspectedCorpinfoName']=''; + searchData['projectName']=''; + searchData['inspectionUserName']=''; + searchData['year']=''; + }); + final Map pd = { + ...searchData, + }; + Navigator.of(context).pop(pd); + } + + void _confirm() { + final Map pd = { + ...searchData, + }; + // for (Map subject in subjectList) { + // if (subject['bianma'] == pd['inspectionSubject']) { + // pd['inspectionSubject'] = subject['name']; + // } + // } + Navigator.of(context).pop(pd); + } + + +}