结构修改
							parent
							
								
									7ef5d4ccdc
								
							
						
					
					
						commit
						4accf55b81
					
				|  | @ -270,7 +270,6 @@ class RepairedPhotoSection extends StatefulWidget { | |||
|     this.onMediaAdded, | ||||
|     this.onMediaRemoved, | ||||
|   }) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   _RepairedPhotoSectionState createState() => _RepairedPhotoSectionState(); | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,611 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/toast_util.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/hotwork_safe_func_sure.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqgl_work_detail/hotwork_aqgl_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dbbz_work_detail/hotwork_dbbz_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dhsp_work_detail/hotwork_dhsp_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jhr_work_detail/hotwork_jhr_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jszy_work_detail/hotwork_jszy_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/kszy_work_detail/hotwork_kszy_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szaq_work_detail/hotwork_set_safe_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szdw_work_detail/hotwork_szdw_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/zyfz_work_detail/hotwork_zyfz_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| import 'package:qhd_prevention/customWidget/bottom_picker.dart'; | ||||
| import 'package:qhd_prevention/customWidget/custom_button.dart'; | ||||
| import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/jsjd_work_detail/hotwork_jsjd_detail.dart'; | ||||
| 
 | ||||
| class HotWorkListPage extends StatefulWidget { | ||||
|   final String flow; | ||||
|   final String workTypeTitle; | ||||
|   const HotWorkListPage({Key? key, required this.flow, required this.workTypeTitle}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   _HotWorkListPageState createState() => _HotWorkListPageState(); | ||||
| } | ||||
| 
 | ||||
| class _HotWorkListPageState extends State<HotWorkListPage> { | ||||
|   // Data and state variables | ||||
|   List<dynamic> list = []; | ||||
|   int currentPage = 1; | ||||
|   int rows = 10; | ||||
|   int totalPage = 1; | ||||
|   bool isLoading = false; | ||||
|   final TextEditingController _searchController = TextEditingController(); | ||||
| 
 | ||||
|   List<Map<String, dynamic>> stepList = []; | ||||
|   int sindex = 0; | ||||
|   String searchKeywords = ''; | ||||
| 
 | ||||
|   List<Map<String, dynamic>> flowList = []; | ||||
|   final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); | ||||
| 
 | ||||
|   final ScrollController _scrollController = ScrollController(); | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _fetchSteps(); | ||||
|     _fetchData(); | ||||
|     _scrollController.addListener(_onScroll); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _scrollController.dispose(); | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   void _onScroll() { | ||||
|     if (_scrollController.position.pixels >= | ||||
|             _scrollController.position.maxScrollExtent && | ||||
|         !isLoading) { | ||||
|       if (currentPage < totalPage) { | ||||
|         currentPage++; | ||||
|         _fetchData(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _fetchSteps() async { | ||||
|     try { | ||||
|       final response = await ApiService.dhHotGetTaskSetps(1); | ||||
|       setState(() { | ||||
|         stepList = [ | ||||
|           {'STEP_NAME': '全部', 'STEP_ID': ''}, | ||||
|           ...response['list'] ?? [], | ||||
|         ]; | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching steps: $e'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _fetchData() async { | ||||
|     if (isLoading) return; | ||||
|     setState(() => isLoading = true); | ||||
| 
 | ||||
|     try { | ||||
|       final data = { | ||||
|         'CREATOR': | ||||
|             widget.flow == '提交申请' ? SessionService.instance.loginUserId : '', | ||||
|         'GASCHECK': | ||||
|             widget.flow == '气体检测' ? SessionService.instance.loginUserId : '', | ||||
|         'STEP_NAME': | ||||
|             (widget.flow == '提交申请' || widget.flow == '气体检测') ? '' : widget.flow, | ||||
|         'STEP_ID': sindex > 0 ? stepList[sindex]['STEP_ID'] : '', | ||||
|         'KEYWORDS': searchKeywords, | ||||
|         'WORK_STATE': '0', | ||||
|       }; | ||||
|       final url = '/app/hotwork/list?showCount=-1¤tPage=$currentPage'; | ||||
|       final response = await ApiService.hotCheckWorkCount(data, url); | ||||
| 
 | ||||
|       setState(() { | ||||
|         if (currentPage == 1) { | ||||
|           list = response['varList']; | ||||
|         } else { | ||||
|           list.addAll(response['varList']); | ||||
|         } | ||||
|         Map<String, dynamic> page = response['page']; | ||||
|         totalPage = page['totalPage'] ?? 1; | ||||
|         isLoading = false; | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching data: $e'); | ||||
|       setState(() => isLoading = false); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void _search() { | ||||
|     currentPage = 1; | ||||
|     list.clear(); | ||||
|     _fetchData(); | ||||
|   } | ||||
|   /// 申请 | ||||
|   void _handleApply() { | ||||
|     // 处理申请按钮点击逻辑 | ||||
|     pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context); | ||||
|   } | ||||
| 
 | ||||
|   /// 打开流程图 | ||||
|   Future<void> _openFlowDrawer(String hotworkId) async { | ||||
|     try { | ||||
|       final response = await ApiService.dhGetFlowList(hotworkId); | ||||
|       final List<dynamic>? newFlow = response['flowList']; | ||||
|       if (newFlow == null || newFlow.isEmpty) { | ||||
|         ToastUtil.showNormal(context, '暂无流程图数据'); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       setState(() { | ||||
|         flowList = List<Map<String, dynamic>>.from(newFlow); | ||||
|       }); | ||||
|       Future.microtask(() { | ||||
|         _scaffoldKey.currentState?.openEndDrawer(); | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching flow data: $e'); | ||||
|       ScaffoldMessenger.of( | ||||
|         context, | ||||
|       ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void _goToDetail(Map<String, dynamic> item) async { | ||||
|     final Map<String, dynamic> data = {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow}; | ||||
|     String routeName = ''; | ||||
|     switch (widget.flow) { | ||||
|       case '提交申请': | ||||
|         await pushPage(HotworkApplyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         _fetchData(); | ||||
|         break; | ||||
|       case '气体检测': | ||||
|         await pushPage(HotworkGasList(HOTWORK_ID: item['HOTWORK_ID'], addFlag:true), context); | ||||
|         break; | ||||
|       case '设置安全措施确认人': | ||||
|         await pushPage(HotworkSetSafeDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '安全措施确认': | ||||
|         await pushPage(HotworkSafeFuncSure(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '监护人签字': | ||||
|         routeName = '/hotwork-guardian-detail'; | ||||
|         await pushPage(HotworkJhrDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '安全交底人签字': | ||||
|         routeName = '/hotwork-confess-detail'; | ||||
|         await pushPage(HotworkAqjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '接受交底人签字': | ||||
|         routeName = '/hotwork-acceptconfess-detail'; | ||||
|         await pushPage(HotworkJsjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '作业负责人签字': | ||||
|         routeName = '/hotwork-confirm-detail'; | ||||
|         await pushPage(HotworkZyfzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '所在单位签字': | ||||
|         routeName = '/hotwork-leader-detail'; | ||||
|         await pushPage(HotworkSzdwDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '安全管理部门签字': | ||||
|         routeName = '/hotwork-audit-detail'; | ||||
|         await pushPage(HotworkAqglDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '审批人签字': | ||||
|         routeName = '/hotwork-approve-detail'; | ||||
|         await pushPage(HotworkDhspDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '当班班长验票': | ||||
|         routeName = '/hotwork-monitor-detail'; | ||||
|         await pushPage(HotworkDbbzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '开始作业': | ||||
|         routeName = '/hotwork-startwork-detail'; | ||||
|         await pushPage(HotworkKszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '结束作业': | ||||
|         routeName = '/hotwork-endwork-detail'; | ||||
|         await pushPage(HotworkJszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '验收签字': | ||||
|         routeName = '/hotwork-accept-detail'; | ||||
|         await pushPage(HotworkYsgdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       default: | ||||
|         routeName = '/hotwork-detail'; | ||||
|     } | ||||
|     setState(() { | ||||
|       _fetchSteps(); | ||||
|       _fetchData(); | ||||
|     }); | ||||
|     // Navigator.pushNamed( | ||||
|     //   context, | ||||
|     //   routeName, | ||||
|     //   arguments: {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow}, | ||||
|     // ); | ||||
|   } | ||||
| 
 | ||||
|   Widget _buildFlowStepItem({ | ||||
|     required Map<String, dynamic> item, | ||||
|     required bool isFirst, | ||||
|     required bool isLast, | ||||
|     required int status, // 1 = 完成, 0 = 进行中, -1 = 未到达 | ||||
|   }) { | ||||
|     // 依据状态设色 | ||||
|     final Color dotColor = | ||||
|         status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey); | ||||
|     final Color textColor = | ||||
|         status == 1 | ||||
|             ? Colors.green | ||||
|             : (status == 0 ? Colors.blue : Colors.black); | ||||
| 
 | ||||
|     return ListTile( | ||||
|       visualDensity: VisualDensity(vertical: -4), | ||||
| 
 | ||||
|       contentPadding: const EdgeInsets.symmetric(horizontal: 16), | ||||
|       leading: Container( | ||||
|         width: 24, | ||||
|         alignment: Alignment.center, | ||||
|         child: Column( | ||||
|           mainAxisSize: MainAxisSize.max, | ||||
|           children: [ | ||||
|             // 上方线段或占位 | ||||
|             isFirst | ||||
|                 ? SizedBox(height: 6 + 5) | ||||
|                 : Expanded(child: Container(width: 1, color: Colors.grey[300])), | ||||
|             // 圆点 | ||||
|             CircleAvatar(radius: 6, backgroundColor: dotColor), | ||||
|             // 下方线段或占位 | ||||
|             isLast | ||||
|                 ? SizedBox(height: 6 + 5) | ||||
|                 : Expanded(child: Container(width: 1, color: Colors.grey[300])), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|       title: Text( | ||||
|         item['STEP_NAME'] ?? '', | ||||
|         style: TextStyle(color: textColor, fontSize: 15), | ||||
|       ), | ||||
|       subtitle: Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         children: [ | ||||
|           if (item['SIGN_USER'] != null) | ||||
|             Text( | ||||
|               item['SIGN_USER'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['FINISHED_SIGN_USER'] != null) | ||||
|             Text( | ||||
|               item['FINISHED_SIGN_USER'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['ACT_USER_NAME'] != null) | ||||
|             Text( | ||||
|               item['ACT_USER_NAME'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['ACT_TIME'] != null) | ||||
|             Text( | ||||
|               item['ACT_TIME'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   Widget _buildListItem(Map<String, dynamic> item) { | ||||
|     return Card( | ||||
|       color: Colors.white, | ||||
|       margin: const EdgeInsets.all(8.0), | ||||
|       child: InkWell( | ||||
|         onTap: () => _goToDetail(item), | ||||
|         child: Padding( | ||||
|           padding: const EdgeInsets.all(12.0), | ||||
|           child: Column( | ||||
|             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|             children: [ | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("编号: ${item['CHECK_NO'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),), | ||||
|                   Text("作业级别: ${item['WORK_LEVEL'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"), | ||||
|                   Text("分析人: ${item['ANALYZE_USER_NAME'] ?? ''}"), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"), | ||||
|                   Text("批准人: ${item['APPROVE_USER_NAME'] ?? ''}"), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"), | ||||
|                     Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"), | ||||
|                     Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|               if (item['AUDIT_USER_NAME'] != null) | ||||
|                 Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}"), | ||||
|                     Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Expanded( | ||||
|                     child: Text( | ||||
|                       "审核状态: ${_getStatusText(item)}", | ||||
|                       overflow: TextOverflow.ellipsis, | ||||
|                     ), | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row(children: [ | ||||
|                 CustomButton( | ||||
|                   text: '查看流程图', | ||||
|                   height: 35, | ||||
|                   padding: EdgeInsets.symmetric(horizontal: 12), | ||||
|                   margin: EdgeInsets.only(left: 0), | ||||
|                   backgroundColor: Colors.blue, | ||||
|                   onPressed: () => _openFlowDrawer(item['HOTWORK_ID']), | ||||
|                 ), | ||||
|                 SizedBox(width: 1,) | ||||
|               ],) | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   String _getStatusText(Map<String, dynamic> item) { | ||||
|     // 安全取出 STEP_ID 和 STATUS | ||||
|     final int stepId = (item['STEP_ID'] is int) ? item['STEP_ID'] as int : 0; | ||||
|     final int status = (item['STATUS'] is int) ? item['STATUS'] as int : 0; | ||||
| 
 | ||||
|     if (stepId == 0) { | ||||
|       return '暂存'; | ||||
|     } else if (status == -2) { | ||||
|       return '气体检测打回'; | ||||
|     } else if (stepId != -1) { | ||||
|       return item['NEXT_STEP_NAME'] ?? ''; | ||||
|     } else { | ||||
|       return '${item['STEP_NAME'] ?? ''}打回'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // 显示底部选择器 | ||||
|   Future<void> _showStepPicker() async { | ||||
|     if (stepList.isEmpty) { | ||||
|       ScaffoldMessenger.of( | ||||
|         context, | ||||
|       ).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...'))); | ||||
|       await _fetchSteps(); | ||||
|       if (stepList.isEmpty) { | ||||
|         ScaffoldMessenger.of( | ||||
|           context, | ||||
|         ).showSnackBar(SnackBar(content: Text('无法加载步骤数据'))); | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // 创建选项列表 | ||||
|     final options = stepList.map((e) => e['STEP_NAME'] as String).toList(); | ||||
| 
 | ||||
|     // 显示底部选择器 | ||||
|     final choice = await BottomPicker.show<String>( | ||||
|       context, | ||||
|       items: options, | ||||
|       itemBuilder: (item) => Text(item, textAlign: TextAlign.center), | ||||
|       initialIndex: sindex, | ||||
|     ); | ||||
| 
 | ||||
|     if (choice != null) { | ||||
|       // 找到选择的索引 | ||||
|       final newIndex = options.indexOf(choice); | ||||
|       if (newIndex != -1) { | ||||
|         setState(() { | ||||
|           sindex = newIndex; | ||||
|         }); | ||||
|         _search(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Widget _buildListContent() { | ||||
|     if (isLoading && list.isEmpty) { | ||||
|       // 初始加载时显示居中的加载指示器 | ||||
|       return Center(child: CircularProgressIndicator()); | ||||
|     } else if (list.isEmpty) { | ||||
|       // 没有数据 | ||||
|       return NoDataWidget.show(); | ||||
|     } else { | ||||
|       // 有数据或加载更多 | ||||
|       return ListView.builder( | ||||
|         padding: EdgeInsets.zero, | ||||
| 
 | ||||
|         controller: _scrollController, | ||||
|         itemCount: list.length + (isLoading ? 1 : 0), | ||||
|         itemBuilder: (context, index) { | ||||
|           if (index >= list.length) { | ||||
|             // 加载更多时在列表底部显示加载指示器 | ||||
|             return Padding( | ||||
|               padding: const EdgeInsets.symmetric(vertical: 16.0), | ||||
|               child: Center(child: CircularProgressIndicator()), | ||||
|             ); | ||||
|           } | ||||
|           return _buildListItem(list[index]); | ||||
|         }, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1); | ||||
| 
 | ||||
|     return Scaffold( | ||||
|       key: _scaffoldKey, | ||||
|       appBar: MyAppbar( | ||||
|         title: '${widget.workTypeTitle}${widget.flow}', | ||||
|         actions: [ | ||||
|           if (widget.flow == '提交申请') | ||||
|             TextButton( | ||||
|               onPressed: _handleApply, | ||||
|               child: const Text( | ||||
|                 '申请', | ||||
|                 style: TextStyle(color: Colors.white, fontSize: 17), | ||||
|               ), | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|       endDrawer: Drawer( | ||||
|         child: SafeArea( | ||||
|           child: | ||||
|               flowList.isEmpty | ||||
|                   ? Center(child: Text('暂无流程图数据')) | ||||
|                   : ListView.builder( | ||||
|                     padding: const EdgeInsets.symmetric(vertical: 16), | ||||
|                     itemCount: flowList.length + 1, // +1 用来放标题 | ||||
|                     itemBuilder: (context, i) { | ||||
|                       if (i == 0) { | ||||
|                         return Padding( | ||||
|                           padding: const EdgeInsets.symmetric( | ||||
|                             horizontal: 16, | ||||
|                             vertical: 8, | ||||
|                           ), | ||||
|                           child: Text( | ||||
|                             '查看流程图', | ||||
|                             style: TextStyle( | ||||
|                               fontSize: 18, | ||||
|                               fontWeight: FontWeight.bold, | ||||
|                             ), | ||||
|                           ), | ||||
|                         ); | ||||
|                       } | ||||
|                       final idx = i - 1; | ||||
|                       final item = flowList[idx]; | ||||
|                       final bool isFirst = idx == 0; | ||||
|                       final bool isLast = idx == flowList.length - 1; | ||||
| 
 | ||||
|                       // 根据 lastDoneIndex 自动计算“进行中” | ||||
|                       final int status; | ||||
|                       if (idx <= lastDoneIndex) { | ||||
|                         status = 1; // 已完成 | ||||
|                       } else if (idx == lastDoneIndex + 1) { | ||||
|                         status = 0; // 进行中 | ||||
|                       } else { | ||||
|                         status = -1; // 未到达 | ||||
|                       } | ||||
| 
 | ||||
|                       return _buildFlowStepItem( | ||||
|                         item: item, | ||||
|                         isFirst: isFirst, | ||||
|                         isLast: isLast, | ||||
|                         status: status, | ||||
|                       ); | ||||
|                     }, | ||||
|                   ), | ||||
|         ), | ||||
|       ), | ||||
| 
 | ||||
|       body: Column( | ||||
|         children: [ | ||||
|           // Filter bar | ||||
|           Container( | ||||
|             color: Colors.white, | ||||
|             padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8), | ||||
|             child: Row( | ||||
|               children: [ | ||||
|                 // 底部弹窗选择器 | ||||
|                 SizedBox( | ||||
|                   width: 65, | ||||
|                   child: TextButton( | ||||
|                     onPressed: _showStepPicker, | ||||
|                     style: TextButton.styleFrom( | ||||
|                       padding: EdgeInsets.symmetric( | ||||
|                         vertical: 12, | ||||
|                         horizontal: 5, | ||||
|                       ), | ||||
|                     ), | ||||
|                     child: Row( | ||||
|                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                       children: [ | ||||
|                         Text( | ||||
|                           '筛选', | ||||
|                           style: TextStyle(color: Colors.black87, fontSize: 16), | ||||
|                         ), | ||||
|                         Icon(Icons.arrow_drop_down, color: Colors.grey), | ||||
|                       ], | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|                 Expanded( | ||||
|                   flex: 2, | ||||
|                   child: SearchBarWidget( | ||||
|                     showResetButton: false, | ||||
|                     hintText: "请输入关键字", | ||||
|                     // isClickableOnly: true, | ||||
|                     onSearch: (text) { | ||||
|                       _search(); | ||||
|                     }, | ||||
|                     controller: _searchController, | ||||
|                   ), | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ), | ||||
|           const Divider(height: 1), | ||||
|           // List | ||||
|           Expanded(child: _buildListContent()), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,621 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/toast_util.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dh_work_detai/hotwork_apply_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqcs_work_detail/hotwork_safe_func_sure.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqgl_work_detail/hotwork_aqgl_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/aqjd_work_detail/hotwork_aqjd_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dbbz_work_detail/hotwork_dbbz_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/dhsp_work_detail/hotwork_dhsp_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jhr_work_detail/hotwork_jhr_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/jszy_work_detail/hotwork_jszy_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/kszy_work_detail/hotwork_kszy_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szaq_work_detail/hotwork_set_safe_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/szdw_work_detail/hotwork_szdw_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/ysgd_work_detail/hotwork_ysgd_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/zyfz_work_detail/hotwork_zyfz_detail.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| import 'package:qhd_prevention/customWidget/bottom_picker.dart'; | ||||
| import 'package:qhd_prevention/customWidget/custom_button.dart'; | ||||
| import 'package:qhd_prevention/customWidget/search_bar_widget.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/qtfx_work_detail/hotwork_gas_list.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_Wrok/dh_work/jsjd_work_detail/hotwork_jsjd_detail.dart'; | ||||
| 
 | ||||
| class HighworkListPage extends StatefulWidget { | ||||
|   final String flow; | ||||
|   final String workTypeTitle; | ||||
|   const HighworkListPage({Key? key, required this.flow, required this.workTypeTitle}) : super(key: key); | ||||
| 
 | ||||
|   @override | ||||
|   _HighworkListPageState createState() => _HighworkListPageState(); | ||||
| } | ||||
| 
 | ||||
| class _HighworkListPageState extends State<HighworkListPage> { | ||||
|   // Data and state variables | ||||
|   List<dynamic> list = []; | ||||
|   int currentPage = 1; | ||||
|   int rows = 10; | ||||
|   int totalPage = 1; | ||||
|   bool isLoading = false; | ||||
|   final TextEditingController _searchController = TextEditingController(); | ||||
| 
 | ||||
|   List<Map<String, dynamic>> stepList = []; | ||||
|   int sindex = 0; | ||||
|   String searchKeywords = ''; | ||||
| 
 | ||||
|   List<Map<String, dynamic>> flowList = []; | ||||
|   final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); | ||||
| 
 | ||||
|   final ScrollController _scrollController = ScrollController(); | ||||
| 
 | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _fetchSteps(); | ||||
|     _fetchData(); | ||||
|     _scrollController.addListener(_onScroll); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   void dispose() { | ||||
|     _scrollController.dispose(); | ||||
|     super.dispose(); | ||||
|   } | ||||
| 
 | ||||
|   void _onScroll() { | ||||
|     if (_scrollController.position.pixels >= | ||||
|             _scrollController.position.maxScrollExtent && | ||||
|         !isLoading) { | ||||
|       if (currentPage < totalPage) { | ||||
|         currentPage++; | ||||
|         _fetchData(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _fetchSteps() async { | ||||
|     try { | ||||
|       final response = await ApiService.dhHotGetTaskSetps(1); | ||||
|       setState(() { | ||||
|         stepList = [ | ||||
|           {'STEP_NAME': '全部', 'STEP_ID': ''}, | ||||
|           ...response['list'] ?? [], | ||||
|         ]; | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching steps: $e'); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Future<void> _fetchData() async { | ||||
|     if (isLoading) return; | ||||
|     setState(() => isLoading = true); | ||||
| 
 | ||||
|     try { | ||||
|       final data = { | ||||
|         'CREATOR': | ||||
|             widget.flow == '提交申请' ? SessionService.instance.loginUserId : '', | ||||
|         'GASCHECK': | ||||
|             widget.flow == '气体检测' ? SessionService.instance.loginUserId : '', | ||||
|         'STEP_NAME': | ||||
|             (widget.flow == '提交申请' || widget.flow == '气体检测') ? '' : widget.flow, | ||||
|         'STEP_ID': sindex > 0 ? stepList[sindex]['STEP_ID'] : '', | ||||
|         'KEYWORDS': searchKeywords, | ||||
|         'WORK_STATE': '0', | ||||
|       }; | ||||
|       final url = '/app/highwork/list?showCount=-1¤tPage=$currentPage'; | ||||
|       final response = await ApiService.hotCheckWorkCount(data, url); | ||||
| 
 | ||||
|       setState(() { | ||||
|         if (currentPage == 1) { | ||||
|           list = response['varList']; | ||||
|         } else { | ||||
|           list.addAll(response['varList']); | ||||
|         } | ||||
|         Map<String, dynamic> page = response['page']; | ||||
|         totalPage = page['totalPage'] ?? 1; | ||||
|         isLoading = false; | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching data: $e'); | ||||
|       setState(() => isLoading = false); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void _search() { | ||||
|     currentPage = 1; | ||||
|     list.clear(); | ||||
|     _fetchData(); | ||||
|   } | ||||
|   /// 申请 | ||||
|   void _handleApply() { | ||||
|     // 处理申请按钮点击逻辑 | ||||
|     pushPage(HotworkApplyDetail(HOTWORK_ID: '', flow: widget.flow), context); | ||||
|   } | ||||
| 
 | ||||
|   /// 打开流程图 | ||||
|   Future<void> _openFlowDrawer(String hotworkId) async { | ||||
|     try { | ||||
|       final response = await ApiService.dhGetFlowList(hotworkId); | ||||
|       final List<dynamic>? newFlow = response['flowList']; | ||||
|       if (newFlow == null || newFlow.isEmpty) { | ||||
|         ToastUtil.showNormal(context, '暂无流程图数据'); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
|       setState(() { | ||||
|         flowList = List<Map<String, dynamic>>.from(newFlow); | ||||
|       }); | ||||
|       Future.microtask(() { | ||||
|         _scaffoldKey.currentState?.openEndDrawer(); | ||||
|       }); | ||||
|     } catch (e) { | ||||
|       print('Error fetching flow data: $e'); | ||||
|       ScaffoldMessenger.of( | ||||
|         context, | ||||
|       ).showSnackBar(SnackBar(content: Text('获取流程图失败: $e'))); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   void _goToDetail(Map<String, dynamic> item) async { | ||||
|     final Map<String, dynamic> data = {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow}; | ||||
|     String routeName = ''; | ||||
|     switch (widget.flow) { | ||||
|       case '提交申请': | ||||
|         //await pushPage(HotworkApplyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '设置安全措施确认人': | ||||
|         //await pushPage(HotworkSetSafeDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '安全措施确认': | ||||
|         //await pushPage(HotworkSafeFuncSure(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '监护人签字': | ||||
|         routeName = '/hotwork-guardian-detail'; | ||||
|         //await pushPage(HotworkJhrDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
|         break; | ||||
|       case '安全交底人签字': | ||||
|         routeName = '/hotwork-confess-detail'; | ||||
|         //await pushPage(HotworkAqjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '接受交底人签字': | ||||
|         routeName = '/hotwork-acceptconfess-detail'; | ||||
|         //await pushPage(HotworkJsjdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '作业负责人签字': | ||||
|         routeName = '/hotwork-confirm-detail'; | ||||
|         //await pushPage(HotworkZyfzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '所在单位签字': | ||||
|         routeName = '/hotwork-leader-detail'; | ||||
|         //await pushPage(HotworkSzdwDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '安全管理部门签字': | ||||
|         routeName = '/hotwork-audit-detail'; | ||||
|         //await pushPage(HotworkAqglDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '审批人签字': | ||||
|         routeName = '/hotwork-approve-detail'; | ||||
|         //await pushPage(HotworkDhspDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '当班班长验票': | ||||
|         routeName = '/hotwork-monitor-detail'; | ||||
|         //await pushPage(HotworkDbbzDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '开始作业': | ||||
|         routeName = '/hotwork-startwork-detail'; | ||||
|         //await pushPage(HotworkKszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '结束作业': | ||||
|         routeName = '/hotwork-endwork-detail'; | ||||
|         //await pushPage(HotworkJszyDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       case '验收签字': | ||||
|         routeName = '/hotwork-accept-detail'; | ||||
|         //await pushPage(HotworkYsgdDetail(HOTWORK_ID: item['HOTWORK_ID'], flow: widget.flow), context); | ||||
| 
 | ||||
|         break; | ||||
|       default: | ||||
|         routeName = '/hotwork-detail'; | ||||
|     } | ||||
|     setState(() { | ||||
|       _fetchSteps(); | ||||
|       _fetchData(); | ||||
|     }); | ||||
|     // Navigator.pushNamed( | ||||
|     //   context, | ||||
|     //   routeName, | ||||
|     //   arguments: {'HOTWORK_ID': item['HOTWORK_ID'], 'flow': widget.flow}, | ||||
|     // ); | ||||
|   } | ||||
| 
 | ||||
|   Widget _buildFlowStepItem({ | ||||
|     required Map<String, dynamic> item, | ||||
|     required bool isFirst, | ||||
|     required bool isLast, | ||||
|     required int status, // 1 = 完成, 0 = 进行中, -1 = 未到达 | ||||
|   }) { | ||||
|     // 依据状态设色 | ||||
|     final Color dotColor = | ||||
|         status == 1 ? Colors.green : (status == 0 ? Colors.blue : Colors.grey); | ||||
|     final Color textColor = | ||||
|         status == 1 | ||||
|             ? Colors.green | ||||
|             : (status == 0 ? Colors.blue : Colors.black); | ||||
| 
 | ||||
|     return ListTile( | ||||
|       visualDensity: VisualDensity(vertical: -4), | ||||
| 
 | ||||
|       contentPadding: const EdgeInsets.symmetric(horizontal: 16), | ||||
|       leading: Container( | ||||
|         width: 24, | ||||
|         alignment: Alignment.center, | ||||
|         child: Column( | ||||
|           mainAxisSize: MainAxisSize.max, | ||||
|           children: [ | ||||
|             // 上方线段或占位 | ||||
|             isFirst | ||||
|                 ? SizedBox(height: 6 + 5) | ||||
|                 : Expanded(child: Container(width: 1, color: Colors.grey[300])), | ||||
|             // 圆点 | ||||
|             CircleAvatar(radius: 6, backgroundColor: dotColor), | ||||
|             // 下方线段或占位 | ||||
|             isLast | ||||
|                 ? SizedBox(height: 6 + 5) | ||||
|                 : Expanded(child: Container(width: 1, color: Colors.grey[300])), | ||||
|           ], | ||||
|         ), | ||||
|       ), | ||||
|       title: Text( | ||||
|         item['STEP_NAME'] ?? '', | ||||
|         style: TextStyle(color: textColor, fontSize: 15), | ||||
|       ), | ||||
|       subtitle: Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         children: [ | ||||
|           if (item['SIGN_USER'] != null) | ||||
|             Text( | ||||
|               item['SIGN_USER'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['FINISHED_SIGN_USER'] != null) | ||||
|             Text( | ||||
|               item['FINISHED_SIGN_USER'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['ACT_USER_NAME'] != null) | ||||
|             Text( | ||||
|               item['ACT_USER_NAME'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|           if (item['ACT_TIME'] != null) | ||||
|             Text( | ||||
|               item['ACT_TIME'], | ||||
|               style: TextStyle(color: textColor, fontSize: 13), | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
|   String _getWorkLevelText(dynamic level) { | ||||
|     switch (level?.toString()) { | ||||
|       case '1': | ||||
|         return 'I级高处作业'; | ||||
|       case '2': | ||||
|         return 'II级高处作业'; | ||||
|       case '3': | ||||
|         return 'III级高处作业'; | ||||
|       default: | ||||
|         return 'IV级高处作业'; | ||||
|     } | ||||
|   } | ||||
|   Widget _buildListItem(Map<String, dynamic> item) { | ||||
|     return Card( | ||||
|       color: Colors.white, | ||||
|       margin: const EdgeInsets.all(8.0), | ||||
|       child: InkWell( | ||||
|         onTap: () => _goToDetail(item), | ||||
|         child: Padding( | ||||
|           padding: const EdgeInsets.all(12.0), | ||||
|           child: Column( | ||||
|             crossAxisAlignment: CrossAxisAlignment.start, | ||||
|             children: [ | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("编号: ${item['CHECK_NO'] ?? ''}", style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),), | ||||
|                   Text( | ||||
|                     "作业级别: ${_getWorkLevelText(item['WORK_LEVEL'])}", | ||||
|                     style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("申请人: ${item['APPLY_USER_NAME'] ?? ''}"), | ||||
|                   Text("监护人: ${item['GUARDIAN_USER_NAME'] ?? ''}"), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Text("安全交底人: ${item['CONFESS_USER_NAME'] ?? ''}"), | ||||
|                   Text("接受交底人: ${item['ACCEPT_CONFESS_USER_NAME'] ?? ''}"), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"), | ||||
|                     Text("所在单位负责人: ${item['LEADER_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("作业负责人: ${item['CONFIRM_USER_NAME'] ?? ''}"), | ||||
|                     Text("动火点负责人: ${item['LEADER_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|               if (item['AUDIT_USER_NAME'] != null) | ||||
|                 Text("安全管理部门负责人: ${item['AUDIT_USER_NAME'] ?? ''}"), | ||||
|               const SizedBox(height: 8), | ||||
|                 Row( | ||||
|                   mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                   children: [ | ||||
|                     Text("动火前在岗班长: ${item['MONITOR_USER_NAME'] ?? ''}"), | ||||
|                     Text("验收部门负责人: ${item['ACCEPT_USER_NAME'] ?? ''}"), | ||||
|                   ], | ||||
|                 ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row( | ||||
|                 mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                 children: [ | ||||
|                   Expanded( | ||||
|                     child: Text( | ||||
|                       "审核状态: ${_getStatusText(item)}", | ||||
|                       overflow: TextOverflow.ellipsis, | ||||
|                     ), | ||||
|                   ), | ||||
|                 ], | ||||
|               ), | ||||
|               const SizedBox(height: 8), | ||||
|               Row(children: [ | ||||
|                 CustomButton( | ||||
|                   text: '查看流程图', | ||||
|                   height: 35, | ||||
|                   padding: EdgeInsets.symmetric(horizontal: 12), | ||||
|                   margin: EdgeInsets.only(left: 0), | ||||
|                   backgroundColor: Colors.blue, | ||||
|                   onPressed: () => _openFlowDrawer(item['HOTWORK_ID']), | ||||
|                 ), | ||||
|                 SizedBox(width: 1,) | ||||
|               ],) | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| 
 | ||||
|   String _getStatusText(Map<String, dynamic> item) { | ||||
|     // 安全取出 STEP_ID 和 STATUS | ||||
|     final int stepId = (item['STEP_ID'] is int) ? item['STEP_ID'] as int : 0; | ||||
|     final int status = (item['STATUS'] is int) ? item['STATUS'] as int : 0; | ||||
| 
 | ||||
|     if (stepId == 0) { | ||||
|       return '暂存'; | ||||
|     } else if (status == -2) { | ||||
|       return '气体检测打回'; | ||||
|     } else if (stepId != -1) { | ||||
|       return item['NEXT_STEP_NAME'] ?? ''; | ||||
|     } else { | ||||
|       return '${item['STEP_NAME'] ?? ''}打回'; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // 显示底部选择器 | ||||
|   Future<void> _showStepPicker() async { | ||||
|     if (stepList.isEmpty) { | ||||
|       ScaffoldMessenger.of( | ||||
|         context, | ||||
|       ).showSnackBar(SnackBar(content: Text('正在加载步骤数据,请稍后...'))); | ||||
|       await _fetchSteps(); | ||||
|       if (stepList.isEmpty) { | ||||
|         ScaffoldMessenger.of( | ||||
|           context, | ||||
|         ).showSnackBar(SnackBar(content: Text('无法加载步骤数据'))); | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
| 
 | ||||
|     // 创建选项列表 | ||||
|     final options = stepList.map((e) => e['STEP_NAME'] as String).toList(); | ||||
| 
 | ||||
|     // 显示底部选择器 | ||||
|     final choice = await BottomPicker.show<String>( | ||||
|       context, | ||||
|       items: options, | ||||
|       itemBuilder: (item) => Text(item, textAlign: TextAlign.center), | ||||
|       initialIndex: sindex, | ||||
|     ); | ||||
| 
 | ||||
|     if (choice != null) { | ||||
|       // 找到选择的索引 | ||||
|       final newIndex = options.indexOf(choice); | ||||
|       if (newIndex != -1) { | ||||
|         setState(() { | ||||
|           sindex = newIndex; | ||||
|         }); | ||||
|         _search(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   Widget _buildListContent() { | ||||
|     if (isLoading && list.isEmpty) { | ||||
|       // 初始加载时显示居中的加载指示器 | ||||
|       return Center(child: CircularProgressIndicator()); | ||||
|     } else if (list.isEmpty) { | ||||
|       // 没有数据 | ||||
|       return NoDataWidget.show(); | ||||
|     } else { | ||||
|       // 有数据或加载更多 | ||||
|       return ListView.builder( | ||||
|         padding: EdgeInsets.zero, | ||||
| 
 | ||||
|         controller: _scrollController, | ||||
|         itemCount: list.length + (isLoading ? 1 : 0), | ||||
|         itemBuilder: (context, index) { | ||||
|           if (index >= list.length) { | ||||
|             // 加载更多时在列表底部显示加载指示器 | ||||
|             return Padding( | ||||
|               padding: const EdgeInsets.symmetric(vertical: 16.0), | ||||
|               child: Center(child: CircularProgressIndicator()), | ||||
|             ); | ||||
|           } | ||||
|           return _buildListItem(list[index]); | ||||
|         }, | ||||
|       ); | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     final int lastDoneIndex = flowList.lastIndexWhere((e) => e['STATUS'] == 1); | ||||
| 
 | ||||
|     return Scaffold( | ||||
|       key: _scaffoldKey, | ||||
|       appBar: MyAppbar( | ||||
|         title: '${widget.workTypeTitle}${widget.flow}', | ||||
|         actions: [ | ||||
|           if (widget.flow == '提交申请') | ||||
|             TextButton( | ||||
|               onPressed: _handleApply, | ||||
|               child: const Text( | ||||
|                 '申请', | ||||
|                 style: TextStyle(color: Colors.white, fontSize: 17), | ||||
|               ), | ||||
|             ), | ||||
|         ], | ||||
|       ), | ||||
|       endDrawer: Drawer( | ||||
|         child: SafeArea( | ||||
|           child: | ||||
|               flowList.isEmpty | ||||
|                   ? Center(child: Text('暂无流程图数据')) | ||||
|                   : ListView.builder( | ||||
|                     padding: const EdgeInsets.symmetric(vertical: 16), | ||||
|                     itemCount: flowList.length + 1, // +1 用来放标题 | ||||
|                     itemBuilder: (context, i) { | ||||
|                       if (i == 0) { | ||||
|                         return Padding( | ||||
|                           padding: const EdgeInsets.symmetric( | ||||
|                             horizontal: 16, | ||||
|                             vertical: 8, | ||||
|                           ), | ||||
|                           child: Text( | ||||
|                             '查看流程图', | ||||
|                             style: TextStyle( | ||||
|                               fontSize: 18, | ||||
|                               fontWeight: FontWeight.bold, | ||||
|                             ), | ||||
|                           ), | ||||
|                         ); | ||||
|                       } | ||||
|                       final idx = i - 1; | ||||
|                       final item = flowList[idx]; | ||||
|                       final bool isFirst = idx == 0; | ||||
|                       final bool isLast = idx == flowList.length - 1; | ||||
| 
 | ||||
|                       // 根据 lastDoneIndex 自动计算“进行中” | ||||
|                       final int status; | ||||
|                       if (idx <= lastDoneIndex) { | ||||
|                         status = 1; // 已完成 | ||||
|                       } else if (idx == lastDoneIndex + 1) { | ||||
|                         status = 0; // 进行中 | ||||
|                       } else { | ||||
|                         status = -1; // 未到达 | ||||
|                       } | ||||
| 
 | ||||
|                       return _buildFlowStepItem( | ||||
|                         item: item, | ||||
|                         isFirst: isFirst, | ||||
|                         isLast: isLast, | ||||
|                         status: status, | ||||
|                       ); | ||||
|                     }, | ||||
|                   ), | ||||
|         ), | ||||
|       ), | ||||
| 
 | ||||
|       body: Column( | ||||
|         children: [ | ||||
|           // Filter bar | ||||
|           Container( | ||||
|             color: Colors.white, | ||||
|             padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 8), | ||||
|             child: Row( | ||||
|               children: [ | ||||
|                 // 底部弹窗选择器 | ||||
|                 SizedBox( | ||||
|                   width: 65, | ||||
|                   child: TextButton( | ||||
|                     onPressed: _showStepPicker, | ||||
|                     style: TextButton.styleFrom( | ||||
|                       padding: EdgeInsets.symmetric( | ||||
|                         vertical: 12, | ||||
|                         horizontal: 5, | ||||
|                       ), | ||||
|                     ), | ||||
|                     child: Row( | ||||
|                       mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
|                       children: [ | ||||
|                         Text( | ||||
|                           '筛选', | ||||
|                           style: TextStyle(color: Colors.black87, fontSize: 16), | ||||
|                         ), | ||||
|                         Icon(Icons.arrow_drop_down, color: Colors.grey), | ||||
|                       ], | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|                 Expanded( | ||||
|                   flex: 2, | ||||
|                   child: SearchBarWidget( | ||||
|                     showResetButton: false, | ||||
|                     hintText: "请输入关键字", | ||||
|                     // isClickableOnly: true, | ||||
|                     onSearch: (text) { | ||||
|                       _search(); | ||||
|                     }, | ||||
|                     controller: _searchController, | ||||
|                   ), | ||||
|                 ), | ||||
|               ], | ||||
|             ), | ||||
|           ), | ||||
|           const Divider(height: 1), | ||||
|           // List | ||||
|           Expanded(child: _buildListContent()), | ||||
|         ], | ||||
|       ), | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/work_tab_icon_grid.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/work_tab_icon_grid.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/work_tab_icon_grid.dart'; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,8 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/gc_work/highwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| 
 | ||||
|  | @ -124,7 +125,7 @@ class _WorkTabGcListState extends State<WorkTabGcList> { | |||
|       default: | ||||
|         print("按钮 $index 被点击"); | ||||
|     } | ||||
|     pushPage(HotWorkListPage(flow: title, workTypeTitle: '高处作业',), context); | ||||
|     pushPage(HighworkListPage(flow: title, workTypeTitle: '高处作业',), context); | ||||
|   } | ||||
| 
 | ||||
|   @override | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import 'package:flutter/material.dart'; | ||||
| import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; | ||||
| import 'package:qhd_prevention/http/ApiService.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hot_work_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/home/tap/tabList/special_wrok/dh_work/hotwork_list_page.dart'; | ||||
| import 'package:qhd_prevention/pages/my_appbar.dart'; | ||||
| import 'package:qhd_prevention/tools/tools.dart'; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue