feat: 无用路由删除,图片预览调整

dev_1.0.1
岑溪 2026-06-29 11:59:34 +08:00
parent 390d34e8d0
commit 6896708fb6
7 changed files with 92 additions and 166 deletions

View File

@ -10,7 +10,7 @@ module.exports = {
javaGitBranch: "<branch-name>", javaGitBranch: "<branch-name>",
// 本地联调 safety-eval-servicecontext-path: /safety-eval默认端口 8095 // 本地联调 safety-eval-servicecontext-path: /safety-eval默认端口 8095
// 可通过环境变量覆盖: SAFETY_EVAL_API_HOST=http://192.168.x.x: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: { production: {
// 应用后端分支名称,部署上线需要 // 应用后端分支名称,部署上线需要

View File

@ -407,7 +407,7 @@ export function fromStaffForm(values = {}) {
export function toStaffCertForm(data = {}) { export function toStaffCertForm(data = {}) {
const certImgs = data.certAttachmentUrl const certImgs = data.certAttachmentUrl
? [{ url: data.certAttachmentUrl, fileName: data.certName }] ? parseAttachmentUrls(data.certAttachmentUrl, data.certName || "证书附件.jpg")
: data.certImgFiles || []; : data.certImgFiles || [];
return { return {
id: asId(data.id), id: asId(data.id),
@ -465,7 +465,7 @@ export function isQualificationEnabled(record = {}) {
export function toQualificationForm(data = {}) { export function toQualificationForm(data = {}) {
const certImgs = data.certImageUrl const certImgs = data.certImageUrl
? [{ url: data.certImageUrl, fileName: data.certName }] ? parseAttachmentUrls(data.certImageUrl, data.certName || "证书图片.jpg")
: data.certImgFiles || []; : data.certImgFiles || [];
return { return {
id: asId(data.id), id: asId(data.id),

View File

@ -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 <span>暂无图片</span>;
}
return (
<Image.PreviewGroup>
{srcList.map((src, index) => (
<Image
key={`${src}-${index}`}
src={src}
alt=""
width={width}
height={height}
wrapperStyle={{ marginRight: 10, marginBottom: 10 }}
/>
))}
</Image.PreviewGroup>
);
}
export function CertTooltipPreviewImg({ files = [] }) {
const items = (files || []).filter(Boolean);
const srcList = items.map(resolvePreviewSrc).filter(Boolean);
return (
<Tooltip
placement="top"
title={srcList.length
? <CertPreviewImg files={files} />
: <span>暂无图片</span>}
>
<Tag>预览</Tag>
</Tooltip>
);
}
CertPreviewImg.displayName = "CertPreviewImg";
CertTooltipPreviewImg.displayName = "CertTooltipPreviewImg";
export default CertPreviewImg;

View File

@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder"; import FormBuilder from "zy-react-library/components/FormBuilder";
import AddIcon from "zy-react-library/components/Icon/AddIcon"; import AddIcon from "zy-react-library/components/Icon/AddIcon";
import Page from "zy-react-library/components/Page"; 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 Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; import Table from "zy-react-library/components/Table";
import Upload from "zy-react-library/components/Upload"; import Upload from "zy-react-library/components/Upload";
@ -334,7 +334,7 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) {
<Descriptions.Item label="证书有效开始日期">{info.validStartDate}</Descriptions.Item> <Descriptions.Item label="证书有效开始日期">{info.validStartDate}</Descriptions.Item>
<Descriptions.Item label="证书有效结束日期">{info.validEndDate}</Descriptions.Item> <Descriptions.Item label="证书有效结束日期">{info.validEndDate}</Descriptions.Item>
<Descriptions.Item label="复合日期">{info.reviewDate}</Descriptions.Item> <Descriptions.Item label="复合日期">{info.reviewDate}</Descriptions.Item>
<Descriptions.Item label="证书图片"><PreviewImg files={info.certImgs} /></Descriptions.Item> <Descriptions.Item label="证书图片"><CertPreviewImg files={info.certImgs} /></Descriptions.Item>
</Descriptions> </Descriptions>
</Modal> </Modal>
); );

View File

@ -1,6 +1,7 @@
import { Button, Descriptions, Modal, Space, Table } from "antd"; 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 FilePreviewModal, { FilePreviewContent } from "~/components/FilePreviewModal";
import { resolvePreviewSrc } from "~/components/CertPreviewImg";
import { fetchStaffCertDetail, fetchStaffCertListByPersonnelId } from "~/api/staffCertificate"; import { fetchStaffCertDetail, fetchStaffCertListByPersonnelId } from "~/api/staffCertificate";
import { safeRequest } from "~/utils"; import { safeRequest } from "~/utils";
@ -22,6 +23,12 @@ export default function StaffViewModal({
const [certPreview, setCertPreview] = useState(null); const [certPreview, setCertPreview] = useState(null);
const [certPreviewLoading, setCertPreviewLoading] = useState(false); const [certPreviewLoading, setCertPreviewLoading] = useState(false);
const [certPreviewInfo, setCertPreviewInfo] = useState(null); 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(() => { useEffect(() => {
if (!open || !currentId) { if (!open || !currentId) {
@ -31,10 +38,11 @@ export default function StaffViewModal({
} }
let cancelled = false; let cancelled = false;
setDetailLoading(true); setDetailLoading(true);
const loadCertList = requestCertListRef.current;
Promise.all([ Promise.all([
safeRequest(requestDetails, { id: currentId }), safeRequest(requestDetailsRef.current, { id: currentId }),
typeof requestCertList === "function" typeof loadCertList === "function"
? Promise.resolve(requestCertList(currentId)).catch((err) => { ? Promise.resolve(loadCertList(currentId)).catch((err) => {
console.warn("[StaffViewModal] load certificates failed:", err); console.warn("[StaffViewModal] load certificates failed:", err);
return []; return [];
}) })
@ -52,18 +60,18 @@ export default function StaffViewModal({
return () => { return () => {
cancelled = true; cancelled = true;
}; };
}, [open, currentId, requestDetails, requestCertList]); }, [open, currentId]);
const openCertPreview = async (record) => { const openCertPreview = async (record) => {
setCertPreview(record); setCertPreview(record);
setCertPreviewInfo(null); setCertPreviewInfo(null);
if (typeof requestCertDetails !== "function") { if (typeof requestCertDetailsRef.current !== "function") {
setCertPreviewInfo(record); setCertPreviewInfo(record);
return; return;
} }
setCertPreviewLoading(true); setCertPreviewLoading(true);
try { try {
const res = await safeRequest(requestCertDetails, { id: record.id }); const res = await safeRequest(requestCertDetailsRef.current, { id: record.id });
setCertPreviewInfo(res?.data || record); setCertPreviewInfo(res?.data || record);
} }
finally { finally {
@ -75,7 +83,7 @@ export default function StaffViewModal({
const certPreviewFiles = certPreviewInfo?.certImgs?.length const certPreviewFiles = certPreviewInfo?.certImgs?.length
? certPreviewInfo.certImgs ? certPreviewInfo.certImgs
: certPreviewInfo?.certImgFiles || []; : certPreviewInfo?.certImgFiles || [];
const certPreviewUrl = certPreviewFiles[0]?.url; const certPreviewUrl = resolvePreviewSrc(certPreviewFiles[0]);
const certPreviewName = certPreviewFiles[0]?.fileName || certPreviewFiles[0]?.name || certPreviewInfo?.certName; const certPreviewName = certPreviewFiles[0]?.fileName || certPreviewFiles[0]?.name || certPreviewInfo?.certName;
return ( return (

View File

@ -4,14 +4,13 @@ import { useEffect, useState } from "react";
import FormBuilder from "zy-react-library/components/FormBuilder"; import FormBuilder from "zy-react-library/components/FormBuilder";
import AddIcon from "zy-react-library/components/Icon/AddIcon"; import AddIcon from "zy-react-library/components/Icon/AddIcon";
import Page from "zy-react-library/components/Page"; 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 Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table"; 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 Upload from "zy-react-library/components/Upload";
import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender"; import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender";
import useGetFile from "zy-react-library/hooks/useGetFile"; import useGetFile from "zy-react-library/hooks/useGetFile";
import useTable from "zy-react-library/hooks/useTable"; import useTable from "zy-react-library/hooks/useTable";
import CertPreviewImg, { CertTooltipPreviewImg } from "~/components/CertPreviewImg";
import { NS_ORG_QUALIFICATION_CERT } from "~/enumerate/namespace"; import { NS_ORG_QUALIFICATION_CERT } from "~/enumerate/namespace";
import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions"; import { QUALIFICATION_INDUSTRY_OPTIONS } from "~/enumerate/enterpriseOptions";
import { formSelectField } from "~/utils/enterpriseForm"; import { formSelectField } from "~/utils/enterpriseForm";
@ -141,7 +140,7 @@ function QualificationCertPage(props) {
width: 100, width: 100,
render: (_, record) => ( render: (_, record) => (
record.certImgFiles?.length record.certImgFiles?.length
? <TooltipPreviewImg files={record.certImgFiles} /> ? <CertTooltipPreviewImg files={record.certImgFiles} />
: <span></span> : <span></span>
), ),
}, },
@ -447,7 +446,7 @@ function CertViewModal({ open, currentId, requestDetails, onCancel }) {
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="备注">{info.remark || "-"}</Descriptions.Item> <Descriptions.Item label="备注">{info.remark || "-"}</Descriptions.Item>
<Descriptions.Item label="证书图片"> <Descriptions.Item label="证书图片">
<PreviewImg files={info.certImgs} /> <CertPreviewImg files={info.certImgs} />
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>
</Modal> </Modal>

View File

@ -26,11 +26,6 @@ const menuItems = [
label: "监管端", label: "监管端",
icon: <DashboardOutlined />, icon: <DashboardOutlined />,
children: [ children: [
{
key: "/certificate/container/Supervision/test2",
label: "Test2 测试",
icon: <ExperimentOutlined />,
},
{ {
key: "/certificate/container/Supervision/BasicInfo", key: "/certificate/container/Supervision/BasicInfo",
label: "基础信息管理", label: "基础信息管理",
@ -58,144 +53,7 @@ const menuItems = [
}, },
], ],
}, },
{ ]
key: "/certificate/container/Supervision/EnterpriseLicense",
label: "企业证照",
icon: <FileProtectOutlined />,
children: [
{
key: "/certificate/container/Supervision/EnterpriseLicense/EnterpriseLicense",
label: "企业证照管理",
icon: <IdcardOutlined />,
},
{
key: "/certificate/container/Supervision/EnterpriseLicense/BranchStatistics/List",
label: "分公司统计",
icon: <BarChartOutlined />,
},
{
key: "/certificate/container/Supervision/EnterpriseLicense/StakeholderStatistics/List",
label: "干系人统计",
icon: <PieChartOutlined />,
},
],
},
{
key: "/certificate/container/Supervision/PersonnelLicense",
label: "人员证照",
icon: <TeamOutlined />,
children: [
{
key: "/certificate/container/Supervision/PersonnelLicense/PersonInCharge/List",
label: "负责人",
icon: <UserOutlined />,
},
{
key: "/certificate/container/Supervision/PersonnelLicense/SecurityAdmini/List",
label: "安全管理员",
icon: <SafetyCertificateOutlined />,
},
{
key: "/certificate/container/Supervision/PersonnelLicense/SpecialDevice/List",
label: "特种设备",
icon: <ToolOutlined />,
},
{
key: "/certificate/container/Supervision/PersonnelLicense/SpecialPersonnel/List",
label: "特种作业人员",
icon: <IdcardOutlined />,
},
{
key: "/certificate/container/Supervision/PersonnelLicense/BranchCompanyStat/List",
label: "分公司人员统计",
icon: <BarChartOutlined />,
},
{
key: "/certificate/container/Supervision/PersonnelLicense/StakeholderStat/List",
label: "干系人人员统计",
icon: <PieChartOutlined />,
},
],
},
],
},
{
key: "/certificate/container/BranchCompany",
label: "分公司端",
icon: <BankOutlined />,
children: [
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/EnterpriseLicense",
label: "企业证照管理",
icon: <IdcardOutlined />,
},
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense",
label: "人员证照",
icon: <TeamOutlined />,
children: [
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/PersonInCharge/List",
label: "负责人",
icon: <UserOutlined />,
},
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SecurityAdmini/List",
label: "安全管理员",
icon: <SafetyCertificateOutlined />,
},
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SpecialDevice/List",
label: "特种设备",
icon: <ToolOutlined />,
},
{
key: "/certificate/container/BranchCompany/EnterpriseLicense/PersonnelLicense/SpecialPersonnel/List",
label: "特种作业人员",
icon: <IdcardOutlined />,
},
],
},
],
},
{
key: "/certificate/container/Stakeholder",
label: "干系人端",
icon: <UserSwitchOutlined />,
children: [
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/EnterpriseLicense",
label: "企业证照管理",
icon: <IdcardOutlined />,
},
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense",
label: "人员证照",
icon: <TeamOutlined />,
children: [
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/PersonInCharge/List",
label: "负责人",
icon: <UserOutlined />,
},
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SecurityAdmini/List",
label: "安全管理员",
icon: <SafetyCertificateOutlined />,
},
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SpecialDevice/List",
label: "特种设备",
icon: <ToolOutlined />,
},
{
key: "/certificate/container/Stakeholder/EnterpriseLicense/PersonnelLicense/SpecialPersonnel/List",
label: "特种作业人员",
icon: <IdcardOutlined />,
},
],
},
],
}, },
{ {
key: "/certificate/container/EnterpriseInfo", key: "/certificate/container/EnterpriseInfo",
@ -238,12 +96,7 @@ const menuItems = [
icon: <ToolOutlined />, icon: <ToolOutlined />,
}, },
], ],
}, }
{
key: "/certificate/container/Test",
label: "测试页面",
icon: <ExperimentOutlined />,
},
]; ];
export default menuItems; export default menuItems;