From 9f4fc71d90b2c5ddcc53e97f71796fd7abe3a31d Mon Sep 17 00:00:00 2001 From: tangjie <122778500@qq.com> Date: Fri, 28 Aug 2026 16:07:33 +0800 Subject: [PATCH] fix --- jjb.config.js | 4 +- public/从业告知书模板.docx | Bin 0 -> 16068 bytes src/api/safetyEvalBusiness/index.js | 10 +++ src/components/AttachmentUpload/index.js | 38 ++++++-- .../EvalProject/List/index.js | 4 + .../ProjectFlow/ControlContent.js | 39 +------- .../ProjectFlow/SurveyContent.js | 84 +++++++++++++----- .../ProjectFlow/TeamContent.js | 83 +++++++++++++---- 8 files changed, 177 insertions(+), 85 deletions(-) create mode 100644 public/从业告知书模板.docx diff --git a/jjb.config.js b/jjb.config.js index d3739cf..5336dea 100644 --- a/jjb.config.js +++ b/jjb.config.js @@ -12,9 +12,9 @@ module.exports = { // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 //API_HOST: "http://localhost:80", - API_HOST: "http://192.168.0.134", + // API_HOST: "http://192.168.0.134", // API_HOST: "http://192.168.0.150", //太浅 - // API_HOST: "https://gbs-gateway.qhdsafety.com", + API_HOST: "https://gbs-gateway.qhdsafety.com", // API_HOST: "http://192.168.0.103", //huwei }, production: { diff --git a/public/从业告知书模板.docx b/public/从业告知书模板.docx new file mode 100644 index 0000000000000000000000000000000000000000..84ffa2ed96953b5a436c21f05eb036ce6e80cc5b GIT binary patch literal 16068 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 /safetyEval/institution/eval-project-member/page", ); +export const evalProjectEstablishedAttachSave = declareRequest( + "projectEstablishedAttachSaveLoading", + "Post > /safetyEval/institution/eval-project-member/saveProjectEstablishedAttach", +); + +export const evalProjectEstablishedAttachGet = declareRequest( + "projectEstablishedAttachGetLoading", + "Get > /safetyEval/institution/eval-project-member/getProjectEstablishedAttach", +); + export const evalProjectMemberSave = declareRequest( "memberSaveLoading", "Post > @/safetyEval/institution/eval-project-member/save", diff --git a/src/components/AttachmentUpload/index.js b/src/components/AttachmentUpload/index.js index 397d81c..990d6a5 100644 --- a/src/components/AttachmentUpload/index.js +++ b/src/components/AttachmentUpload/index.js @@ -1,6 +1,6 @@ -import { Form, Image, Upload, message } from "antd"; +import { Button, Form, Image, Upload, message } from "antd"; import { useEffect, useRef, useState } from "react"; -import { PlusOutlined } from "@ant-design/icons"; +import { PlusOutlined, UploadOutlined } from "@ant-design/icons"; /** 批量上传接口:一次请求上传 1~N 个文件,表单字段名为 files */ const BATCH_UPLOAD_ACTION = `${window.process.env.app.API_HOST}/safetyEval/file/upload/batch`; @@ -8,7 +8,23 @@ const BATCH_UPLOAD_ACTION = `${window.process.env.app.API_HOST}/safetyEval/file/ const isImage = (url) => /\.(png|jpe?g|gif|bmp|webp|svg)(\?.*)?$/i.test(url || ""); -export default function AttachmentUpload({ name, label, disabled, maxCount, accept, extra ,rules, style, keepOriginFile }) { +/** + * @param {string} [listType] - 上传列表样式,默认 picture-card;传 text 时为按钮触发形态 + * @param {string} [uploadText] - 触发区文案,默认“上传附件” + */ +export default function AttachmentUpload({ + name, + label, + disabled, + maxCount, + accept, + extra, + rules, + style, + keepOriginFile, + listType = "picture-card", + uploadText = "上传附件", +}) { const [previewImage, setPreviewImage] = useState(""); // 同一次选择的文件先入队,等微任务结束后合并为一个批量请求 const queueRef = useRef([]); @@ -104,7 +120,7 @@ export default function AttachmentUpload({ name, label, disabled, maxCount, acce > 1} customRequest={customRequest} @@ -136,10 +152,16 @@ export default function AttachmentUpload({ name, label, disabled, maxCount, acce } }} > - + {listType === "text" ? ( + + ) : ( + + )} {previewImage && { > 删除 + ), }, diff --git a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ControlContent.js b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ControlContent.js index 81d5ed8..247aac1 100644 --- a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ControlContent.js +++ b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/ControlContent.js @@ -235,44 +235,7 @@ const ControlContent = ({ readOnly, ...props }) => { } - {!readOnly&& -
  • 合同签订前是否进行项目风险分析。
  • -
  • 是否签订技术服务合同。
  • -
  • 是否下达项目任务通知单。
  • -
  • 是否有项目组成立和项目负责人任命记录。
  • -
  • 是否编制项目实施计划。
  • -
  • 现场检查记录是否完整、有效。
  • -
  • 是否有书面整改通知单并由被评价单位盖章或签字确认。
  • -
  • - 是否进行现场复查,复查单是否双方签名或盖章并注明日期。 -
  • -
  • 是否有现场勘查、整改复查影像资料。
  • -
  • 是否完成内审、技审并保留审核记录、签字和日期。
  • -
  • 委托方提供资料是否齐全并由被评价单位盖章。
  • -
  • - 委托方资料、评价过程资料和评价报告存档是否符合要求。 -
  • -
  • 存档资料是否完整且具有可追溯性。
  • - - ), - }, - ]} - />} + )} diff --git a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/SurveyContent.js b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/SurveyContent.js index 10745ff..f241702 100644 --- a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/SurveyContent.js +++ b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/SurveyContent.js @@ -1,12 +1,14 @@ import React, { useState, useEffect } from "react"; import { Form, Button, Flex, Typography, Steps, Tag, Card, Table, message, Popover, Image, Checkbox } from "antd"; -import { DownloadOutlined, QuestionOutlined, PictureOutlined } from "@ant-design/icons"; +import { DownloadOutlined, QuestionOutlined, PictureOutlined } from "@ant-design/icons"; import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { tools } from "@cqsjjb/jjb-common-lib"; import AttachmentUpload from "~/components/AttachmentUpload"; -import { ROLE_DEFINITIONS_MAP } from '~/enumerate/constant' +import { ROLE_DEFINITIONS_MAP, ROLE_DEFINITIONS } from '~/enumerate/constant' +import { QUALIFICATION_INDUSTRY_OPTIONS_MAP } from "~/enumerate/enterpriseOptions"; import LayoutFooterPortal from "~/components/LayoutFooterPortal"; +import { fillDocxTemplate } from "~/utils/fillDocxTemplate"; import "./index.less"; import dayjs from "dayjs"; @@ -36,22 +38,9 @@ const attachRequiredRules = (label) => [ }, ]; -const downloadTemplate = async () => { - try { - const res = await fetch("https://test-dragon-yf-pub.oss-cn-hangzhou.aliyuncs.com/jjb/6a6bff3ee4b021a75404adfb.docx"); - const blob = await res.blob(); - const url = URL.createObjectURL(blob); - const a = document.createElement("a"); - a.href = url; - a.download = "从业告知书模板.docx"; - a.click(); - URL.revokeObjectURL(url); - } catch { - message.error("下载失败,请重试"); - } -}; -const NoticePanel = ({ readOnly }) => ( + +const NoticePanel = ({ readOnly, downloadTemplate }) => (
    @@ -138,8 +127,8 @@ const InspectionPanel = ({ dataSource = [], evalProjectDetailData = {}, readOnly { title: "项目角色", dataIndex: "role", render: (v) => Array.isArray(v) ? v.map(item => ROLE_DEFINITIONS_MAP[item]).join('、') : v, ellipsis: true }, { title: "人脸识别", dataIndex: "faceState", render: (v) => {v === 1 ? "通过" : "未通过"} }, { title: "GPS定位", dataIndex: "gpsState", render: (v) => {v === 1 ? "正常" : "异常"} }, - { title: "签到时间", dataIndex: "singInTime" , render: (time, record)=>{return renderTimeWithFace(time, record, 0);}}, - { title: "签退时间", dataIndex: "signOutTime" , render: (time, record)=>{return renderTimeWithFace(time, record, 1);}}, + { title: "签到时间", dataIndex: "singInTime", render: (time, record) => { return renderTimeWithFace(time, record, 0); } }, + { title: "签退时间", dataIndex: "signOutTime", render: (time, record) => { return renderTimeWithFace(time, record, 1); } }, { title: "在场时长", render: (_, r) => calcDuration(r.singInTime, r.signOutTime) }, { title: "现场照片", dataIndex: "sceneUrl", render: (v) => { @@ -256,7 +245,7 @@ const SurveyContent = ({ readOnly, ...props }) => { const [activeStage, setActiveStage] = useState("PRACTICE_NOTIFICATION"); const [attachMap, setAttachMap] = useState({}); const [surveyPersonnel, setSurveyPersonnel] = useState([]); - const { evalSurveyListLoading, evalSurveySaveAttachLoading, evalProjectDetailData } = props.safetyEvalBusiness; + const { evalSurveySaveAttachLoading, evalProjectDetailData } = props.safetyEvalBusiness; const projectId = router.query?.id; const currentIdx = STAGES.findIndex((s) => s.key === activeStage); const isFirst = currentIdx === 0; @@ -295,6 +284,57 @@ const SurveyContent = ({ readOnly, ...props }) => { } }; + const downloadTemplate = async () => { + const orgInfo = JSON.parse(sessionStorage.getItem('orgInfo')); + const industryText = String(evalProjectDetailData.industryCode || "") + .split(",") + .map((code) => QUALIFICATION_INDUSTRY_OPTIONS_MAP[code]) + .join("、"); + // 项目组成员(同项目组 tab 页数据):姓名/专业/工作任务 + const memberRes = await props.evalProjectMemberPage({ projectId }); + const members = (memberRes?.data || []).map((item) => ({ + name: item.personnelName, + major: item.capacity || "", + task: + item.responsibility || + (item.role || []) + .map((r) => ROLE_DEFINITIONS.find((d) => d.value === r)?.summary) + .filter(Boolean) + .join("、"), + isLeader: (item.role || []).includes("PROJECT_LEAD"), + })); + // 项目组组长取自项目组成员中的 PROJECT_LEAD,展示同 namesByRole:如"张三(化工)" + const projectLeader = members + .filter((m) => m.isLeader) + .map((m) => `${m.name}${m.major ? `(${m.major})` : ""}`) + .join("、"); + const data = { + account: orgInfo.account, + qualificationCertNo: orgInfo.qualificationCertNo, + infoDisclosureUrl: orgInfo.infoDisclosureUrl, + businessAddress: orgInfo.businessAddress, + legalRepresentative: orgInfo.legalRepresentative, + contactName: orgInfo.contactName, + contactPhone: orgInfo.contactPhone, + projectName: evalProjectDetailData.projectName, + projectAddress: evalProjectDetailData.customerAddress || "", + industryText, + projectLeader, + members, + }; + try { + await fillDocxTemplate( + 'https://gbs-cqaqpj.oss-cn-beijing.aliyuncs.com/jjb/6a913235e4b0b3767a78622d.docx', + data, + `安全评价检测检验机构从业告知书.docx`, + { download: true }, + ); + message.success("导出成功"); + } catch { + message.error("导出失败,请重试"); + } + }; + useEffect(() => { loadAttachments(); }, []); @@ -388,14 +428,14 @@ const SurveyContent = ({ readOnly, ...props }) => { ); return { title: s.label, - ...(uploaded ? { status: "finish" } : {status: "wait"}), + ...(uploaded ? { status: "finish" } : { status: "wait" }), }; })} />
    - +
    diff --git a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/TeamContent.js b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/TeamContent.js index 6969f57..bd286af 100644 --- a/src/pages/Container/SafetyEvalBusiness/ProjectFlow/TeamContent.js +++ b/src/pages/Container/SafetyEvalBusiness/ProjectFlow/TeamContent.js @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { useEffect, useRef, useState } from "react"; import { Tag, Button, @@ -7,6 +7,7 @@ import { Modal, Radio, Checkbox, + Form, message, Spin, Card, @@ -18,6 +19,7 @@ import { NS_SAFETY_EVAL_BUSINESS } from "~/enumerate/namespace"; import { tools } from "@cqsjjb/jjb-common-lib"; import { ROLE_DEFINITIONS, EVAL_TYPE_MAP } from "~/enumerate/constant"; import StatCardGroup from "~/components/StatCardGroup"; +import AttachmentUpload from "~/components/AttachmentUpload"; import LayoutFooterPortal from "~/components/LayoutFooterPortal"; import { fillDocxTemplate } from "~/utils/fillDocxTemplate"; @@ -33,6 +35,8 @@ const TeamContent = ({ readOnly, ...props }) => { evalProjectMemberParticipantSave, evalProjectMemberParticipantList, evalSignTaskSave, + evalProjectEstablishedAttachSave, + evalProjectEstablishedAttachGet, } = props; const { evalProjectDetailData, @@ -49,6 +53,9 @@ const TeamContent = ({ readOnly, ...props }) => { const [selectedRole, setSelectedRole] = useState(null); const [selectedPersons, setSelectedPersons] = useState([]); const [teamMembers, setTeamMembers] = useState([]); + // 人员任命书附件(项目成立附件 PROJECT_ESTABLISHED):局部表单承载上传,保存记录主键供更新 + const [attachForm] = Form.useForm(); + const establishedAttachIdRef = useRef(null); // 参与风险分析人员签字 const [participantModalOpen, setParticipantModalOpen] = useState(false); const [selectedParticipantIds, setSelectedParticipantIds] = useState([]); @@ -77,6 +84,39 @@ const TeamContent = ({ readOnly, ...props }) => { if (signRes?.success !== false) { setSigners(signRes?.data || []); } + // 人员任命书附件回显 + const attachRes = await evalProjectEstablishedAttachGet({ projectId }); + if (attachRes?.data) { + establishedAttachIdRef.current = attachRes.data.id || null; + let files = []; + try { + files = JSON.parse(attachRes.data.fileUrl) || []; + } catch {} + attachForm.setFieldsValue({ + appointmentFiles: Array.isArray(files) ? files : [], + }); + } + }; + + // 人员任命书上传/删除后自动保存;接口不回传主键,保存后重查同步 id 供下次更新 + const handleAttachChange = async (_, { appointmentFiles: files = [] }) => { + if (readOnly) return; + if (files.some((f) => f.status === "uploading")) return; + if (files.length && files.some((f) => !(f.status === "done" && f.url))) return; + if (!files.length && !establishedAttachIdRef.current) return; + const res = await evalProjectEstablishedAttachSave({ + ...(establishedAttachIdRef.current + ? { id: establishedAttachIdRef.current } + : {}), + projectId, + attachTypeCode: "PROJECT_ESTABLISHED", + fileUrl: JSON.stringify(files), + }); + if (res?.success !== false) { + message.success("人员任命书已保存"); + const getRes = await evalProjectEstablishedAttachGet({ projectId }); + if (getRes?.data?.id) establishedAttachIdRef.current = getRes.data.id; + } }; useEffect(() => { @@ -520,20 +560,33 @@ const TeamContent = ({ readOnly, ...props }) => { pagination={false} scroll={{ x: 800 }} /> - {!readOnly && ( - - )} + + {!readOnly && ( + + )} + + + + {!readOnly &&