支持企微通讯录缺失手机号(07-26-internal-ops-recovery-baseline)
这个提交包含在:
@@ -468,7 +468,7 @@ function normalizeWecomHrProfile({ contact = {}, staff = {}, departmentMap = new
|
||||
};
|
||||
|
||||
profile.missingRequiredFields = [];
|
||||
for (const field of ["externalUserId", "name", "phone", "email"]) {
|
||||
for (const field of ["externalUserId", "name", "email"]) {
|
||||
if (!isMeaningfulString(profile[field])) profile.missingRequiredFields.push(field);
|
||||
}
|
||||
if (!isMeaningfulString(profile.departmentExternalId) && !isMeaningfulString(profile.departmentName)) {
|
||||
@@ -721,18 +721,21 @@ async function detectUniqueConflicts(prisma, employeeId, profile) {
|
||||
|
||||
function buildEmployeeChanges(employee, profile, department) {
|
||||
if (!employee) {
|
||||
return {
|
||||
const changes = {
|
||||
name: buildChange("name", null, profile.name),
|
||||
phone: buildChange("phone", null, profile.phone),
|
||||
email: buildChange("email", null, profile.email),
|
||||
department: buildChange("department", null, department.name),
|
||||
title: buildChange("title", null, profile.title),
|
||||
};
|
||||
if (profile.phone) changes.phone = buildChange("phone", null, profile.phone);
|
||||
return changes;
|
||||
}
|
||||
|
||||
const changes = {};
|
||||
if (employee.name !== profile.name) changes.name = buildChange("name", employee.name, profile.name);
|
||||
if (employee.phone !== profile.phone) changes.phone = buildChange("phone", employee.phone, profile.phone);
|
||||
if (profile.phone && employee.phone !== profile.phone) {
|
||||
changes.phone = buildChange("phone", employee.phone, profile.phone);
|
||||
}
|
||||
if (employee.email !== profile.email) changes.email = buildChange("email", employee.email, profile.email);
|
||||
if (department.id && employee.department_id !== department.id) {
|
||||
changes.department = buildChange("department", employee.department_id, department.name);
|
||||
@@ -854,7 +857,7 @@ async function processProfile(prisma, runId, profile, context) {
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
name: profile.name,
|
||||
phone: profile.phone,
|
||||
...(profile.phone ? { phone: profile.phone } : {}),
|
||||
email: profile.email,
|
||||
department_id: department.id,
|
||||
title: profile.title,
|
||||
@@ -866,7 +869,7 @@ async function processProfile(prisma, runId, profile, context) {
|
||||
: await prisma.employee.create({
|
||||
data: {
|
||||
name: profile.name,
|
||||
phone: profile.phone,
|
||||
phone: profile.phone || null,
|
||||
email: profile.email,
|
||||
department_id: department.id,
|
||||
title: profile.title,
|
||||
@@ -1077,6 +1080,8 @@ async function runWecomHrMasterSync({
|
||||
userids: rawUserids,
|
||||
limit: rawLimit,
|
||||
fetchImpl = fetch,
|
||||
sourceProfiles = null,
|
||||
sourceLabel = "manual_export",
|
||||
}) {
|
||||
const mode = normalizeMode(rawMode);
|
||||
const userids = normalizeUserids(rawUserids);
|
||||
@@ -1095,12 +1100,17 @@ async function runWecomHrMasterSync({
|
||||
|
||||
let source = null;
|
||||
try {
|
||||
source = await fetchWecomHrProfiles({
|
||||
config,
|
||||
userids,
|
||||
limit,
|
||||
fetchImpl,
|
||||
});
|
||||
source = Array.isArray(sourceProfiles)
|
||||
? {
|
||||
profiles: sourceProfiles.slice(0, limit),
|
||||
tokenSource: { offline: toSafeString(sourceLabel, 40) || "manual_export" },
|
||||
}
|
||||
: await fetchWecomHrProfiles({
|
||||
config,
|
||||
userids,
|
||||
limit,
|
||||
fetchImpl,
|
||||
});
|
||||
} catch (error) {
|
||||
const status = error instanceof WecomHrMasterSyncError && error.code === "wecom_token_unavailable"
|
||||
? "skipped"
|
||||
|
||||
@@ -115,7 +115,7 @@ async function fetchWecomOAuthOnboardingProfile({
|
||||
};
|
||||
|
||||
const missing = [];
|
||||
for (const field of ["name", "phone", "email", "departmentExternalId", "departmentName"]) {
|
||||
for (const field of ["name", "email", "departmentExternalId", "departmentName"]) {
|
||||
if (!profile[field]) missing.push(field);
|
||||
}
|
||||
if (missing.length) {
|
||||
@@ -186,7 +186,12 @@ async function resolveEmployee(tx, profile) {
|
||||
},
|
||||
});
|
||||
const contactMatches = await tx.employee.findMany({
|
||||
where: { OR: [{ phone: profile.phone }, { email: profile.email }] },
|
||||
where: {
|
||||
OR: [
|
||||
...(profile.phone ? [{ phone: profile.phone }] : []),
|
||||
{ email: profile.email },
|
||||
],
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
status: true,
|
||||
@@ -229,7 +234,7 @@ async function provisionWecomOAuthEmployee({
|
||||
where: { id: existing.id },
|
||||
data: {
|
||||
name: profile.name,
|
||||
phone: profile.phone,
|
||||
...(profile.phone ? { phone: profile.phone } : {}),
|
||||
email: profile.email,
|
||||
department_id: departmentId,
|
||||
title: profile.title,
|
||||
@@ -241,7 +246,7 @@ async function provisionWecomOAuthEmployee({
|
||||
: await tx.employee.create({
|
||||
data: {
|
||||
name: profile.name,
|
||||
phone: profile.phone,
|
||||
phone: profile.phone || null,
|
||||
email: profile.email,
|
||||
department_id: departmentId,
|
||||
title: profile.title,
|
||||
@@ -294,7 +299,7 @@ async function provisionWecomOAuthEmployee({
|
||||
extra: {
|
||||
created: !existing,
|
||||
source: "wecom_oauth",
|
||||
fieldPresence: { phone: true, email: true },
|
||||
fieldPresence: { phone: Boolean(profile.phone), email: true },
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
在新工单中引用
屏蔽一个用户