344 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Dart
		
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Dart
		
	
	
| import 'package:flutter/material.dart';
 | |
| import 'package:qhd_prevention/customWidget/custom_button.dart';
 | |
| import 'package:qhd_prevention/customWidget/toast_util.dart';
 | |
| import 'package:qhd_prevention/pages/home/work/custom_driver_drawer.dart';
 | |
| import 'package:qhd_prevention/pages/home/risk/risk_detail_page.dart';
 | |
| import 'package:qhd_prevention/pages/my_appbar.dart';
 | |
| import 'package:qhd_prevention/tools/tools.dart';
 | |
| import '../../../http/ApiService.dart';
 | |
| import '../../../tools/h_colors.dart';
 | |
| import '/customWidget/search_bar_widget.dart';
 | |
| 
 | |
| class RiskControlPage extends StatefulWidget {
 | |
|   const RiskControlPage({super.key});
 | |
| 
 | |
|   @override
 | |
|   State<RiskControlPage> createState() => _RiskControlPageState();
 | |
| }
 | |
| 
 | |
| class _RiskControlPageState extends State<RiskControlPage> {
 | |
| 
 | |
|   int _page = 1;
 | |
|   String searchKey="";
 | |
|   int _totalPage=1;
 | |
|   late List<dynamic> _list = [];
 | |
|   bool _isLoading = false;
 | |
|   bool _hasMore = true;
 | |
| 
 | |
|   String treeJson="";
 | |
| 
 | |
| 
 | |
| 
 | |
|   // 风险等级颜色
 | |
|   final List<Color> _fxColors = [
 | |
|     const Color(0xFFFADBD9),
 | |
|     const Color(0xFFFCE6D2),
 | |
|     const Color(0xFFFDF2CE),
 | |
|     const Color(0xFFCCE6FF),
 | |
|   ];
 | |
|   final TextEditingController _searchController = TextEditingController();
 | |
| 
 | |
|   // 风险等级文本
 | |
|   final List<String> _levelTexts = ["重大风险/A级", "较大风险/B级", "一般风险/C级", "低风险/D级"];
 | |
| 
 | |
| 
 | |
|   @override
 | |
|   void initState() {
 | |
|     super.initState();
 | |
| 
 | |
|     getListData(false,"");
 | |
|     _getListTree();
 | |
|     SessionService.instance.setRiskWaitInfo("");
 | |
| 
 | |
|   }
 | |
| 
 | |
| 
 | |
|   @override
 | |
|   Widget build(BuildContext context) {
 | |
|     // 取屏幕宽度
 | |
|     final double screenWidth = MediaQuery.of(context).size.width;
 | |
| 
 | |
|     return Scaffold(
 | |
|       appBar: MyAppbar(
 | |
|         title: "风险分布",
 | |
|         actions: [
 | |
|           // 用 Builder 拿到 Scaffold 之下的 context
 | |
|           Builder(
 | |
|             builder: (innerContext) {
 | |
|               return TextButton(
 | |
|                 onPressed: () {
 | |
|                   // 通过 innerContext 调用 openEndDrawer
 | |
|                   Scaffold.of(innerContext).openEndDrawer();
 | |
|                 },
 | |
|                 child: Text(
 | |
|                   "查询",
 | |
|                   style: TextStyle(color: Colors.white, fontSize: 16),
 | |
|                 ),
 | |
|               );
 | |
|             },
 | |
|           ),
 | |
|         ],
 | |
|       ),
 | |
| 
 | |
|       //弹窗
 | |
|       endDrawer: Drawer(
 | |
|         // 用 Container 限制宽度为屏幕的 3/5
 | |
|         child: Container(
 | |
|           width: screenWidth * 3 / 5,
 | |
|           color: Colors.white,
 | |
|           child:  CustomDriverDrawer(
 | |
|             treeJson,
 | |
|             onClose: (String riskId,String dept,String level) {
 | |
| 
 | |
|               // _getDangerRecord(-1,_page,startDate,endDate,hazardLevelOption,investigationMethodOption,
 | |
|               //     dangerStatusOption,selectedCategoryId,selectedDepartmentId,"",searchKey,false);
 | |
|               _page=1;
 | |
|               _getRiskRecord(_page,riskId,dept,level,searchKey,false);
 | |
| 
 | |
|             },
 | |
|           ),
 | |
|         ),
 | |
|       ),
 | |
| 
 | |
| 
 | |
|       body: SafeArea(
 | |
|           child: NotificationListener<ScrollNotification>(
 | |
|               onNotification: _onScroll,
 | |
|               child:_vcDetailWidget()
 | |
|           )
 | |
|       ),
 | |
|       backgroundColor: Colors.white,
 | |
|     );
 | |
|   }
 | |
| 
 | |
|   Widget _vcDetailWidget() {
 | |
|     return Column(
 | |
|       children: [
 | |
|         Padding(
 | |
|           padding: EdgeInsets.all(10),
 | |
|           child: SearchBarWidget(
 | |
|             controller: _searchController,
 | |
|             onSearch: (keyboard) {
 | |
|               // 输入请求接口
 | |
|               _page=1;
 | |
|               searchKey=keyboard;
 | |
|               getListData(false,keyboard);
 | |
|             },
 | |
|           ),
 | |
|         ),
 | |
|         Container(
 | |
|           height: 5,
 | |
|           color: h_backGroundColor(),
 | |
|         ),
 | |
|         Expanded(
 | |
|           child:  _list.isEmpty
 | |
|               ? NoDataWidget.show()
 | |
|               : ListView.separated(
 | |
|             separatorBuilder: (_, __) => const Divider(height: 1),
 | |
|             itemCount: _list.length,
 | |
|             itemBuilder: (context, index) {
 | |
|               final item = _list[index];
 | |
|               return _fxitemCell(item);
 | |
|             },
 | |
|           ),
 | |
|         ),
 | |
|       ],
 | |
|     );
 | |
|   }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|   Widget _fxitemCell(final item) {
 | |
|     int level;
 | |
|     // 确保level在有效范围内 (1-4)
 | |
|     // level = level.clamp(1, 4) - 1;
 | |
|     if(item['LEVELID']=="levelA"){
 | |
|       level=0;
 | |
|     }else if(item['LEVELID']=="levelB"){
 | |
|       level=1;
 | |
|     }else if(item['LEVELID']=="levelC"){
 | |
|       level=2;
 | |
|     }else {
 | |
|       level=3;
 | |
|     }
 | |
| 
 | |
|     // 使用GestureDetector包裹整个列表项以添加点击事件
 | |
|     return GestureDetector(
 | |
|       onTap: () {
 | |
|         // 点击后跳转到详情页面
 | |
|         Navigator.push(
 | |
|           context,
 | |
|           MaterialPageRoute(
 | |
|             builder: (context) => RiskDetailPage(itemData: item),
 | |
|           ),
 | |
|         );
 | |
|       },
 | |
|       child: Container(
 | |
| 
 | |
|         color: Colors.white,
 | |
|         padding: EdgeInsets.symmetric(horizontal: 16), // 添加水平内边距
 | |
|         child: Row(
 | |
|           mainAxisAlignment: MainAxisAlignment.spaceBetween,
 | |
|           children: [
 | |
|             // 左侧信息列
 | |
|             Expanded(
 | |
|               child: Column(
 | |
|                 mainAxisAlignment: MainAxisAlignment.center,
 | |
|                 crossAxisAlignment: CrossAxisAlignment.start,
 | |
|                 children: [
 | |
|                   Text(
 | |
|                     '部位名称:${item['PARTSNAME'] ?? ''}',
 | |
|                     style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
 | |
|                     maxLines: 1,
 | |
|                     overflow: TextOverflow.ellipsis,
 | |
|                   ),
 | |
|                   SizedBox(height: 8),
 | |
|                   Text(
 | |
|                     '风险点(单元):${item['RISKUNITNAME'] ?? ''}',
 | |
|                     style: TextStyle(fontSize: 14, color: Colors.grey),
 | |
|                     maxLines: 2,
 | |
|                     overflow: TextOverflow.ellipsis,
 | |
|                   ),
 | |
|                   SizedBox(height: 4),
 | |
|                   Text(
 | |
|                     '管控部门:${item['DEPT_NAME'] ?? ''}',
 | |
|                     style: TextStyle(fontSize: 14, color: Colors.grey),
 | |
|                   ),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
| 
 | |
|             // 右侧风险等级和箭头
 | |
|             Padding(
 | |
|               padding: EdgeInsets.only(top: 5,bottom: 5),
 | |
|               child: Row(
 | |
|                 mainAxisAlignment: MainAxisAlignment.center,
 | |
|                 crossAxisAlignment: CrossAxisAlignment.center,
 | |
|                 children: [
 | |
|                   // 风险等级标签
 | |
|                   Row(
 | |
|                     children: [
 | |
|                       Container(
 | |
|                         padding: EdgeInsets.symmetric(
 | |
|                           horizontal: 8,
 | |
|                           vertical: 4,
 | |
|                         ),
 | |
|                         decoration: BoxDecoration(
 | |
|                           color: _fxColors[level],
 | |
|                           borderRadius: BorderRadius.circular(2),
 | |
|                         ),
 | |
|                         child: Text(
 | |
|                           _levelTexts[level],
 | |
|                           style: TextStyle(fontSize: 12),
 | |
|                         ),
 | |
|                       ),
 | |
|                       SizedBox(width: 30),
 | |
|                     ],
 | |
|                   ),
 | |
|                   SizedBox(height: 12), // 添加间距
 | |
|                   Row(
 | |
|                     children: [
 | |
| 
 | |
|                       Icon(Icons.arrow_forward_ios_rounded, size: 16),
 | |
|                     ],
 | |
|                   ),
 | |
|                 ],
 | |
|               ),
 | |
|             ),
 | |
|           ],
 | |
|         ),
 | |
|       ),
 | |
|     );
 | |
|   }
 | |
| 
 | |
| 
 | |
|   void getListData(bool addList,String keyWord){
 | |
|         _getRiskRecord(_page,"","","",keyWord,addList);
 | |
| 
 | |
|   }
 | |
| 
 | |
|   Future<void> _getRiskRecord(int currentPage,
 | |
|       String riskId,String dept,String level,String keyWord,bool loadMore) async {
 | |
|     try {
 | |
|       if (_isLoading) return;
 | |
|       _isLoading = true;
 | |
| 
 | |
|       LoadingDialogHelper.show();
 | |
|       final result = await ApiService.getRiskRecordList(  currentPage,
 | |
|            riskId, dept, level, keyWord);
 | |
|       LoadingDialogHelper.hide();
 | |
|       if (result['result'] == 'success') {
 | |
| 
 | |
|         _totalPage =result["page"]['totalPage'] ?? 1;
 | |
|         final List<dynamic> newList = result['varList'] ?? [];
 | |
|         // setState(() {
 | |
|         //   _list.addAll(newList);
 | |
|         // });
 | |
| 
 | |
|         setState(() {
 | |
|           if (loadMore) {
 | |
|             _list.addAll(newList);
 | |
|           } else {
 | |
|             _list = newList;
 | |
|           }
 | |
|           _hasMore = _page < _totalPage;
 | |
|           // if (_hasMore) _page++;
 | |
|         });
 | |
| 
 | |
|       }else{
 | |
|         ToastUtil.showNormal(context, "加载数据失败");
 | |
|         // _showMessage('加载数据失败');
 | |
|       }
 | |
| 
 | |
|     } catch (e) {
 | |
|       LoadingDialogHelper.hide();
 | |
|       // 出错时可以 Toast 或者在页面上显示错误状态
 | |
|       print('加载数据失败:$e');
 | |
|     } finally {
 | |
|       // if (!loadMore) LoadingDialogHelper.hide();
 | |
|       _isLoading = false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   bool _onScroll(ScrollNotification n) {
 | |
|     if (n.metrics.pixels > n.metrics.maxScrollExtent - 100 &&
 | |
|         _hasMore && !_isLoading) {
 | |
| 
 | |
|       _page++;
 | |
|       getListData(true,"");
 | |
| 
 | |
|     }
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
| 
 | |
|   Future<void> _getListTree() async {
 | |
|     try {
 | |
| 
 | |
|       final result = await ApiService.getHiddenTreatmentListTree();
 | |
|       if (result['result'] == 'success') {
 | |
|         setState(() {
 | |
|           treeJson= result['zTreeNodes'];
 | |
|         });
 | |
| 
 | |
|       }else{
 | |
|         ToastUtil.showNormal(context, "加载数据失败");
 | |
|         // _showMessage('加载数据失败');
 | |
|       }
 | |
|     } catch (e) {
 | |
|       // 出错时可以 Toast 或者在页面上显示错误状态
 | |
|       print('加载数据失败:$e');
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void _showMessage(String msg) {
 | |
|     ToastUtil.showNormal(context, msg);
 | |
|   }
 | |
| 
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 |