WHMSLIVE 部署验证企微HR主数据镜像
这个提交包含在:
@@ -300,6 +300,10 @@ function hrTokenCandidates(config) {
|
||||
];
|
||||
}
|
||||
|
||||
function canFallbackToAgentSecret(error) {
|
||||
return error instanceof WecomHrMasterSyncError && error.code === "wecom_errcode_48009";
|
||||
}
|
||||
|
||||
function normalizeDepartmentMap(payload) {
|
||||
const map = new Map();
|
||||
const departments = Array.isArray(payload?.department) ? payload.department : [];
|
||||
@@ -419,6 +423,78 @@ function normalizeWecomHrProfile({ contact = {}, staff = {}, departmentMap = new
|
||||
return profile;
|
||||
}
|
||||
|
||||
async function fetchContactProfilesInput({ config, token, userids, limit, fetchImpl, timeoutMs }) {
|
||||
const departmentMap = await fetchDepartmentMap({
|
||||
accessToken: token.accessToken,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
const departmentId = toSafeString(config.wecomContactDefaultDepartmentId, 32) || "1";
|
||||
const contacts = userids.length
|
||||
? await Promise.all(userids.map((userid) => fetchContactMember({
|
||||
accessToken: token.accessToken,
|
||||
userid,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
})))
|
||||
: await listContactMembers({
|
||||
accessToken: token.accessToken,
|
||||
departmentId,
|
||||
limit,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
return { departmentMap, contacts, tokenSource: token.source };
|
||||
}
|
||||
|
||||
async function fetchContactProfilesInputWithFallback({ config, contactToken, userids, limit, fetchImpl, timeoutMs }) {
|
||||
try {
|
||||
return await fetchContactProfilesInput({
|
||||
config,
|
||||
token: contactToken,
|
||||
userids,
|
||||
limit,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
} catch (error) {
|
||||
if (!canFallbackToAgentSecret(error) || contactToken.source === "WECOM_AGENT_SECRET_FALLBACK") {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const fallback = await getTokenFromCandidates({
|
||||
config,
|
||||
candidates: [{ source: "WECOM_AGENT_SECRET_FALLBACK", secret: config?.wecomAgentSecret }],
|
||||
timeoutMs,
|
||||
fetchImpl,
|
||||
});
|
||||
if (!fallback.ok) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
try {
|
||||
return await fetchContactProfilesInput({
|
||||
config,
|
||||
token: fallback,
|
||||
userids,
|
||||
limit,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
} catch (fallbackError) {
|
||||
if (canFallbackToAgentSecret(fallbackError)) {
|
||||
fallbackError.details = {
|
||||
...(fallbackError.details ?? {}),
|
||||
firstTokenSource: contactToken.source,
|
||||
fallbackTokenSource: fallback.source,
|
||||
};
|
||||
}
|
||||
throw fallbackError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchWecomHrProfiles({ config, userids, limit, fetchImpl = fetch }) {
|
||||
const timeoutMs = config.wecomRequestTimeoutMs ?? 10000;
|
||||
const contactToken = await getTokenFromCandidates({
|
||||
@@ -441,29 +517,17 @@ async function fetchWecomHrProfiles({ config, userids, limit, fetchImpl = fetch
|
||||
throw new WecomHrMasterSyncError(hrToken.code, hrToken.message, { missing: hrToken.missing });
|
||||
}
|
||||
|
||||
const departmentMap = await fetchDepartmentMap({
|
||||
accessToken: contactToken.accessToken,
|
||||
const contactInput = await fetchContactProfilesInputWithFallback({
|
||||
config,
|
||||
contactToken,
|
||||
userids,
|
||||
limit,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
const departmentId = toSafeString(config.wecomContactDefaultDepartmentId, 32) || "1";
|
||||
const contacts = userids.length
|
||||
? await Promise.all(userids.map((userid) => fetchContactMember({
|
||||
accessToken: contactToken.accessToken,
|
||||
userid,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
})))
|
||||
: await listContactMembers({
|
||||
accessToken: contactToken.accessToken,
|
||||
departmentId,
|
||||
limit,
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
|
||||
const profiles = [];
|
||||
for (const contact of contacts) {
|
||||
for (const contact of contactInput.contacts) {
|
||||
const userid = toSafeString(contact.userid, 128);
|
||||
if (!userid) continue;
|
||||
const staff = await fetchHrStaffInfo({
|
||||
@@ -472,13 +536,13 @@ async function fetchWecomHrProfiles({ config, userids, limit, fetchImpl = fetch
|
||||
fetchImpl,
|
||||
timeoutMs,
|
||||
});
|
||||
profiles.push(normalizeWecomHrProfile({ contact, staff, departmentMap }));
|
||||
profiles.push(normalizeWecomHrProfile({ contact, staff, departmentMap: contactInput.departmentMap }));
|
||||
}
|
||||
|
||||
return {
|
||||
profiles,
|
||||
tokenSource: {
|
||||
contact: contactToken.source,
|
||||
contact: contactInput.tokenSource,
|
||||
hr: hrToken.source,
|
||||
},
|
||||
};
|
||||
|
||||
在新工单中引用
屏蔽一个用户