From 950980d48b133ed3810886402f49b7bfd728a95f Mon Sep 17 00:00:00 2001 From: tangjie <122778500@qq.com> Date: Tue, 7 Jul 2026 09:07:19 +0800 Subject: [PATCH] feat --- src/api/staffCertificate/index.js | 86 ++--- src/api/staffChangeLog/index.js | 59 ++- src/api/staffInfo/index.js | 62 ++- src/api/staffResignationApply/index.js | 38 +- .../DepartmentPosition/index.js | 5 +- .../EnterpriseInfo/PersonnelChange/index.js | 335 +++++++++------- .../PersonnelInfo/Certificate/index.js | 358 ++++++++++-------- .../PersonnelInfo/List/index.js | 344 +++++++++-------- .../PersonnelInfo/StaffViewModal.js | 27 +- .../EnterpriseInfo/ResignationApply/index.js | 354 ++++++++++------- 10 files changed, 927 insertions(+), 741 deletions(-) diff --git a/src/api/staffCertificate/index.js b/src/api/staffCertificate/index.js index 7c8442d..cfe44b6 100644 --- a/src/api/staffCertificate/index.js +++ b/src/api/staffCertificate/index.js @@ -1,55 +1,53 @@ import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; -import { - fromPageResponse, - fromSingleResponse, - fromStaffCertForm, - toPageQuery, - toStaffCertForm, -} from "../enterpriseInfo/adapter"; -import { apiGet, apiPost, apiPostDelete, safeAction, safePageResult } from "../enterpriseInfo/http"; +import { Get } from "@cqsjjb/jjb-common-lib/http"; -export const staffCertificateList = declareRequest("staffCertificateLoading", safePageResult(async (params) => { - const query = toPageQuery(params, { - eqStaffId: "personnelId", - likeCertNo: "certNo", - }); - const res = await apiGet("/safetyEval/org-personnel-cert/page", query); - return fromPageResponse(res, toStaffCertForm); -})); +export const staffCertificateList = declareRequest( + "staffCertificateLoading", + "Get > /safetyEval/org-personnel-cert/page", + "staffCertificateList: [] | res.data || [] & staffCertificateTotal: 0 | res.data?.total || 0", +); -export const staffCertificateInfo = declareRequest("staffCertificateLoading", safeAction(async (params) => { - const res = await apiGet("/safetyEval/org-personnel-cert/get", { id: params.id }); - return fromSingleResponse(res, toStaffCertForm); -})); +export const staffCertificateInfo = declareRequest( + "staffCertificateLoading", + "Get > /safetyEval/org-personnel-cert/get", + "staffCertificateDetail: {} | res.data || {}", +); -export const staffCertificateAdd = declareRequest("staffCertificateLoading", safeAction(async (values) => { - const res = await apiPost("/safetyEval/org-personnel-cert/save", fromStaffCertForm(values)); - return fromSingleResponse(res, toStaffCertForm); -})); +export const staffCertificateAdd = declareRequest( + "staffCertificateLoading", + "Post > @/safetyEval/org-personnel-cert/save", +); -export const staffCertificateEdit = declareRequest("staffCertificateLoading", safeAction(async (values) => { - const res = await apiPost("/safetyEval/org-personnel-cert/modify", fromStaffCertForm(values)); - return fromSingleResponse(res, toStaffCertForm); -})); +export const staffCertificateEdit = declareRequest( + "staffCertificateLoading", + "Post > @/safetyEval/org-personnel-cert/modify", +); -export const staffCertificateRemove = declareRequest("staffCertificateLoading", safeAction(async ({ id }) => { - return apiPostDelete("/safetyEval/org-personnel-cert/delete", id); -})); +export const staffCertificateRemove = declareRequest( + "staffCertificateLoading", + "Post > @/safetyEval/org-personnel-cert/delete", +); +/** StaffViewModal 直接调用的辅助函数 — 获取人员下所有证书列表 */ export async function fetchStaffCertListByPersonnelId(personnelId) { - const query = toPageQuery({ - pageIndex: 1, - pageSize: 999, - eqStaffId: personnelId, - }, { - eqStaffId: "personnelId", - }); - const res = await apiGet("/safetyEval/org-personnel-cert/page", query); - const page = fromPageResponse(res, toStaffCertForm); - return page?.data || []; + try { + const res = await Get("/safetyEval/org-personnel-cert/page", { + current: 1, + size: 999, + personnelId, + }); + return res?.data || []; + } catch { + return []; + } } +/** StaffViewModal 直接调用的辅助函数 — 获取证书详情 */ export async function fetchStaffCertDetail({ id }) { - const res = await apiGet("/safetyEval/org-personnel-cert/get", { id }); - return fromSingleResponse(res, toStaffCertForm); -} + try { + const res = await Get("/safetyEval/org-personnel-cert/get", { id }); + return res?.data || null; + } catch { + return null; + } +} \ No newline at end of file diff --git a/src/api/staffChangeLog/index.js b/src/api/staffChangeLog/index.js index d16fd62..7a3fbbd 100644 --- a/src/api/staffChangeLog/index.js +++ b/src/api/staffChangeLog/index.js @@ -1,42 +1,29 @@ import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; -import { - fromPageResponse, - fromResignAuditForm, - fromSingleResponse, - toChangeLogForm, - toPageQuery, - toResignApplyForm, - toStaffChangeSummary, -} from "../enterpriseInfo/adapter"; -import { apiGet, apiPost, apiPostDelete, safeAction, safePageResult } from "../enterpriseInfo/http"; -export const staffChangeLogStaffList = declareRequest("staffChangeLogLoading", safePageResult(async (params) => { - const query = toPageQuery(params, { - likeAccount: "account", - likeStaffName: "userName", - employmentStatus: "employmentStatusCode", - resignAuditStatus: "resignAuditStatus", - }); - const res = await apiGet("/safetyEval/org-personnel/page", query); - return fromPageResponse(res, toStaffChangeSummary); -})); +export const staffChangeLogStaffList = declareRequest( + "staffChangeLogLoading", + "Get > /safetyEval/org-personnel/page", + "staffChangeLogStaffList: [] | res.data || [] & staffChangeLogStaffTotal: 0 | res.total || 0", +); -export const staffChangeLogList = declareRequest("staffChangeLogLoading", safePageResult(async (params) => { - const query = toPageQuery(params, { eqStaffId: "personnelId" }); - const res = await apiGet("/safetyEval/org-personnel-change/page", query); - return fromPageResponse(res, toChangeLogForm); -})); +export const staffChangeLogList = declareRequest( + "staffChangeLogLoading", + "Get > /safetyEval/org-personnel-change/page", + "staffChangeLogChangeList: [] | res.data || [] & staffChangeLogChangeTotal: 0 | res.total || 0", +); -export const staffChangeLogRemove = declareRequest("staffChangeLogLoading", safeAction(async ({ id }) => { - return apiPostDelete("/safetyEval/org-personnel-change/delete", id); -})); +export const staffChangeLogRemove = declareRequest( + "staffChangeLogLoading", + "Post > @/safetyEval/org-personnel-change/delete", +); -export const staffResignationAudit = declareRequest("staffChangeLogLoading", safeAction(async (params) => { - const res = await apiPost("/safetyEval/org-resign-apply/modify", fromResignAuditForm(params)); - return fromSingleResponse(res, toResignApplyForm); -})); +export const staffResignationAudit = declareRequest( + "staffChangeLogLoading", + "Post > @/safetyEval/org-resign-apply/modify", +); -export const staffResignationInfo = declareRequest("staffChangeLogLoading", safeAction(async (params) => { - const res = await apiGet("/safetyEval/org-resign-apply/get", { id: params.id }); - return fromSingleResponse(res, toResignApplyForm); -})); +export const staffResignationInfo = declareRequest( + "staffChangeLogLoading", + "Get > /safetyEval/org-resign-apply/get", + "staffResignationDetail: {} | res.data || {}", +); \ No newline at end of file diff --git a/src/api/staffInfo/index.js b/src/api/staffInfo/index.js index b4ff7d3..d47b007 100644 --- a/src/api/staffInfo/index.js +++ b/src/api/staffInfo/index.js @@ -1,43 +1,33 @@ import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; -import { - fromPageResponse, - fromSingleResponse, - fromStaffForm, - toPageQuery, - toStaffForm, -} from "../enterpriseInfo/adapter"; -import { apiGet, apiPost, apiPostDelete, safeAction, safePageResult } from "../enterpriseInfo/http"; -export const staffInfoList = declareRequest("staffInfoLoading", safePageResult(async (params) => { - const query = toPageQuery(params, { - likeStaffName: "userName", - eqDeptId: "deptId", - eqPositionId: "postId", - }); - const res = await apiGet("/safetyEval/org-personnel/page", query); - return fromPageResponse(res, toStaffForm); -})); +export const staffInfoList = declareRequest( + "staffInfoLoading", + "Get > /safetyEval/org-personnel/page", + "staffInfoList: [] | res.data || [] & staffInfoTotal: 0 | res.data?.total || 0", +); -export const staffInfoGet = declareRequest("staffInfoLoading", safeAction(async (params) => { - const res = await apiGet("/safetyEval/org-personnel/get", { id: params.id }); - return fromSingleResponse(res, toStaffForm); -})); +export const staffInfoGet = declareRequest( + "staffInfoLoading", + "Get > /safetyEval/org-personnel/get", + "staffInfoDetail: {} | res.data || {}", +); -export const staffInfoAdd = declareRequest("staffInfoLoading", safeAction(async (values) => { - const res = await apiPost("/safetyEval/org-personnel/save", fromStaffForm(values)); - return fromSingleResponse(res, toStaffForm); -})); +export const staffInfoAdd = declareRequest( + "staffInfoLoading", + "Post > @/safetyEval/org-personnel/save", +); -export const staffInfoEdit = declareRequest("staffInfoLoading", safeAction(async (values) => { - const res = await apiPost("/safetyEval/org-personnel/modify", fromStaffForm(values)); - return fromSingleResponse(res, toStaffForm); -})); +export const staffInfoEdit = declareRequest( + "staffInfoLoading", + "Post > @/safetyEval/org-personnel/modify", +); -export const staffInfoRemove = declareRequest("staffInfoLoading", safeAction(async ({ id }) => { - return apiPostDelete("/safetyEval/org-personnel/delete", id); -})); +export const staffInfoRemove = declareRequest( + "staffInfoLoading", + "Post > @/safetyEval/org-personnel/delete", +); -/** 后端暂未提供重置密码接口 */ -export const staffInfoResetPassword = declareRequest("staffInfoLoading", safeAction(async ({ id }) => { - return apiPost(`/safetyEval/org-personnel/reset-password?id=${id}`); -})); +export const staffInfoResetPassword = declareRequest( + "staffInfoLoading", + "Get > /safetyEval/org-personnel/reset-password", +); \ No newline at end of file diff --git a/src/api/staffResignationApply/index.js b/src/api/staffResignationApply/index.js index fb03b9b..d97c325 100644 --- a/src/api/staffResignationApply/index.js +++ b/src/api/staffResignationApply/index.js @@ -1,28 +1,18 @@ import { declareRequest } from "@cqsjjb/jjb-dva-runtime"; -import { - fromPageResponse, - fromResignApplyForm, - fromSingleResponse, - toPageQuery, - toResignApplyForm, -} from "../enterpriseInfo/adapter"; -import { apiGet, apiPost, safeAction, safePageResult } from "../enterpriseInfo/http"; -export const staffResignationApplyList = declareRequest("staffResignationApplyLoading", safePageResult(async (params) => { - const query = toPageQuery(params, { - likeStaffName: "applicantName", - auditStatus: "auditStatusCode", - }); - const res = await apiGet("/safetyEval/org-resign-apply/page", query); - return fromPageResponse(res, toResignApplyForm); -})); +export const staffResignationApplyList = declareRequest( + "staffResignationApplyLoading", + "Get > /safetyEval/org-resign-apply/page", + "staffResignationApplyList: [] | res.data || [] & staffResignationApplyTotal: 0 | res.total || 0", +); -export const staffResignationApplyInfo = declareRequest("staffResignationApplyLoading", safeAction(async (params) => { - const res = await apiGet("/safetyEval/org-resign-apply/get", { id: params.id }); - return fromSingleResponse(res, toResignApplyForm); -})); +export const staffResignationApplyInfo = declareRequest( + "staffResignationApplyLoading", + "Get > /safetyEval/org-resign-apply/get", + "resignApplyDetail: {} | res.data || {}", +); -export const staffResignationApplyAdd = declareRequest("staffResignationApplyLoading", safeAction(async (values) => { - const res = await apiPost("/safetyEval/org-resign-apply/save", fromResignApplyForm(values)); - return fromSingleResponse(res, toResignApplyForm); -})); +export const staffResignationApplyAdd = declareRequest( + "staffResignationApplyLoading", + "Post > @/safetyEval/org-resign-apply/save", +); \ No newline at end of file diff --git a/src/pages/Container/EnterpriseInfo/DepartmentPosition/index.js b/src/pages/Container/EnterpriseInfo/DepartmentPosition/index.js index ff70910..0b47aff 100644 --- a/src/pages/Container/EnterpriseInfo/DepartmentPosition/index.js +++ b/src/pages/Container/EnterpriseInfo/DepartmentPosition/index.js @@ -1,5 +1,6 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; import { Button, Empty, Form, Input, message, Modal, Row, Col, Select, Space, Tree } from "antd"; +import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction"; import { useEffect, useMemo, useRef, useState } from "react"; import AddIcon from "zy-react-library/components/Icon/AddIcon"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; @@ -271,10 +272,10 @@ function DepartmentPositionPage(props) { title: "操作", width: 160, render: (_, record) => ( - + - + ), }, ]} diff --git a/src/pages/Container/EnterpriseInfo/PersonnelChange/index.js b/src/pages/Container/EnterpriseInfo/PersonnelChange/index.js index 3757e8a..e0b8cf6 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelChange/index.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelChange/index.js @@ -1,18 +1,30 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; -import { Button, Descriptions, Form, Input, message, Modal, Select, Space, Typography } from "antd"; +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 Search from "zy-react-library/components/Search"; -import Table from "zy-react-library/components/Table"; -import useTable from "zy-react-library/hooks/useTable"; +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 { safeListRequest, safeRequest } from "~/utils"; -import { CHANGE_COUNT_STYLE, formSelectField, getChangeCount, getEmploymentStatusLabel, getResignAuditStatusLabel } from "~/utils/enterpriseForm"; +import { + CHANGE_COUNT_STYLE, + RESIGN_AUDIT_STATUS_LABEL, + AUDIT_STATUS_COLOR, +} from "~/utils/enterpriseForm"; +const { router } = tools; -const EMPLOYMENT_STATUS = { 1: "在职", 2: "离职" }; -const RESIGN_AUDIT_STATUS = { 0: "未审核", 1: "已审核", 2: "已退回" }; -const SEARCH_COL = { xs: 24, sm: 12, md: 8, lg: 6 }; +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"); @@ -22,27 +34,34 @@ function PersonnelChangePage(props) { 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 { staffChangeLog } = props; + const { + staffChangeLogStaffList: staffList, + staffChangeLogStaffTotal: staffTotal, + staffChangeLogLoading: loading, + staffChangeLogChangeList: changeList, + staffChangeLogChangeTotal: changeTotal, + } = staffChangeLog || {}; - const { tableProps: logTableProps, getData: getLogData } = useTable( - safeListRequest(props.staffChangeLogList), - { - form: logForm, - transform: () => ({ eqStaffId: selectedStaff?.staffId }), - }, - ); + const handleSearch = () => { + props.staffChangeLogStaffList({ ...router.query }); + }; useEffect(() => { - getData(); + searchForm.setFieldsValue(router.query); + handleSearch(); }, []); + const handleLogSearch = () => { + if (selectedStaff?.staffId) { + props.staffChangeLogList({ eqStaffId: selectedStaff.staffId }); + } + }; + useEffect(() => { if (viewMode === "log" && selectedStaff?.staffId) { - getLogData(); + handleLogSearch(); } }, [viewMode, selectedStaff?.staffId]); @@ -56,9 +75,8 @@ function PersonnelChangePage(props) { const res = await props.staffInfoRemove?.({ id: record.staffId || record.id }); if (res?.success !== false) { message.success("删除成功"); - getData(); - } - else { + handleSearch(); + } else { message.error(res?.message || "删除失败"); } }, @@ -67,26 +85,23 @@ function PersonnelChangePage(props) { const openResignAudit = async (record) => { try { - const res = await safeRequest(props.staffResignationInfo, { id: record.resignApplyId }); - setResignInfo(res?.data || {}); + const res = await props.staffResignationInfo({ id: record.resignApplyId }); + const data = res?.data || {}; + setResignInfo(data); setSelectedStaff(record); setRejectReason(""); setAuditModalOpen(true); - } - catch (err) { - console.warn("[PersonnelChange] openResignAudit failed:", err); + } catch { message.error("获取离职申请详情失败"); } }; const openResignView = async (record) => { try { - const res = await safeRequest(props.staffResignationInfo, { id: record.resignApplyId }); + const res = await props.staffResignationInfo({ id: record.resignApplyId }); setResignInfo(res?.data || {}); setViewResignOpen(true); - } - catch (err) { - console.warn("[PersonnelChange] openResignView failed:", err); + } catch { message.error("获取离职申请详情失败"); } }; @@ -99,39 +114,121 @@ function PersonnelChangePage(props) { try { const res = await props.staffResignationAudit({ id: resignInfo.id, - auditStatus: passed ? 1 : 2, + auditStatusCode: passed ? 1 : 2, + auditStatusName: passed ? "已审核" : "已退回", rejectReason: passed ? undefined : rejectReason, }); if (res?.success !== false) { message.success(passed ? "审核通过" : "已退回"); setAuditModalOpen(false); - getData(); - } - else { + handleSearch(); + } else { message.error(res?.message || "审核操作失败"); } - } - catch (err) { - console.warn("[PersonnelChange] submitAudit failed:", err); + } 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 {n}; + } + return ( + { + setSelectedStaff(record); + setViewMode("log"); + }} + > + {n} + + ); + }, + }, + { + title: "就职状态", + dataIndex: "employmentStatusCode", + width: 90, + render: (_, record) => { + const code = record.employmentStatusCode ?? record.employmentStatus; + return {code === 2 ? "离职" : "在职"}; + }, + }, + { + title: "离职申请审核状态", + dataIndex: "resignAuditStatus", + width: 140, + render: (_, record) => { + const code = record.resignAuditStatus ?? record.auditStatus ?? record.auditStatusCode; + const label = RESIGN_AUDIT_STATUS_LABEL[code] ?? "-"; + return {label}; + }, + }, + { + title: "操作", + width: 200, + fixed: "right", + render: (_, record) => ( + + + {record.resignApplyId && Number(record.resignAuditStatus) === 0 && ( + + )} + + + ), + }, + ]; + + const logColumns = [ + { title: "变更事项", dataIndex: "changeItem", width: 200 }, + { title: "变更时间", dataIndex: "changeTime", width: 160 }, + { title: "操作人", dataIndex: "createBy", width: 100 }, + ]; + if (viewMode === "log") { return ( - -
- 人员: - {selectedStaff?.staffName} -
+ +
人员:{selectedStaff?.staffName || selectedStaff?.userName}
`共 ${t} 条`, + current: router.query.current || 1, + pageSize: router.query.size || 10, + onChange: (page, pageSize) => { + router.query = { ...router.query, current: page, size: pageSize }; + handleLogSearch(); + }, + }} /> ); @@ -148,82 +245,60 @@ function PersonnelChangePage(props) { } > - ({ 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: "请选择复核状态" }, - ), + loading={loading} + formLine={[ + + + , + + + , + + + {EMPLOYMENT_STATUS_OPTIONS.map((o) => ( + {o.label} + ))} + + , + + + {RESIGN_AUDIT_OPTIONS.map((o) => ( + {o.label} + ))} + + , ]} - onFinish={getData} + onReset={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} + onFinish={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} /> +
{ - const n = getChangeCount(record); - const style = n > 0 ? CHANGE_COUNT_STYLE.active : CHANGE_COUNT_STYLE.zero; - if (n <= 0) { - return {n}; - } - return ( - { - setSelectedStaff(record); - setViewMode("log"); - }} - > - {n} - - ); - }, + 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(); }, - { - 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) => ( - - - {record.resignApplyId && Number(record.resignAuditStatus) === 0 && ( - - )} - - - ), - }, - ]} - {...tableProps} + }} /> - )} + } onCancel={() => setAuditModalOpen(false)} > {resignInfo.applicantName} {resignInfo.applyTime} - {resignInfo.expectedLeaveDate} - {resignInfo.leaveReason} + {resignInfo.expectedResignDate} + {resignInfo.resignReason} {resignInfo.remark} @@ -264,8 +339,8 @@ function PersonnelChangePage(props) { {resignInfo.applicantName} {resignInfo.applyTime} - {resignInfo.expectedLeaveDate} - {resignInfo.leaveReason} + {resignInfo.expectedResignDate} + {resignInfo.resignReason} {resignInfo.remark} @@ -273,4 +348,4 @@ function PersonnelChangePage(props) { ); } -export default Connect([NS_STAFF_CHANGE_LOG, NS_STAFF_INFO], true)(PersonnelChangePage); +export default Connect([NS_STAFF_CHANGE_LOG, NS_STAFF_INFO], true)(AntdTableFuncControl(PersonnelChangePage)); \ No newline at end of file diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js index 6645da3..b3692cc 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/Certificate/index.js @@ -1,45 +1,42 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; -import { Button, Descriptions, Form, message, Modal, Space } from "antd"; +import { Button, DatePicker, Descriptions, Form, Input, message, Modal, Select, Table, Upload } from "antd"; +import { UploadOutlined } from "@ant-design/icons"; import { useEffect, useState } from "react"; -import FormBuilder from "zy-react-library/components/FormBuilder"; -import AddIcon from "zy-react-library/components/Icon/AddIcon"; import PageLayout from "@cqsjjb/jjb-react-admin-component/PageLayout"; -import CertPreviewImg from "~/components/CertPreviewImg"; -import Search from "zy-react-library/components/Search"; -import Table from "zy-react-library/components/Table"; -import Upload from "zy-react-library/components/Upload"; -import { FORM_ITEM_RENDER_ENUM } from "zy-react-library/enum/formItemRender"; -import useGetFile from "zy-react-library/hooks/useGetFile"; -import useGetUrlQuery from "zy-react-library/hooks/useGetUrlQuery"; -import useTable from "zy-react-library/hooks/useTable"; +import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm"; +import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper"; +import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction"; +import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd"; +import { tools } from "@cqsjjb/jjb-common-lib"; import { NS_STAFF_CERTIFICATE } from "~/enumerate/namespace"; -import { safeGetFiles, safeListRequest, safeRequest } from "~/utils"; -import { mockUploadFileList, resolveUploadFileId } from "~/utils/mockUpload"; +import CertPreviewImg from "~/components/CertPreviewImg"; import { dateRangeRule } from "~/utils/validators"; +const { router } = tools; function StaffCertificatePage(props) { - const query = useGetUrlQuery(); - const staffId = query.staffId; - const staffName = query.staffName; + const urlParams = Object.fromEntries(new URLSearchParams(window.location.search)); + const staffId = urlParams.staffId; + const staffName = urlParams.staffName ? decodeURIComponent(urlParams.staffName) : ""; const [addModalOpen, setAddModalOpen] = useState(false); const [viewModalOpen, setViewModalOpen] = useState(false); const [currentId, setCurrentId] = useState(""); - const [form] = Form.useForm(); - - const { tableProps, getData } = useTable(safeListRequest(props.staffCertificateList), { - form, - transform: (formData) => ({ - ...formData, - eqStaffId: staffId, - }), - }); + const [searchForm] = Form.useForm(); + const { staffCertificate } = props; + const { + staffCertificateList: dataSource, + staffCertificateTotal: total, + staffCertificateLoading: loading, + } = staffCertificate || {}; useEffect(() => { - if (staffId) { - getData(); - } - }, [staffId]); + searchForm.setFieldsValue(router.query); + handleSearch(); + }, []); + + const handleSearch = () => { + props.staffCertificateList({ ...router.query, personnelId: staffId }); + }; const goBack = () => { window.location.href = window.location.pathname.replace(/\/Certificate.*$/, "/List"); @@ -55,7 +52,7 @@ function StaffCertificatePage(props) { const res = await props.staffCertificateRemove({ id }); if (res?.success !== false) { message.success("删除成功"); - getData(); + handleSearch(); } }, }); @@ -64,28 +61,32 @@ function StaffCertificatePage(props) { return ( - + + , + + + , + + + , ]} - onFinish={getData} + onReset={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} + onFinish={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} />
( - - )} + rowKey="id" columns={[ { title: "证书类型", dataIndex: "certCategory" }, { title: "证书作业类别", dataIndex: "certWorkCategory" }, @@ -94,19 +95,33 @@ function StaffCertificatePage(props) { title: "操作", width: 200, render: (_, record) => ( - - - - - + + ), }, ]} - {...tableProps} + dataSource={dataSource} + scroll={{ y: props.scrollY }} + loading={loading} + pagination={{ + total, + showSizeChanger: true, + showQuickJumper: true, + showTotal: (t) => `共 ${t} 条`, + current: Number(router.query.current) || 1, + pageSize: Number(router.query.size) || 10, + onChange: (page, pageSize) => { + router.query = { ...router.query, current: page, size: pageSize }; + handleSearch(); + }, + }} /> {addModalOpen && ( @@ -114,21 +129,21 @@ function StaffCertificatePage(props) { open={addModalOpen} staffId={staffId} currentId={currentId} - requestAdd={props.staffCertificateAdd} - requestEdit={props.staffCertificateEdit} - requestDetails={props.staffCertificateInfo} + staffCertificateAdd={props.staffCertificateAdd} + staffCertificateEdit={props.staffCertificateEdit} + staffCertificateInfo={props.staffCertificateInfo} onCancel={() => { setAddModalOpen(false); setCurrentId(""); }} - onSuccess={getData} + onSuccess={handleSearch} /> )} {viewModalOpen && ( { setViewModalOpen(false); setCurrentId(""); @@ -140,83 +155,91 @@ function StaffCertificatePage(props) { } function CertModal({ - open, staffId, currentId, requestAdd, requestEdit, requestDetails, onCancel, onSuccess, + open, staffId, currentId, staffCertificateAdd, staffCertificateEdit, staffCertificateInfo, onCancel, onSuccess, }) { const [form] = Form.useForm(); const [submitting, setSubmitting] = useState(false); const [detailLoading, setDetailLoading] = useState(false); - const { getFile } = useGetFile(); + const [uploadFileList, setUploadFileList] = useState([]); useEffect(() => { - if (!open) { - return; - } + if (!open) return; if (!currentId) { form.resetFields(); - form.setFieldsValue({ certImgs: mockUploadFileList("证书附件.jpg") }); + setUploadFileList([]); return; } let cancelled = false; (async () => { setDetailLoading(true); try { - const res = await safeRequest(requestDetails, { id: currentId }); - if (cancelled || !res?.data) { - return; - } + const res = await staffCertificateInfo({ id: currentId }); + if (cancelled || !res?.data) return; const data = { ...res.data }; - data.validDate = [data.validStartDate, data.validEndDate]; - data.certImgs = data.certImgFiles?.length ? data.certImgFiles : mockUploadFileList("证书附件.jpg"); + // 将 validStartDate/validEndDate 合并为 validDate(RangePicker) + if (data.validStartDate || data.validEndDate) { + data.validDate = [data.validStartDate, data.validEndDate]; + } + // 处理证书附件 fileList + let fileList = []; + if (Array.isArray(data.certImgFiles)) { + fileList = data.certImgFiles.map((f, i) => ({ + uid: f.uid || `-${i}`, + name: f.fileName || f.name || `证书附件${i + 1}`, + status: "done", + url: f.url, + })); + } else if (data.certAttachmentUrl) { + fileList = data.certAttachmentUrl.split(",").filter(Boolean).map((url, i) => ({ + uid: `-${i}`, + name: url.split("/").pop() || `证书附件${i + 1}`, + status: "done", + url, + })); + } + data.certAttachmentUrl = fileList; + setUploadFileList(fileList); form.setFieldsValue(data); - setDetailLoading(false); - - const files = await safeGetFiles( - getFile, - { eqType: "staff_cert", eqForeignKey: data.id }, - data.certImgFiles || [], - ); - if (!cancelled && files.length) { - form.setFieldValue("certImgs", files); - } - } - catch (err) { + } catch (err) { console.warn("[StaffCertificate] load detail failed:", err); - } - finally { - if (!cancelled) { - setDetailLoading(false); - } + } finally { + if (!cancelled) setDetailLoading(false); } })(); - return () => { - cancelled = true; - }; + return () => { cancelled = true; }; }, [open, currentId]); const handleCancel = () => { form.resetFields(); + setUploadFileList([]); onCancel(); }; const handleSubmit = async (values) => { try { setSubmitting(true); - values.validStartDate = values.validDate?.[0]; - values.validEndDate = values.validDate?.[1]; - values.staffId = staffId; - values.certAttachmentUrl = resolveUploadFileId(values.certImgs); - const request = currentId ? requestEdit : requestAdd; - if (currentId) { - values.id = currentId; - } - const res = await request(values); + const payload = { + ...values, + personnelId: staffId, + validStartDate: values.validDate?.[0], + validEndDate: values.validDate?.[1], + certAttachmentUrl: Array.isArray(values.certAttachmentUrl) + ? values.certAttachmentUrl.map((f) => f.url || f.response?.url).filter(Boolean).join(",") + : "", + }; + delete payload.validDate; + delete payload.certImgFiles; + if (currentId) payload.id = currentId; + const request = currentId ? staffCertificateEdit : staffCertificateAdd; + const res = await request(payload); if (res?.success !== false) { message.success(currentId ? "编辑成功" : "添加成功"); handleCancel(); onSuccess(); + } else { + message.error(res?.message || "操作失败"); } - } - finally { + } finally { setSubmitting(false); } }; @@ -232,46 +255,60 @@ function CertModal({ onCancel={handleCancel} onOk={form.submit} > - setDeleteFiles(prev => [...prev, file])} - /> - ), - }, - ]} - labelCol={{ span: 24 }} - wrapperCol={{ span: 24 }} - /> +
+ + + + + + + + + + + + + + + + + + + + + + { + if (Array.isArray(e)) return e; + return e?.fileList; + }} + > + { + setUploadFileList(info.fileList); + }} + > + + + + ); } -function ViewModal({ open, currentId, requestDetails, onCancel }) { +function ViewModal({ open, currentId, staffCertificateInfo, onCancel }) { const [info, setInfo] = useState({}); const [detailLoading, setDetailLoading] = useState(false); - const { getFile } = useGetFile(); useEffect(() => { if (!open || !currentId) { @@ -282,36 +319,29 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) { (async () => { setDetailLoading(true); try { - const res = await safeRequest(requestDetails, { id: currentId }); - if (cancelled || !res?.data) { - return; - } + const res = await staffCertificateInfo({ id: currentId }); + if (cancelled || !res?.data) return; const data = { ...res.data }; - data.certImgs = data.certImgFiles || []; + // 处理 certImgFiles + if (Array.isArray(data.certImgFiles)) { + data.certDisplayFiles = data.certImgFiles; + } else if (data.certAttachmentUrl) { + data.certDisplayFiles = data.certAttachmentUrl.split(",").filter(Boolean).map((url, i) => ({ + uid: `-${i}`, + fileName: url.split("/").pop() || `证书附件${i + 1}`, + url, + })); + } else { + data.certDisplayFiles = []; + } setInfo(data); - setDetailLoading(false); - - const files = await safeGetFiles( - getFile, - { eqType: "staff_cert", eqForeignKey: data.id }, - data.certImgFiles || [], - ); - if (!cancelled && files.length) { - setInfo((prev) => ({ ...prev, certImgs: files })); - } - } - catch (err) { + } catch (err) { console.warn("[StaffCertificate] load view failed:", err); - } - finally { - if (!cancelled) { - setDetailLoading(false); - } + } finally { + if (!cancelled) setDetailLoading(false); } })(); - return () => { - cancelled = true; - }; + return () => { cancelled = true; }; }, [open, currentId]); return ( @@ -333,10 +363,10 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) { {info.validStartDate} {info.validEndDate} {info.reviewDate} - + ); } -export default Connect([NS_STAFF_CERTIFICATE], true)(StaffCertificatePage); +export default Connect([NS_STAFF_CERTIFICATE], true)(AntdTableFuncControl(StaffCertificatePage)); \ No newline at end of file diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js index 3de47a5..1702e89 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/List/index.js @@ -1,13 +1,16 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; -import { Button, DatePicker, Form, Input, message, Modal, Row, Col, Select, Space } from "antd"; +import { Button, DatePicker, Form, Input, message, Modal, Row, Col, Select, Table, Upload } from "antd"; +import { UploadOutlined } from "@ant-design/icons"; import { useEffect, useRef, useState } from "react"; -import AddIcon from "zy-react-library/components/Icon/AddIcon"; +import dayjs from "dayjs"; 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 Upload from "zy-react-library/components/Upload"; -import useTable from "zy-react-library/hooks/useTable"; -import { NS_ORG_DEPARTMENT, NS_ORG_POSITION, NS_STAFF_INFO } from "~/enumerate/namespace"; +import SearchForm from "@cqsjjb/jjb-react-admin-component/SearchForm"; +import ControlWrapper from "@cqsjjb/jjb-react-admin-component/ControlWrapper"; +import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction"; +import { AntdTableFuncControl } from "@cqsjjb/jjb-common-decorator/antd"; +import { tools } from "@cqsjjb/jjb-common-lib"; +import { Get } from "@cqsjjb/jjb-common-lib/http"; +import { NS_STAFF_INFO } from "~/enumerate/namespace"; import { EDUCATION_LEVEL_OPTIONS, EDUCATION_TYPE_OPTIONS, @@ -16,21 +19,11 @@ import { QUALIFICATION_INDUSTRY_OPTIONS, REGISTER_ENGINEER_OPTIONS, } from "~/enumerate/enterpriseOptions"; -import { ensureOrgContext, fetchOrgDepartmentPage, fetchOrgPositionPage } from "~/api/enterpriseInfo/orgBootstrap"; -import { asId, sameId } from "~/api/enterpriseInfo/idUtil"; -import { getBirthDateFromIdCard, safeListRequest, safeRequest } from "~/utils"; -import { toDayjs } from "~/utils/dateFormat"; -import { formSelectField } from "~/utils/enterpriseForm"; +import { getBirthDateFromIdCard } from "~/utils"; import { idCardRule, mobileRule } from "~/utils/validators"; import StaffViewModal from "../StaffViewModal"; -function mapPositionOptions(list = []) { - return list.map((p) => ({ - label: p.positionName, - value: asId(p.id), - deptId: asId(p.deptId), - })); -} +const { router } = tools; function PersonnelInfoPage(props) { const [formModalOpen, setFormModalOpen] = useState(false); @@ -39,43 +32,47 @@ function PersonnelInfoPage(props) { const [searchForm] = Form.useForm(); const [deptOptions, setDeptOptions] = useState([]); const [positionOptions, setPositionOptions] = useState([]); + const { staffInfo } = props; + const { + staffInfoList: dataSource, + staffInfoTotal: total, + staffInfoLoading: loading, + } = staffInfo || {}; useEffect(() => { let cancelled = false; (async () => { try { - await ensureOrgContext(); const [deptRes, posRes] = await Promise.all([ - fetchOrgDepartmentPage({ pageIndex: 1, pageSize: 200 }), - fetchOrgPositionPage({ pageIndex: 1, pageSize: 200 }), + Get("/safetyEval/org-department/page", { current: 1, size: 200 }), + Get("/safetyEval/org-position/page", { current: 1, size: 200 }), ]); - if (cancelled) { - return; - } - setDeptOptions((deptRes?.data || []).map((d) => ({ label: d.deptName, value: asId(d.id) }))); - setPositionOptions(mapPositionOptions(posRes?.data)); - } - catch (err) { + if (cancelled) return; + setDeptOptions((deptRes?.data || []).map((d) => ({ label: d.deptName, value: d.id }))); + setPositionOptions((posRes?.data || []).map((p) => ({ + label: p.positionName, + value: p.id, + deptId: p.deptId, + }))); + } catch (err) { console.warn("[PersonnelInfo] load dept/position options failed:", err); } })(); - return () => { - cancelled = true; - }; + return () => { cancelled = true; }; }, []); - const { tableProps, getData } = useTable(safeListRequest(props.staffInfoList), { - form: searchForm, - transform: (formData) => ({ - ...formData, - eqDeptId: formData.deptId, - eqPositionId: formData.positionId, - }), - }); + useEffect(() => { + searchForm.setFieldsValue(router.query); + handleSearch(); + }, []); - const goCertificate = (staffId, staffName) => { + const handleSearch = () => { + props.staffInfoList({ ...router.query }); + }; + + const goCertificate = (id, staffName) => { const base = window.location.pathname.replace(/\/List.*$/, ""); - window.location.href = `${base}/Certificate?staffId=${staffId}&staffName=${encodeURIComponent(staffName || "")}`; + window.location.href = `${base}/Certificate?staffId=${id}&staffName=${encodeURIComponent(staffName || "")}`; }; const onDelete = (id) => { @@ -88,7 +85,7 @@ function PersonnelInfoPage(props) { const res = await props.staffInfoRemove({ id }); if (res?.success !== false) { message.success("删除成功"); - getData(); + handleSearch(); } }, }); @@ -120,30 +117,42 @@ function PersonnelInfoPage(props) { } > - + + , + + + {deptOptions.map((d) => ( + {d.label} + ))} + + , + + + {positionOptions.map((p) => ( + {p.label} + ))} + + , ]} - onFinish={getData} + onReset={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} + onFinish={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} />
( - - )} + rowKey="id" columns={[ - { title: "用户名称", dataIndex: "staffName" }, + { title: "用户名称", dataIndex: "userName" }, { title: "账号", dataIndex: "account" }, { title: "部门", dataIndex: "deptName" }, { title: "岗位", dataIndex: "positionName" }, @@ -157,38 +166,53 @@ function PersonnelInfoPage(props) { title: "操作", width: 320, render: (_, record) => ( - - - - - - - + + + ), }, ]} - {...tableProps} + dataSource={dataSource} + scroll={{ y: props.scrollY }} + loading={loading} + pagination={{ + total, + showSizeChanger: true, + showQuickJumper: true, + showTotal: (t) => `共 ${t} 条`, + current: Number(router.query.current) || 1, + pageSize: Number(router.query.size) || 10, + onChange: (page, pageSize) => { + router.query = { ...router.query, current: page, size: pageSize }; + handleSearch(); + }, + }} /> {formModalOpen && ( { setFormModalOpen(false); setCurrentId(""); }} - onSuccess={getData} + onSuccess={handleSearch} /> )} {viewModalOpen && ( @@ -207,60 +231,41 @@ function PersonnelInfoPage(props) { } function StaffFormModal({ - open, currentId, requestAdd, requestEdit, requestDetails, deptOptions, onCancel, onSuccess, + open, currentId, staffInfoGet, staffInfoAdd, staffInfoEdit, deptOptions, positionOptions, onCancel, onSuccess, }) { const [form] = Form.useForm(); const [submitting, setSubmitting] = useState(false); const [detailLoading, setDetailLoading] = useState(false); const [deptPositionOptions, setDeptPositionOptions] = useState([]); const [positionLoading, setPositionLoading] = useState(false); + const [uploadFileList, setUploadFileList] = useState([]); const watchedDeptId = Form.useWatch("deptId", form); const wasOpenRef = useRef(false); const inflightDeptRef = useRef(null); - const requestDetailsRef = useRef(requestDetails); - requestDetailsRef.current = requestDetails; - const loadPositionsByDept = async (deptId, currentStaff = null) => { - const id = asId(deptId); + const loadPositionsByDept = async (deptId) => { + const id = deptId; if (!id) { setDeptPositionOptions([]); return []; } - const key = id; - if (inflightDeptRef.current === key) { - return deptPositionOptions; - } - inflightDeptRef.current = key; + if (inflightDeptRef.current === id) return deptPositionOptions; + inflightDeptRef.current = id; setPositionLoading(true); try { - let res = await fetchOrgPositionPage({ - pageIndex: 1, - pageSize: 200, - eqDeptId: id, - }); - let options = mapPositionOptions(res?.data); - // 兼容历史岗位 dept_id 因 Number() 精度丢失与部门 id 不完全一致 - if (!options.length) { - const allRes = await fetchOrgPositionPage({ pageIndex: 1, pageSize: 500 }); - options = mapPositionOptions(allRes?.data).filter((p) => sameId(p.deptId, id)); - } - const positionId = asId(currentStaff?.positionId); - const positionName = currentStaff?.positionName; - if (positionId && positionName && !options.some((item) => sameId(item.value, positionId))) { - options = [{ label: positionName, value: positionId, deptId: id }, ...options]; - } + const res = await Get("/safetyEval/org-position/page", { current: 1, size: 200, deptId: id }); + const options = (res?.data || []).map((p) => ({ + label: p.positionName, + value: p.id, + })); setDeptPositionOptions(options); return options; - } - catch (err) { + } catch (err) { console.warn("[PersonnelInfo] load positions by dept failed:", err); setDeptPositionOptions([]); return []; - } - finally { - if (inflightDeptRef.current === key) { - inflightDeptRef.current = null; - } + } finally { + if (inflightDeptRef.current === id) inflightDeptRef.current = null; setPositionLoading(false); } }; @@ -270,51 +275,53 @@ function StaffFormModal({ if (!currentId) { form.resetFields(); setDeptPositionOptions([]); + setUploadFileList([]); form.setFieldsValue({ - personType: "基础人员", registerEngineerFlag: 2, }); } } if (!open) { setDeptPositionOptions([]); + setUploadFileList([]); } wasOpenRef.current = open; }, [open, currentId, form]); useEffect(() => { - if (!open || !currentId) { - return; - } + if (!open || !currentId) return; let cancelled = false; setDetailLoading(true); - safeRequest(requestDetailsRef.current, { id: currentId }).then(async (res) => { - if (!cancelled && res?.data) { - const data = res.data; - await loadPositionsByDept(data.deptId, data); - if (!cancelled) { - form.setFieldsValue({ - ...data, - deptId: asId(data.deptId), - positionId: asId(data.positionId), - birthDate: toDayjs(data.birthDate), - proofMaterials: data.proofMaterials?.length ? data.proofMaterials : [], - }); - } - } + staffInfoGet({ id: currentId }).then((res) => { + if (cancelled || !res?.data) return; + const data = { ...res.data }; + loadPositionsByDept(data.deptId); + if (cancelled) return; + const setFields = { + ...data, + }; + if (data.birthDate) setFields.birthDate = dayjs(data.birthDate); + const fileList = data.proofMaterialUrl + ? data.proofMaterialUrl.split(",").filter(Boolean).map((url, i) => ({ + uid: `-${i}`, + name: url.split("/").pop() || `附件${i + 1}`, + status: "done", + url, + })) + : []; + setFields.proofMaterialUrl = fileList; + setUploadFileList(fileList); + form.setFieldsValue(setFields); }).finally(() => { - if (!cancelled) { - setDetailLoading(false); - } + if (!cancelled) setDetailLoading(false); }); - return () => { - cancelled = true; - }; + return () => { cancelled = true; }; }, [open, currentId]); const handleCancel = () => { form.resetFields(); setDeptPositionOptions([]); + setUploadFileList([]); onCancel(); }; @@ -322,11 +329,11 @@ function StaffFormModal({ if ("idCardNo" in changed && changed.idCardNo) { const birth = getBirthDateFromIdCard(changed.idCardNo); if (birth) { - form.setFieldValue("birthDate", toDayjs(birth)); + form.setFieldValue("birthDate", dayjs(birth)); } } if ("deptId" in changed) { - form.setFieldValue("positionId", undefined); + form.setFieldValue("postId", undefined); loadPositionsByDept(changed.deptId); } }; @@ -334,21 +341,37 @@ function StaffFormModal({ const handleSubmit = async (values) => { try { setSubmitting(true); - const request = currentId ? requestEdit : requestAdd; - if (currentId) { - values.id = currentId; + const payload = { + ...values, + genderName: values.genderCode === 1 ? "男" : values.genderCode === 2 ? "女" : undefined, + personTypeCode: values.personTypeName, + personTypeName: values.personTypeName, + professionalLevelCode: values.professionalLevelName, + professionalLevelName: values.professionalLevelName, + educationTypeCode: values.educationTypeName, + educationTypeName: values.educationTypeName, + educationLevelCode: values.educationLevelName, + educationLevelName: values.educationLevelName, + proofMaterialUrl: Array.isArray(values.proofMaterialUrl) + ? values.proofMaterialUrl.map((f) => f.url || f.response?.url).filter(Boolean).join(",") + : "", + }; + if (payload.birthDate && typeof payload.birthDate !== "string") { + payload.birthDate = payload.birthDate.format("YYYY-MM-DD"); } - const res = await request(values); + if (currentId) payload.id = currentId; + delete payload.proofMaterials; + + const request = currentId ? staffInfoEdit : staffInfoAdd; + const res = await request(payload); if (res?.success !== false) { message.success(currentId ? "编辑成功" : "添加成功"); handleCancel(); onSuccess(); - } - else { + } else { message.error(res?.message || "操作失败"); } - } - finally { + } finally { setSubmitting(false); } }; @@ -372,12 +395,12 @@ function StaffFormModal({ > - + - + - + @@ -438,12 +461,12 @@ function StaffFormModal({ - + @@ -473,12 +496,24 @@ function StaffFormModal({ - - + { + if (Array.isArray(e)) return e; + return e?.fileList; + }}> + { + setUploadFileList(info.fileList); + }} + > + + - + @@ -497,15 +532,10 @@ function StaffFormModal({ - - - - - ); } -export default Connect([NS_STAFF_INFO, NS_ORG_DEPARTMENT, NS_ORG_POSITION], true)(PersonnelInfoPage); +export default Connect([NS_STAFF_INFO], true)(AntdTableFuncControl(PersonnelInfoPage)); \ No newline at end of file diff --git a/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js b/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js index b849ab2..fa082b7 100644 --- a/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js +++ b/src/pages/Container/EnterpriseInfo/PersonnelInfo/StaffViewModal.js @@ -1,10 +1,9 @@ -import { Button, Descriptions, Modal, Space, Table } from "antd"; +import { Button, Descriptions, Modal, Table } from "antd"; import { useEffect, useRef, useState } from "react"; import FilePreviewModal, { FilePreviewContent } from "~/components/FilePreviewModal"; import { resolvePreviewSrc } from "~/components/CertPreviewImg"; import { fetchStaffCertDetail, fetchStaffCertListByPersonnelId } from "~/api/staffCertificate"; import { fetchOrgPersonnelDetail } from "~/api/qualFiling/personnelHelper"; -import { safeRequest } from "~/utils"; const GENDER_MAP = { 1: "男", 2: "女" }; const REGISTER_ENGINEER_MAP = { 1: "是", 2: "否" }; @@ -39,9 +38,13 @@ export default function StaffViewModal({ } let cancelled = false; setDetailLoading(true); + const loadCertList = requestCertListRef.current; Promise.all([ - safeRequest(requestDetailsRef.current, { id: currentId }), + Promise.resolve(requestDetailsRef.current({ id: currentId })).catch((err) => { + console.warn("[StaffViewModal] load detail failed:", err); + return { data: {} }; + }), typeof loadCertList === "function" ? Promise.resolve(loadCertList(currentId)).catch((err) => { console.warn("[StaffViewModal] load certificates failed:", err); @@ -72,10 +75,12 @@ export default function StaffViewModal({ } setCertPreviewLoading(true); try { - const res = await safeRequest(requestCertDetailsRef.current, { id: record.id }); + const res = await requestCertDetailsRef.current({ id: record.id }); setCertPreviewInfo(res?.data || record); - } - finally { + } catch (err) { + console.warn("[StaffViewModal] load cert detail failed:", err); + setCertPreviewInfo(record); + } finally { setCertPreviewLoading(false); } }; @@ -133,11 +138,11 @@ export default function StaffViewModal({ {proofFiles.length ? ( - +
{proofFiles.map((file, index) => { const fileName = file.name || file.fileName || `专业能力证明${index + 1}.pdf`; return ( - +
); })} -
+
) : "-"}
@@ -226,4 +231,4 @@ export default function StaffViewModal({ ); -} +} \ No newline at end of file diff --git a/src/pages/Container/EnterpriseInfo/ResignationApply/index.js b/src/pages/Container/EnterpriseInfo/ResignationApply/index.js index cd97ccc..39fa4b2 100644 --- a/src/pages/Container/EnterpriseInfo/ResignationApply/index.js +++ b/src/pages/Container/EnterpriseInfo/ResignationApply/index.js @@ -1,20 +1,35 @@ import { Connect } from "@cqsjjb/jjb-dva-runtime"; -import { Button, DatePicker, Descriptions, Form, Input, message, Modal, Select } from "antd"; +import { + Button, + DatePicker, + Descriptions, + Form, + Input, + message, + Modal, + Select, + Table, + Tag, + Upload, +} from "antd"; +import TableAction from "@cqsjjb/jjb-react-admin-component/TableAction"; +import { UploadOutlined } from "@ant-design/icons"; import { useEffect, useState } from "react"; -import AddIcon from "zy-react-library/components/Icon/AddIcon"; 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 Upload from "zy-react-library/components/Upload"; -import useTable from "zy-react-library/hooks/useTable"; -import { asId } from "~/api/enterpriseInfo/idUtil"; -import { NS_STAFF_INFO, NS_STAFF_RESIGNATION_APPLY } from "~/enumerate/namespace"; -import { safeListRequest, safeRequest } from "~/utils"; -import { formSelectField, getResignAuditStatusLabel } from "~/utils/enterpriseForm"; -import { DEFAULT_UPLOAD_FILE_URL, mockUploadFileList, resolveUploadFileId } from "~/utils/mockUpload"; +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 RESIGN_AUDIT_STATUS = { 0: "未审核", 1: "已审核", 2: "已退回" }; +const { router } = tools; function ResignationApplyPage(props) { const [addModalOpen, setAddModalOpen] = useState(false); @@ -22,27 +37,39 @@ function ResignationApplyPage(props) { const [currentId, setCurrentId] = useState(""); const [staffOptions, setStaffOptions] = useState([]); const [searchForm] = Form.useForm(); + const { staffResignationApply } = props; + const { + staffResignationApplyList: dataSource, + staffResignationApplyTotal: total, + staffResignationApplyLoading: loading, + } = staffResignationApply || {}; - const { tableProps, getData } = useTable(safeListRequest(props.staffResignationApplyList), { form: searchForm }); + const handleSearch = () => { + props.staffResignationApplyList({ ...router.query }); + }; useEffect(() => { - getData(); + searchForm.setFieldsValue(router.query); + handleSearch(); }, []); useEffect(() => { let cancelled = false; - props.staffInfoList?.({ pageIndex: 1, pageSize: 500 }).then((res) => { - if (!cancelled) { - setStaffOptions((res?.data || []).map((s) => ({ - label: `${s.staffName}(${s.account})`, - value: asId(s.id), - staffName: s.staffName, - account: s.account, - }))); - } - }).catch((err) => { - console.warn("[ResignationApply] load staff options failed:", err); - }); + props + .staffInfoList?.({ current: 1, size: 500 }) + .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; }; @@ -58,82 +85,126 @@ function ResignationApplyPage(props) { } + extra={ + + } > - ({ label, value: Number(value) })), - { colProps: { xs: 24, sm: 12, md: 8, lg: 8 }, placeholder: "请选择审核状态" }, - ), + loading={loading} + formLine={[ + + + , + + + {Object.entries(RESIGN_AUDIT_STATUS_LABEL).map( + ([value, label]) => ( + + {label} + + ), + )} + + , ]} - onFinish={getData} + onReset={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} + onFinish={() => { + router.query = { ...router.query, current: 1, size: 10 }; + handleSearch(); + }} />
( - - )} + rowKey="id" columns={[ - { title: "账户", dataIndex: "account" }, - { title: "姓名", dataIndex: "applicantName" }, - { title: "部门", dataIndex: "deptName" }, - { title: "申请时间", dataIndex: "applyTime" }, + { title: "账户", dataIndex: "account", width: 140 }, + { title: "姓名", dataIndex: "applicantName", width: 100 }, + { title: "部门", dataIndex: "deptName", width: 160 }, + { title: "申请时间", dataIndex: "applyTime", width: 160 }, { title: "离职申请审核状态", - dataIndex: "auditStatus", - render: (_, record) => getResignAuditStatusLabel(record), + dataIndex: "auditStatusCode", + width: 140, + render: (_, record) => { + const code = record.auditStatusCode ?? record.auditStatus; + const label = RESIGN_AUDIT_STATUS_LABEL[code] ?? "-"; + return {label}; + }, }, { title: "操作", - width: 100, + width: 80, render: (_, record) => ( - + + + ), }, ]} - {...tableProps} + 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(); + }, + }} /> - {addModalOpen && ( - setAddModalOpen(false)} - onSuccess={getData} - /> - )} - {viewModalOpen && ( - { - setViewModalOpen(false); - setCurrentId(""); - }} - /> - )} + setAddModalOpen(false)} + onSuccess={handleSearch} + /> + { + setViewModalOpen(false); + setCurrentId(""); + }} + /> ); } @@ -141,36 +212,33 @@ function ResignationApplyPage(props) { function AddModal({ open, staffOptions, requestAdd, onCancel, onSuccess }) { const [form] = Form.useForm(); const [submitting, setSubmitting] = useState(false); + const [uploading, setUploading] = useState(false); const handleCancel = () => { form.resetFields(); onCancel(); }; - const onApplicantChange = (personnelId) => { - const staff = staffOptions.find((s) => String(s.value) === String(personnelId)); - form.setFieldsValue({ - applicantName: staff?.staffName || "", - }); - }; - - const handleSubmit = async (values) => { + const handleSubmit = async () => { try { + const values = await form.validateFields(); setSubmitting(true); - const staff = staffOptions.find((s) => String(s.value) === String(values.personnelId)); - values.applicantName = staff?.staffName || values.applicantName; - values.attachmentId = resolveUploadFileId(values.resignReport); + values.applyTime = + values.applyTime?.format?.("YYYY-MM-DD HH:mm:ss") || values.applyTime; + values.expectedResignDate = + values.expectedResignDate?.format?.("YYYY-MM-DD") || + values.expectedResignDate; const res = await requestAdd(values); if (res?.success !== false) { message.success("提交成功"); handleCancel(); onSuccess(); - } - else { + } else { message.error(res?.message || "提交失败"); } - } - finally { + } catch { + // validation error + } finally { setSubmitting(false); } }; @@ -183,9 +251,9 @@ function AddModal({ open, staffOptions, requestAdd, onCancel, onSuccess }) { width={720} confirmLoading={submitting} onCancel={handleCancel} - onOk={form.submit} + onOk={handleSubmit} > -
+ - @@ -227,25 +291,40 @@ function AddModal({ open, staffOptions, requestAdd, onCancel, onSuccess }) { e?.fileList} - initialValue={mockUploadFileList("离职通知报告.pdf")} > + accept=".pdf" + onChange={(info) => { + if (info.file.status === "uploading") { + setUploading(true); + } else { + setUploading(false); + if (info.file.status === "done") { + const data = info.file.response?.data; + if (data) { + form.setFieldsValue({ reportFileUrl: data.url || data }); + } + } + } + }} + > + + ); } -function ViewModal({ open, currentId, requestDetails, onCancel }) { +function ViewModal({ open, currentId, requestDetail, onCancel }) { const [info, setInfo] = useState({}); const [detailLoading, setDetailLoading] = useState(false); @@ -256,21 +335,13 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) { } let cancelled = false; setDetailLoading(true); - safeRequest(requestDetails, { id: currentId }).then((res) => { - if (!cancelled) { - const data = res?.data || {}; - setInfo({ - ...data, - resignReport: data.attachmentId - ? [{ name: "离职通知报告.pdf", fileName: "离职通知报告.pdf", url: data.attachmentId || DEFAULT_UPLOAD_FILE_URL }] - : [], - }); - } - }).finally(() => { - if (!cancelled) { - setDetailLoading(false); - } - }); + requestDetail({ id: currentId }) + .then((res) => { + if (!cancelled) setInfo(res?.data || {}); + }) + .finally(() => { + if (!cancelled) setDetailLoading(false); + }); return () => { cancelled = true; }; @@ -288,17 +359,26 @@ function ViewModal({ open, currentId, requestDetails, onCancel }) { onCancel={onCancel} > - {info.applicantName} + + {info.applicantName} + {info.applyTime} - {info.expectedLeaveDate} - {info.leaveReason} + + {info.expectedResignDate} + + + {info.resignReason} + {info.remark} - {info.resignReport?.[0]?.fileName || info.resignReport?.[0]?.name || "-"} + {info.reportFileUrl || "-"} ); } -export default Connect([NS_STAFF_RESIGNATION_APPLY, NS_STAFF_INFO], true)(ResignationApplyPage); +export default Connect( + [NS_STAFF_RESIGNATION_APPLY, NS_STAFF_INFO], + true, +)(AntdTableFuncControl(ResignationApplyPage));