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

372 lines
11 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,
DatePicker,
Descriptions,
Form,
Input,
message,
Modal,
Select,
Table,
Tag,
} from "antd";
import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction";
import AttachmentUpload from "~/components/AttachmentUpload";
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_INFO,
NS_STAFF_RESIGNATION_APPLY,
} from "~/enumerate/namespace";
import {
RESIGN_AUDIT_STATUS_LABEL,
AUDIT_STATUS_COLOR,
} from "~/utils/enterpriseForm";
const { router } = tools;
function ResignationApplyPage(props) {
const [addModalOpen, setAddModalOpen] = useState(false);
const [viewModalOpen, setViewModalOpen] = useState(false);
const [currentId, setCurrentId] = useState("");
const [staffOptions, setStaffOptions] = useState([]);
const [searchForm] = Form.useForm();
const { staffResignationApply } = props;
const {
staffResignationApplyList: dataSource,
staffResignationApplyTotal: total,
staffResignationApplyLoading: loading,
} = staffResignationApply || {};
const handleSearch = () => {
props.staffResignationApplyList({ ...router.query });
};
useEffect(() => {
searchForm.setFieldsValue(router.query);
handleSearch();
}, []);
useEffect(() => {
let cancelled = false;
props
.staffInfoList?.({ current: 1, size: 500, employmentStatusCode: 1 })
.then((res) => {
if (!cancelled) {
setStaffOptions(
(res?.data || []).map((s) => ({
label: `${s.userName ?? s.staffName}${s.account}`,
value: s.id,
staffName: s.userName ?? s.staffName,
account: s.account,
})),
);
}
})
.catch(() => {});
return () => {
cancelled = true;
};
}, []);
return (
<PageLayout
title={
<div>
<span>离职申请管理</span>
<div className="pageLayout-extra">
机构管理员在人员信息管理页面进行相应的修改操作
</div>
</div>
}
extra={
<Button
type="primary"
style={{ marginTop: 16 }}
onClick={() => {
setCurrentId("");
setAddModalOpen(true);
}}
>
新增离职申请
</Button>
}
>
<SearchForm
style={{ marginBottom: 24 }}
form={searchForm}
loading={loading}
formLine={[
<Form.Item key="applicantName" name="applicantName">
<ControlWrapper.Input
label="姓名"
placeholder="请输入"
allowClear
/>
</Form.Item>,
<Form.Item key="auditStatusCode" name="auditStatusCode">
<ControlWrapper.Select
label="离职申请审核状态"
placeholder="请选择"
allowClear
style={{ width: "100%" }}
>
{Object.entries(RESIGN_AUDIT_STATUS_LABEL).map(
([value, label]) => (
<Select.Option key={value} value={Number(value)}>
{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="id"
columns={[
{ title: "账户", dataIndex: "account", width: 140 },
{ title: "姓名", dataIndex: "applicantName", width: 100 },
{ title: "部门", dataIndex: "deptName", width: 160 },
{ title: "申请时间", dataIndex: "applyTime", width: 160 },
{
title: "离职申请审核状态",
dataIndex: "auditStatusCode",
width: 140,
render: (_, record) => {
const code = record.auditStatusCode ?? record.auditStatus;
const label = RESIGN_AUDIT_STATUS_LABEL[code] ?? "-";
return <Tag color={AUDIT_STATUS_COLOR[code]}>{label}</Tag>;
},
},
{
title: "操作",
width: 80,
render: (_, record) => (
<TableAction>
<Button
type="link"
size="small"
onClick={() => {
setCurrentId(record.id);
setViewModalOpen(true);
}}
>
查看
</Button>
</TableAction>
),
},
]}
dataSource={dataSource}
scroll={{ y: props.scrollY }}
loading={loading}
pagination={{
total,
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();
},
}}
/>
<AddModal
open={addModalOpen}
staffOptions={staffOptions}
requestAdd={props.staffResignationApplyAdd}
onCancel={() => setAddModalOpen(false)}
onSuccess={handleSearch}
/>
<ViewModal
open={viewModalOpen}
currentId={currentId}
requestDetail={props.staffResignationApplyInfo}
onCancel={() => {
setViewModalOpen(false);
setCurrentId("");
}}
/>
</PageLayout>
);
}
function AddModal({ open, staffOptions, requestAdd, onCancel, onSuccess }) {
const [form] = Form.useForm();
const [submitting, setSubmitting] = useState(false);
const handleCancel = () => {
form.resetFields();
onCancel();
};
const handleSubmit = async () => {
try {
const values = await form.validateFields();
if (!values.reportFileUrl?.length) {
form.setFields([
{ name: "reportFileUrl", errors: ["请上传离职通知报告"] },
]);
return;
}
setSubmitting(true);
values.applyTime =
values.applyTime?.format?.("YYYY-MM-DD HH:mm:ss") || values.applyTime;
values.expectedResignDate =
values.expectedResignDate?.format?.("YYYY-MM-DD") ||
values.expectedResignDate;
values.reportFileUrl = values.reportFileUrl?.map?.((f) => f.url).filter(Boolean).join(",") || undefined;
const res = await requestAdd(values);
if (res?.success !== false) {
message.success("提交成功");
handleCancel();
onSuccess();
}
} catch {
// validation error
} finally {
setSubmitting(false);
}
};
return (
<Modal
open={open}
destroyOnHidden
title="添加离职申请"
width={720}
confirmLoading={submitting}
onCancel={handleCancel}
onOk={handleSubmit}
>
<Form form={form} layout="vertical">
<Form.Item
name="personnelId"
label="申请人"
rules={[{ required: true, message: "请选择申请人" }]}
>
<Select
showSearch
placeholder="请选择申请人"
options={staffOptions}
optionFilterProp="label"
/>
</Form.Item>
<Form.Item
name="applyTime"
label="申请时间"
rules={[{ required: true, message: "请选择申请时间" }]}
>
<DatePicker showTime style={{ width: "100%" }} />
</Form.Item>
<Form.Item
name="expectedResignDate"
label="预计离职日期"
rules={[{ required: true, message: "请选择预计离职日期" }]}
>
<DatePicker style={{ width: "100%" }} />
</Form.Item>
<Form.Item
name="resignReason"
label="离职原因"
rules={[{ required: true, message: "请输入离职原因" }]}
>
<Input.TextArea rows={3} placeholder="请输入离职原因" />
</Form.Item>
<Form.Item name="remark" label="备注">
<Input.TextArea rows={2} placeholder="请输入备注" />
</Form.Item>
<AttachmentUpload
name="reportFileUrl"
label="离职通知报告"
maxCount={1}
accept=".pdf"
/>
</Form>
</Modal>
);
}
function ViewModal({ open, currentId, requestDetail, onCancel }) {
const [info, setInfo] = useState({});
const [detailLoading, setDetailLoading] = useState(false);
useEffect(() => {
if (!open || !currentId) {
setInfo({});
return;
}
let cancelled = false;
setDetailLoading(true);
requestDetail({ id: currentId })
.then((res) => {
if (!cancelled) setInfo(res?.data || {});
})
.finally(() => {
if (!cancelled) setDetailLoading(false);
});
return () => {
cancelled = true;
};
}, [open, currentId]);
return (
<Modal
open={open}
destroyOnHidden
title="查看离职申请"
width={720}
loading={detailLoading}
cancelText="返回"
okButtonProps={{ style: { display: "none" } }}
onCancel={onCancel}
>
<Descriptions bordered column={1} labelStyle={{ width: 120 }}>
<Descriptions.Item label="申请人">
{info.applicantName}
</Descriptions.Item>
<Descriptions.Item label="申请时间">{info.applyTime}</Descriptions.Item>
<Descriptions.Item label="预计离职日期">
{info.expectedResignDate}
</Descriptions.Item>
<Descriptions.Item label="离职原因">
{info.resignReason}
</Descriptions.Item>
<Descriptions.Item label="备注">{info.remark}</Descriptions.Item>
<Descriptions.Item label="离职通知报告">
{info.reportFileUrl ? (
<a href={info.reportFileUrl} target="_blank" rel="noopener noreferrer">
查看文件
</a>
) : (
"-"
)}
</Descriptions.Item>
</Descriptions>
</Modal>
);
}
export default Connect(
[NS_STAFF_RESIGNATION_APPLY, NS_STAFF_INFO],
true,
)(AntdTableFuncControl(ResignationApplyPage));