flutter_integrated_whb/lib/pages/home/risk/risk_detail_page.dart

426 lines
12 KiB
Dart

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<RiskDetailPage> createState() => _RiskDetailPageState();
}
class _RiskDetailPageState extends State<RiskDetailPage> {
late List<dynamic> _list = [];
// 风险等级文本
final List<String> _levelTexts = ["重大风险", "较大风险", "一般风险", "低风险"];
// 风险等级颜色
final List<Color> _fxColors = [
const Color(0xFFFADBD9),
const Color(0xFFFCE6D2),
const Color(0xFFFDF2CE),
const Color(0xFFCCE6FF),
];
@override
void initState() {
// TODO: implement initState
super.initState();
_getForIdentification();
}
Future<void> _getForIdentification() async {
try {
final result = await ApiService.getForIdentification( widget.itemData["IDENTIFICATIONPARTS_ID"]);
if (result['result'] == 'success') {
final List<dynamic> newList = result['varList'] ?? [];
setState(() {
_list.addAll(newList);
});
}else{
_showMessage('加载数据失败');
}
} catch (e) {
// 出错时可以 Toast 或者在页面上显示错误状态
print('加载数据失败:$e');
}
}
Future<void> _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<String>;
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<Position> _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)));
}
}