dev_1.0.1
tangjie 2026-07-07 15:27:25 +08:00
parent 3aefacff95
commit 716da66338
7 changed files with 254 additions and 121 deletions

View File

@ -14,7 +14,6 @@ export default function AttachmentUpload({ name, label, disabled = false, maxCou
label={label} label={label}
valuePropName="fileList" valuePropName="fileList"
getValueProps={(value) => { getValueProps={(value) => {
if (Array.isArray(value)) { if (Array.isArray(value)) {
return { fileList: value }; return { fileList: value };
} }
@ -30,7 +29,6 @@ export default function AttachmentUpload({ name, label, disabled = false, maxCou
}; };
}} }}
getValueFromEvent={({ fileList }) => { getValueFromEvent={({ fileList }) => {
return ( return (
fileList?.map((file) => ({ fileList?.map((file) => ({
url: file.response?.data?.url || file.url, url: file.response?.data?.url || file.url,

View File

@ -1,6 +1,16 @@
import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, DatePicker, Form, Input, message, Modal, Row, Col, Select, Table, Upload } from "antd"; import {
import { UploadOutlined } from "@ant-design/icons"; Button,
DatePicker,
Form,
Input,
message,
Modal,
Row,
Col,
Select,
Table,
} from "antd";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import dayjs from "dayjs"; import dayjs from "dayjs";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
@ -21,6 +31,7 @@ import {
} from "~/enumerate/enterpriseOptions"; } from "~/enumerate/enterpriseOptions";
import { getBirthDateFromIdCard } from "~/utils"; import { getBirthDateFromIdCard } from "~/utils";
import { idCardRule, mobileRule } from "~/utils/validators"; import { idCardRule, mobileRule } from "~/utils/validators";
import AttachmentUpload from "~/components/AttachmentUpload";
import StaffViewModal from "../StaffViewModal"; import StaffViewModal from "../StaffViewModal";
const { router } = tools; const { router } = tools;
@ -48,17 +59,26 @@ function PersonnelInfoPage(props) {
Get("/safetyEval/org-position/page", { current: 1, size: 200 }), Get("/safetyEval/org-position/page", { current: 1, size: 200 }),
]); ]);
if (cancelled) return; if (cancelled) return;
setDeptOptions((deptRes?.data || []).map((d) => ({ label: d.deptName, value: d.id }))); setDeptOptions(
setPositionOptions((posRes?.data || []).map((p) => ({ (deptRes?.data || []).map((d) => ({
label: d.deptName,
value: d.id,
})),
);
setPositionOptions(
(posRes?.data || []).map((p) => ({
label: p.positionName, label: p.positionName,
value: p.id, value: p.id,
deptId: p.deptId, deptId: p.deptId,
}))); })),
);
} catch (err) { } catch (err) {
console.warn("[PersonnelInfo] load dept/position options failed:", err); console.warn("[PersonnelInfo] load dept/position options failed:", err);
} }
})(); })();
return () => { cancelled = true; }; return () => {
cancelled = true;
};
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -134,19 +154,37 @@ function PersonnelInfoPage(props) {
loading={loading} loading={loading}
formLine={[ formLine={[
<Form.Item key="userName" name="userName"> <Form.Item key="userName" name="userName">
<ControlWrapper.Input label="用户名称" placeholder="请输入用户名称" allowClear /> <ControlWrapper.Input
label="用户名称"
placeholder="请输入用户名称"
allowClear
/>
</Form.Item>, </Form.Item>,
<Form.Item key="deptId" name="deptId"> <Form.Item key="deptId" name="deptId">
<ControlWrapper.Select label="部门" placeholder="请选择部门" allowClear style={{ width: "100%" }}> <ControlWrapper.Select
label="部门"
placeholder="请选择部门"
allowClear
style={{ width: "100%" }}
>
{deptOptions.map((d) => ( {deptOptions.map((d) => (
<Select.Option key={d.value} value={d.value}>{d.label}</Select.Option> <Select.Option key={d.value} value={d.value}>
{d.label}
</Select.Option>
))} ))}
</ControlWrapper.Select> </ControlWrapper.Select>
</Form.Item>, </Form.Item>,
<Form.Item key="postId" name="postId"> <Form.Item key="postId" name="postId">
<ControlWrapper.Select label="岗位" placeholder="请选择岗位" allowClear style={{ width: "100%" }}> <ControlWrapper.Select
label="岗位"
placeholder="请选择岗位"
allowClear
style={{ width: "100%" }}
>
{positionOptions.map((p) => ( {positionOptions.map((p) => (
<Select.Option key={p.value} value={p.value}>{p.label}</Select.Option> <Select.Option key={p.value} value={p.value}>
{p.label}
</Select.Option>
))} ))}
</ControlWrapper.Select> </ControlWrapper.Select>
</Form.Item>, </Form.Item>,
@ -166,7 +204,7 @@ function PersonnelInfoPage(props) {
{ title: "用户名称", dataIndex: "userName" }, { title: "用户名称", dataIndex: "userName" },
{ title: "账号", dataIndex: "account" }, { title: "账号", dataIndex: "account" },
{ title: "部门", dataIndex: "deptName" }, { title: "部门", dataIndex: "deptName" },
{ title: "岗位", dataIndex: "positionName" }, { title: "岗位", dataIndex: "postName" },
{ {
title: "证照名称", title: "证照名称",
dataIndex: "certNames", dataIndex: "certNames",
@ -178,17 +216,51 @@ function PersonnelInfoPage(props) {
width: 320, width: 320,
render: (_, record) => ( render: (_, record) => (
<TableAction> <TableAction>
<Button type="link" size="small" onClick={() => { setCurrentId(record.id); setViewModalOpen(true); }}> <Button
type="link"
size="small"
onClick={() => {
setCurrentId(record.id);
setViewModalOpen(true);
}}
>
查看 查看
</Button> </Button>
<Button type="link" size="small" onClick={() => { setCurrentId(record.id); setFormModalOpen(true); }}> <Button
type="link"
size="small"
onClick={() => {
setCurrentId(record.id);
setFormModalOpen(true);
}}
>
编辑 编辑
</Button> </Button>
<Button type="link" size="small" onClick={() => { setCurrentId(record.id); goCertificate(record.id, record.userName); }}> <Button
type="link"
size="small"
onClick={() => {
setCurrentId(record.id);
goCertificate(record.id, record.userName);
}}
>
证书 证书
</Button> </Button>
<Button type="link" size="small" onClick={() => onResetPassword(record.id)}>重置密码</Button> <Button
<Button danger type="link" size="small" onClick={() => onDelete(record.id)}>删除</Button> type="link"
size="small"
onClick={() => onResetPassword(record.id)}
>
重置密码
</Button>
<Button
danger
type="link"
size="small"
onClick={() => onDelete(record.id)}
>
删除
</Button>
</TableAction> </TableAction>
), ),
}, },
@ -242,14 +314,21 @@ function PersonnelInfoPage(props) {
} }
function StaffFormModal({ function StaffFormModal({
open, currentId, staffInfoGet, staffInfoAdd, staffInfoEdit, deptOptions, positionOptions, onCancel, onSuccess, open,
currentId,
staffInfoGet,
staffInfoAdd,
staffInfoEdit,
deptOptions,
positionOptions,
onCancel,
onSuccess,
}) { }) {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false); const [submitting, setSubmitting] = useState(false);
const [detailLoading, setDetailLoading] = useState(false); const [detailLoading, setDetailLoading] = useState(false);
const [deptPositionOptions, setDeptPositionOptions] = useState([]); const [deptPositionOptions, setDeptPositionOptions] = useState([]);
const [positionLoading, setPositionLoading] = useState(false); const [positionLoading, setPositionLoading] = useState(false);
const [uploadFileList, setUploadFileList] = useState([]);
const watchedDeptId = Form.useWatch("deptId", form); const watchedDeptId = Form.useWatch("deptId", form);
const wasOpenRef = useRef(false); const wasOpenRef = useRef(false);
const inflightDeptRef = useRef(null); const inflightDeptRef = useRef(null);
@ -264,7 +343,11 @@ function StaffFormModal({
inflightDeptRef.current = id; inflightDeptRef.current = id;
setPositionLoading(true); setPositionLoading(true);
try { try {
const res = await Get("/safetyEval/org-position/page", { current: 1, size: 200, deptId: id }); const res = await Get("/safetyEval/org-position/page", {
current: 1,
size: 200,
deptId: id,
});
const options = (res?.data || []).map((p) => ({ const options = (res?.data || []).map((p) => ({
label: p.positionName, label: p.positionName,
value: p.id, value: p.id,
@ -286,7 +369,6 @@ function StaffFormModal({
if (!currentId) { if (!currentId) {
form.resetFields(); form.resetFields();
setDeptPositionOptions([]); setDeptPositionOptions([]);
setUploadFileList([]);
form.setFieldsValue({ form.setFieldsValue({
registerEngineerFlag: 2, registerEngineerFlag: 2,
}); });
@ -294,7 +376,6 @@ function StaffFormModal({
} }
if (!open) { if (!open) {
setDeptPositionOptions([]); setDeptPositionOptions([]);
setUploadFileList([]);
} }
wasOpenRef.current = open; wasOpenRef.current = open;
}, [open, currentId, form]); }, [open, currentId, form]);
@ -303,7 +384,8 @@ function StaffFormModal({
if (!open || !currentId) return; if (!open || !currentId) return;
let cancelled = false; let cancelled = false;
setDetailLoading(true); setDetailLoading(true);
staffInfoGet({ id: currentId }).then((res) => { staffInfoGet({ id: currentId })
.then((res) => {
if (cancelled || !res?.data) return; if (cancelled || !res?.data) return;
const data = { ...res.data }; const data = { ...res.data };
loadPositionsByDept(data.deptId); loadPositionsByDept(data.deptId);
@ -312,27 +394,24 @@ function StaffFormModal({
...data, ...data,
}; };
if (data.birthDate) setFields.birthDate = dayjs(data.birthDate); if (data.birthDate) setFields.birthDate = dayjs(data.birthDate);
const fileList = data.proofMaterialUrl
? data.proofMaterialUrl.split(",").filter(Boolean).map((url, i) => ({ if (setFields.proofMaterialUrl) {
uid: `-${i}`, setFields.proofMaterialUrl = JSON.parse(setFields.proofMaterialUrl);
name: url.split("/").pop() || `附件${i + 1}`, }
status: "done",
url,
}))
: [];
setFields.proofMaterialUrl = fileList;
setUploadFileList(fileList);
form.setFieldsValue(setFields); form.setFieldsValue(setFields);
}).finally(() => { })
.finally(() => {
if (!cancelled) setDetailLoading(false); if (!cancelled) setDetailLoading(false);
}); });
return () => { cancelled = true; }; return () => {
cancelled = true;
};
}, [open, currentId]); }, [open, currentId]);
const handleCancel = () => { const handleCancel = () => {
form.resetFields(); form.resetFields();
setDeptPositionOptions([]); setDeptPositionOptions([]);
setUploadFileList([]);
onCancel(); onCancel();
}; };
@ -354,7 +433,12 @@ function StaffFormModal({
setSubmitting(true); setSubmitting(true);
const payload = { const payload = {
...values, ...values,
genderName: values.genderCode === 1 ? "男" : values.genderCode === 2 ? "女" : undefined, genderName:
values.genderCode === 1
? "男"
: values.genderCode === 2
? "女"
: undefined,
personTypeCode: values.personTypeName, personTypeCode: values.personTypeName,
personTypeName: values.personTypeName, personTypeName: values.personTypeName,
professionalLevelCode: values.professionalLevelName, professionalLevelCode: values.professionalLevelName,
@ -364,8 +448,8 @@ function StaffFormModal({
educationLevelCode: values.educationLevelName, educationLevelCode: values.educationLevelName,
educationLevelName: values.educationLevelName, educationLevelName: values.educationLevelName,
proofMaterialUrl: Array.isArray(values.proofMaterialUrl) proofMaterialUrl: Array.isArray(values.proofMaterialUrl)
? values.proofMaterialUrl.map((f) => f.url || f.response?.url).filter(Boolean).join(",") ? JSON.stringify(values.proofMaterialUrl)
: "", : undefined,
}; };
if (payload.birthDate && typeof payload.birthDate !== "string") { if (payload.birthDate && typeof payload.birthDate !== "string") {
payload.birthDate = payload.birthDate.format("YYYY-MM-DD"); payload.birthDate = payload.birthDate.format("YYYY-MM-DD");
@ -406,15 +490,26 @@ function StaffFormModal({
> >
<Row gutter={16}> <Row gutter={16}>
<Col span={12}> <Col span={12}>
<Form.Item name="userName" label="姓名" rules={[{ required: true, message: "请输入姓名" }]}> <Form.Item
name="userName"
label="姓名"
rules={[{ required: true, message: "请输入姓名" }]}
>
<Input placeholder="请输入姓名" /> <Input placeholder="请输入姓名" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="genderCode" label="性别" rules={[{ required: true, message: "请选择性别" }]}> <Form.Item
name="genderCode"
label="性别"
rules={[{ required: true, message: "请选择性别" }]}
>
<Select <Select
placeholder="请选择性别" placeholder="请选择性别"
options={[{ label: "男", value: 1 }, { label: "女", value: 2 }]} options={[
{ label: "男", value: 1 },
{ label: "女", value: 2 },
]}
/> />
</Form.Item> </Form.Item>
</Col> </Col>
@ -424,17 +519,35 @@ function StaffFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="account" label="账号" rules={[mobileRule("账号", true)]}> <Form.Item
name="account"
label="账号"
rules={[mobileRule("账号", true)]}
>
<Input placeholder="请输入账号" /> <Input placeholder="请输入账号" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="deptId" label="部门" rules={[{ required: true, message: "请选择部门" }]}> <Form.Item
<Select placeholder="请选择部门" options={deptOptions} allowClear showSearch optionFilterProp="label" /> name="deptId"
label="部门"
rules={[{ required: true, message: "请选择部门" }]}
>
<Select
placeholder="请选择部门"
options={deptOptions}
allowClear
showSearch
optionFilterProp="label"
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="postId" label="岗位" rules={[{ required: true, message: "请选择岗位" }]}> <Form.Item
name="postId"
label="岗位"
rules={[{ required: true, message: "请选择岗位" }]}
>
<Select <Select
placeholder="请选择岗位" placeholder="请选择岗位"
options={deptPositionOptions} options={deptPositionOptions}
@ -447,23 +560,38 @@ function StaffFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="idCardNo" label="身份证号" rules={[idCardRule(true)]}> <Form.Item
name="idCardNo"
label="身份证号"
rules={[idCardRule(true)]}
>
<Input placeholder="请输入身份证号" /> <Input placeholder="请输入身份证号" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="personTypeName" label="人员类型"> <Form.Item name="personTypeName" label="人员类型">
<Select placeholder="请选择人员类型" options={PERSON_TYPE_OPTIONS} /> <Select
placeholder="请选择人员类型"
options={PERSON_TYPE_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="qualScope" label="资质范围"> <Form.Item name="qualScope" label="资质范围">
<Select placeholder="请选择资质范围" allowClear options={QUALIFICATION_INDUSTRY_OPTIONS} /> <Select
placeholder="请选择资质范围"
allowClear
options={QUALIFICATION_INDUSTRY_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="professionalLevelName" label="职业等级"> <Form.Item name="professionalLevelName" label="职业等级">
<Select placeholder="请选择职业等级" allowClear options={PROFESSIONAL_LEVEL_OPTIONS} /> <Select
placeholder="请选择职业等级"
allowClear
options={PROFESSIONAL_LEVEL_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
@ -473,12 +601,20 @@ function StaffFormModal({
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="educationTypeName" label="学历类型"> <Form.Item name="educationTypeName" label="学历类型">
<Select placeholder="请选择学历类型" allowClear options={EDUCATION_TYPE_OPTIONS} /> <Select
placeholder="请选择学历类型"
allowClear
options={EDUCATION_TYPE_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="educationLevelName" label="学历层次"> <Form.Item name="educationLevelName" label="学历层次">
<Select placeholder="请选择学历层次" allowClear options={EDUCATION_LEVEL_OPTIONS} /> <Select
placeholder="请选择学历层次"
allowClear
options={EDUCATION_LEVEL_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
@ -487,17 +623,30 @@ function StaffFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="registerEngineerFlag" label="是否注册安全工程师" initialValue={2}> <Form.Item
<Select placeholder="请选择" options={REGISTER_ENGINEER_OPTIONS} /> name="registerEngineerFlag"
label="是否注册安全工程师"
initialValue={2}
>
<Select
placeholder="请选择"
options={REGISTER_ENGINEER_OPTIONS}
/>
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="publications" label="出版学术专著、专利、获奖、发表学术论文等"> <Form.Item
name="publications"
label="出版学术专著、专利、获奖、发表学术论文等"
>
<Input.TextArea rows={2} placeholder="请输入" /> <Input.TextArea rows={2} placeholder="请输入" />
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="abilityDeclaration" label="自我申报的专业能力及认定方式"> <Form.Item
name="abilityDeclaration"
label="自我申报的专业能力及认定方式"
>
<Input.TextArea rows={2} placeholder="请输入" /> <Input.TextArea rows={2} placeholder="请输入" />
</Form.Item> </Form.Item>
</Col> </Col>
@ -507,21 +656,11 @@ function StaffFormModal({
</Form.Item> </Form.Item>
</Col> </Col>
<Col span={24}> <Col span={24}>
<Form.Item name="proofMaterialUrl" label="申报专业能力证明材料" valuePropName="fileList" getValueFromEvent={(e) => { <AttachmentUpload
if (Array.isArray(e)) return e; name="proofMaterialUrl"
return e?.fileList; label="申报专业能力证明材料"
}}>
<Upload
action="/api/upload"
maxCount={5} maxCount={5}
fileList={uploadFileList} />
onChange={(info) => {
setUploadFileList(info.fileList);
}}
>
<Button icon={<UploadOutlined />}>上传文件</Button>
</Upload>
</Form.Item>
</Col> </Col>
<Col span={12}> <Col span={12}>
<Form.Item name="currentAddress" label="现住地址"> <Form.Item name="currentAddress" label="现住地址">
@ -549,4 +688,7 @@ function StaffFormModal({
); );
} }
export default Connect([NS_STAFF_INFO], true)(AntdTableFuncControl(PersonnelInfoPage)); export default Connect(
[NS_STAFF_INFO],
true,
)(AntdTableFuncControl(PersonnelInfoPage));

View File

@ -1,4 +1,4 @@
import { Button, Descriptions, Modal, Table } from "antd"; import { Button, Descriptions, Modal, Table, Upload } from "antd";
import { useEffect, useRef, 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 { resolvePreviewSrc } from "~/components/CertPreviewImg";
@ -85,7 +85,9 @@ export default function StaffViewModal({
} }
}; };
const proofFiles = info.proofMaterials || [];
const proofMaterialUrl= info.proofMaterialUrl? JSON.parse(info.proofMaterialUrl) : [];
const certPreviewFiles = certPreviewInfo?.certImgs?.length const certPreviewFiles = certPreviewInfo?.certImgs?.length
? certPreviewInfo.certImgs ? certPreviewInfo.certImgs
: certPreviewInfo?.certImgFiles || []; : certPreviewInfo?.certImgFiles || [];
@ -105,25 +107,25 @@ export default function StaffViewModal({
onCancel={onCancel} onCancel={onCancel}
> >
<Descriptions bordered column={2} labelStyle={{ width: 120 }}> <Descriptions bordered column={2} labelStyle={{ width: 120 }}>
<Descriptions.Item label="姓名">{info.staffName}</Descriptions.Item> <Descriptions.Item label="姓名">{info.userName}</Descriptions.Item>
<Descriptions.Item label="性别">{GENDER_MAP[info.gender]}</Descriptions.Item> <Descriptions.Item label="性别">{GENDER_MAP[info.genderCode]}</Descriptions.Item>
<Descriptions.Item label="出生日期">{info.birthDate}</Descriptions.Item> <Descriptions.Item label="出生日期">{info.birthDate}</Descriptions.Item>
<Descriptions.Item label="账号">{info.account}</Descriptions.Item> <Descriptions.Item label="账号">{info.account}</Descriptions.Item>
<Descriptions.Item label="部门">{info.deptName}</Descriptions.Item> <Descriptions.Item label="部门">{info.deptName}</Descriptions.Item>
<Descriptions.Item label="岗位">{info.positionName}</Descriptions.Item> <Descriptions.Item label="岗位">{info.postName}</Descriptions.Item>
<Descriptions.Item label="人员类型">{info.personType || "基础人员"}</Descriptions.Item> <Descriptions.Item label="人员类型">{info.personType || "基础人员"}</Descriptions.Item>
<Descriptions.Item label="资质范围">{info.qualScope || "-"}</Descriptions.Item> <Descriptions.Item label="资质范围">{info.qualScope || "-"}</Descriptions.Item>
<Descriptions.Item label="职业等级">{info.professionalLevel || "-"}</Descriptions.Item> <Descriptions.Item label="职业等级">{info.professionalLevelName || "-"}</Descriptions.Item>
<Descriptions.Item label="证书编号">{info.evaluatorCertNo || "-"}</Descriptions.Item> <Descriptions.Item label="证书编号">{info.evaluatorCertNo || "-"}</Descriptions.Item>
<Descriptions.Item label="学历类型">{info.educationType || "-"}</Descriptions.Item> <Descriptions.Item label="学历类型">{info.educationTypeName || "-"}</Descriptions.Item>
<Descriptions.Item label="学历层次">{info.educationLevel || "-"}</Descriptions.Item> <Descriptions.Item label="学历层次">{info.educationLevelName || "-"}</Descriptions.Item>
<Descriptions.Item label="职称">{info.titleName || "-"}</Descriptions.Item> <Descriptions.Item label="职称">{info.titleName || "-"}</Descriptions.Item>
<Descriptions.Item label="是否注册安全工程师"> <Descriptions.Item label="是否注册安全工程师">
{REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"} {REGISTER_ENGINEER_MAP[info.registerEngineerFlag] ?? "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="身份证号">{info.idCardNo}</Descriptions.Item> <Descriptions.Item label="身份证号">{info.idCardNo}</Descriptions.Item>
<Descriptions.Item label="学历">{info.education || "-"}</Descriptions.Item>
<Descriptions.Item label="现住地址" span={2}>{info.homeAddress}</Descriptions.Item> <Descriptions.Item label="现住地址" span={2}>{info.currentAddress}</Descriptions.Item>
<Descriptions.Item label="办公地址" span={2}>{info.officeAddress}</Descriptions.Item> <Descriptions.Item label="办公地址" span={2}>{info.officeAddress}</Descriptions.Item>
<Descriptions.Item label="毕业院校">{info.graduateSchool}</Descriptions.Item> <Descriptions.Item label="毕业院校">{info.graduateSchool}</Descriptions.Item>
<Descriptions.Item label="专业">{info.major}</Descriptions.Item> <Descriptions.Item label="专业">{info.major}</Descriptions.Item>
@ -137,26 +139,14 @@ export default function StaffViewModal({
{info.workExperience || "-"} {info.workExperience || "-"}
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="申报专业能力证明材料" span={2}> <Descriptions.Item label="申报专业能力证明材料" span={2}>
{proofFiles.length ? ( {proofMaterialUrl.length ? proofMaterialUrl.map((item) => (
<div style={{ display: "flex", flexDirection: "column", gap: 4 }}> <div key={item.id}>
{proofFiles.map((file, index) => { <a href={item.url} target="_blank" rel="noopener noreferrer">
const fileName = file.name || file.fileName || `专业能力证明${index + 1}.pdf`; {item.fileName || item.name || item.url}
return ( </a>
<div key={`${fileName}-${index}`} style={{ display: "flex", alignItems: "center", gap: 8 }}>
<Button
type="link"
size="small"
style={{ padding: 0 }}
onClick={() => setAttachmentPreview({ url: file.url, fileName })}
>
查看附件
</Button>
<span>{fileName}</span>
</div> </div>
); )) : "-"
})} }
</div>
) : "-"}
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>

View File

@ -223,6 +223,7 @@ function AddModal({ open, staffOptions, requestAdd, onCancel, onSuccess }) {
setSubmitting(true); setSubmitting(true);
values.applyTime = values.applyTime =
values.applyTime?.format?.("YYYY-MM-DD HH:mm:ss") || values.applyTime; values.applyTime?.format?.("YYYY-MM-DD HH:mm:ss") || values.applyTime;
values.expectedResignDate = values.expectedResignDate =
values.expectedResignDate?.format?.("YYYY-MM-DD") || values.expectedResignDate?.format?.("YYYY-MM-DD") ||
values.expectedResignDate; values.expectedResignDate;
@ -342,7 +343,9 @@ function ViewModal({ open, currentId, requestDetail, 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="离职通知报告">
{info.reportFileUrl || "-"} <a href={info.reportFileUrl} target="_blank" rel="noopener noreferrer">
查看
</a>
</Descriptions.Item> </Descriptions.Item>
</Descriptions> </Descriptions>
</Modal> </Modal>

View File

@ -95,7 +95,7 @@ function OrgPersonnelSelectModalInner(props) {
columns={[ columns={[
{ title: "人员姓名", dataIndex: "userName" }, { title: "人员姓名", dataIndex: "userName" },
{ title: "类型", dataIndex: "personTypeName" }, { title: "类型", dataIndex: "personTypeName" },
{ title: "职务", dataIndex: "positionName" },
{ title: "职称", dataIndex: "titleName" }, { title: "职称", dataIndex: "titleName" },
{ {
title: "操作", title: "操作",

View File

@ -38,7 +38,7 @@ export default function PersonnelStep({
{ title: "序号", width: 60, render: (_, __, index) => index + 1 }, { title: "序号", width: 60, render: (_, __, index) => index + 1 },
{ title: "人员姓名", dataIndex: "userName" }, { title: "人员姓名", dataIndex: "userName" },
{ title: "类型", dataIndex: "personTypeName" }, { title: "类型", dataIndex: "personTypeName" },
{ title: "职务", dataIndex: "positionName" },
{ title: "职称", dataIndex: "titleName" }, { title: "职称", dataIndex: "titleName" },
{ {
title: "操作", title: "操作",

View File

@ -124,7 +124,7 @@ const FilingTabs = ({
{ title: "序号", width: 60, render: (_, __, i) => i + 1 }, { title: "序号", width: 60, render: (_, __, i) => i + 1 },
{ title: "人员姓名", dataIndex: "personName", width: 100 }, { title: "人员姓名", dataIndex: "personName", width: 100 },
{ title: "类型", dataIndex: "personTypeName", width: 100 }, { title: "类型", dataIndex: "personTypeName", width: 100 },
{ title: "职务", dataIndex: "positionName", width: 120 },
{ title: "职称", dataIndex: "titleName", width: 100 }, { title: "职称", dataIndex: "titleName", width: 100 },
{ title: "操作", width: 80, { title: "操作", width: 80,
render: (_, record) => ( render: (_, record) => (