import 'package:flutter/material.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'package:geolocator/geolocator.dart'; import '../../../http/ApiService.dart'; import '../../../tools/h_colors.dart'; class RiskDetailPage extends StatefulWidget { const RiskDetailPage({super.key, required this.itemData}); final dynamic itemData; @override State createState() => _RiskDetailPageState(); } class _RiskDetailPageState extends State { late List _list = []; // 风险等级文本 final List _levelTexts = ["重大风险", "较大风险", "一般风险", "低风险"]; // 风险等级颜色 final List _fxColors = [ const Color(0xFFFADBD9), const Color(0xFFFCE6D2), const Color(0xFFFDF2CE), const Color(0xFFCCE6FF), ]; @override void initState() { // TODO: implement initState super.initState(); _getForIdentification(); } Future _getForIdentification() async { try { final result = await ApiService.getForIdentification( widget.itemData["IDENTIFICATIONPARTS_ID"]); if (result['result'] == 'success') { final List newList = result['varList'] ?? []; setState(() { _list.addAll(newList); }); }else{ _showMessage('加载数据失败'); } } catch (e) { // 出错时可以 Toast 或者在页面上显示错误状态 print('加载数据失败:$e'); } } Future _addCoordinate() async { try { Position position = await _determinePosition(); final result = await ApiService.addCoordinate( widget.itemData["IDENTIFICATIONPARTS_ID"], position.longitude.toString(),position.latitude.toString()); if (result['result'] == 'success') { setState(() { _showMessage('提交成功'); Navigator.pop(context); }); }else{ _showMessage('加载数据失败'); } } catch (e) { // 出错时可以 Toast 或者在页面上显示错误状态 print('加载数据失败:$e'); } } @override @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: "风险分布-详情"), body: SafeArea( child: LayoutBuilder( builder: (context, constraints) { // 设置底部最小高度,要预留出来 const double bottomAreaHeight = 100; final double maxCardHeight = constraints.maxHeight - bottomAreaHeight; return Column( children: [ // 卡片区:最大高度受限 Padding( padding: const EdgeInsets.all(15), child: ConstrainedBox( constraints: BoxConstraints(maxHeight: maxCardHeight), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), boxShadow: [/* ... */], ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildHeader(), const Divider( height: .5, thickness: .5, color: Colors.grey, ), // ★ 这个 Flexible 包裹 SingleChildScrollView ★ Flexible( fit: FlexFit.loose, child: SingleChildScrollView( padding: const EdgeInsets.symmetric(vertical: 10), physics: const ClampingScrollPhysics(), child: Column( mainAxisSize: MainAxisSize.min, children: [ _itemCell("存在风险",0), _itemCell("主要管控措施",1), _itemCell("管控部门",2), _itemCell("事故类型",3), const Divider( height: .5, thickness: .5, color: Colors.grey, ), _buildFooter(), ], // children: _dataInfos.map(_itemCell).toList(), ), ), ), ], ), ), ), ), Spacer(), // 底部按钮固定 _buildBottomButton(), SizedBox(height: 10,) ], ); }, ), ), ); } // 头部信息组件 Widget _buildHeader() { return Padding( padding: const EdgeInsets.all(15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( widget.itemData['RISKUNITNAME']?? "", style: TextStyle(fontSize: 16, color: Colors.black54), ), Text( widget.itemData['PARTSNAME'] ?? "未知地区", style: const TextStyle(fontSize: 16, color: Colors.black54), ), ], ), ); } // 风险等级标签 Widget _buildFooter() { return Padding( padding: const EdgeInsets.all(15), child: Row( children: [ Container( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(5), decoration: BoxDecoration( color: _getLevelColor(), borderRadius: BorderRadius.circular(2), ), child: Text( _getLevel(), style: TextStyle(color: Colors.black), ), ), const Spacer(), ], ), ); } String _getLevel(){ int level; // 确保level在有效范围内 (1-4) // level = level.clamp(1, 4) - 1; if(widget.itemData['LEVELID']=="levelA"){ level=0; }else if(widget.itemData['LEVELID']=="levelB"){ level=1; }else if(widget.itemData['LEVELID']=="levelC"){ level=2; }else { level=3; } return _levelTexts[level]; } Color _getLevelColor(){ int level; // 确保level在有效范围内 (1-4) // level = level.clamp(1, 4) - 1; if(widget.itemData['LEVELID']=="levelA"){ level=0; }else if(widget.itemData['LEVELID']=="levelB"){ level=1; }else if(widget.itemData['LEVELID']=="levelC"){ level=2; }else { level=3; } return _fxColors[level]; } // 底部按钮 Widget _buildBottomButton() { return Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), child: SizedBox( width: double.infinity, height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 3, ), onPressed: () { // 按钮点击事件 _addCoordinate(); }, child: const Text( "提交位置", style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), ), ), ); } // 多项项信息组件 Widget _itemCell(String title,int type) { // final details = item["detail"] as List; return Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // 标题行 Row( children: [ Container( width: 4, height: 16, decoration: BoxDecoration( color: Colors.black38, borderRadius: BorderRadius.circular(2), ), ), const SizedBox(width: 5), Text( title, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black87, ), ), ], ), const SizedBox(height: 10), // // 内容区域 // ...details.map((text) => _textItem(text, false)).toList(), if(0==type||1==type) Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ for(int i = 0; i < _list.length; i++) _getWitchItem(type, i), ],) else _getWitchItemTwo(type, type), ], ), ); } Widget _getWitchItem(int type,int position) { String text=""; switch(type){ case 0: text= "$position.${_list[position]["RISK_DESCR"]}"; break; case 1: text= "$position.${_list[position]["MEASURES"]}"; break; // case 2: // text= _list[position]["RISK_DESCR"]; // break; // case 3: // text= _list[position]["RISK_DESCR"]; // break; } return _textItem(text,false); } Widget _getWitchItemTwo(int type,int position) { String text=""; switch(type){ // case 0: // text= _list[position]["RISK_DESCR"]; // break; // case 1: // text= _list[position]["MEASURES"]; // break; case 2: text= widget.itemData["DEPT_NAME"]; break; case 3: for(int i=0;i<_list.length;i++){ if(text.isEmpty){ text=_list[i]["ACCIDENTS_NAME"]; }else{ text="$text,${_list[i]["ACCIDENTS_NAME"]}"; } } break; } return _textItem(text,false); } // 文本项组件 Widget _textItem(String text, bool isInfinity) { return Container( width: isInfinity ? double.infinity : null, margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: h_backGroundColor(), borderRadius: BorderRadius.circular(6), ), child: Text( text, style: const TextStyle( fontSize: 14, color: Colors.black87, height: 1.5, ), ), ); } Future _determinePosition() async { bool serviceEnabled; LocationPermission permission; // 检查定位服务是否启用 serviceEnabled = await Geolocator.isLocationServiceEnabled(); if (!serviceEnabled) { return Future.error('Location services are disabled.'); } // 获取权限 permission = await Geolocator.checkPermission(); if (permission == LocationPermission.denied) { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) { return Future.error('Location permissions are denied'); } } if (permission == LocationPermission.deniedForever) { return Future.error( 'Location permissions are permanently denied, we cannot request permissions.'); } // 获取当前位置 return await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high); } void _showMessage(String msg) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(msg))); } }