From 390d34e8d0598cf6a543c872e0184bc56ae4a560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B2=91=E6=BA=AA?= <1015733727@qq.com> Date: Mon, 29 Jun 2026 11:06:09 +0800 Subject: [PATCH 1/2] feat: token --- src/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.js b/src/main.js index 7e88ce6..c3389f5 100644 --- a/src/main.js +++ b/src/main.js @@ -32,7 +32,7 @@ if (!window.__POWERED_BY_QIANKUN__) { // 本地开发时注入 Token,使 API 请求可携带认证信息 sessionStorage.setItem( "token", - "jjb-saas-auth:oauth:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJjbGllbnRJZFwiOlwiWlFBUVBKXCIsXCJhY2NvdW50SWRcIjoyMDY5NTk2NDEwNTAzODg4ODk2LFwidXNlclR5cGVFbnVtXCI6XCJQTEFURk9STVwiLFwidXNlcklkXCI6MjA2OTU5NjM5NzkyMDg0OTkyMCxcInRlbmFudElkXCI6MjA2OTU5NjM5NzkyMDg0OTkyMCxcInRlbmFudE5hbWVcIjpcIumHjeW6huWuieWFqOivhOS7t1wiLFwidGVuYW50UGFyZW50SWRzXCI6XCIwLDIwNjk1OTYzOTc5MjA4NDk5MjBcIixcIm5hbWVcIjpcIumHjeW6huWuieWFqOivhOS7t1wiLFwiYWNjZXNzVGlja2V0XCI6XCJ1R2FVSWJvd210dHlJQzdsMWhiWmNQeDFPVHZxb00yZm1mUDVZZ1A5a1BBM3c2cFh0NHVUc29DMGIzaHJcIixcInJlZnJlc2hUaWNrZXRcIjpcIjA0SVVxdVBraGZXd0RkbVpyWkZDc212S3RtellhNVlOQVcxSFlncUlFUHhlQkZod1dqbVZUYzRCWHRBdFwiLFwiZXhwaXJlSW5cIjo2MDQ3OTksXCJyZWZyZXNoRXhwaXJlc0luXCI6NjA0Nzk5LFwib3JnSWRcIjoyMDY5NTk2Mzk3OTIwODQ5OTIwLFwib3JnTmFtZVwiOlwi6YeN5bqG5a6J5YWo6K-E5Lu3XCIsXCJvcmdJZHNcIjpbMjA2OTU5NjM5NzkyMDg0OTkyMF0sXCJyb2xlc1R5cGVzXCI6W1wiVEVOQU5UX0FETUlOXCJdLFwicm9sZUlkc1wiOls1MDAyXSxcInNjb3Blc1wiOltdLFwicnBjVHlwZUVudW1cIjpcIkhUVFBcIixcImJpbmRNb2JpbGVTaWduXCI6XCJGQUxTRVwifSIsImlzcyI6InByby1zZXJ2ZXIiLCJleHAiOjE3ODMwNjc3MjF9.wZFmRnwKlzDWskgfRVG8BnMTyJAA9ssnmGc4BleepGU" + "jjb-saas-auth:oauth:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ7XCJjbGllbnRJZFwiOlwiWlFBUVBKXCIsXCJhY2NvdW50SWRcIjoyMDY5Njc0MjM3ODc0MDEyMTYwLFwidXNlclR5cGVFbnVtXCI6XCJQTEFURk9STVwiLFwidXNlcklkXCI6MjA2OTY3NDIzNzE3MzQzNjQxNixcInRlbmFudElkXCI6MjA2OTU5NjM5NzkyMDg0OTkyMCxcInRlbmFudE5hbWVcIjpcIumHjeW6huWuieWFqOivhOS7t1wiLFwidGVuYW50UGFyZW50SWRzXCI6XCIwLDIwNjk1OTYzOTc5MjA4NDk5MjBcIixcIm5hbWVcIjpcInRlc3QwMVwiLFwiYWNjZXNzVGlja2V0XCI6XCJ0eGd0MjA3dktBd21OeTUwY3ppdmhUZlNaSm9ZbmxZV003ZHJQbUlsS0wxV2ZYTnNFckp2OUxCMzNBSXRcIixcInJlZnJlc2hUaWNrZXRcIjpcIkl3cHdlMWpCeXZnQTRvTlNtZXNzdHl4cXQ3WWdmb3NuMlZyd01RVUtkanNyWjFpSFBHMXZQQVRRT1A3c1wiLFwiZXhwaXJlSW5cIjo2MDQ4MDAsXCJyZWZyZXNoRXhwaXJlc0luXCI6NjA0ODAwLFwib3JnSWRcIjoyMDY5NTk2Mzk3OTIwODQ5OTIwLFwib3JnTmFtZVwiOlwi6YeN5bqG5a6J5YWo6K-E5Lu3XCIsXCJvcmdJZHNcIjpbMjA2OTU5NjM5NzkyMDg0OTkyMF0sXCJyb2xlc1R5cGVzXCI6W1wiR0xZSlNcIl0sXCJyb2xlSWRzXCI6WzIwNjk2NzEzMDc1OTg4OTMwNThdLFwic2NvcGVzXCI6W10sXCJycGNUeXBlRW51bVwiOlwiSFRUUFwiLFwiYmluZE1vYmlsZVNpZ25cIjpcIkZBTFNFXCJ9IiwiaXNzIjoicHJvLXNlcnZlciIsImV4cCI6MTc4MzMwNDY3OX0.HSQlvOrqikDKAOPfTuXGQbm5W8YrUQkYmkhKg03OjuM" ); } From 6896708fb67000f99c3664ed196ce40a6e7af67a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B2=91=E6=BA=AA?= <1015733727@qq.com> Date: Mon, 29 Jun 2026 11:59:34 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=97=A0=E7=94=A8=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E5=88=A0=E9=99=A4,=E5=9B=BE=E7=89=87=E9=A2=84?= =?UTF-8?q?=E8=A7=88=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jjb.config.js | 2 +- src/api/enterpriseInfo/adapter.js | 4 +- src/components/CertPreviewImg/index.js | 66 ++++++++ .../PersonnelInfo/Certificate/index.js | 4 +- .../PersonnelInfo/StaffViewModal.js | 24 ++- .../EnterpriseInfo/QualificationCert/index.js | 7 +- src/pages/Container/Layout/menuConfig.js | 151 +----------------- 7 files changed, 92 insertions(+), 166 deletions(-) create mode 100644 src/components/CertPreviewImg/index.js diff --git a/jjb.config.js b/jjb.config.js index 04d4428..83eb003 100644 --- a/jjb.config.js +++ b/jjb.config.js @@ -10,7 +10,7 @@ module.exports = { javaGitBranch: "", // 本地联调 safety-eval-service(context-path: /safety-eval,默认端口 8095) // 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x:8095 - API_HOST: process.env.SAFETY_EVAL_API_HOST || "http://127.0.0.1:8095", + API_HOST: process.env.SAFETY_EVAL_API_HOST || "http://192.168.0.124:8095", }, production: { // 应用后端分支名称,部署上线需要 diff --git a/src/api/enterpriseInfo/adapter.js b/src/api/enterpriseInfo/adapter.js index fa5d6cd..76310fe 100644 --- a/src/api/enterpriseInfo/adapter.js +++ b/src/api/enterpriseInfo/adapter.js @@ -407,7 +407,7 @@ export function fromStaffForm(values = {}) { export function toStaffCertForm(data = {}) { const certImgs = data.certAttachmentUrl - ? [{ url: data.certAttachmentUrl, fileName: data.certName }] + ? parseAttachmentUrls(data.certAttachmentUrl, data.certName || "证书附件.jpg") : data.certImgFiles || []; return { id: asId(data.id), @@ -465,7 +465,7 @@ export function isQualificationEnabled(record = {}) { export function toQualificationForm(data = {}) { const certImgs = data.certImageUrl - ? [{ url: data.certImageUrl, fileName: data.certName }] + ? parseAttachmentUrls(data.certImageUrl, data.certName || "证书图片.jpg") : data.certImgFiles || []; return { id: asId(data.id), diff --git a/src/components/CertPreviewImg/index.js b/src/components/CertPreviewImg/index.js new file mode 100644 index 0000000..172a7bb --- /dev/null +++ b/src/components/CertPreviewImg/index.js @@ -0,0 +1,66 @@ +import { Image, Tooltip, Tag } from "antd"; +import { getFileUrl } from "zy-react-library/utils"; + +/** 解析附件对象的可访问地址,兼容 filePath(相对路径)与 url(绝对/相对) */ +export function resolvePreviewSrc(file = {}) { + const base = getFileUrl?.() || window.fileUrl || ""; + const path = file.filePath; + const url = file.url; + if (path) { + const p = String(path); + if (/^https?:\/\//i.test(p)) { + return p; + } + return base ? `${base}${p}` : p; + } + if (url) { + const u = String(url); + if (/^https?:\/\//i.test(u)) { + return u; + } + return base ? `${base}${u}` : u; + } + return ""; +} + +function CertPreviewImg({ files = [], width = 100, height = 100 }) { + const items = (files || []).filter(Boolean); + const srcList = items.map(resolvePreviewSrc).filter(Boolean); + if (!srcList.length) { + return 暂无图片; + } + return ( + + {srcList.map((src, index) => ( + + ))} + + ); +} + +export function CertTooltipPreviewImg({ files = [] }) { + const items = (files || []).filter(Boolean); + const srcList = items.map(resolvePreviewSrc).filter(Boolean); + return ( + + : 暂无图片} + > + 预览 + + ); +} + +CertPreviewImg.displayName = "CertPreviewImg"; +CertTooltipPreviewImg.displayName = "CertTooltipPreviewImg"; + +export default CertPreviewImg; diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js index 60d4ea4..b902e1a 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js @@ -4,7 +4,7 @@ import { useEffect, useState } from "react"; import FormBuilder from "zy-react-library/components/FormBuilder"; import AddIcon from "zy-react-library/components/Icon/AddIcon"; import Page from "zy-react-library/components/Page"; -import PreviewImg from "zy-react-library/components/PreviewImg"; +import CertPreviewImg from "~/components/CertPreviewImg"; import Search from "zy-react-library/components/Search"; import Table from "zy-react-library/components/Table"; import Upload from "zy-react-library/components/Upload"; @@ -334,7 +334,7 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) { {info.validStartDate} {info.validEndDate} {info.reviewDate} - + ); diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js index fb84f93..b9a1b1d 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js @@ -1,6 +1,7 @@ import { Button, Descriptions, Modal, Space, Table } from "antd"; -import { useEffect, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import FilePreviewModal, { FilePreviewContent } from "~/components/FilePreviewModal"; +import { resolvePreviewSrc } from "~/components/CertPreviewImg"; import { fetchStaffCertDetail, fetchStaffCertListByPersonnelId } from "~/api/staffCertificate"; import { safeRequest } from "~/utils"; @@ -22,6 +23,12 @@ export default function StaffViewModal({ const [certPreview, setCertPreview] = useState(null); const [certPreviewLoading, setCertPreviewLoading] = useState(false); const [certPreviewInfo, setCertPreviewInfo] = useState(null); + const requestDetailsRef = useRef(requestDetails); + const requestCertListRef = useRef(requestCertList); + const requestCertDetailsRef = useRef(requestCertDetails); + requestDetailsRef.current = requestDetails; + requestCertListRef.current = requestCertList; + requestCertDetailsRef.current = requestCertDetails; useEffect(() => { if (!open || !currentId) { @@ -31,10 +38,11 @@ export default function StaffViewModal({ } let cancelled = false; setDetailLoading(true); + const loadCertList = requestCertListRef.current; Promise.all([ - safeRequest(requestDetails, { id: currentId }), - typeof requestCertList === "function" - ? Promise.resolve(requestCertList(currentId)).catch((err) => { + safeRequest(requestDetailsRef.current, { id: currentId }), + typeof loadCertList === "function" + ? Promise.resolve(loadCertList(currentId)).catch((err) => { console.warn("[StaffViewModal] load certificates failed:", err); return []; }) @@ -52,18 +60,18 @@ export default function StaffViewModal({ return () => { cancelled = true; }; - }, [open, currentId, requestDetails, requestCertList]); + }, [open, currentId]); const openCertPreview = async (record) => { setCertPreview(record); setCertPreviewInfo(null); - if (typeof requestCertDetails !== "function") { + if (typeof requestCertDetailsRef.current !== "function") { setCertPreviewInfo(record); return; } setCertPreviewLoading(true); try { - const res = await safeRequest(requestCertDetails, { id: record.id }); + const res = await safeRequest(requestCertDetailsRef.current, { id: record.id }); setCertPreviewInfo(res?.data || record); } finally { @@ -75,7 +83,7 @@ export default function StaffViewModal({ const certPreviewFiles = certPreviewInfo?.certImgs?.length ? certPreviewInfo.certImgs : certPreviewInfo?.certImgFiles || []; - const certPreviewUrl = certPreviewFiles[0]?.url; + const certPreviewUrl = resolvePreviewSrc(certPreviewFiles[0]); const certPreviewName = certPreviewFiles[0]?.fileName || certPreviewFiles[0]?.name || certPreviewInfo?.certName; return ( diff --git a/src/pages/Container/EnterpriseInfo/QualificationCert/index.js b/src/pages/Container/EnterpriseInfo/QualificationCert/index.js index 0fd99ea..42a3512 100644 --- a/src/pages/Container/EnterpriseInfo/QualificationCert/index.js +++ b/src/pages/Container/EnterpriseInfo/QualificationCert/index.js @@ -4,14 +4,13 @@ import { useEffect, useState } from "react"; import FormBuilder from "zy-react-library/components/FormBuilder"; import AddIcon from "zy-react-library/components/Icon/AddIcon"; import Page from "zy-react-library/components/Page"; -import PreviewImg from "zy-react-library/components/PreviewImg"; import Search from "zy-react-library/components/Search"; import Table from "zy-react-library/components/Table"; -import TooltipPreviewImg from "zy-react-library/components/TooltipPreviewImg"; import Upload from "zy-react-library/components/Upload"; import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender"; import useGetFile from "zy-react-library/hooks/useGetFile"; import useTable from "zy-react-library/hooks/useTable"; +import CertPreviewImg, { CertTooltipPreviewImg } from "~/components/CertPreviewImg"; import { NS_ORG_QUALIFICATION_CERT } from "~/enumerate/namespace"; import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions"; import { formSelectField } from "~/utils/enterpriseForm"; @@ -141,7 +140,7 @@ function QualificationCertPage(props) { width: 100, render: (_, record) => ( record.certImgFiles?.length - ? + ? : ), }, @@ -447,7 +446,7 @@ function CertViewModal({ open, currentId, requestDetails, onCancel }) { {info.remark || "-"} - + diff --git a/src/pages/Container/Layout/menuConfig.js b/src/pages/Container/Layout/menuConfig.js index af84429..28ef462 100644 --- a/src/pages/Container/Layout/menuConfig.js +++ b/src/pages/Container/Layout/menuConfig.js @@ -26,11 +26,6 @@ const menuItems = [ label: "监管端", icon: , children: [ - { - key: "/certificate/container/Supervision/test2", - label: "Test2 测试", - icon: , - }, { key: "/certificate/container/Supervision/BasicInfo", label: "基础信息管理", @@ -58,144 +53,7 @@ const menuItems = [ }, ], }, - { - key: "/certificate/container/Supervision/EnterpriseLicense", - label: "企业证照", - icon: , - children: [ - { - key: "/certificate/container/Supervision/EnterpriseLicense/EnterpriseLicense", - label: "企业证照管理", - icon: , - }, - { - key: "/certificate/container/Supervision/EnterpriseLicense/BranchStatistics/List", - label: "分公司统计", - icon: , - }, - { - key: "/certificate/container/Supervision/EnterpriseLicense/StakeholderStatistics/List", - label: "干系人统计", - icon: , - }, - ], - }, - { - key: "/certificate/container/Supervision/PersonnelLicense", - label: "人员证照", - icon: , - children: [ - { - key: "/certificate/container/Supervision/PersonnelLicense/PersonInCharge/List", - label: "负责人", - icon: , - }, - { - key: "/certificate/container/Supervision/PersonnelLicense/SecurityAdmini/List", - label: "安全管理员", - icon: , - }, - { - key: "/certificate/container/Supervision/PersonnelLicense/SpecialDevice/List", - label: "特种设备", - icon: , - }, - { - key: "/certificate/container/Supervision/PersonnelLicense/SpecialPersonnel/List", - label: "特种作业人员", - icon: , - }, - { - key: "/certificate/container/Supervision/PersonnelLicense/BranchCompanyStat/List", - label: "分公司人员统计", - icon: , - }, - { - key: "/certificate/container/Supervision/PersonnelLicense/StakeholderStat/List", - label: "干系人人员统计", - icon: , - }, - ], - }, - ], - }, - { - key: "/certificate/container/BranchCompany", - label: "分公司端", - icon: , - children: [ - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/EnterpriseLicense", - label: "企业证照管理", - icon: , - }, - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense", - label: "人员证照", - icon: , - children: [ - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/PersonInCharge/List", - label: "负责人", - icon: , - }, - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SecurityAdmini/List", - label: "安全管理员", - icon: , - }, - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SpecialDevice/List", - label: "特种设备", - icon: , - }, - { - key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SpecialPersonnel/List", - label: "特种作业人员", - icon: , - }, - ], - }, - ], - }, - { - key: "/certificate/container/Stakeholder", - label: "干系人端", - icon: , - children: [ - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/EnterpriseLicense", - label: "企业证照管理", - icon: , - }, - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense", - label: "人员证照", - icon: , - children: [ - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/PersonInCharge/List", - label: "负责人", - icon: , - }, - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SecurityAdmini/List", - label: "安全管理员", - icon: , - }, - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SpecialDevice/List", - label: "特种设备", - icon: , - }, - { - key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SpecialPersonnel/List", - label: "特种作业人员", - icon: , - }, - ], - }, - ], + ] }, { key: "/certificate/container/EnterpriseInfo", @@ -238,12 +96,7 @@ const menuItems = [ icon: , }, ], - }, - { - key: "/certificate/container/Test", - label: "测试页面", - icon: , - }, + } ]; export default menuItems;