2026-06-23 18:07:30 +08:00
|
|
|
|
import { Connect } from "@cqsjjb/jjb-dva-runtime";
|
2026-07-07 09:07:19 +08:00
|
|
|
|
import { Button, Descriptions, Form, Input, message, Modal, Select, Space, Table, Tag, Typography } from "antd";
|
|
|
|
|
|
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
|
2026-06-23 18:07:30 +08:00
|
|
|
|
import { useEffect, useState } from "react";
|
2026-06-29 16:45:58 +08:00
|
|
|
|
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
|
2026-07-07 09:07:19 +08:00
|
|
|
|
import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm";
|
|
|
|
|
|
import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper";
|
|
|
|
|
|
import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd";
|
|
|
|
|
|
import { tools } from "@cqsjjb/jjb-common-lib";
|
2026-06-23 18:07:30 +08:00
|
|
|
|
import { NS_STAFF_CHANGE_LOG, NS_STAFF_INFO } from "~/enumerate/namespace";
|
2026-07-07 09:07:19 +08:00
|
|
|
|
import {
|
|
|
|
|
|
CHANGE_COUNT_STYLE,
|
|
|
|
|
|
RESIGN_AUDIT_STATUS_LABEL,
|
|
|
|
|
|
AUDIT_STATUS_COLOR,
|
|
|
|
|
|
} from "~/utils/enterpriseForm";
|
2026-06-29 16:45:58 +08:00
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const { router } = tools;
|
2026-06-23 18:07:30 +08:00
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const EMPLOYMENT_STATUS_OPTIONS = [
|
|
|
|
|
|
{ value: 1, label: "在职" },
|
|
|
|
|
|
{ value: 2, label: "离职" },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const RESIGN_AUDIT_OPTIONS = Object.entries(RESIGN_AUDIT_STATUS_LABEL).map(([value, label]) => ({
|
|
|
|
|
|
value: Number(value),
|
|
|
|
|
|
label,
|
|
|
|
|
|
}));
|
2026-06-23 18:07:30 +08:00
|
|
|
|
|
|
|
|
|
|
function PersonnelChangePage(props) {
|
|
|
|
|
|
const [viewMode, setViewMode] = useState("list");
|
|
|
|
|
|
const [selectedStaff, setSelectedStaff] = useState(null);
|
|
|
|
|
|
const [auditModalOpen, setAuditModalOpen] = useState(false);
|
|
|
|
|
|
const [viewResignOpen, setViewResignOpen] = useState(false);
|
|
|
|
|
|
const [resignInfo, setResignInfo] = useState({});
|
|
|
|
|
|
const [rejectReason, setRejectReason] = useState("");
|
|
|
|
|
|
const [searchForm] = Form.useForm();
|
|
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const { staffChangeLog } = props;
|
|
|
|
|
|
const {
|
|
|
|
|
|
staffChangeLogStaffList: staffList,
|
|
|
|
|
|
staffChangeLogStaffTotal: staffTotal,
|
|
|
|
|
|
staffChangeLogLoading: loading,
|
|
|
|
|
|
staffChangeLogChangeList: changeList,
|
|
|
|
|
|
staffChangeLogChangeTotal: changeTotal,
|
|
|
|
|
|
} = staffChangeLog || {};
|
2026-06-23 18:07:30 +08:00
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const handleSearch = () => {
|
|
|
|
|
|
props.staffChangeLogStaffList({ ...router.query });
|
|
|
|
|
|
};
|
2026-06-23 18:07:30 +08:00
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
2026-07-07 09:07:19 +08:00
|
|
|
|
searchForm.setFieldsValue(router.query);
|
|
|
|
|
|
handleSearch();
|
2026-06-23 18:07:30 +08:00
|
|
|
|
}, []);
|
|
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const handleLogSearch = () => {
|
|
|
|
|
|
if (selectedStaff?.staffId) {
|
|
|
|
|
|
props.staffChangeLogList({ eqStaffId: selectedStaff.staffId });
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-06-23 18:07:30 +08:00
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
if (viewMode === "log" && selectedStaff?.staffId) {
|
2026-07-07 09:07:19 +08:00
|
|
|
|
handleLogSearch();
|
2026-06-23 18:07:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
}, [viewMode, selectedStaff?.staffId]);
|
|
|
|
|
|
|
|
|
|
|
|
const onDelete = (record) => {
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
|
title: "提示",
|
|
|
|
|
|
content: "数据将会删除,您是否确认删除?",
|
|
|
|
|
|
okText: "是",
|
|
|
|
|
|
cancelText: "否",
|
|
|
|
|
|
onOk: async () => {
|
2026-07-07 15:58:05 +08:00
|
|
|
|
const id = record.id ?? record.staffId;
|
|
|
|
|
|
if (!id) {
|
|
|
|
|
|
message.error("缺少人员ID,无法删除");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
const res = await props.staffInfoRemove?.({ id });
|
2026-06-23 18:07:30 +08:00
|
|
|
|
if (res?.success !== false) {
|
|
|
|
|
|
message.success("删除成功");
|
2026-07-07 09:07:19 +08:00
|
|
|
|
handleSearch();
|
|
|
|
|
|
} else {
|
2026-06-23 18:07:30 +08:00
|
|
|
|
message.error(res?.message || "删除失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const openResignAudit = async (record) => {
|
|
|
|
|
|
try {
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const res = await props.staffResignationInfo({ id: record.resignApplyId });
|
|
|
|
|
|
const data = res?.data || {};
|
|
|
|
|
|
setResignInfo(data);
|
2026-06-23 18:07:30 +08:00
|
|
|
|
setSelectedStaff(record);
|
|
|
|
|
|
setRejectReason("");
|
|
|
|
|
|
setAuditModalOpen(true);
|
2026-07-07 09:07:19 +08:00
|
|
|
|
} catch {
|
2026-06-23 18:07:30 +08:00
|
|
|
|
message.error("获取离职申请详情失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const openResignView = async (record) => {
|
2026-07-07 15:58:05 +08:00
|
|
|
|
if (!record?.resignApplyId) {
|
|
|
|
|
|
message.warning("该人员暂无离职申请记录");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
try {
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const res = await props.staffResignationInfo({ id: record.resignApplyId });
|
2026-06-23 18:07:30 +08:00
|
|
|
|
setResignInfo(res?.data || {});
|
|
|
|
|
|
setViewResignOpen(true);
|
2026-07-07 09:07:19 +08:00
|
|
|
|
} catch {
|
2026-06-23 18:07:30 +08:00
|
|
|
|
message.error("获取离职申请详情失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const submitAudit = async (passed) => {
|
|
|
|
|
|
if (!passed && !rejectReason?.trim()) {
|
|
|
|
|
|
message.warning("请填写退回原因");
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
|
|
|
const res = await props.staffResignationAudit({
|
|
|
|
|
|
id: resignInfo.id,
|
2026-07-07 09:07:19 +08:00
|
|
|
|
auditStatusCode: passed ? 1 : 2,
|
|
|
|
|
|
auditStatusName: passed ? "已审核" : "已退回",
|
2026-06-23 18:07:30 +08:00
|
|
|
|
rejectReason: passed ? undefined : rejectReason,
|
|
|
|
|
|
});
|
|
|
|
|
|
if (res?.success !== false) {
|
|
|
|
|
|
message.success(passed ? "审核通过" : "已退回");
|
|
|
|
|
|
setAuditModalOpen(false);
|
2026-07-07 09:07:19 +08:00
|
|
|
|
handleSearch();
|
|
|
|
|
|
} else {
|
2026-06-23 18:07:30 +08:00
|
|
|
|
message.error(res?.message || "审核操作失败");
|
|
|
|
|
|
}
|
2026-07-07 09:07:19 +08:00
|
|
|
|
} catch {
|
2026-06-23 18:07:30 +08:00
|
|
|
|
message.error("审核操作失败");
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
const staffColumns = [
|
|
|
|
|
|
{ title: "账户", dataIndex: "account", width: 130 },
|
|
|
|
|
|
{ title: "姓名", dataIndex: "userName", width: 100 },
|
|
|
|
|
|
{ title: "部门", dataIndex: "deptName", width: 120 },
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "信息变更数",
|
|
|
|
|
|
dataIndex: "changeCount",
|
|
|
|
|
|
width: 110,
|
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
|
const n = Number(record.changeCount ?? 0);
|
|
|
|
|
|
const style = n > 0 ? CHANGE_COUNT_STYLE.active : CHANGE_COUNT_STYLE.zero;
|
|
|
|
|
|
if (n <= 0) {
|
|
|
|
|
|
return <span style={style}>{n}</span>;
|
|
|
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Typography.Link
|
|
|
|
|
|
style={style}
|
|
|
|
|
|
onClick={() => {
|
|
|
|
|
|
setSelectedStaff(record);
|
|
|
|
|
|
setViewMode("log");
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{n}
|
|
|
|
|
|
</Typography.Link>
|
|
|
|
|
|
);
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "就职状态",
|
|
|
|
|
|
dataIndex: "employmentStatusCode",
|
|
|
|
|
|
width: 90,
|
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
|
const code = record.employmentStatusCode ?? record.employmentStatus;
|
|
|
|
|
|
return <Tag color={code === 2 ? "error" : "success"}>{code === 2 ? "离职" : "在职"}</Tag>;
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "离职申请审核状态",
|
|
|
|
|
|
dataIndex: "resignAuditStatus",
|
|
|
|
|
|
width: 140,
|
|
|
|
|
|
render: (_, record) => {
|
|
|
|
|
|
const code = record.resignAuditStatus ?? record.auditStatus ?? record.auditStatusCode;
|
2026-07-07 16:50:31 +08:00
|
|
|
|
const label = RESIGN_AUDIT_STATUS_LABEL[code];
|
|
|
|
|
|
return label ? <Tag color={AUDIT_STATUS_COLOR[code]}>{label}</Tag> : "-";
|
2026-07-07 09:07:19 +08:00
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: "操作",
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
fixed: "right",
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<TableAction>
|
|
|
|
|
|
<Button type="link" size="small" onClick={() => openResignView(record)}>
|
2026-07-07 15:58:05 +08:00
|
|
|
|
查看离职状态
|
2026-07-07 09:07:19 +08:00
|
|
|
|
</Button>
|
|
|
|
|
|
{record.resignApplyId && Number(record.resignAuditStatus) === 0 && (
|
|
|
|
|
|
<Button type="link" size="small" onClick={() => openResignAudit(record)}>
|
|
|
|
|
|
离职审核
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
)}
|
|
|
|
|
|
<Button danger type="link" size="small" onClick={() => onDelete(record)}>
|
|
|
|
|
|
删除
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</TableAction>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
const logColumns = [
|
|
|
|
|
|
{ title: "变更事项", dataIndex: "changeItem", width: 200 },
|
|
|
|
|
|
{ title: "变更时间", dataIndex: "changeTime", width: 160 },
|
|
|
|
|
|
{ title: "操作人", dataIndex: "createBy", width: 100 },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
2026-06-23 18:07:30 +08:00
|
|
|
|
if (viewMode === "log") {
|
|
|
|
|
|
return (
|
2026-06-29 16:45:58 +08:00
|
|
|
|
<PageLayout title="人员变更次数">
|
2026-07-07 09:07:19 +08:00
|
|
|
|
<Button style={{ marginBottom: 16 }} onClick={() => setViewMode("list")}>
|
|
|
|
|
|
返回
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
<div style={{ marginBottom: 8 }}>人员:{selectedStaff?.staffName || selectedStaff?.userName}</div>
|
2026-06-23 18:07:30 +08:00
|
|
|
|
<Table
|
2026-07-07 09:07:19 +08:00
|
|
|
|
rowKey="id"
|
|
|
|
|
|
columns={logColumns}
|
|
|
|
|
|
dataSource={changeList}
|
|
|
|
|
|
scroll={{ y: props.scrollY }}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={{
|
|
|
|
|
|
total: changeTotal,
|
|
|
|
|
|
showSizeChanger: true,
|
|
|
|
|
|
showQuickJumper: true,
|
|
|
|
|
|
showTotal: (t) => `共 ${t} 条`,
|
|
|
|
|
|
current: router.query.current || 1,
|
|
|
|
|
|
pageSize: router.query.size || 10,
|
|
|
|
|
|
onChange: (page, pageSize) => {
|
|
|
|
|
|
router.query = { ...router.query, current: page, size: pageSize };
|
|
|
|
|
|
handleLogSearch();
|
|
|
|
|
|
},
|
|
|
|
|
|
}}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
/>
|
2026-06-29 16:45:58 +08:00
|
|
|
|
</PageLayout>
|
2026-06-23 18:07:30 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
2026-06-30 18:30:30 +08:00
|
|
|
|
<PageLayout
|
|
|
|
|
|
title={
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<span>人员变更管理</span>
|
|
|
|
|
|
<div className="pageLayout-extra">
|
|
|
|
|
|
机构管理员在人员信息管理页面进行相应的修改操作
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
}
|
|
|
|
|
|
>
|
2026-07-07 09:07:19 +08:00
|
|
|
|
<SearchForm
|
|
|
|
|
|
style={{ marginBottom: 24 }}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
form={searchForm}
|
2026-07-07 09:07:19 +08:00
|
|
|
|
loading={loading}
|
|
|
|
|
|
formLine={[
|
|
|
|
|
|
<Form.Item key="account" name="account">
|
|
|
|
|
|
<ControlWrapper.Input label="账户" placeholder="请输入" allowClear />
|
|
|
|
|
|
</Form.Item>,
|
|
|
|
|
|
<Form.Item key="userName" name="userName">
|
|
|
|
|
|
<ControlWrapper.Input label="姓名" placeholder="请输入" allowClear />
|
|
|
|
|
|
</Form.Item>,
|
|
|
|
|
|
<Form.Item key="employmentStatusCode" name="employmentStatusCode">
|
|
|
|
|
|
<ControlWrapper.Select label="就职状态" placeholder="请选择" allowClear style={{ width: "100%" }}>
|
|
|
|
|
|
{EMPLOYMENT_STATUS_OPTIONS.map((o) => (
|
|
|
|
|
|
<Select.Option key={o.value} value={o.value}>{o.label}</Select.Option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ControlWrapper.Select>
|
|
|
|
|
|
</Form.Item>,
|
|
|
|
|
|
<Form.Item key="resignAuditStatus" name="resignAuditStatus">
|
|
|
|
|
|
<ControlWrapper.Select label="复核状态" placeholder="请选择" allowClear style={{ width: "100%" }}>
|
|
|
|
|
|
{RESIGN_AUDIT_OPTIONS.map((o) => (
|
|
|
|
|
|
<Select.Option key={o.value} value={o.value}>{o.label}</Select.Option>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ControlWrapper.Select>
|
|
|
|
|
|
</Form.Item>,
|
2026-06-23 18:07:30 +08:00
|
|
|
|
]}
|
2026-07-07 11:39:02 +08:00
|
|
|
|
onReset={(value) => {
|
|
|
|
|
|
router.query = { ...value, current: 1, size: 10 };
|
2026-07-07 09:07:19 +08:00
|
|
|
|
handleSearch();
|
|
|
|
|
|
}}
|
2026-07-07 11:39:02 +08:00
|
|
|
|
onFinish={(value) => {
|
|
|
|
|
|
router.query = { ...value, current: 1, size: 10 };
|
2026-07-07 09:07:19 +08:00
|
|
|
|
handleSearch();
|
|
|
|
|
|
}}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
/>
|
2026-07-07 09:07:19 +08:00
|
|
|
|
|
2026-06-23 18:07:30 +08:00
|
|
|
|
<Table
|
2026-07-07 09:07:19 +08:00
|
|
|
|
rowKey={(record) => record.id || record.staffId}
|
|
|
|
|
|
columns={staffColumns}
|
|
|
|
|
|
dataSource={staffList}
|
|
|
|
|
|
scroll={{ y: props.scrollY }}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={{
|
|
|
|
|
|
total: staffTotal,
|
|
|
|
|
|
showSizeChanger: true,
|
|
|
|
|
|
showQuickJumper: true,
|
|
|
|
|
|
showTotal: (t) => `共 ${t} 条`,
|
|
|
|
|
|
current: router.query.current || 1,
|
|
|
|
|
|
pageSize: router.query.size || 10,
|
|
|
|
|
|
onChange: (page, pageSize) => {
|
|
|
|
|
|
router.query = { ...router.query, current: page, size: pageSize };
|
|
|
|
|
|
handleSearch();
|
2026-06-23 18:07:30 +08:00
|
|
|
|
},
|
2026-07-07 09:07:19 +08:00
|
|
|
|
}}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
open={auditModalOpen}
|
2026-07-06 18:06:49 +08:00
|
|
|
|
destroyOnHidden
|
2026-06-23 18:07:30 +08:00
|
|
|
|
title="审核离职申请"
|
|
|
|
|
|
width={720}
|
2026-07-07 09:07:19 +08:00
|
|
|
|
footer={
|
2026-06-23 18:07:30 +08:00
|
|
|
|
<Space>
|
|
|
|
|
|
<Button onClick={() => setAuditModalOpen(false)}>取消</Button>
|
|
|
|
|
|
<Button danger onClick={() => submitAudit(false)}>退回</Button>
|
|
|
|
|
|
<Button type="primary" onClick={() => submitAudit(true)}>通过</Button>
|
|
|
|
|
|
</Space>
|
2026-07-07 09:07:19 +08:00
|
|
|
|
}
|
2026-06-23 18:07:30 +08:00
|
|
|
|
onCancel={() => setAuditModalOpen(false)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Descriptions bordered column={1} labelStyle={{ width: 120 }}>
|
|
|
|
|
|
<Descriptions.Item label="申请人">{resignInfo.applicantName}</Descriptions.Item>
|
|
|
|
|
|
<Descriptions.Item label="申请时间">{resignInfo.applyTime}</Descriptions.Item>
|
2026-07-07 09:07:19 +08:00
|
|
|
|
<Descriptions.Item label="预计离职日期">{resignInfo.expectedResignDate}</Descriptions.Item>
|
|
|
|
|
|
<Descriptions.Item label="离职原因">{resignInfo.resignReason}</Descriptions.Item>
|
2026-06-23 18:07:30 +08:00
|
|
|
|
<Descriptions.Item label="备注">{resignInfo.remark}</Descriptions.Item>
|
|
|
|
|
|
</Descriptions>
|
|
|
|
|
|
<Form.Item label="退回原因" style={{ marginTop: 16 }}>
|
|
|
|
|
|
<Input.TextArea rows={3} value={rejectReason} onChange={(e) => setRejectReason(e.target.value)} />
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Modal>
|
|
|
|
|
|
|
|
|
|
|
|
<Modal
|
|
|
|
|
|
open={viewResignOpen}
|
2026-07-06 18:06:49 +08:00
|
|
|
|
destroyOnHidden
|
2026-06-23 18:07:30 +08:00
|
|
|
|
title="查看离职申请"
|
|
|
|
|
|
width={720}
|
|
|
|
|
|
cancelText="返回"
|
|
|
|
|
|
okButtonProps={{ style: { display: "none" } }}
|
|
|
|
|
|
onCancel={() => setViewResignOpen(false)}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Descriptions bordered column={1} labelStyle={{ width: 120 }}>
|
|
|
|
|
|
<Descriptions.Item label="申请人">{resignInfo.applicantName}</Descriptions.Item>
|
|
|
|
|
|
<Descriptions.Item label="申请时间">{resignInfo.applyTime}</Descriptions.Item>
|
2026-07-07 09:07:19 +08:00
|
|
|
|
<Descriptions.Item label="预计离职日期">{resignInfo.expectedResignDate}</Descriptions.Item>
|
|
|
|
|
|
<Descriptions.Item label="离职原因">{resignInfo.resignReason}</Descriptions.Item>
|
2026-06-23 18:07:30 +08:00
|
|
|
|
<Descriptions.Item label="备注">{resignInfo.remark}</Descriptions.Item>
|
|
|
|
|
|
</Descriptions>
|
|
|
|
|
|
</Modal>
|
2026-06-29 16:45:58 +08:00
|
|
|
|
</PageLayout>
|
2026-06-23 18:07:30 +08:00
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-07-07 09:07:19 +08:00
|
|
|
|
export default Connect([NS_STAFF_CHANGE_LOG, NS_STAFF_INFO], true)(AntdTableFuncControl(PersonnelChangePage));
|