import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:qhd_prevention/constants/app_enums.dart'; import 'package:qhd_prevention/customWidget/MultiDictValuesPicker.dart'; import 'package:qhd_prevention/customWidget/custom_alert_dialog.dart'; import 'package:qhd_prevention/customWidget/custom_button.dart'; import 'package:qhd_prevention/customWidget/item_list_widget.dart'; import 'package:qhd_prevention/customWidget/photo_picker_row.dart'; import 'package:qhd_prevention/customWidget/picker/CupertinoDatePicker.dart'; import 'package:qhd_prevention/customWidget/toast_util.dart'; import 'package:qhd_prevention/http/ApiService.dart'; import 'package:qhd_prevention/http/modules/basic_info_api.dart'; import 'package:qhd_prevention/pages/my_appbar.dart'; import 'package:qhd_prevention/customWidget/bottom_picker.dart'; import 'package:qhd_prevention/services/SessionService.dart'; import 'package:qhd_prevention/tools/tools.dart'; import 'dart:io'; import 'certificate_list_page.dart'; enum CertifitcateTypeMode { // 特种设备 specialEquipment('tzsbczry', 2), // 主要负责人 principal('zyfzr', 3), //安全生产管理人员 safetyManager('aqscglry', 4), // 特种作业人员 specialWorker('tezhongzuoye', 1), // 默认 normal('nor', 0); const CertifitcateTypeMode(this.value, this.type); final String value; final int type; } class CertificateDetailPage extends StatefulWidget { const CertificateDetailPage({ super.key, required this.model, required this.id, }); final String id; final CertifitcateEditMode model; @override State createState() => _CertificateDetailPageState(); } class _CertificateDetailPageState extends State { late Map pd = {}; // 证书类型 List _cerTypes = []; /// 特种作业数据字典 List _specialWorkList = []; List _chooseWorkTypeList = []; // 证书照片 List _cerImgList = []; List _idCartImgIds = []; // 已删除的证书照片 List _cerImgRemoveList = []; List cerPhotos = []; /// 特种设备数据字典 List _equipmentList = []; List _chooseEquipmentTypeList = []; bool _isEdit = false; late CertifitcateTypeMode _chooseMode = CertifitcateTypeMode.normal; @override void initState() { super.initState(); _isEdit = widget.model == CertifitcateEditMode.add || widget.model == CertifitcateEditMode.edit; _getKeyValues(); } Future _getData() async { try { final result = await CertificateApi.getCertificateDetail(widget.id); LoadingDialogHelper.dismiss(); if (result['success'] == true) { setState(() { pd = result['data']; _chooseMode = CertifitcateTypeMode.normal; if (pd['type'] == CertifitcateTypeMode.principal.value) { _chooseMode = CertifitcateTypeMode.principal; } if (pd['type'] == CertifitcateTypeMode.safetyManager.value) { _chooseMode = CertifitcateTypeMode.safetyManager; } if (pd['type'] == CertifitcateTypeMode.specialEquipment.value) { _chooseMode = CertifitcateTypeMode.specialEquipment; for (Map item in _equipmentList) { if (item['dictValue'] == pd['assignmentOperatingItemsCode']) { _chooseEquipmentTypeList = item['children'] ?? []; break; } } } if (pd['type'] == CertifitcateTypeMode.specialWorker.value) { _chooseMode = CertifitcateTypeMode.specialWorker; for (Map item in _specialWorkList) { if (item['dictValue'] == pd['industryCategoryCode']) { _chooseWorkTypeList = item['children'] ?? []; break; } } } for (Map item in _cerTypes) { if (item['dictValue'] == pd['type']) { pd['typeName'] = item['dictLabel'] ?? ''; break; } } _getCertificatePhotos(pd['userCertificateId']); }); } else { ToastUtil.showNormal(context, result['errMessage'] ?? ''); } } catch (e) { LoadingDialogHelper.dismiss(); } } // 获取证书照片 Future _getCertificatePhotos(String userCertificateId) async { var fileEnum = _getFileType(); try { final result = await FileApi.getImagePath(userCertificateId, fileEnum); setState(() { List resultList = result['data']; _cerImgList = resultList.map((item) => item['filePath'].toString()).toList(); _idCartImgIds = resultList.map((item) => item['id'].toString()).toList(); }); } catch (e) { print(e); } } UploadFileType _getFileType() { switch (_chooseMode) { case CertifitcateTypeMode.specialWorker: return UploadFileType.specialOperationPersonnelPhoto; case CertifitcateTypeMode.specialEquipment: return UploadFileType.specialEquipmentOperatorPhoto; case CertifitcateTypeMode.principal: return UploadFileType.mainResponsiblePersonPhoto; case CertifitcateTypeMode.safetyManager: return UploadFileType.photosSafetyProductionManagementPersonnel; default: return UploadFileType.specialOperationPersonnelPhoto; } } Future _getKeyValues() async { LoadingDialogHelper.show(); try { await BasicInfoApi.getDictValues('zslx').then((res) { _cerTypes = res['data']; }); /// 特种作业 await BasicInfoApi.getDictValues('tzzyryhylb0000').then((res) { _specialWorkList = res['data']; }); /// 特种设备 await BasicInfoApi.getDictValues('tzsbczryczxmzylb0000').then((res) { _equipmentList = res['data']; }); if (widget.model == CertifitcateEditMode.edit || widget.model == CertifitcateEditMode.detail) { _getData(); } else { LoadingDialogHelper.dismiss(); } } catch (e) { print(e); LoadingDialogHelper.dismiss(); } } void _uploadChooseType(Map found) { String typeCode = found['dictValue']; String typeName = found['dictLabel']; setState(() { if (typeCode == CertifitcateTypeMode.principal.value) { // 主要负责人 _chooseMode = CertifitcateTypeMode.principal; } if (typeCode == CertifitcateTypeMode.specialEquipment.value) { // 特种设备 _chooseMode = CertifitcateTypeMode.specialEquipment; } if (typeCode == CertifitcateTypeMode.specialWorker.value) { // 特种作业人员 _chooseMode = CertifitcateTypeMode.specialWorker; } if (typeCode == CertifitcateTypeMode.safetyManager.value) { // 安全管理人员 _chooseMode = CertifitcateTypeMode.safetyManager; } pd['type'] = typeCode; pd['typeName'] = typeName; }); } Future _submit() async { if (!_checkSubmit()) { return; } LoadingDialogHelper.show(); // 删除证照 await _checkDeleteImage(); // 先上传证书照片 if (!await _uploadCertificatePhotos()) { return; } try { if (!FormUtils.hasValue(pd, 'corpinfoId')) { pd['corpinfoId'] = SessionService.instance.tenantId; } if (!FormUtils.hasValue(pd, 'userId')) { pd['userId'] = SessionService.instance.accountId; } final result; if (widget.model == CertifitcateEditMode.add) { result = await CertificateApi.addCertificate(pd); } else { result = await CertificateApi.updateCertificate(pd); } LoadingDialogHelper.hide(); if (result['success'] == true) { ToastUtil.showNormal(context, '保存成功'); Navigator.of(context).pop(); } else { ToastUtil.showNormal(context, result['errMessage'] ?? '保存失败'); } LoadingDialogHelper.dismiss(); } catch (e) { print(e); ToastUtil.showNormal(context, '保存失败'); LoadingDialogHelper.dismiss(); } } Future _checkDeleteImage() async { late bool isSuccess = true; if (_cerImgRemoveList.isNotEmpty) { final delIds = _cerImgRemoveList; try { await FileApi.deleteImages(delIds).then((result) { if (result['success']) { isSuccess = true; } else { isSuccess = false; } }); } catch (e) { LoadingDialogHelper.hide(); } } else { isSuccess = true; } return isSuccess; } // 上传证书照片 Future _uploadCertificatePhotos() async { if (cerPhotos.isEmpty) { return true; } var fileEnum = _getFileType(); try { final result = await FileApi.uploadFiles( cerPhotos, fileEnum, pd['userCertificateId'] ?? '', ); if (result['success'] == true) { if (!FormUtils.hasValue(pd, 'userCertificateId')) { // 说明已经上传过,或者是编辑 pd['userCertificateId'] = result['data']['foreignKey'] ?? ''; } return true; } else { ToastUtil.showNormal(context, result['errMessage'] ?? '保存失败'); } } catch (e) { LoadingDialogHelper.hide(); return false; print(e); } return false; } bool _checkSubmit() { if (cerPhotos.length + _cerImgList.length < 2) { ToastUtil.showNormal(context, '请上传证书正面和反面照片'); return false; } if (!FormUtils.hasValue(pd, 'typeName')) { ToastUtil.showNormal(context, '请选择证书类型'); return false; } if (!FormUtils.hasValue(pd, 'certificateName')) { ToastUtil.showNormal(context, '请填写证书名称'); return false; } if (!FormUtils.hasValue(pd, 'certificateCode')) { ToastUtil.showNormal(context, '请填写证书编号'); return false; } if (!(_chooseMode == CertifitcateTypeMode.specialEquipment || _chooseMode == CertifitcateTypeMode.specialWorker)) { if (!FormUtils.hasValue(pd, 'postName')) { ToastUtil.showNormal(context, '请选择岗位'); return false; } } if (!FormUtils.hasValue(pd, 'issuingAuthority')) { ToastUtil.showNormal(context, '请填写发证机构'); return false; } if (_chooseMode == CertifitcateTypeMode.specialWorker) { if (!FormUtils.hasValue(pd, 'industryCategoryName')) { ToastUtil.showNormal(context, '请选择行业类型'); return false; } if (!FormUtils.hasValue(pd, 'industryOperatingItemsName')) { ToastUtil.showNormal(context, '请选择操作项目'); return false; } } if (_chooseMode == CertifitcateTypeMode.specialEquipment) { if (!FormUtils.hasValue(pd, 'assignmentOperatingItemsName')) { ToastUtil.showNormal(context, '请选择操作项目'); return false; } if (!FormUtils.hasValue(pd, 'assignmentCategoryName')) { ToastUtil.showNormal(context, '请选择作业类型'); return false; } } if (!FormUtils.hasValue(pd, 'dateIssue')) { ToastUtil.showNormal(context, '请选择发证日期'); return false; } if (!FormUtils.hasValue(pd, 'certificateDateStart')) { ToastUtil.showNormal(context, '请选择有效期开始时间'); return false; } if (!FormUtils.hasValue(pd, 'certificateDateEnd')) { ToastUtil.showNormal(context, '请选择有效期结束时间'); return false; } if (_chooseMode == CertifitcateTypeMode.specialWorker || _chooseMode == CertifitcateTypeMode.specialEquipment) { if (!FormUtils.hasValue(pd, 'reviewDate')) { ToastUtil.showNormal(context, '请选择复审时间'); return false; } } return true; } @override Widget build(BuildContext context) { bool isShowIdImg = false; bool isDetail = widget.model == CertifitcateEditMode.edit || widget.model == CertifitcateEditMode.detail; if (isDetail && _cerImgList.isNotEmpty) { isShowIdImg = true; } else { if (widget.model == CertifitcateEditMode.add) { isShowIdImg = true; } } return Scaffold( appBar: MyAppbar( title: widget.model == CertifitcateEditMode.add ? '证书信息添加' : '查看信息', isBack: true, ), body: SafeArea( child: ItemListWidget.itemContainer( horizontal: 5, ListView( children: [ if (isShowIdImg) ...[ RepairedPhotoSection( title: '证书照片', isRequired: _isEdit, maxCount: 2, initialMediaPaths: _cerImgList .map((item) => ApiService.baseImgPath + item) .toList(), isEdit: _isEdit, horizontalPadding: _isEdit ? 12 : 0, inlineImageWidth: 60, onChanged: (files) { cerPhotos = files.map((file) => file.path).toList(); }, onMediaRemovedForIndex: (index) async { final deleFile = _cerImgList[index]; final deleId = _idCartImgIds[index]; var fileEnum = _getFileType(); if (deleFile.contains(fileEnum.path)) { _cerImgList.removeAt(index); _idCartImgIds.removeAt(index); _cerImgRemoveList.add(deleId); } }, onAiIdentify: () {}, ), if (_isEdit) ItemListWidget.itemContainer( const Text( '温馨提示:用户要上传证书正反面(证书照片数量是2张才能保存)', style: TextStyle(color: Colors.red, fontSize: 10), ), ), const Divider(), ], ItemListWidget.selectableLineTitleTextRightButton( label: '证书作业类型:', isEditable: widget.model == CertifitcateEditMode.add, text: pd['typeName'] ?? '请选择', isRequired: widget.model == CertifitcateEditMode.add, onTap: () async { final found = await BottomPicker.show( context, items: _cerTypes, itemBuilder: (i) => Text(i['dictLabel']!, textAlign: TextAlign.center), initialIndex: 0, ); //FocusHelper.clearFocus(context); if (found != null) { _uploadChooseType(found); } }, ), const Divider(), ItemListWidget.singleLineTitleText( label: '证书名称:', isRequired: _isEdit, text: pd['certificateName'] ?? '', hintText: '请输入证书名称', isEditable: _isEdit, onChanged: (value) { pd['certificateName'] = value; }, ), const Divider(), ItemListWidget.singleLineTitleText( label: '证书编号:', isRequired: _isEdit, text: pd['certificateCode'] ?? '', hintText: '请输入证书编号', isEditable: _isEdit, onChanged: (value) { pd['certificateCode'] = value; }, ), const Divider(), if (_chooseMode == CertifitcateTypeMode.principal || _chooseMode == CertifitcateTypeMode.safetyManager) ...[ ItemListWidget.selectableLineTitleTextRightButton( label: '岗位名称:', isEditable: _isEdit, text: pd['postName'] ?? '请选择', isRequired: _isEdit, onTap: () async { showModalBottomSheet( context: context, isScrollControlled: true, barrierColor: Colors.black54, backgroundColor: Colors.transparent, builder: (_) => MultiDictValuesPicker( title: '岗位名称', dictType: _chooseMode == CertifitcateTypeMode.principal ? 'zyfzrgwmc0000' : 'aqscglrygwmc0000', allowSelectParent: false, onSelected: (id, name, extraData) { setState(() { pd['postId'] = extraData?['dictValue']; pd['postName'] = name; }); }, ), ); }, ), const Divider(), ], ItemListWidget.singleLineTitleText( label: '发证机构:', isRequired: _isEdit, text: pd['issuingAuthority'] ?? '', hintText: '请输入发证机构', isEditable: _isEdit, onChanged: (value) { pd['issuingAuthority'] = value; }, ), const Divider(), if (_chooseMode == CertifitcateTypeMode.specialWorker) ...[ ItemListWidget.selectableLineTitleTextRightButton( label: '操作项目:', isEditable: _isEdit, text: pd['industryOperatingItemsName'] ?? '请选择', isRequired: _isEdit, onTap: () async { if (_chooseWorkTypeList.isEmpty) { ToastUtil.showNormal(context, '暂无操作项目'); return; } final found = await BottomPicker.show( context, items: _chooseWorkTypeList, itemBuilder: (i) => Text( i['dictLabel']!, textAlign: TextAlign.center, ), initialIndex: 0, ); //FocusHelper.clearFocus(context); if (found != null) { pd['industryOperatingItemsName'] = found['dictLabel']; pd['industryOperatingItemsCode'] = found['dictValue']; } }, ), const Divider(), ItemListWidget.selectableLineTitleTextRightButton( label: '行业类别:', isEditable: _isEdit, text: pd['industryCategoryName'] ?? '请选择', isRequired: _isEdit, onTap: () async { final found = await BottomPicker.show( context, items: _specialWorkList, itemBuilder: (i) => Text( i['dictLabel']!, textAlign: TextAlign.center, ), initialIndex: 0, ); //FocusHelper.clearFocus(context); if (found != null) { setState(() { pd['industryCategoryName'] = found['dictLabel']; pd['industryCategoryCode'] = found['dictValue']; _chooseWorkTypeList = found['children'] ?? []; pd['industryOperatingItemsName'] = ''; pd['industryOperatingItemsCode'] = ''; }); } }, ), const Divider(), ], if (_chooseMode == CertifitcateTypeMode.specialEquipment) ...[ ItemListWidget.selectableLineTitleTextRightButton( label: '操作项目:', isEditable: _isEdit, text: pd['assignmentOperatingItemsName'] ?? '请选择', isRequired: _isEdit, onTap: () async { final found = await BottomPicker.show( context, items: _equipmentList, itemBuilder: (i) => Text( i['dictLabel']!, textAlign: TextAlign.center, ), initialIndex: 0, ); //FocusHelper.clearFocus(context); if (found != null) { setState(() { pd['assignmentOperatingItemsName'] = found['dictLabel']; pd['assignmentOperatingItemsCode'] = found['dictValue']; _chooseEquipmentTypeList = found['children'] ?? []; pd['assignmentCategoryName'] = ''; pd['assignmentCategoryCode'] = ''; }); } }, ), const Divider(), ItemListWidget.selectableLineTitleTextRightButton( label: '作业类别:', isEditable: _isEdit, text: pd['assignmentCategoryName'] ?? '请选择', isRequired: _isEdit, onTap: () async { if (_chooseEquipmentTypeList.isEmpty) { ToastUtil.showNormal(context, '暂无行业类型'); return; } final found = await BottomPicker.show( context, items: _chooseEquipmentTypeList, itemBuilder: (i) => Text( i['dictLabel']!, textAlign: TextAlign.center, ), initialIndex: 0, ); //FocusHelper.clearFocus(context); if (found != null) { pd['assignmentCategoryName'] = found['dictLabel']; pd['assignmentCategoryCode'] = found['dictValue']; } }, ), const Divider(), ], ItemListWidget.selectableLineTitleTextRightButton( label: '发证日期:', isEditable: _isEdit, text: pd['dateIssue'] ?? '请选择', isRequired: _isEdit, onTap: () async { DateTime? picked = await BottomDateTimePicker.showDate( mode: BottomPickerMode.date, context, ); if (picked != null) { setState(() { pd['dateIssue'] = DateFormat('yyyy-MM-dd').format(picked); }); //FocusHelper.clearFocus(context); } }, ), const Divider(), ItemListWidget.selectableLineTitleTextRightButton( label: '有效期开始时间:', isEditable: _isEdit, text: pd['certificateDateStart'] ?? '请选择', isRequired: _isEdit, onTap: () async { DateTime? picked = await BottomDateTimePicker.showDate( mode: BottomPickerMode.date, context, ); if (picked != null) { setState(() { pd['certificateDateStart'] = DateFormat( 'yyyy-MM-dd', ).format(picked); // 如果已经选择结束时间,且结束时间小于开始时间,则结束时间清空 if (FormUtils.hasValue(pd, 'certificateDateEnd') && isAfterStr( pd['certificateDateStart'], pd['certificateDateEnd'], )) { pd['certificateDateEnd'] = ''; } }); //FocusHelper.clearFocus(context); } }, ), const Divider(), ItemListWidget.selectableLineTitleTextRightButton( label: '有效期结束时间:', isEditable: _isEdit, text: pd['certificateDateEnd'] ?? '请选择', isRequired: _isEdit, onTap: () async { DateTime? picked = await BottomDateTimePicker.showDate( mode: BottomPickerMode.date, context, minTimeStr: pd['certificateDateStart'], ); if (picked != null) { setState(() { pd['certificateDateEnd'] = DateFormat( 'yyyy-MM-dd', ).format(picked); }); //FocusHelper.clearFocus(context); } }, ), const Divider(), if (_chooseMode == CertifitcateTypeMode.specialWorker || _chooseMode == CertifitcateTypeMode.specialEquipment) ...[ ItemListWidget.selectableLineTitleTextRightButton( label: '复审时间:', isEditable: _isEdit, text: pd['reviewDate'] ?? '请选择', isRequired: _isEdit, onTap: () async { DateTime? picked = await BottomDateTimePicker.showDate( mode: BottomPickerMode.date, context, ); if (picked != null) { setState(() { pd['reviewDate'] = DateFormat( 'yyyy-MM-dd', ).format(picked); }); //FocusHelper.clearFocus(context); } }, ), const Divider(), ], const SizedBox(height: 20), if (_isEdit) CustomButton( text: '保存', backgroundColor: Colors.blue, onPressed: () { _submit(); }, ), ], ), ), ), ); } }