safety-eval-service-frontend/src/pages/Container/EnterpriseInfo/PersonnelChange/index.js

271 lines
9.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { Connect } from "@cqsjjb/jjb-dva-runtime";
import { Button, Descriptions, Form, Input, message, Modal, Select, Space, Typography } from "antd";
import { useEffect, useState } from "react";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
import Search from "zy-react-library/components/Search";
import Table from "zy-react-library/components/Table";
import useTable from "zy-react-library/hooks/useTable";
import { NS_STAFF_CHANGE_LOG, NS_STAFF_INFO } from "~/enumerate/namespace";
import { safeListRequest, safeRequest } from "~/utils";
import { CHANGE_COUNT_STYLE, formSelectField, getChangeCount, getEmploymentStatusLabel, getResignAuditStatusLabel } from "~/utils/enterpriseForm";
const EMPLOYMENT_STATUS = { 1: "在职", 2: "离职" };
const RESIGN_AUDIT_STATUS = { 0: "未审核", 1: "已审核", 2: "已退回" };
const SEARCH_COL = { xs: 24, sm: 12, md: 8, lg: 6 };
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();
const [logForm] = Form.useForm();
const { tableProps, getData } = useTable(safeListRequest(props.staffChangeLogStaffList), {
form: searchForm,
});
const { tableProps: logTableProps, getData: getLogData } = useTable(
safeListRequest(props.staffChangeLogList),
{
form: logForm,
transform: () => ({ eqStaffId: selectedStaff?.staffId }),
},
);
useEffect(() => {
getData();
}, []);
useEffect(() => {
if (viewMode === "log" && selectedStaff?.staffId) {
getLogData();
}
}, [viewMode, selectedStaff?.staffId]);
const onDelete = (record) => {
Modal.confirm({
title: "提示",
content: "数据将会删除,您是否确认删除?",
okText: "是",
cancelText: "否",
onOk: async () => {
const res = await props.staffInfoRemove?.({ id: record.staffId || record.id });
if (res?.success !== false) {
message.success("删除成功");
getData();
}
else {
message.error(res?.message || "删除失败");
}
},
});
};
const openResignAudit = async (record) => {
try {
const res = await safeRequest(props.staffResignationInfo, { id: record.resignApplyId });
setResignInfo(res?.data || {});
setSelectedStaff(record);
setRejectReason("");
setAuditModalOpen(true);
}
catch (err) {
console.warn("[PersonnelChange] openResignAudit failed:", err);
message.error("获取离职申请详情失败");
}
};
const openResignView = async (record) => {
try {
const res = await safeRequest(props.staffResignationInfo, { id: record.resignApplyId });
setResignInfo(res?.data || {});
setViewResignOpen(true);
}
catch (err) {
console.warn("[PersonnelChange] openResignView failed:", err);
message.error("获取离职申请详情失败");
}
};
const submitAudit = async (passed) => {
if (!passed && !rejectReason?.trim()) {
message.warning("请填写退回原因");
return;
}
try {
const res = await props.staffResignationAudit({
id: resignInfo.id,
auditStatus: passed ? 1 : 2,
rejectReason: passed ? undefined : rejectReason,
});
if (res?.success !== false) {
message.success(passed ? "审核通过" : "已退回");
setAuditModalOpen(false);
getData();
}
else {
message.error(res?.message || "审核操作失败");
}
}
catch (err) {
console.warn("[PersonnelChange] submitAudit failed:", err);
message.error("审核操作失败");
}
};
if (viewMode === "log") {
return (
<PageLayout title="人员变更次数">
<Button style={{ marginBottom: 16 }} onClick={() => setViewMode("list")}>返回</Button>
<div style={{ marginBottom: 8 }}>
人员
{selectedStaff?.staffName}
</div>
<Table
columns={[
{ title: "变更事项", dataIndex: "changeItem" },
{ title: "变更时间", dataIndex: "changeTime" },
{ title: "操作人", dataIndex: "createBy" },
]}
{...logTableProps}
/>
</PageLayout>
);
}
return (
<PageLayout title="人员变更管理">
<p style={{ margin: 0, marginBottom: 24, color: "rgba(0, 0, 0, 0.45)" }}>
机构管理员在人员信息管理页面进行相应的修改操作
</p>
<Search
form={searchForm}
options={[
{ name: "likeAccount", label: "账户", placeholder: "请输入账户", colProps: SEARCH_COL },
{ name: "likeStaffName", label: "姓名", placeholder: "请输入姓名", colProps: SEARCH_COL },
formSelectField(
"employmentStatus",
"就职状态",
Object.entries(EMPLOYMENT_STATUS).map(([value, label]) => ({ label, value: Number(value) })),
{ colProps: SEARCH_COL },
),
formSelectField(
"resignAuditStatus",
"复核状态",
Object.entries(RESIGN_AUDIT_STATUS).map(([value, label]) => ({ label, value: Number(value) })),
{ colProps: SEARCH_COL, placeholder: "请选择复核状态" },
),
]}
onFinish={getData}
/>
<Table
columns={[
{ title: "账户", dataIndex: "account", width: 130 },
{ title: "姓名", dataIndex: "staffName", width: 100 },
{ title: "部门", dataIndex: "deptName", width: 120 },
{
title: "信息变更数",
dataIndex: "changeCount",
width: 110,
render: (_, record) => {
const n = getChangeCount(record);
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: "employmentStatusName",
width: 90,
render: (_, record) => getEmploymentStatusLabel(record),
},
{
title: "离职申请审核状态",
dataIndex: "resignAuditStatus",
width: 140,
render: (_, record) => getResignAuditStatusLabel(record),
},
{
title: "操作",
width: 220,
fixed: "right",
render: (_, record) => (
<Space>
<Button type="link" style={{ padding: 0 }} onClick={() => openResignView(record)}>查看</Button>
{record.resignApplyId && Number(record.resignAuditStatus) === 0 && (
<Button type="link" style={{ padding: 0 }} onClick={() => openResignAudit(record)}>离职审核</Button>
)}
<Button danger type="link" style={{ padding: 0 }} onClick={() => onDelete(record)}>删除</Button>
</Space>
),
},
]}
{...tableProps}
/>
<Modal
open={auditModalOpen}
destroyOnClose
title="审核离职申请"
width={720}
footer={(
<Space>
<Button onClick={() => setAuditModalOpen(false)}>取消</Button>
<Button danger onClick={() => submitAudit(false)}>退回</Button>
<Button type="primary" onClick={() => submitAudit(true)}>通过</Button>
</Space>
)}
onCancel={() => setAuditModalOpen(false)}
>
<Descriptions bordered column={1} labelStyle={{ width: 120 }}>
<Descriptions.Item label="申请人">{resignInfo.applicantName}</Descriptions.Item>
<Descriptions.Item label="申请时间">{resignInfo.applyTime}</Descriptions.Item>
<Descriptions.Item label="预计离职日期">{resignInfo.expectedLeaveDate}</Descriptions.Item>
<Descriptions.Item label="离职原因">{resignInfo.leaveReason}</Descriptions.Item>
<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}
destroyOnClose
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>
<Descriptions.Item label="预计离职日期">{resignInfo.expectedLeaveDate}</Descriptions.Item>
<Descriptions.Item label="离职原因">{resignInfo.leaveReason}</Descriptions.Item>
<Descriptions.Item label="备注">{resignInfo.remark}</Descriptions.Item>
</Descriptions>
</Modal>
</PageLayout>
);
}
export default Connect([NS_STAFF_CHANGE_LOG, NS_STAFF_INFO], true)(PersonnelChangePage);