|
|
@@ -19,6 +19,30 @@ function compact(object) {
|
|
|
}, {});
|
|
|
}
|
|
|
|
|
|
+function isHttpUrl(value) {
|
|
|
+ return typeof value === "string" && /^https?:\/\//i.test(value);
|
|
|
+}
|
|
|
+
|
|
|
+/** 证照附件:接口字段 fileObj 为文件对象数组 */
|
|
|
+function toFileObj(value) {
|
|
|
+ if (value == null || value === "") return [];
|
|
|
+ const list = Array.isArray(value) ? value : [value];
|
|
|
+ return list
|
|
|
+ .map((item) => {
|
|
|
+ if (item == null || item === "") return null;
|
|
|
+ if (typeof item === "object") return item;
|
|
|
+ if (isHttpUrl(item)) return null;
|
|
|
+ return { id: item };
|
|
|
+ })
|
|
|
+ .filter(Boolean);
|
|
|
+}
|
|
|
+
|
|
|
+function toFileIds(value) {
|
|
|
+ return toFileObj(value)
|
|
|
+ .map((item) => item.id ?? item.fileId ?? null)
|
|
|
+ .filter((id) => id != null && id !== "");
|
|
|
+}
|
|
|
+
|
|
|
function formatDate(value) {
|
|
|
if (!value) return "";
|
|
|
const text = String(value);
|
|
|
@@ -455,8 +479,13 @@ function adaptCertificates(list = []) {
|
|
|
startDate: formatDate(item.validityStartTime),
|
|
|
endDate: formatDate(item.validityEndTime),
|
|
|
issueDate: formatDate(item.enactorTime),
|
|
|
- attachment: [],
|
|
|
+ attachment: item.fileObj || item.fileIds || item.files || item.attachment || [],
|
|
|
remark: item.remark || "",
|
|
|
+ hrCertificateId: item.hrCertificateId,
|
|
|
+ holder: item.holder || "",
|
|
|
+ holderId: item.holderId || "",
|
|
|
+ holderType: item.holderType || "1",
|
|
|
+ enactor: item.enactor || "",
|
|
|
}));
|
|
|
}
|
|
|
|
|
|
@@ -635,6 +664,7 @@ export function adaptEmployee(raw = {}, extras = {}) {
|
|
|
education: raw.educationBackground || "",
|
|
|
school: raw.school || "",
|
|
|
major: raw.major || "",
|
|
|
+ degree: raw.degree || "",
|
|
|
graduationDate: formatDate(raw.graduateDate),
|
|
|
registeredAddress: raw.censusAddress || "",
|
|
|
currentAddress: raw.currentAddress || "",
|
|
|
@@ -691,11 +721,11 @@ export function adaptEmployee(raw = {}, extras = {}) {
|
|
|
certificates: adaptCertificates(raw.identityPhotos),
|
|
|
workTypes: adaptWorkTypes(raw.professions),
|
|
|
previousJobs: adaptWorkExperiences(extras.workExperiences || []),
|
|
|
- educations: raw.educationBackground
|
|
|
+ educations: raw.educationBackground || raw.school || raw.major || raw.degree || raw.graduateDate
|
|
|
? [
|
|
|
{
|
|
|
education: raw.educationBackground || "",
|
|
|
- degree: "",
|
|
|
+ degree: raw.degree || "",
|
|
|
graduationDate: formatDate(raw.graduateDate),
|
|
|
school: raw.school || "",
|
|
|
major: raw.major || "",
|
|
|
@@ -740,17 +770,142 @@ export function adaptEmployee(raw = {}, extras = {}) {
|
|
|
/** 合并 profile 聚合视图 */
|
|
|
export function adaptEmployeeProfile(profile = {}) {
|
|
|
const user = profile.user || {};
|
|
|
- return adaptEmployee(user, {
|
|
|
+ return adaptEmployee(
|
|
|
+ {
|
|
|
+ ...user,
|
|
|
+ identityPhotos: user.identityPhotos || profile.identityPhotos || [],
|
|
|
+ },
|
|
|
+ {
|
|
|
workExperiences: profile.workExperiences || [],
|
|
|
history: profile.history || [],
|
|
|
performanceRecords: profile.performanceRecords || [],
|
|
|
changes: profile.changes || [],
|
|
|
- });
|
|
|
+ },
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function pickEducation(form = {}) {
|
|
|
+ const row = Array.isArray(form.educations) && form.educations[0] ? form.educations[0] : {};
|
|
|
+ return {
|
|
|
+ educationBackground: row.education || form.education || "",
|
|
|
+ degree: row.degree || form.degree || "",
|
|
|
+ school: row.school || form.school || "",
|
|
|
+ major: row.major || form.major || "",
|
|
|
+ graduateDate: row.graduationDate || form.graduationDate || "",
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function serializeBankCardList(form = {}) {
|
|
|
+ const bankAccounts = Array.isArray(form.bankAccounts) ? form.bankAccounts : [];
|
|
|
+ return bankAccounts
|
|
|
+ .filter((item) => item.bankName && item.bankAccount)
|
|
|
+ .map((item) => ({
|
|
|
+ openingBank: String(item.bankName).trim(),
|
|
|
+ cardNumber: String(item.bankAccount).trim(),
|
|
|
+ accountName: String(item.bankAccountName || form.name || "").trim(),
|
|
|
+ }))
|
|
|
+ .filter((item) => item.accountName);
|
|
|
+}
|
|
|
+
|
|
|
+function serializeSocialSecurityList(form = {}) {
|
|
|
+ return (form.socialSecurityRecords || [])
|
|
|
+ .filter((item) => item.type)
|
|
|
+ .map((item) =>
|
|
|
+ compact({
|
|
|
+ socialType: item.type || "",
|
|
|
+ socialBase: Number(item.base) || undefined,
|
|
|
+ insuredDate: item.insuredDate || "",
|
|
|
+ stopDate: item.stopDate || "",
|
|
|
+ stopRecord: item.stopReason || "",
|
|
|
+ }),
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function serializeIdentityPhotos(form = {}) {
|
|
|
+ return (form.certificates || [])
|
|
|
+ .filter((item) => item.type || item.number)
|
|
|
+ .map((item) =>
|
|
|
+ compact({
|
|
|
+ id: toApiId(item.id),
|
|
|
+ type: CERT_TYPE[item.type] ?? 4,
|
|
|
+ code: item.number || "",
|
|
|
+ level: CERT_LEVEL[item.level] || item.level || "",
|
|
|
+ status: item.status === "失效" ? 0 : 1,
|
|
|
+ validityStartTime: item.startDate || "",
|
|
|
+ validityEndTime: item.endDate || "",
|
|
|
+ enactor: item.enactor || "",
|
|
|
+ enactorTime: item.issueDate || "",
|
|
|
+ remark: item.remark || "",
|
|
|
+ holderType: item.holderType || "1",
|
|
|
+ holder: item.holder || form.name || "",
|
|
|
+ holderId: item.holderId != null && item.holderId !== "" ? String(item.holderId) : form.id != null ? String(form.id) : undefined,
|
|
|
+ fileObj: toFileObj(item.attachment),
|
|
|
+ hrCertificateId: toApiId(item.hrCertificateId),
|
|
|
+ }),
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function serializeRewards(form = {}) {
|
|
|
+ return (form.rewardPunishmentRecords || []).map((item) =>
|
|
|
+ compact({
|
|
|
+ userId: toApiId(form.id),
|
|
|
+ type: /惩罚|处分|警告/.test(item.type) ? 2 : 1,
|
|
|
+ desce: item.description || item.name || "",
|
|
|
+ startTime: item.startDate || item.date || "",
|
|
|
+ endTime: item.endDate || "",
|
|
|
+ status: REWARD_STATUS[item.status] ?? 2,
|
|
|
+ remark: item.remark || "",
|
|
|
+ fileAttach: toFileObj(item.attachment),
|
|
|
+ }),
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+function serializePositionList(form = {}, positionIds = []) {
|
|
|
+ if (!positionIds.length) return [];
|
|
|
+ const id = positionIds[0];
|
|
|
+ const binding =
|
|
|
+ (Array.isArray(form.positionBindings) ? form.positionBindings : []).find(
|
|
|
+ (item) => String(item.positionId) === String(id),
|
|
|
+ ) || {};
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ positionId: toApiId(id),
|
|
|
+ positionLevelId: toApiId(binding.positionLevelId),
|
|
|
+ positionSequenceId: toApiId(binding.positionSequenceId),
|
|
|
+ primaryFlag: 1,
|
|
|
+ },
|
|
|
+ ];
|
|
|
+}
|
|
|
+
|
|
|
+function serializeCriticalTaskList(form = {}) {
|
|
|
+ const text = String(form.keyProcess || "").trim();
|
|
|
+ if (!text) return [];
|
|
|
+ const rawList = Array.isArray(form.raw?.criticalTaskList) ? form.raw.criticalTaskList : [];
|
|
|
+ return text
|
|
|
+ .split(/[,,]/)
|
|
|
+ .map((item) => String(item).trim())
|
|
|
+ .filter(Boolean)
|
|
|
+ .map((value) => {
|
|
|
+ if (/^\d+$/.test(value)) return compact({ taskId: Number(value), taskName: value });
|
|
|
+ const matched = rawList.find(
|
|
|
+ (item) => String(item.taskName) === value || String(item.taskId) === value,
|
|
|
+ );
|
|
|
+ if (matched) {
|
|
|
+ return compact({
|
|
|
+ taskId: toApiId(matched.taskId),
|
|
|
+ taskName: matched.taskName || value,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return compact({ taskName: value });
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 员工档案表单 → 后端「员工新增或修改参数」
|
|
|
- * 合同 contracts 已废弃,不提交;工作履历走独立接口
|
|
|
+ * 对照 POST /main/user/saveNew:只提交文档中的字段。
|
|
|
+ * 岗位 / 部门 / 银行卡 / 社保 / 证照 / 奖惩 / 关键工序:未传保持、空数组清空、非空整单覆盖。
|
|
|
+ * 合同 contracts、技能 skills、培训 trainRecords、考勤 attendanceRecords 已废弃,禁止提交。
|
|
|
+ * 工作履历走独立接口。学历提交 educationBackground / degree / school / major / graduateDate。
|
|
|
*/
|
|
|
export function serializeEmployee(form = {}) {
|
|
|
const statusText = form.formStatus || form.status;
|
|
|
@@ -762,9 +917,9 @@ export function serializeEmployee(form = {}) {
|
|
|
? 5
|
|
|
: Number(statusText) || 1);
|
|
|
|
|
|
- const education = form.educations?.[0] || {};
|
|
|
- const bankAccounts = form.bankAccounts || [];
|
|
|
- const firstBank = bankAccounts[0] || {};
|
|
|
+ const education = pickEducation(form);
|
|
|
+ const bankCardList = serializeBankCardList(form);
|
|
|
+ const firstBank = bankCardList[0] || {};
|
|
|
const positionIds = (
|
|
|
form.positionId
|
|
|
? [form.positionId]
|
|
|
@@ -778,13 +933,24 @@ export function serializeEmployee(form = {}) {
|
|
|
const professionIds = (form.workTypes || [])
|
|
|
.map((item) => item.id)
|
|
|
.filter((id) => id != null && id !== "");
|
|
|
- const avatarUrl =
|
|
|
- typeof form.avatar === "string" && /^https?:\/\//i.test(form.avatar)
|
|
|
- ? form.avatar
|
|
|
+ const avatarUrl = isHttpUrl(form.avatar) ? form.avatar : undefined;
|
|
|
+ const avatarFiles = Array.isArray(form.avatar) && form.avatar.length && typeof form.avatar[0] === "object"
|
|
|
+ ? form.avatar
|
|
|
+ : Array.isArray(form.avatarFiles) && form.avatarFiles.length
|
|
|
+ ? form.avatarFiles
|
|
|
: undefined;
|
|
|
+ const deptIds = (Array.isArray(form.deptIds) && form.deptIds.length
|
|
|
+ ? form.deptIds
|
|
|
+ : form.deptId
|
|
|
+ ? [form.deptId]
|
|
|
+ : []
|
|
|
+ )
|
|
|
+ .map((id) => toApiId(id))
|
|
|
+ .filter((id) => id != null);
|
|
|
|
|
|
return compact({
|
|
|
- id: form.id || undefined,
|
|
|
+ id: toApiId(form.id),
|
|
|
+ accountId: toApiId(form.accountId || form.raw?.accountId),
|
|
|
name: form.name || "",
|
|
|
jobNumber: form.employeeNo || "",
|
|
|
sex: EMPLOYEE_SEX[form.gender] ?? form.gender,
|
|
|
@@ -799,10 +965,11 @@ export function serializeEmployee(form = {}) {
|
|
|
censusAddress: form.registeredAddress || "",
|
|
|
currentAddress: form.currentAddress || "",
|
|
|
address: form.workAddress || "",
|
|
|
- educationBackground: education.education || form.education || "",
|
|
|
- school: education.school || form.school || "",
|
|
|
- major: education.major || form.major || "",
|
|
|
- graduateDate: education.graduationDate || form.graduationDate || "",
|
|
|
+ educationBackground: education.educationBackground,
|
|
|
+ degree: education.degree,
|
|
|
+ school: education.school,
|
|
|
+ major: education.major,
|
|
|
+ graduateDate: education.graduateDate,
|
|
|
phone: form.phone || "",
|
|
|
email: form.email || "",
|
|
|
wxId: form.wechat || "",
|
|
|
@@ -811,90 +978,33 @@ export function serializeEmployee(form = {}) {
|
|
|
positiveDate: form.regularDate || "",
|
|
|
leaveDate: form.leaveInfo?.leaveDate || "",
|
|
|
isEnabled: form.enabled === false || statusText === "disabled" ? 0 : 1,
|
|
|
- openingBank: firstBank.bankName || form.bankName || "",
|
|
|
- cardNumber: firstBank.bankAccount || form.bankAccount || "",
|
|
|
- bankCardList: bankAccounts.length
|
|
|
- ? bankAccounts
|
|
|
- .filter((item) => item.bankAccount || item.bankName)
|
|
|
- .map((item) => ({
|
|
|
- openingBank: item.bankName || "",
|
|
|
- cardNumber: item.bankAccount || "",
|
|
|
- accountName: item.bankAccountName || form.name || "",
|
|
|
- }))
|
|
|
- : undefined,
|
|
|
+ openingBank: firstBank.openingBank || form.bankName || "",
|
|
|
+ cardNumber: firstBank.cardNumber || form.bankAccount || "",
|
|
|
+ bankCardList,
|
|
|
secondLinkName: form.emergencyContact || "",
|
|
|
secondLinkPhone: form.emergencyPhone || "",
|
|
|
secondLinkRelation: form.emergencyRelation || "",
|
|
|
pic: avatarUrl,
|
|
|
+ avatar: avatarFiles,
|
|
|
professionId: professionIds.length ? professionIds.map(String).join(",") : undefined,
|
|
|
workTypeId: professionIds.length ? toApiId(professionIds[0]) : undefined,
|
|
|
remark: form.remarks || "",
|
|
|
- groupId: form.groupId || undefined,
|
|
|
- deptIds: (Array.isArray(form.deptIds) && form.deptIds.length
|
|
|
- ? form.deptIds
|
|
|
- : form.deptId
|
|
|
- ? [form.deptId]
|
|
|
- : []
|
|
|
- )
|
|
|
- .map((id) => toApiId(id))
|
|
|
- .filter((id) => id != null),
|
|
|
+ groupId: toApiId(form.groupId),
|
|
|
+ deptIds,
|
|
|
deptName: form.deptName || "",
|
|
|
managerUserId: toApiId(form.managerId || form.managerUserId),
|
|
|
- // 岗位:界面只选岗位;提交仍需 positionList 必填的层级/序列主键(由前端按岗位档案解析)
|
|
|
postId: positionIds.length ? positionIds.join(",") : undefined,
|
|
|
postName: form.position || undefined,
|
|
|
- positionList: positionIds.length
|
|
|
- ? [
|
|
|
- (() => {
|
|
|
- const id = positionIds[0];
|
|
|
- const binding =
|
|
|
- (Array.isArray(form.positionBindings) ? form.positionBindings : []).find(
|
|
|
- (item) => String(item.positionId) === String(id),
|
|
|
- ) || {};
|
|
|
- return {
|
|
|
- positionId: toApiId(id),
|
|
|
- positionLevelId: toApiId(binding.positionLevelId),
|
|
|
- positionSequenceId: toApiId(binding.positionSequenceId),
|
|
|
- primaryFlag: 1,
|
|
|
- };
|
|
|
- })(),
|
|
|
- ]
|
|
|
- : [],
|
|
|
- factoryId: form.factoryId ? toApiId(form.factoryId) : undefined,
|
|
|
- socialSecurityList: (form.socialSecurityRecords || [])
|
|
|
- .filter((item) => item.type || item.insuredDate)
|
|
|
- .map((item) => ({
|
|
|
- socialType: item.type || "",
|
|
|
- socialBase: Number(item.base) || 0,
|
|
|
- insuredDate: item.insuredDate || "",
|
|
|
- stopDate: item.stopDate || "",
|
|
|
- stopRecord: item.stopReason || "",
|
|
|
- })),
|
|
|
- // skills / trainRecords 已废弃:非空提交会被后端拒绝,技能/培训走独立 HR / EHS 接口
|
|
|
- rewardsPunishments: (form.rewardPunishmentRecords || []).map((item) => ({
|
|
|
- id: item.id || undefined,
|
|
|
- type: /惩罚|处分|警告/.test(item.type) ? 2 : 1,
|
|
|
- desce: item.description || item.name || "",
|
|
|
- startTime: item.startDate || item.date || "",
|
|
|
- endTime: item.endDate || "",
|
|
|
- status: REWARD_STATUS[item.status] ?? 2,
|
|
|
- remark: item.remark || "",
|
|
|
- })),
|
|
|
- identityPhotos: (form.certificates || [])
|
|
|
- .filter((item) => item.type || item.number)
|
|
|
- .map((item) => ({
|
|
|
- id: item.id || undefined,
|
|
|
- type: CERT_TYPE[item.type] ?? 4,
|
|
|
- code: item.number || "",
|
|
|
- level: CERT_LEVEL[item.level] || item.level || "",
|
|
|
- status: item.status === "失效" ? 0 : 1,
|
|
|
- validityStartTime: item.startDate || "",
|
|
|
- validityEndTime: item.endDate || "",
|
|
|
- enactorTime: item.issueDate || "",
|
|
|
- remark: item.remark || "",
|
|
|
- holderType: "1",
|
|
|
- holder: form.name || "",
|
|
|
- })),
|
|
|
+ positionList: serializePositionList(form, positionIds),
|
|
|
+ factoryId: toApiId(form.factoryId),
|
|
|
+ criticalTaskList: serializeCriticalTaskList(form),
|
|
|
+ socialSecurityList: serializeSocialSecurityList(form),
|
|
|
+ rewardsPunishments: serializeRewards(form),
|
|
|
+ identityPhotos: serializeIdentityPhotos(form),
|
|
|
+ socialSecurityAccount: form.socialSecurityAccount || form.raw?.socialSecurityAccount || undefined,
|
|
|
+ socialSecurityAddress: form.socialSecurityAddress || form.raw?.socialSecurityAddress || undefined,
|
|
|
+ socialSecurityAddressId: toApiId(form.socialSecurityAddressId || form.raw?.socialSecurityAddressId),
|
|
|
+ accumulationFundAccount: form.accumulationFundAccount || form.raw?.accumulationFundAccount || undefined,
|
|
|
});
|
|
|
}
|
|
|
|