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/bottom_picker.dart'; import 'package:qhd_prevention/customWidget/bottom_picker_two.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/date_picker_dialog.dart'; import 'package:qhd_prevention/customWidget/department_person_picker.dart'; import 'package:qhd_prevention/customWidget/department_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/home/tap/item_list_widget.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 HazardRegistrationPage extends StatefulWidget { const HazardRegistrationPage(this.item, this.result, this.type, {super.key,required this.onClose}); final item; final int type; final Map result; final Function(String,String) onClose; @override State createState() => _HazardRegistrationPageState(); } class _HazardRegistrationPageState extends State { final _standardController = TextEditingController(); final _partController = TextEditingController(); final _dangerDetailController = TextEditingController(); String _repairLevelName = ""; String hazardLeve =""; late bool _isDanger = false;//true 1 false 2 late bool _canClick = true; late List _hazardLeveLlist = []; //隐患级别 // 存储各单位的人员列表 List> _personCache = []; List _yinHuanImages = []; List _yinHuanVido = []; // 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 = []; String unqualifiedInspectionItemID=""; String neiRong=""; @override void initState() { // TODO: implement initState super.initState(); setState(() { neiRong=widget.item['CHECK_CONTENT'] ?? ''; _standardController.text=widget.item["CHECK_UNQUALIFIED"]??""; }); unqualifiedInspectionItemID=SessionService.instance.unqualifiedInspectionItemID.toString(); setState(() { if(unqualifiedInspectionItemID.isNotEmpty){ List hImgs=widget.result["hImgs"]; List rImgs=widget.result["rImgs"]; dynamic pd=widget.result["pd"]; for(int i=0;i ApiService.baseImgPath +e["FILEPATH"]).toList(); _standardController.text=pd["HIDDENDESCR"]; _partController.text=pd["HIDDENPART"]; _repairLevelName =pd["HIDDENLEVELNAME"]; hazardLeve =pd["HIDDENLEVEL"]; _yinHuanTypeIds= pd["HIDDENTYPE"].toString().split(","); _yinHuanTypeNames= pd["HIDDENTYPE_NAME"].toString().split("/"); yinHuanName=pd["HIDDENTYPE_NAME"].toString(); if(pd["RECTIFICATIONTYPE"]=="1"){ _isDanger=true; }else{ _isDanger=false; } buMenId=pd["RECTIFICATIONDEPT"]; buMenPDId=pd["HIDDENFINDDEPT"]; buMenName=pd["RECTIFICATIONDEPTNAME"]; responsibleId=pd["RECTIFICATIONOR"]; responsibleName=pd["RECTIFICATIONORNAME"]; dataTime=pd["RECTIFICATIONDEADLINE"]; _dangerDetailController.text=pd["RECTIFYDESCR"]; _zhengGaiImages= rImgs.map((e) => ApiService.baseImgPath +e["FILEPATH"]).toList(); // _zhengGaiImages整改图片"rImgs" -> [_GrowableList] } }); _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: ItemListWidget.multiLineTitleTextField( label: '检查内容:', isEditable: false, text: widget.item['CHECK_CONTENT'] ?? '', ), ), _buildSectionContainer( child: RepairedPhotoSection( title: "隐患照片", maxCount: 4, mediaType: MediaType.image, initialMediaPaths:_yinHuanImages, isShowAI: true, onMediaAdded: (value) { _yinHuanImages.add(value); }, onMediaRemoved: (value) { }, 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, initialMediaPaths: _yinHuanVido, onMediaAdded: (value) { _yinHuanVido.add(value); }, 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"]; hazardLeve = _hazardLeve["BIANMA"]; 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?truncateText(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, initialMediaPaths: _zhengGaiImages, onMediaAdded: (value) { _zhengGaiImages.add(value); }, 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 { LoadingDialogHelper.show(); 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; } 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; } } 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 Map result; if(widget.type==1){ result = await ApiService.temporaryStorageOfHiddenYinHuan( unqualifiedInspectionItemID.isNotEmpty?"riskListCheckEdit":"riskListCheckAdd",widget.item,unqualifiedInspectionItemID, hazardDescription, partDescription, latitude, longitude, dangerDetail, dataTime, type, responsibleId, yinHuanTypeIds, hazardLeve, buMenId, buMenPDId, yinHuanTypeNames, hiddenType1, hiddenType2, hiddenType3,widget.result); }else{ result = await ApiService.temporaryStorageOfHidden( unqualifiedInspectionItemID.isNotEmpty?"edit":"add",widget.item,unqualifiedInspectionItemID, 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'] ; SessionService.instance.setUnqualifiedInspectionItemIDJson(hiddenId); for (int i=0;i<_yinHuanImages.length;i++){ _addImgFiles(_yinHuanImages[i],"3",hiddenId); } if(_yinHuanVido.isNotEmpty) { _addImgFiles(_yinHuanVido[0],"3",hiddenId); } if(_isDanger){ for (int i=0;i<_zhengGaiImages.length;i++){ _addImgFiles(_zhengGaiImages[i],"4",hiddenId); } } LoadingDialogHelper.hide(); setState(() { ToastUtil.showNormal(context, "提交成功"); Navigator.pop(context); widget.onClose(hiddenId,_standardController.text.trim()); }); } } 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); } String truncateText(String text, {int maxLength = 17}) { if (text.length <= maxLength) return text; return '${text.substring(0, maxLength)}...'; } }