From c812071d8a68937c498cca154c2c6991c4a0bbe8 Mon Sep 17 00:00:00 2001 From: fuenmao <980740792@qq.com> Date: Fri, 18 Sep 2026 10:53:56 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=9B=B8=E5=85=B3=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components.d.ts | 3 - src/views/biz/onboarding/employee/index.vue | 164 +++++++++++++++++++- 2 files changed, 159 insertions(+), 8 deletions(-) diff --git a/components.d.ts b/components.d.ts index 1cff276..124043e 100644 --- a/components.d.ts +++ b/components.d.ts @@ -21,12 +21,10 @@ declare module 'vue' { ElAlert: typeof import('element-plus/es')['ElAlert'] ElAside: typeof import('element-plus/es')['ElAside'] ElAvatar: typeof import('element-plus/es')['ElAvatar'] - ElBadge: typeof import('element-plus/es')['ElBadge'] ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb'] ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem'] ElButton: typeof import('element-plus/es')['ElButton'] ElCard: typeof import('element-plus/es')['ElCard'] - ElCascader: typeof import('element-plus/es')['ElCascader'] ElCheckbox: typeof import('element-plus/es')['ElCheckbox'] ElCol: typeof import('element-plus/es')['ElCol'] ElCollapse: typeof import('element-plus/es')['ElCollapse'] @@ -52,7 +50,6 @@ declare module 'vue' { ElImageViewer: typeof import('element-plus/es')['ElImageViewer'] ElInput: typeof import('element-plus/es')['ElInput'] ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] - ElLink: typeof import('element-plus/es')['ElLink'] ElMain: typeof import('element-plus/es')['ElMain'] ElMenu: typeof import('element-plus/es')['ElMenu'] ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] diff --git a/src/views/biz/onboarding/employee/index.vue b/src/views/biz/onboarding/employee/index.vue index cd5facf..007b39c 100644 --- a/src/views/biz/onboarding/employee/index.vue +++ b/src/views/biz/onboarding/employee/index.vue @@ -162,7 +162,7 @@ {{ detail.employee.positionName || employeeInfo.onboardingPosition || "-" }} - {{ detail.employee.employeeNo || employeeInfo.employeeNo || "-" }} + {{ resolvedEmployeeNo }} {{ formatDate(detail.employee.entryDate) }} {{ formatSeniority(detail.employee.entryDate) }} {{ employmentTypeText(detail.employee.employmentType) }} @@ -256,6 +256,23 @@
备注:{{ record.remark }}
+
+
变更明细
+ + + + + +
+
+ 该记录未保存修改前后值 +
>(() => detail.value?.employeeInfo || {}); + +const resolvedEmployeeNo = computed(() => { + if (detail.value?.employee?.employeeNo && String(detail.value.employee.employeeNo).trim()) { + return String(detail.value.employee.employeeNo).trim(); + } + const snapshots = detail.value?.contractSnapshots || []; + for (const item of snapshots) { + if (item?.employeeNo && String(item.employeeNo).trim()) { + return String(item.employeeNo).trim(); + } + if (item?.variablesJson) { + try { + const vars = typeof item.variablesJson === "string" ? JSON.parse(item.variablesJson) : item.variablesJson; + const target = vars?.["hr.EmployeeNo"] || vars?.["hr.employeeno"]; + const val = typeof target === "object" ? target?.variableValue : target; + if (val && String(val).trim()) { + return String(val).trim(); + } + } catch { + // 忽略变量快照反序列化异常 + } + } + } + if (employeeInfo.value?.employeeNo && String(employeeInfo.value.employeeNo).trim()) { + return String(employeeInfo.value.employeeNo).trim(); + } + return "-"; +}); const materialPreviewUrls = reactive>({}); const materialPreviewLoading = reactive>({}); const materialPreviewFailed = reactive>({}); @@ -911,10 +957,10 @@ function safeDownloadName(value: string) { } function getEmployeeDownloadPrefix(): string { + const empNo = resolvedEmployeeNo.value !== "-" ? resolvedEmployeeNo.value : ""; const taskNo = String( detail.value?.task?.taskNo - || detail.value?.employee?.employeeNo - || detail.value?.employeeInfo?.employeeNo + || empNo || "" ).trim(); const employeeName = String( @@ -1160,6 +1206,90 @@ function changeTypeText(value?: string) { return map[value || ""] || value || "人事变更"; } +type EmployeeChangeFieldKey = + | "employmentType" + | "regularizationStatus" + | "regularizationDate" + | "contractNature" + | "socialInsuranceStatus" + | "socialInsuranceCompany"; + +type EmployeeChangeDiffRow = { + key: EmployeeChangeFieldKey; + label: string; + beforeText: string; + afterText: string; +}; + +const employeeChangeFields: Array<{ key: EmployeeChangeFieldKey; label: string }> = [ + { key: "employmentType", label: "用工类型" }, + { key: "regularizationStatus", label: "转正状态" }, + { key: "regularizationDate", label: "转正日期" }, + { key: "contractNature", label: "合同性质" }, + { key: "socialInsuranceStatus", label: "社保状态" }, + { key: "socialInsuranceCompany", label: "合同社保单位" } +]; + +function parseChangeSnapshot(value: unknown): Record | null { + if (value && typeof value === "object" && !Array.isArray(value)) { + return value as Record; + } + if (typeof value !== "string" || !value.trim()) return null; + try { + const parsed = JSON.parse(value); + return parsed && typeof parsed === "object" && !Array.isArray(parsed) + ? parsed as Record + : null; + } catch { + return null; + } +} + +function getSnapshot(record: any, field: "beforeJson" | "afterJson") { + const pascalField = field === "beforeJson" ? "BeforeJson" : "AfterJson"; + return parseChangeSnapshot(record?.[field] ?? record?.[pascalField]); +} + +function getSnapshotValue(snapshot: Record, key: string) { + const matchedKey = Object.keys(snapshot).find(item => item.toLowerCase() === key.toLowerCase()); + return matchedKey ? snapshot[matchedKey] : undefined; +} + +function normalizeChangeValue(value: unknown) { + if (value === null || value === undefined) return ""; + return typeof value === "string" ? value.trim() : JSON.stringify(value); +} + +function formatChangeValue(key: EmployeeChangeFieldKey, value: unknown) { + if (value === null || value === undefined || value === "") return "—"; + const text = String(value); + if (key === "employmentType") return employmentTypeText(text); + if (key === "regularizationStatus") return regularizationText(text); + if (key === "regularizationDate") return formatDate(text); + if (key === "socialInsuranceStatus") return socialInsuranceText(text); + return text; +} + +function hasChangeSnapshot(record: any) { + return Boolean(getSnapshot(record, "beforeJson") || getSnapshot(record, "afterJson")); +} + +function changeDiffRows(record: any): EmployeeChangeDiffRow[] { + const before = getSnapshot(record, "beforeJson") || {}; + const after = getSnapshot(record, "afterJson") || {}; + return employeeChangeFields.flatMap(field => { + const beforeValue = getSnapshotValue(before, field.key); + const afterValue = getSnapshotValue(after, field.key); + if (normalizeChangeValue(beforeValue) === normalizeChangeValue(afterValue)) return []; + return [{ + key: field.key, + label: field.label, + beforeText: formatChangeValue(field.key, beforeValue), + afterText: formatChangeValue(field.key, afterValue) + }]; + }); +} + function canRegularize(employee?: OnboardingEmployee) { return Boolean( employee @@ -1301,9 +1431,9 @@ async function saveHrInfo() { await onboardingTaskApi.updateEmployeeHrInfo({ id: hrForm.id, employmentType: hrForm.employmentType, - contractNature: hrForm.contractNature.trim() || undefined, + contractNature: String(hrForm.contractNature ?? "").trim() || undefined, socialInsuranceStatus: hrForm.socialInsuranceStatus, - socialInsuranceCompany: hrForm.socialInsuranceCompany.trim() || undefined + socialInsuranceCompany: String(hrForm.socialInsuranceCompany ?? "").trim() || undefined }); hrEditVisible.value = false; await refreshEmployee(hrForm.id); @@ -1647,6 +1777,30 @@ onBeforeUnmount(clearMaterialPreviews); margin-top: 6px; } +.change-diff { + margin-top: 12px; +} + +.change-diff-title { + margin-bottom: 8px; + color: #334155; + font-size: 13px; + font-weight: 600; +} + +.change-diff-table { + width: 100%; +} + +.change-record-empty { + margin-top: 10px; + padding: 8px 10px; + border-radius: 4px; + background: #f1f5f9; + color: #94a3b8; + font-size: 13px; +} + .change-attachments { display: flex; flex-wrap: wrap;