import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:qhd_prevention/customWidget/big_video_viewer.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'dart:convert'; import 'package:video_player/video_player.dart'; import '../../customWidget/ItemWidgetFactory.dart'; import '../../customWidget/custom_button.dart'; import '../../customWidget/department_person_picker.dart'; import '../../customWidget/department_picker.dart'; import '../../customWidget/full_screen_video_page.dart'; import '../../customWidget/single_image_viewer.dart'; import '../../customWidget/toast_util.dart'; import '../../customWidget/video_player_widget.dart'; import '../../http/ApiService.dart'; import '../../tools/h_colors.dart'; import '../../tools/tools.dart'; import 'danner_repair.dart'; import 'danger_wait_list_page.dart'; class PendingRectificationDetailPage extends StatefulWidget { const PendingRectificationDetailPage(this.dangerType, this.item, {super.key,required this.onClose}); final Function(String) onClose; // 回调函数 final DangerType dangerType; final item; @override _PendingRectificationDetailPageState createState() => _PendingRectificationDetailPageState(); } class _PendingRectificationDetailPageState extends State { late Map pd = {}; late Map hs = {}; List files = []; List files2 = []; List files4 = []; List files5 = []; List files6 = []; List videoList = []; List checkList = []; bool modalShow = false; String videoSrc = ""; VideoPlayerController? _videoController; // 是否整改 bool _accepted = true; String buMenId=""; String buMenName=""; String renYuanId=""; String renYuanName=""; // 存储各单位的人员列表 late List> _personCache = []; late DannerRepair dannerRepair; // 在父组件中 final GlobalKey dannerRepairKey = GlobalKey(); @override void initState() { super.initState(); if("2"==widget.item['HIDDEN_RISKSTANDARD']){ getDataTwo(); }else { getData(); } } @override void dispose() { _videoController?.dispose(); super.dispose(); } Future getData() async { try { final data = await ApiService.getDangerDetail(widget.item['HIDDEN_ID']); if (data['result'] == 'success') { setState(() { pd = data['pd']; buMenId=pd["RECTIFICATIONDEPT"]; buMenName=pd["RECTIFICATIONDEPTNAME"]; renYuanId=pd["RECTIFICATIONOR"]; renYuanName=pd["RECTIFICATIONORNAME"]; hs = data['hs'] ?? {}; // 处理图片和视频 for (var img in data['hImgs']) { if (img['FILEPATH'].toString().endsWith('.mp4')) { videoList.add(img); } else { files.add(img["FILEPATH"]); } } // List filesZheng = data['rImgs'] ?? []; for (var img in data['rImgs']) { files2.add(img["FILEPATH"]); } // files2=data['rImgs'] ?? []; files4 = data['sImgs'] ?? []; files5 = data['pImgs'] ?? []; files6 = data['yImgs'] ?? []; checkList = data['checkList'] ?? []; }); } } catch (e) { print('Error fetching data: $e'); } } Future getDataTwo() async { try { final data = await ApiService.getDangerDetailTwo(widget.item['HIDDEN_ID']); if (data['result'] == 'success') { setState(() { pd = data['pd']; buMenId=pd["RECTIFICATIONDEPT"]; buMenName=pd["RECTIFICATIONDEPTNAME"]; renYuanId=pd["RECTIFICATIONOR"]; renYuanName=pd["RECTIFICATIONORNAME"]; hs = data['hs'] ?? {}; // 处理图片和视频 for (var img in data['hImgs']) { if (img['FILEPATH'].toString().endsWith('.mp4')) { videoList.add(img); } else { files.add(img["FILEPATH"]); } } // List filesZheng = data['rImgs'] ?? []; for (var img in data['rImgs']) { files2.add(img["FILEPATH"]); } // files2=data['rImgs'] ?? []; files4 = data['sImgs'] ?? []; files5 = data['pImgs'] ?? []; files6 = data['yImgs'] ?? []; checkList = data['checkList'] ?? []; }); } } catch (e) { print('Error fetching data: $e'); } } Widget _buildInfoItem(String title, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 8), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 120, child: Text( title, style: const TextStyle(fontWeight: FontWeight.bold), ), ), Expanded(child: Text(value,textAlign: TextAlign.right,)), ], ), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: MyAppbar(title: widget.dangerType.detailTitle), body: pd.isEmpty ? const Center(child: CircularProgressIndicator()) : LayoutBuilder( builder: (context, constraints) { return SingleChildScrollView( child: ConstrainedBox( constraints: BoxConstraints( minHeight: constraints.maxHeight, ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildInfoItem('隐患描述', pd['HIDDENDESCR'] ?? ''), Divider(height: 1), // 隐患来源 _buildInfoItem('隐患来源', _getSourceText(pd['SOURCE'])), Divider(height: 1), // 条件渲染部分 if (pd['SOURCE'] == '2') ...[ _buildInfoItem('风险点(单元)', pd['RISK_UNIT'] ?? ''), Divider(height: 1), _buildInfoItem('辨识部位', pd['IDENTIFICATION'] ?? ''), Divider(height: 1), _buildInfoItem('存在风险', pd['RISK_DESCR'] ?? ''), Divider(height: 1), _buildInfoItem('风险分级', pd['LEVEL'] ?? ''), Divider(height: 1), _buildInfoItem('检查内容', pd['CHECK_CONTENT'] ?? ''), Divider(height: 1), ], _buildInfoItem('隐患部位', pd['HIDDENPART'] ?? ''), Divider(height: 1), _buildInfoItem('发现人', pd['CREATORNAME'] ?? ''), Divider(height: 1), _buildInfoItem('发现时间', pd['CREATTIME'] ?? ''), Divider(height: 1), if (pd['HIDDEN_CATEGORY']?.isNotEmpty == true) _buildInfoItem('隐患类别', pd['HIDDEN_CATEGORY_NAME'] ?? ''), _buildInfoItem('隐患类型', pd['HIDDENTYPE_NAME'] ?? ''), Divider(height: 1), _buildInfoItem('整改类型', _getRectificationType(pd['RECTIFICATIONTYPE'])), if (pd['RECTIFICATIONTYPE'] == '2') _buildInfoItem('整改期限', pd['RECTIFICATIONDEADLINE'] ?? ''), Divider(height: 1), // 隐患照片 // const Text('隐患照片', style: TextStyle(fontWeight: FontWeight.bold)), // _buildImageGrid(files, onTap: (index) => _showImageGallery(files, index)), ListItemFactory.createTextImageItem( text: "隐患照片", imageUrls: files, onImageTapped: (index) { presentOpaque( SingleImageViewer(imageUrl:ApiService.baseImgPath + files[index]), context, ); }, ), // 隐患视频 if (videoList.isNotEmpty) ...[ const SizedBox(height: 16), const Text('隐患视频', style: TextStyle(fontWeight: FontWeight.bold)), GestureDetector( onTap: () { showDialog( context: context, barrierColor: Colors.black54, builder: (_) => VideoPlayerPopup(videoUrl: ApiService.baseImgPath + videoList[0]['FILEPATH']), ); // present( // BigVideoViewer(videoUrl:ApiService.baseImgPath + videoList[0]['FILEPATH']), // context, // ); }, // => _playVideo(ApiService.baseImgPath + videoList[0]['FILEPATH']), child: Image.asset( 'assets/image/videostart.png', // 替换为你的视频占位图 color: Colors.blue, width: 120, height: 120, ), ), ], SizedBox(height: 10,), // 整改信息部分 // if (pd['STATE'] != null && int.parse(pd['STATE']) >= 2 && int.parse(pd['STATE']) <= 4) ...[ // // const Divider(height: 10,color: Colors.grey,), // const Text('整改信息', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)), // Divider(height: 1), // _buildInfoItem('整改描述', pd['RECTIFYDESCR'] ?? ''), // Divider(height: 1), // _buildInfoItem('整改部门', pd['RECTIFICATIONDEPTNAME'] ?? ''), // Divider(height: 1), // _buildInfoItem('整改人', pd['RECTIFICATIONORNAME'] ?? ''), // Divider(height: 1), // _buildInfoItem('整改时间', pd['RECTIFICATIONTIME'] ?? ''), // Divider(height: 1), // // const Text('整改后图片', style: TextStyle(fontWeight: FontWeight.bold)), // // _buildImageGrid(files2, onTap: (index) => _showImageGallery(files2, index)), // ListItemFactory.createTextImageItem( // text: "整改后图片", // imageUrls: files2, // onImageTapped: (index) { // present( // SingleImageViewer(imageUrl: ApiService.baseImgPath +files2[index]), // context, // ); // }, // ), // // // ... 其他整改信息字段 // ], // 添加底部安全区域间距 // 隐患整改 _danner_type_wait(), SizedBox(height: MediaQuery.of(context).padding.bottom + 20), ], ), ), ), ); }, ), ); } /// 隐患整改 Widget _danner_type_wait() { return SizedBox( child: Column( children: [ ListItemFactory.createYesNoSection( horizontalPadding: 0, title: '是否正常整改', yesLabel: '是', noLabel: '否', groupValue: _accepted, onChanged: (val) { setState(() { _accepted = val; }); }, ), // 整改选项 _accepted ? _getRepairState() : _noAccepet_repair(_accepted), const SizedBox(height: 20), CustomButton( text: "提交", backgroundColor: Colors.blue, onPressed: () { // ToastUtil //接口请求 // _submitToServer(); _accepted ? _normalRectificationSubmission() : _rectificationSubmission(); }, ), ], ), ); } Widget _getRepairState() { dannerRepair= DannerRepair(pd,key: dannerRepairKey, ); return dannerRepair; } // #region 不整改 Widget _noAccepet_repair(bool _accept) { return Column( children: [ GestureDetector( onTap: () { showModalBottomSheet( context: context, isScrollControlled: true, barrierColor: Colors.black54, backgroundColor: Colors.transparent, builder: (ctx) => DepartmentPicker(onSelected: (id, name) async { setState(() { buMenId=id; buMenName=name; // 清空已选人员 renYuanId=""; renYuanName=""; }); // 拉取该单位的人员列表并缓存 final result = await ApiService.getListTreePersonList(id); _personCache=List>.from( result['userList'] as List, ); }), ); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), ), child: ListItemFactory.createRowSpaceBetweenItem( leftText: "整改部门", rightText: buMenName, isRight: true, ), ), ), Divider( height: 10, color: _accept ? h_backGroundColor() : Colors.transparent, ), GestureDetector( onTap: () { if ( renYuanId.isEmpty) { ToastUtil.showNormal(context, '请先选择部门'); return; } DepartmentPersonPicker.show( context, personsData: _personCache, onSelected: (userId, name) { setState(() { renYuanId = userId; renYuanName = name; }); }, ); }, child: Container( padding: EdgeInsets.symmetric(horizontal: 10), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), ), child: ListItemFactory.createRowSpaceBetweenItem( leftText: "整改负责人", rightText: renYuanName, isRight: true, ), ), ), ], ); } Future _normalRectificationSubmission() async { try { String dataTime= dannerRepairKey.currentState!.dataTime; if(dataTime.isEmpty){ ToastUtil.showNormal(context, "请选择整改时间"); return; } String miaoShu= dannerRepairKey.currentState!.miaoShuController.text.trim(); if(miaoShu.isEmpty){ ToastUtil.showNormal(context, "请填整改描述"); return; } List gaiHouImages = dannerRepairKey.currentState!.gaiHouImages; if(gaiHouImages.isEmpty){ ToastUtil.showNormal(context, "请上传整改后照片"); return; } String acceptedPrepareType="0"; String standard=""; String method=""; String fund=""; String person=""; String workTime=""; String time=""; String work=""; String other=""; List fangAnImages =[]; // 是否有整改方案 bool acceptedPrepare= dannerRepairKey.currentState!.acceptedPrepare; if(acceptedPrepare){ acceptedPrepareType="1"; standard= dannerRepairKey.currentState!.standardController.text; if(standard.isEmpty){ ToastUtil.showNormal(context, "请输入治理标准要求"); return; } method= dannerRepairKey.currentState!.methodController.text; if(method.isEmpty){ ToastUtil.showNormal(context, "请输入治理方法"); return; } fund= dannerRepairKey.currentState!.fundController.text; if(fund.isEmpty){ ToastUtil.showNormal(context, "请输入经费和物资的落实"); return; } person= dannerRepairKey.currentState!.personController.text; if(person.isEmpty){ ToastUtil.showNormal(context, "请输入负责治理人员"); return; } workTime= dannerRepairKey.currentState!.workTimeController.text; if(workTime.isEmpty){ ToastUtil.showNormal(context, "请输入工时安排"); return; } time= dannerRepairKey.currentState!.timeController.text; if(time.isEmpty){ ToastUtil.showNormal(context, "请输入时限要求"); return; } work= dannerRepairKey.currentState!.workController.text; if(work.isEmpty){ ToastUtil.showNormal(context, "请输入工作要求"); return; } other= dannerRepairKey.currentState!.otherController.text; if(other.isEmpty){ ToastUtil.showNormal(context, "请输入工作要求"); return; } fangAnImages = dannerRepairKey.currentState!.fangAnImages; if(fangAnImages.isEmpty){ ToastUtil.showNormal(context, "请上传方案照片"); return; } } String acceptedPlanType="0"; List jiHuaImages =[]; // 是否有整改计划 bool acceptedPlan= dannerRepairKey.currentState!.acceptedPlan; if(acceptedPlan){ acceptedPlanType="1"; jiHuaImages = dannerRepairKey.currentState!.jiHuaImages; if(jiHuaImages.isEmpty){ ToastUtil.showNormal(context, "请上传计划照片"); return; } } setState(() { LoadingDialogHelper.show(context); }); List departments = dannerRepairKey.currentState!.departments; bool departmentsAllInput=true; bool departmentsSameMan=false; for(int i=0;i _rectificationSubmission() async { try { LoadingDialogHelper.show(context); final result = await ApiService.rectificationSubmission(pd["HIDDEN_ID"],buMenId,renYuanId); if (result['result'] == 'success') { setState(() { ToastUtil.showNormal(context, "提交成功"); Navigator.of(context).pop(); widget.onClose('关闭详情'); // 触发回调 }); }else{ LoadingDialogHelper.hide(context); ToastUtil.showNormal(context, "加载数据失败"); } } catch (e) { LoadingDialogHelper.hide(context); // 出错时可以 Toast 或者在页面上显示错误状态 print('加载数据失败:$e'); } } String _convertDepartmentsToJson(List departments) { // 1. 将列表中的每个对象转换为 Map List> jsonList = departments .map((dept) => dept.toJson()) .toList(); // 2. 使用 jsonEncode 转换为 JSON 字符串 return jsonEncode(jsonList); } 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 ""; } } String _getSourceText(String? source) { switch (source) { case '1': return '隐患快报'; case '2': return '隐患排查清单检查'; case '3': return '标准排查清单检查'; case '4': return '专项检查'; case '5': return '安全检查'; default: return ''; } } String _getRectificationType(String? type) { switch (type) { case '1': return '立即整改'; case '2': return '限期整改'; default: return ''; } } }