import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/customWidget/ItemWidgetFactory.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/date_picker_dialog.dart'; import 'package:qhd_prevention/customWidget/bottom_picker_two.dart'; import 'package:qhd_prevention/customWidget/department_person_picker.dart'; import 'package:qhd_prevention/customWidget/department_picker_hidden_type.dart'; import 'package:qhd_prevention/customWidget/department_picker_two.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/pages/http/ApiService.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/tools/tools.dart'; import '../../../customWidget/photo_picker_row.dart'; class QuickReportPage extends StatefulWidget { const QuickReportPage({super.key}); @override State createState() => _QuickReportPageState(); } class _QuickReportPageState extends State { final _standardController = TextEditingController(); final _partController = TextEditingController(); final _dangerDetailController = TextEditingController(); String _repairLevelName = ""; late bool _isDanger = false; late bool _canClick = true; late List _hazardLeveLlist = []; //隐患级别 // 存储各单位的人员列表 List> _personCache = []; List _yinHuanImages = []; String _yinHuanVido=""; dynamic _hazardLeve; String yinHuanId = ""; String yinHuanName = ""; String buMenId = ""; String buMenPDId = ""; String buMenName = ""; String responsibleId=""; String responsibleName=""; String dataTime = ""; List _zhengGaiImages = []; List _yinHuanTypeIds = []; List _yinHuanTypeNames = []; @override void initState() { // TODO: implement initState super.initState(); _getHazardLevel(); } Future _getHazardLevel() async { try { final result = await ApiService.getHazardLevel(); if (result['result'] == 'success') { final List newList = result['list'] ?? []; setState(() { _hazardLeveLlist.addAll(newList); }); } } catch (e) { print('Error fetching data: $e'); } } @override void dispose() { _standardController.dispose(); _partController.dispose(); _dangerDetailController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: "隐患随手拍"), body: Column( children: [ // 详情滚动区域 _pageDetail(), // 底部警示文字,固定在页面底部 // Container( // padding: const EdgeInsets.all(15), // color: Colors.white, // child: Text( // ' 严禁在本互联网非涉密平台处理、传输国家秘密和工作秘密,请确认扫描、传输的文件资料不涉及国家秘密和工作秘密', // style: TextStyle(fontSize: 14, color: Colors.red), // ), // ), ], ), ); } Widget _buildSectionContainer({required Widget child}) { return Container( margin: const EdgeInsets.only(top: 10), color: Colors.white, padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10), child: child, ); } Widget _pageDetail() { return Expanded( child: SingleChildScrollView( padding: const EdgeInsets.only(bottom: 20), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ _buildSectionContainer( child: RepairedPhotoSection( title: "隐患照片", maxCount: 4, mediaType: MediaType.image, isShowAI: true, onChanged: (List files) { // 上传图片 files _yinHuanImages.clear(); for(int i=0;i1){ ToastUtil.showNormal(context, "识别暂时只能上传一张图片"); return; } _identifyImg(_yinHuanImages[0]); }, ), ), _buildSectionContainer( child: RepairedPhotoSection( title: "隐患视频", maxCount: 1, mediaType: MediaType.video, onChanged: (List files) { // 上传视频 files _yinHuanVido=files[0].path; }, onAiIdentify: () { // AI 视频识别逻辑 }, ), ), _buildSectionContainer( child: ListItemFactory.createBuildMultilineInput( "隐患描述", "请对隐患进行详细描述(必填项)", _standardController, ), ), _buildSectionContainer( child: ListItemFactory.createBuildMultilineInput( "隐患部位", "请对隐患部位进行详细描述(必填项)", _partController, ), ), GestureDetector( onTap: () async { String choice = await BottomPickerTwo.show( context, items: _hazardLeveLlist, itemBuilder: (item) => Text(item["NAME"], textAlign: TextAlign.center), initialIndex: 0, ); if (choice != null) { for(int i=0;i<_hazardLeveLlist.length;i++){ if(choice==_hazardLeveLlist[i]["NAME"]){ _hazardLeve = _hazardLeveLlist[i]; } } setState(() { _repairLevelName=_hazardLeve["NAME"]; if("5ff9daf78e9a4fb1b40d77980656799d"==_hazardLeve["DICTIONARIES_ID"]){ _isDanger=false; _canClick=false; }else{ _canClick=true; } }); } }, child: _buildSectionContainer( child: ListItemFactory.createRowSpaceBetweenItem( leftText: "隐患级别", rightText: _repairLevelName.isNotEmpty?_repairLevelName:"请选择", isRight: true, ), ), ), GestureDetector( onTap: () { showModalBottomSheet( context: context, isScrollControlled: true, barrierColor: Colors.black54, backgroundColor: Colors.transparent, builder: (ctx) => DepartmentPickerHiddenType( onSelected: (jsonString) { Map> result = jsonString; _yinHuanTypeIds = List.from(result['id']!); _yinHuanTypeNames = List.from(result['name']!); setState(() { yinHuanName=_yinHuanTypeNames[_yinHuanTypeNames.length-1]; }); // print(jsonEncode(json)); // List _yinHuanTypeIds = []; // List _yinHuanTypeNames = []; }, ), ); }, child: _buildSectionContainer( child: ListItemFactory.createRowSpaceBetweenItem( leftText: "隐患类型", rightText: yinHuanName.isNotEmpty?yinHuanName:"请选择", isRight: true, ), ), ), _buildSectionContainer( child: ListItemFactory.createYesNoSectionTwo( title: "是否立即整改", horizontalPadding: 0, verticalPadding: 0, yesLabel: "是", noLabel: "否", groupValue: _isDanger, canClick: _canClick, context:context, onChanged: (val) { setState(() { _isDanger = val; }); }, ), ), if (_isDanger) Column( children: [ _buildSectionContainer( child: ListItemFactory.createBuildMultilineInput( "整改描述", "请对隐患进行整改描述(必填项)", _dangerDetailController, ), ), SizedBox(height: 10), _buildSectionContainer( child: RepairedPhotoSection( title: "整改后图片", maxCount: 4, horizontalPadding: 0, mediaType: MediaType.image, isShowAI: false, onChanged: (List files) { // 上传图片 files _zhengGaiImages.clear(); for(int i=0;i DepartmentPickerTwo( onSelected: (id, name,pdId) async { setState(() { buMenId = id; buMenName = name; buMenPDId=pdId; responsibleId=""; responsibleName=""; }); // 拉取该单位的人员列表并缓存 final result = await ApiService.getListTreePersonList(id); _personCache=List>.from( result['userList'] as List, ); }, ), ); }, child: _buildSectionContainer( child: ListItemFactory.createRowSpaceBetweenItem( leftText: "整改责任部门", rightText: buMenName.isNotEmpty ? buMenName : "请选择", isRight: true, ), ), ), SizedBox(height: 10), GestureDetector( onTap: () { if ( buMenId.isEmpty) { ToastUtil.showNormal(context, '请先选择部门'); return; } DepartmentPersonPicker.show( context, personsData: _personCache, onSelected: (userId, name) { setState(() { // renYuanId = userId; // renYuanName = name; responsibleId=userId; responsibleName=name; }); }, ); }, child:Container( padding: EdgeInsets.symmetric(horizontal: 15), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), ), child: ListItemFactory.createRowSpaceBetweenItem( leftText: "整改负责人", rightText: responsibleName.isNotEmpty?responsibleName:"请选择", isRight: true, ), ), ), GestureDetector( onTap: () { showDialog( context: context, builder: (_) => HDatePickerDialog( initialDate: DateTime.now(), onCancel: () => Navigator.of(context).pop(), onConfirm: (selected) async { Navigator.of(context).pop(); setState(() { dataTime = DateFormat( 'yyyy-MM-dd', ).format(selected); }); }, ), ); }, child: _buildSectionContainer( child: ListItemFactory.createRowSpaceBetweenItem( leftText: "整改期限", rightText: dataTime.isNotEmpty ? dataTime : "请选择", isRight: true, ), ), ), ], ), SizedBox(height: 30), CustomButton( onPressed: () { _riskListCheckAppAdd(); }, text: "提交", backgroundColor: Colors.blue, ), ], ), ), ); } Future _riskListCheckAppAdd() async { if(_yinHuanImages.isEmpty){ ToastUtil.showNormal(context, "请上传隐患图片"); return; } String hazardDescription=_standardController.text.trim(); if(hazardDescription.isEmpty){ ToastUtil.showNormal(context, "请填隐患描述"); return; } String partDescription=_partController.text.trim(); if(partDescription.isEmpty){ ToastUtil.showNormal(context, "请填隐患部位"); return; } if(_hazardLeve.isEmpty){ ToastUtil.showNormal(context, "请选择隐患级别"); return; } String hazardLeve = _hazardLeve["BIANMA"]; if(_yinHuanTypeIds.isEmpty){ ToastUtil.showNormal(context, "请选择隐患类型"); return; } String type="1"; String dangerDetail=""; if(_isDanger){ type="1"; dangerDetail=_dangerDetailController.text.trim(); if(dangerDetail.isEmpty){ ToastUtil.showNormal(context, "请填整改描述"); return; } if(_zhengGaiImages.isEmpty){ ToastUtil.showNormal(context, "请上传整改后图片"); return; } }else{ type="2"; if(buMenId.isEmpty){ ToastUtil.showNormal(context, "请选择整改部门"); return; } if(responsibleId.isEmpty){ ToastUtil.showNormal(context, "请选择整改人"); return; } if(dataTime.isEmpty){ ToastUtil.showNormal(context, "请选择整改期限"); return; } } LoadingDialogHelper.show(); String yinHuanTypeIds=""; String yinHuanTypeNames=""; for(int i=0;i<_yinHuanTypeIds.length;i++){ String yinHuanTypeId= _yinHuanTypeIds[i]; String yinHuanTypeName= _yinHuanTypeNames[i]; if(yinHuanTypeIds.isEmpty){ yinHuanTypeIds=yinHuanTypeId; }else{ yinHuanTypeIds="$yinHuanTypeIds,$yinHuanTypeId"; } if(yinHuanTypeNames.isEmpty){ yinHuanTypeNames=yinHuanTypeName; }else{ yinHuanTypeNames="$yinHuanTypeNames/$yinHuanTypeName"; } } String hiddenType1=""; if(_yinHuanTypeIds.length>1){ hiddenType1=_yinHuanTypeIds[0]; } String hiddenType2=""; if(_yinHuanTypeIds.length>2){ hiddenType1=_yinHuanTypeIds[1]; } String hiddenType3=""; if(_yinHuanTypeIds.length>3){ hiddenType1=_yinHuanTypeIds[2]; } //获取定位 Position position = await _determinePosition(); String longitude=position.longitude.toString(); String latitude=position.latitude.toString(); try { final result = await ApiService.addRiskListCheckApp( hazardDescription, partDescription, latitude, longitude, dangerDetail, dataTime, type, responsibleId, yinHuanTypeIds, hazardLeve, buMenId, buMenPDId, yinHuanTypeNames, hiddenType1, hiddenType2, hiddenType3,); if (result['result'] == 'success') { String hiddenId = result['pd']['HIDDEN_ID'] ; for (int i=0;i<_yinHuanImages.length;i++){ _addImgFiles(_yinHuanImages[i],"3",hiddenId); } _addImgFiles(_yinHuanVido,"3",hiddenId); if(_isDanger){ for (int i=0;i<_zhengGaiImages.length;i++){ _addImgFiles(_zhengGaiImages[i],"4",hiddenId); } } setState(() { LoadingDialogHelper.hide(); ToastUtil.showNormal(context, "提交成功"); Navigator.pop(context); }); }else{ LoadingDialogHelper.hide(); } } catch (e) { LoadingDialogHelper.hide(); print('Error fetching data: $e'); } } Future _addImgFiles(String imagePath,String type,String id) async { try { final raw = await ApiService.addImgFiles( imagePath, type, id); if (raw['result'] == 'success') { return raw['imgPath']; }else{ // _showMessage('反馈提交失败'); return ""; } } catch (e) { // 出错时可以 Toast 或者在页面上显示错误状态 print('加载首页数据失败:$e'); return ""; } } Future _identifyImg(String imagePath) async { try { LoadingDialogHelper.show(); final raw = await ApiService.identifyImg( imagePath); if (raw['result'] == 'success') { final List newList = raw['aiHiddens'] ?? []; String miaoShuText=""; String zhengGaiText=""; for(int i=0;i item1 = jsonDecode(newList[i]); if(miaoShuText.isEmpty){ miaoShuText=item1["hiddenDescr"]; }else{ miaoShuText=miaoShuText+";"+item1["hiddenDescr"]; } if(zhengGaiText.isEmpty){ zhengGaiText=item1["rectificationSuggestions"]; }else{ zhengGaiText=zhengGaiText+";"+item1["rectificationSuggestions"]; } } LoadingDialogHelper.hide(); setState(() { _isDanger=true; _standardController.text=miaoShuText; _dangerDetailController.text=zhengGaiText; }); }else{ ToastUtil.showNormal(context, "识别失败"); LoadingDialogHelper.hide(); // _showMessage('反馈提交失败'); // return ""; } } catch (e) { // 出错时可以 Toast 或者在页面上显示错误状态 print('加载首页数据失败:$e'); // return ""; LoadingDialogHelper.hide(); } } 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); } }