tangjie 2026-07-08 14:44:41 +08:00
parent bb5ec8bb67
commit 353e40b31a
3 changed files with 166 additions and 78 deletions

View File

@ -14,7 +14,7 @@ module.exports = {
},
production: {
// 应用后端分支名称,部署上线需要
javaGitBranch: "<branch-name>",
javaGitBranch: "dev",
// 接口服务地址
API_HOST: "",
},

View File

@ -55,8 +55,8 @@ function toSelectedDept(node) {
}
function DepartmentPositionPage(props) {
const {orgPosition}=props;
const {orgPositionLoading}=orgPosition;
const { orgPosition } = props;
const { orgPositionLoading } = orgPosition;
const [selectedDept, setSelectedDept] = useState(null);
const [treeData, setTreeData] = useState([]);
const [deptModalOpen, setDeptModalOpen] = useState(false);
@ -318,6 +318,7 @@ function DepartmentPositionPage(props) {
</Form.Item>,
]}
onFinish={() => fetchPositionData(1, 10)}
onReset={() => fetchPositionData(1, 10)}
style={{ marginBottom: 16 }}
/>
<Table
@ -547,6 +548,7 @@ function DeptFormModal({
setSubmitting(false);
}
};
return (
<Modal
open={open}
@ -559,23 +561,25 @@ function DeptFormModal({
onOk={form.submit}
>
<Form form={form} layout="vertical" onFinish={handleSubmit}>
<Form.Item
name="parentId"
label="上级部门"
initialValue={selectedDeptId}
>
<TreeSelect
treeData={treeData}
allowClear
fieldNames={{
label: "deptName",
value: "id",
children: "children",
}}
showSearch
placeholder="请选择上级部门"
/>
</Form.Item>
{!currentId && (
<Form.Item
name="parentId"
label="上级部门"
initialValue={selectedDeptId}
>
<TreeSelect
treeData={treeData}
allowClear
fieldNames={{
label: "deptName",
value: "id",
children: "children",
}}
showSearch
placeholder="请选择上级部门"
/>
</Form.Item>
)}
<Form.Item
name="deptName"
label="部门名称"

View File

@ -1,8 +1,13 @@
import { Button, Descriptions, Modal, Table, Upload } from "antd";
import { Button, Descriptions, Image, Modal, Table, Upload } from "antd";
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 { fetchOrgPersonnelDetail } from "~/utils/qualFiling/personnelHelper";
const GENDER_MAP = { 1: "男", 2: "女" };
@ -41,26 +46,30 @@ export default function StaffViewModal({
const loadCertList = requestCertListRef.current;
Promise.all([
Promise.resolve(requestDetailsRef.current({ id: currentId })).catch((err) => {
console.warn("[StaffViewModal] load detail failed:", err);
return { data: {} };
}),
Promise.resolve(requestDetailsRef.current({ id: currentId })).catch(
(err) => {
console.warn("[StaffViewModal] load detail failed:", err);
return { data: {} };
},
),
typeof loadCertList === "function"
? Promise.resolve(loadCertList(currentId)).catch((err) => {
console.warn("[StaffViewModal] load certificates failed:", err);
return [];
})
console.warn("[StaffViewModal] load certificates failed:", err);
return [];
})
: Promise.resolve([]),
]).then(([detailRes, certList]) => {
if (!cancelled) {
setInfo(detailRes?.data || {});
setCertificates(Array.isArray(certList) ? certList : []);
}
}).finally(() => {
if (!cancelled) {
setDetailLoading(false);
}
});
])
.then(([detailRes, certList]) => {
if (!cancelled) {
setInfo(detailRes?.data || {});
setCertificates(Array.isArray(certList) ? certList : []);
}
})
.finally(() => {
if (!cancelled) {
setDetailLoading(false);
}
});
return () => {
cancelled = true;
};
@ -85,14 +94,18 @@ export default function StaffViewModal({
}
};
const proofMaterialUrl = info.proofMaterialUrl
? JSON.parse(info.proofMaterialUrl)
: [];
const proofMaterialUrl= info.proofMaterialUrl? JSON.parse(info.proofMaterialUrl) : [];
const certPreviewFiles = certPreviewInfo?.certImgs?.length
? certPreviewInfo.certImgs
: certPreviewInfo?.certImgFiles || [];
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 (
<>
@ -108,28 +121,57 @@ export default function StaffViewModal({
>
<Descriptions bordered column={2} labelStyle={{ width: 120 }}>
<Descriptions.Item label="姓名">{info.userName}</Descriptions.Item>
<Descriptions.Item label="性别">{GENDER_MAP[info.genderCode]}</Descriptions.Item>
<Descriptions.Item label="出生日期">{info.birthDate}</Descriptions.Item>
<Descriptions.Item label="性别">
{GENDER_MAP[info.genderCode]}
</Descriptions.Item>
<Descriptions.Item label="出生日期">
{info.birthDate}
</Descriptions.Item>
<Descriptions.Item label="账号">{info.account}</Descriptions.Item>
<Descriptions.Item label="部门">{info.deptName}</Descriptions.Item>
<Descriptions.Item label="岗位">{info.postName}</Descriptions.Item>
<Descriptions.Item label="人员类型">{info.personType || "基础人员"}</Descriptions.Item>
<Descriptions.Item label="资质范围">{info.qualScope || "-"}</Descriptions.Item>
<Descriptions.Item label="职业等级">{info.professionalLevelName || "-"}</Descriptions.Item>
<Descriptions.Item label="证书编号">{info.evaluatorCertNo || "-"}</Descriptions.Item>
<Descriptions.Item label="学历类型">{info.educationTypeName || "-"}</Descriptions.Item>
<Descriptions.Item label="学历层次">{info.educationLevelName || "-"}</Descriptions.Item>
<Descriptions.Item label="职称">{info.titleName || "-"}</Descriptions.Item>
<Descriptions.Item label="人员类型">
{info.personType || "基础人员"}
</Descriptions.Item>
<Descriptions.Item label="资质范围">
{info.qualScope || "-"}
</Descriptions.Item>
<Descriptions.Item label="职业等级">
{info.professionalLevelName || "-"}
</Descriptions.Item>
<Descriptions.Item label="证书编号">
{info.evaluatorCertNo || "-"}
</Descriptions.Item>
<Descriptions.Item label="学历类型">
{info.educationTypeName || "-"}
</Descriptions.Item>
<Descriptions.Item label="学历层次">
{info.educationLevelName || "-"}
</Descriptions.Item>
<Descriptions.Item label="职称">
{info.titleName || "-"}
</Descriptions.Item>
<Descriptions.Item label="是否注册安全工程师">
{REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"}
</Descriptions.Item>
<Descriptions.Item label="身份证号">{info.idCardNo}</Descriptions.Item>
<Descriptions.Item label="现住地址" span={2}>{info.currentAddress}</Descriptions.Item>
<Descriptions.Item label="办公地址" span={2}>{info.officeAddress}</Descriptions.Item>
<Descriptions.Item label="毕业院校">{info.graduateSchool}</Descriptions.Item>
<Descriptions.Item label="身份证号">
{info.idCardNo}
</Descriptions.Item>
<Descriptions.Item label="现住地址" span={2}>
{info.currentAddress}
</Descriptions.Item>
<Descriptions.Item label="办公地址" span={2}>
{info.officeAddress}
</Descriptions.Item>
<Descriptions.Item label="毕业院校">
{info.graduateSchool}
</Descriptions.Item>
<Descriptions.Item label="专业">{info.major}</Descriptions.Item>
<Descriptions.Item label="出版学术专著、专利、获奖、发表学术论文等" span={2}>
<Descriptions.Item
label="出版学术专著、专利、获奖、发表学术论文等"
span={2}
>
{info.publications || "-"}
</Descriptions.Item>
<Descriptions.Item label="自我申报的专业能力及认定方式" span={2}>
@ -139,18 +181,32 @@ export default function StaffViewModal({
{info.workExperience || "-"}
</Descriptions.Item>
<Descriptions.Item label="申报专业能力证明材料" span={2}>
{proofMaterialUrl.length ? proofMaterialUrl.map((item) => (
<div key={item.id}>
<a href={item.url} target="_blank" rel="noopener noreferrer">
{item.fileName || item.name || item.url}
</a>
</div>
)) : "-"
}
{proofMaterialUrl.length
? proofMaterialUrl.map((item) => {
const isImage = /\.(jpg|jpeg|png|gif|webp|bmp|svg)(\?.*)?$/i.test(item.url);
return (
<div key={item.id}>
{isImage ? (
<Image
src={item.url}
style={{ maxWidth: 200, cursor: "pointer" }}
preview={{ mask: item.fileName || item.name || "预览" }}
/>
) : (
<Button type="link" onClick={() => window.open(item.url)}>
{item.fileName || item.name || item.url}
</Button>
)}
</div>
);
})
: "-"}
</Descriptions.Item>
</Descriptions>
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>证照信息</div>
<div style={{ marginTop: 16, marginBottom: 8, fontWeight: 600 }}>
证照信息
</div>
<Table
size="small"
bordered
@ -169,7 +225,13 @@ export default function StaffViewModal({
title: "操作",
width: 90,
render: (_, record) => (
<Button type="link" size="small" onClick={() => openCertPreview(record)}>查看证书</Button>
<Button
type="link"
size="small"
onClick={() => openCertPreview(record)}
>
查看证书
</Button>
),
},
]}
@ -192,7 +254,9 @@ export default function StaffViewModal({
loading={certPreviewLoading}
cancelText="关闭"
okText={certPreviewUrl ? "新窗口打开" : "关闭"}
okButtonProps={{ style: certPreviewUrl ? undefined : { display: "none" } }}
okButtonProps={{
style: certPreviewUrl ? undefined : { display: "none" },
}}
onCancel={() => {
setCertPreview(null);
setCertPreviewInfo(null);
@ -207,18 +271,38 @@ export default function StaffViewModal({
>
{certPreviewInfo && (
<div>
<Descriptions bordered column={1} size="small" style={{ marginBottom: 12 }}>
<Descriptions.Item label="证照名称">{certPreviewInfo.certName}</Descriptions.Item>
<Descriptions.Item label="证书编号">{certPreviewInfo.certNo}</Descriptions.Item>
<Descriptions.Item label="证书类别">{certPreviewInfo.certCategory || "-"}</Descriptions.Item>
<Descriptions.Item label="发证机关">{certPreviewInfo.issueOrg || "-"}</Descriptions.Item>
<Descriptions.Item label="有效开始日期">{certPreviewInfo.validStartDate || "-"}</Descriptions.Item>
<Descriptions.Item label="有效结束日期">{certPreviewInfo.validEndDate || "-"}</Descriptions.Item>
<Descriptions
bordered
column={1}
size="small"
style={{ marginBottom: 12 }}
>
<Descriptions.Item label="证照名称">
{certPreviewInfo.certName}
</Descriptions.Item>
<Descriptions.Item label="证书编号">
{certPreviewInfo.certNo}
</Descriptions.Item>
<Descriptions.Item label="证书类别">
{certPreviewInfo.certCategory || "-"}
</Descriptions.Item>
<Descriptions.Item label="发证机关">
{certPreviewInfo.issueOrg || "-"}
</Descriptions.Item>
<Descriptions.Item label="有效开始日期">
{certPreviewInfo.validStartDate || "-"}
</Descriptions.Item>
<Descriptions.Item label="有效结束日期">
{certPreviewInfo.validEndDate || "-"}
</Descriptions.Item>
</Descriptions>
<FilePreviewContent url={certPreviewUrl} fileName={certPreviewName} />
<FilePreviewContent
url={certPreviewUrl}
fileName={certPreviewName}
/>
</div>
)}
</Modal>
</>
);
}
}