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

351 lines
12 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, Table, Tag, Typography } from "antd";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
import { useEffect, useState } from "react";
import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout";
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";
import { NS_STAFF_CHANGE_LOG, NS_STAFF_INFO } from "~/enumerate/namespace";
import {
CHANGE_COUNT_STYLE,
RESIGN_AUDIT_STATUS_LABEL,
AUDIT_STATUS_COLOR,
} from "~/utils/enterpriseForm";
const { router } = tools;
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,
}));
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 { staffChangeLog } = props;
const {
staffChangeLogStaffList: staffList,
staffChangeLogStaffTotal: staffTotal,
staffChangeLogLoading: loading,
staffChangeLogChangeList: changeList,
staffChangeLogChangeTotal: changeTotal,
} = staffChangeLog || {};
const handleSearch = () => {
props.staffChangeLogStaffList({ ...router.query });
};
useEffect(() => {
searchForm.setFieldsValue(router.query);
handleSearch();
}, []);
const handleLogSearch = () => {
if (selectedStaff?.staffId) {
props.staffChangeLogList({ eqStaffId: selectedStaff.staffId });
}
};
useEffect(() => {
if (viewMode === "log" && selectedStaff?.staffId) {
handleLogSearch();
}
}, [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("删除成功");
handleSearch();
} else {
message.error(res?.message || "删除失败");
}
},
});
};
const openResignAudit = async (record) => {
try {
const res = await props.staffResignationInfo({ id: record.resignApplyId });
const data = res?.data || {};
setResignInfo(data);
setSelectedStaff(record);
setRejectReason("");
setAuditModalOpen(true);
} catch {
message.error("获取离职申请详情失败");
}
};
const openResignView = async (record) => {
try {
const res = await props.staffResignationInfo({ id: record.resignApplyId });
setResignInfo(res?.data || {});
setViewResignOpen(true);
} catch {
message.error("获取离职申请详情失败");
}
};
const submitAudit = async (passed) => {
if (!passed && !rejectReason?.trim()) {
message.warning("请填写退回原因");
return;
}
try {
const res = await props.staffResignationAudit({
id: resignInfo.id,
auditStatusCode: passed ? 1 : 2,
auditStatusName: passed ? "已审核" : "已退回",
rejectReason: passed ? undefined : rejectReason,
});
if (res?.success !== false) {
message.success(passed ? "审核通过" : "已退回");
setAuditModalOpen(false);
handleSearch();
} else {
message.error(res?.message || "审核操作失败");
}
} catch {
message.error("审核操作失败");
}
};
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;
const label = RESIGN_AUDIT_STATUS_LABEL[code] ?? "-";
return <Tag color={AUDIT_STATUS_COLOR[code]}>{label}</Tag>;
},
},
{
title: "操作",
width: 200,
fixed: "right",
render: (_, record) => (
<TableAction>
<Button type="link" size="small" onClick={() => openResignView(record)}>
查看
</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 },
];
if (viewMode === "log") {
return (
<PageLayout title="人员变更次数">
<Button style={{ marginBottom: 16 }} onClick={() => setViewMode("list")}>
返回
</Button>
<div style={{ marginBottom: 8 }}>人员{selectedStaff?.staffName || selectedStaff?.userName}</div>
<Table
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();
},
}}
/>
</PageLayout>
);
}
return (
<PageLayout
title={
<div>
<span>人员变更管理</span>
<div className="pageLayout-extra">
机构管理员在人员信息管理页面进行相应的修改操作
</div>
</div>
}
>
<SearchForm
style={{ marginBottom: 24 }}
form={searchForm}
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>,
]}
onReset={(value) => {
router.query = { ...value, current: 1, size: 10 };
handleSearch();
}}
onFinish={(value) => {
router.query = { ...value, current: 1, size: 10 };
handleSearch();
}}
/>
<Table
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();
},
}}
/>
<Modal
open={auditModalOpen}
destroyOnHidden
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.expectedResignDate}</Descriptions.Item>
<Descriptions.Item label="离职原因">{resignInfo.resignReason}</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}
destroyOnHidden
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.expectedResignDate}</Descriptions.Item>
<Descriptions.Item label="离职原因">{resignInfo.resignReason}</Descriptions.Item>
<Descriptions.Item label="备注">{resignInfo.remark}</Descriptions.Item>
</Descriptions>
</Modal>
</PageLayout>
);
}
export default Connect([NS_STAFF_CHANGE_LOG, NS_STAFF_INFO], true)(AntdTableFuncControl(PersonnelChangePage));