|
|
@@ -0,0 +1,167 @@
|
|
|
+import request from "@/utils/request";
|
|
|
+
|
|
|
+function unwrap(response) {
|
|
|
+ const result = response?.data || {};
|
|
|
+ if (Number(result.code) === 0) return result.data;
|
|
|
+ const error = new Error(result.message || "服务调用失败");
|
|
|
+ if (response?.__toastShown) error.__toastShown = true;
|
|
|
+ return Promise.reject(error);
|
|
|
+}
|
|
|
+
|
|
|
+function compact(object = {}) {
|
|
|
+ return Object.keys(object).reduce((result, key) => {
|
|
|
+ const value = object[key];
|
|
|
+ if (value !== "" && value !== null && value !== undefined) result[key] = value;
|
|
|
+ return result;
|
|
|
+ }, {});
|
|
|
+}
|
|
|
+
|
|
|
+function dateOnly(value) {
|
|
|
+ if (!value) return undefined;
|
|
|
+ return String(value).slice(0, 10);
|
|
|
+}
|
|
|
+
|
|
|
+/** 录用审批状态码 → 中文 */
|
|
|
+export const HIRING_STATUS_LABELS = {
|
|
|
+ DRAFT: "草稿",
|
|
|
+ PENDING_MY_APPROVAL: "待我审批",
|
|
|
+ APPROVING: "审批中",
|
|
|
+ APPROVED: "已通过",
|
|
|
+ REJECTED: "已拒绝",
|
|
|
+};
|
|
|
+
|
|
|
+/** 已通过:可发起 Offer */
|
|
|
+export const HIRING_APPROVED_STATUS = new Set(["APPROVED", "已通过"]);
|
|
|
+
|
|
|
+export function normalizeHiringStatus(raw = {}) {
|
|
|
+ const code = String(
|
|
|
+ raw.approvalStatus || raw.status || raw.statusCode || "",
|
|
|
+ ).toUpperCase();
|
|
|
+ const labelMap = {
|
|
|
+ DRAFT: "DRAFT",
|
|
|
+ 草稿: "DRAFT",
|
|
|
+ PENDING_MY_APPROVAL: "PENDING_MY_APPROVAL",
|
|
|
+ WAITING: "PENDING_MY_APPROVAL",
|
|
|
+ 待我审批: "PENDING_MY_APPROVAL",
|
|
|
+ APPROVING: "APPROVING",
|
|
|
+ PENDING_APPROVAL: "APPROVING",
|
|
|
+ 审批中: "APPROVING",
|
|
|
+ APPROVED: "APPROVED",
|
|
|
+ PASSED: "APPROVED",
|
|
|
+ 已通过: "APPROVED",
|
|
|
+ REJECTED: "REJECTED",
|
|
|
+ 已拒绝: "REJECTED",
|
|
|
+ 已驳回: "REJECTED",
|
|
|
+ };
|
|
|
+ return labelMap[code] || labelMap[raw.approvalStatus] || code || "DRAFT";
|
|
|
+}
|
|
|
+
|
|
|
+export function adaptHiringApproval(raw = {}) {
|
|
|
+ const statusCode = normalizeHiringStatus(raw);
|
|
|
+ const hireDate =
|
|
|
+ dateOnly(raw.plannedHireDate || raw.hireDate || raw.onboardingDate) || "";
|
|
|
+ const experienceRaw = raw.experience ?? raw.workYears ?? "";
|
|
|
+ return {
|
|
|
+ ...raw,
|
|
|
+ id: raw.id,
|
|
|
+ approvalNo: raw.approvalNo || (raw.id ? `HA${raw.id}` : ""),
|
|
|
+ candidateId: raw.candidateId,
|
|
|
+ candidateName: raw.candidateName || raw.name || "",
|
|
|
+ gender: raw.gender || raw.title || "",
|
|
|
+ education: raw.education || "",
|
|
|
+ phone: raw.phone || raw.mobile || raw.candidatePhone || "",
|
|
|
+ experience: experienceRaw,
|
|
|
+ positionId: raw.positionId,
|
|
|
+ positionName: raw.positionName || raw.appliedPosition || "",
|
|
|
+ departmentId: raw.departmentId || raw.recruitmentDeptId || raw.deptId,
|
|
|
+ departmentName:
|
|
|
+ raw.departmentName ||
|
|
|
+ raw.recruitmentDeptName ||
|
|
|
+ raw.deptName ||
|
|
|
+ raw.department ||
|
|
|
+ "",
|
|
|
+ proposedSalary: raw.proposedSalary || raw.salaryAdvice || raw.salary || "",
|
|
|
+ probation: raw.probation || raw.probationPeriod || "",
|
|
|
+ salaryStructure: raw.salaryStructure || "",
|
|
|
+ staffingType:
|
|
|
+ raw.staffingType ||
|
|
|
+ raw.positionNature ||
|
|
|
+ raw.positionType ||
|
|
|
+ raw.编制类型 ||
|
|
|
+ "",
|
|
|
+ hireDate,
|
|
|
+ currentNode: raw.currentNode || raw.nodeName || raw.approvalNode || "-",
|
|
|
+ statusCode,
|
|
|
+ status: HIRING_STATUS_LABELS[statusCode] || raw.approvalStatus || "-",
|
|
|
+ remark: raw.remark || raw.approvalComment || "",
|
|
|
+ attachments: Array.isArray(raw.attachments) ? raw.attachments : [],
|
|
|
+ applicationId: raw.applicationId,
|
|
|
+ offerId: raw.offerId,
|
|
|
+ offerSent: Boolean(raw.offerId || raw.offerSent),
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+export function serializeHiringApproval(form = {}) {
|
|
|
+ const experienceYears =
|
|
|
+ form.experience === null ||
|
|
|
+ form.experience === undefined ||
|
|
|
+ form.experience === ""
|
|
|
+ ? undefined
|
|
|
+ : Number(form.experience);
|
|
|
+ const experience =
|
|
|
+ experienceYears == null || Number.isNaN(experienceYears)
|
|
|
+ ? undefined
|
|
|
+ : `${experienceYears}年`;
|
|
|
+ return compact({
|
|
|
+ id: form.id || undefined,
|
|
|
+ candidateId: form.candidateId || undefined,
|
|
|
+ candidateName: form.candidateName || form.name,
|
|
|
+ gender: form.gender || undefined,
|
|
|
+ education: form.education || undefined,
|
|
|
+ phone: form.phone || undefined,
|
|
|
+ experience,
|
|
|
+ workYears: experienceYears,
|
|
|
+ positionId: form.positionId || undefined,
|
|
|
+ positionName: form.positionName || undefined,
|
|
|
+ departmentId: form.departmentId || undefined,
|
|
|
+ departmentName: form.departmentName || undefined,
|
|
|
+ proposedSalary: form.proposedSalary || undefined,
|
|
|
+ probation: form.probation || undefined,
|
|
|
+ plannedHireDate: dateOnly(form.hireDate),
|
|
|
+ salaryStructure: form.salaryStructure || undefined,
|
|
|
+ staffingType: form.staffingType || undefined,
|
|
|
+ remark: form.remark || undefined,
|
|
|
+ applicationId: form.applicationId || undefined,
|
|
|
+ attachmentFileIds: Array.isArray(form.attachmentFileIds)
|
|
|
+ ? form.attachmentFileIds
|
|
|
+ : undefined,
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export const getHiringApprovalPage = async (params = {}) =>
|
|
|
+ unwrap(
|
|
|
+ await request.get("/recruit/hiring-approvals", { params: compact(params) }),
|
|
|
+ );
|
|
|
+
|
|
|
+export const getHiringApprovalById = async (id) =>
|
|
|
+ adaptHiringApproval(
|
|
|
+ await unwrap(await request.get(`/recruit/hiring-approvals/${id}`)),
|
|
|
+ );
|
|
|
+
|
|
|
+export const createHiringApproval = async (data) =>
|
|
|
+ unwrap(await request.post("/recruit/hiring-approvals", data));
|
|
|
+
|
|
|
+export const updateHiringApproval = async (id, data) =>
|
|
|
+ unwrap(await request.put(`/recruit/hiring-approvals/${id}`, data));
|
|
|
+
|
|
|
+export const submitHiringApproval = async (id, data = {}) =>
|
|
|
+ unwrap(await request.post(`/recruit/hiring-approvals/${id}/submit`, data));
|
|
|
+
|
|
|
+export const approveHiringApproval = async (id, data = {}) =>
|
|
|
+ unwrap(await request.post(`/recruit/hiring-approvals/${id}/approve`, data));
|
|
|
+
|
|
|
+export const rejectHiringApproval = async (id, data = {}) =>
|
|
|
+ unwrap(await request.post(`/recruit/hiring-approvals/${id}/reject`, data));
|
|
|
+
|
|
|
+export const deleteHiringApproval = async (id) =>
|
|
|
+ unwrap(await request.delete(`/recruit/hiring-approvals/${id}`));
|