diff --git a/scripts/replace-team-qrcode-url.js b/scripts/replace-team-qrcode-url.js index 3f361b4..0a86886 100644 --- a/scripts/replace-team-qrcode-url.js +++ b/scripts/replace-team-qrcode-url.js @@ -5,8 +5,12 @@ * 目的: * - 扫描 corp.team collection * - 将 team.qrcodes[].qrcode 中旧前缀替换为新前缀 + * - 将 team.qrcodes[].qrcode 中 corpId 参数从旧值替换为新值 + * - 将 team.groupWelcomeConfig 中的建档链接/附件链接同步替换 * - 扫描 corp.staff-qrcode collection * - 将 staff-qrcode.archiveLink.url 中旧前缀替换为新前缀 + * - 将 staff-qrcode.archiveLink.url 中 corpId 参数从旧值替换为新值 + * - 将 staff-qrcode.fileList 中的附件链接同步替换 * * 安全: * - 默认 dry-run(不落库) @@ -90,6 +94,8 @@ function createDefaultOptions() { mongoPass: "", mongoAuthDb: "", corpId: "", + oldCorpId: "", + newCorpId: "", oldPrefix: "https://www.youcan365.com/h5/#/", newPrefix: "https://crm.gykqyy.com/gkPatientWeChat/#/", }; @@ -119,6 +125,8 @@ function parseArgs(argv) { else if (key === "mongopass") opts.mongoPass = value; else if (key === "mongoauthdb") opts.mongoAuthDb = value; else if (key === "corpid") opts.corpId = value; + else if (key === "oldcorpid" || key === "sourcecorpid" || key === "targetcorpid") opts.oldCorpId = value; + else if (key === "newcorpid" || key === "tokencorpid") opts.newCorpId = value; else if (key === "oldprefix") opts.oldPrefix = value; else if (key === "newprefix") opts.newPrefix = value; else if (key === "batchdocs") opts.batchDocs = Number(value); @@ -175,6 +183,12 @@ function parseArgs(argv) { } else if (a === "--corpId") { opts.corpId = takeValue(i); i++; + } else if (a === "--oldCorpId" || a === "--sourceCorpId" || a === "--targetCorpId") { + opts.oldCorpId = takeValue(i); + i++; + } else if (a === "--newCorpId" || a === "--tokenCorpId") { + opts.newCorpId = takeValue(i); + i++; } else if (a === "--oldPrefix") { opts.oldPrefix = takeValue(i); i++; @@ -202,8 +216,10 @@ function parseArgs(argv) { function applyEnvFallbacks(opts) { if (!opts.mongoUri) opts.mongoUri = process.env.MONGO_URI || process.env.GK_MONGO_URI || ""; if (!opts.corpId) { - opts.corpId = process.env.TARGET_CORP_ID || process.env.TOKEN_CORP_ID || ""; + opts.corpId = process.env.TOKEN_CORP_ID || process.env.TARGET_CORP_ID || ""; } + if (!opts.oldCorpId) opts.oldCorpId = process.env.OLD_CORP_ID || process.env.SOURCE_CORP_ID || process.env.TARGET_CORP_ID || ""; + if (!opts.newCorpId) opts.newCorpId = process.env.NEW_CORP_ID || process.env.TOKEN_CORP_ID || ""; if (!opts.oldPrefix && process.env.OLD_QRCODE_PREFIX) opts.oldPrefix = process.env.OLD_QRCODE_PREFIX; if (!opts.newPrefix && process.env.NEW_QRCODE_PREFIX) opts.newPrefix = process.env.NEW_QRCODE_PREFIX; } @@ -281,32 +297,24 @@ function replacePrefix(value, oldPrefix, newPrefix) { return `${newPrefix}${value.slice(oldPrefix.length)}`; } -function updateTeamDoc(doc, { oldPrefix, newPrefix }) { - const qrcodes = Array.isArray(doc.qrcodes) ? doc.qrcodes : []; - let changed = 0; - const nextQrcodes = qrcodes.map((item) => { - if (!item || typeof item !== "object") return item; - const current = item.qrcode; - const next = replacePrefix(current, oldPrefix, newPrefix); - if (next !== current) { - changed++; - return { ...item, qrcode: next }; - } - return item; - }); - return { changed, nextQrcodes }; +function replaceUrlCorpId(value, oldCorpId, newCorpId) { + if (!isNonEmptyString(value) || !isNonEmptyString(oldCorpId) || !isNonEmptyString(newCorpId)) return value; + return value.replace( + /([?&]corpId=)([^&#]*)/g, + (match, prefix, currentCorpId) => (currentCorpId === oldCorpId ? `${prefix}${newCorpId}` : match) + ); } -function updateStaffQrcodeDoc(doc, { oldPrefix, newPrefix }) { - const archiveLink = - doc && doc.archiveLink && typeof doc.archiveLink === "object" - ? doc.archiveLink - : null; - if (!archiveLink) { +function normalizeQrcodeUrl(value, { oldPrefix, newPrefix, oldCorpId, newCorpId }) { + return replaceUrlCorpId(replacePrefix(value, oldPrefix, newPrefix), oldCorpId, newCorpId); +} + +function normalizeArchiveLink(archiveLink, options) { + if (!archiveLink || typeof archiveLink !== "object") { return { changed: 0, nextArchiveLink: archiveLink }; } const current = archiveLink.url; - const next = replacePrefix(current, oldPrefix, newPrefix); + const next = normalizeQrcodeUrl(current, options); if (next === current) { return { changed: 0, nextArchiveLink: archiveLink }; } @@ -316,6 +324,120 @@ function updateStaffQrcodeDoc(doc, { oldPrefix, newPrefix }) { }; } +function normalizeFileList(fileList, options) { + if (!Array.isArray(fileList)) { + return { changed: 0, nextFileList: fileList }; + } + + let changed = 0; + const nextFileList = fileList.map((item) => { + if (!item || typeof item !== "object") return item; + + let nextItem = item; + + function setItemUrl(key) { + const current = item[key]; + const next = normalizeQrcodeUrl(current, options); + if (next !== current) { + changed++; + nextItem = nextItem === item ? { ...item } : nextItem; + nextItem[key] = next; + } + } + + setItemUrl("URL"); + setItemUrl("url"); + setItemUrl("href"); + + if (item.file && typeof item.file === "object") { + let nextFile = item.file; + for (const key of ["url", "URL", "href", "picurl", "imgUrl", "download_url"]) { + const current = item.file[key]; + const next = normalizeQrcodeUrl(current, options); + if (next !== current) { + changed++; + nextFile = nextFile === item.file ? { ...item.file } : nextFile; + nextFile[key] = next; + } + } + if (nextFile !== item.file) { + nextItem = nextItem === item ? { ...item } : nextItem; + nextItem.file = nextFile; + } + } + + return nextItem; + }); + + return { changed, nextFileList }; +} + +function updateTeamDoc(doc, { oldPrefix, newPrefix, oldCorpId, newCorpId }) { + const options = { oldPrefix, newPrefix, oldCorpId, newCorpId }; + const qrcodes = Array.isArray(doc.qrcodes) ? doc.qrcodes : []; + let changed = 0; + const nextQrcodes = qrcodes.map((item) => { + if (!item || typeof item !== "object") return item; + const current = item.qrcode; + const next = normalizeQrcodeUrl(current, options); + if (next !== current) { + changed++; + return { ...item, qrcode: next }; + } + return item; + }); + + const set = {}; + if (changed > 0) { + set.qrcodes = nextQrcodes; + } + + const groupWelcomeConfig = + doc && doc.groupWelcomeConfig && typeof doc.groupWelcomeConfig === "object" + ? doc.groupWelcomeConfig + : null; + if (groupWelcomeConfig) { + let nextGroupWelcomeConfig = groupWelcomeConfig; + const archiveResult = normalizeArchiveLink(groupWelcomeConfig.archiveLink, options); + if (archiveResult.changed > 0) { + changed += archiveResult.changed; + nextGroupWelcomeConfig = { ...nextGroupWelcomeConfig, archiveLink: archiveResult.nextArchiveLink }; + } + + const fileListResult = normalizeFileList(groupWelcomeConfig.fileList, options); + if (fileListResult.changed > 0) { + changed += fileListResult.changed; + nextGroupWelcomeConfig = { ...nextGroupWelcomeConfig, fileList: fileListResult.nextFileList }; + } + + if (nextGroupWelcomeConfig !== groupWelcomeConfig) { + set.groupWelcomeConfig = nextGroupWelcomeConfig; + } + } + + return { changed, set }; +} + +function updateStaffQrcodeDoc(doc, { oldPrefix, newPrefix, oldCorpId, newCorpId }) { + const options = { oldPrefix, newPrefix, oldCorpId, newCorpId }; + let changed = 0; + const set = {}; + + const archiveResult = normalizeArchiveLink(doc && doc.archiveLink, options); + if (archiveResult.changed > 0) { + changed += archiveResult.changed; + set.archiveLink = archiveResult.nextArchiveLink; + } + + const fileListResult = normalizeFileList(doc && doc.fileList, options); + if (fileListResult.changed > 0) { + changed += fileListResult.changed; + set.fileList = fileListResult.nextFileList; + } + + return { changed, set }; +} + async function processCollectionDocs({ collection, filter, @@ -381,6 +503,8 @@ async function main() { --dbName 数据库名,默认 corp --collection collection 名,默认 team --corpId 仅处理指定机构 + --oldCorpId URL 参数中的旧 corpId,默认取 OLD_CORP_ID / SOURCE_CORP_ID / TARGET_CORP_ID + --newCorpId URL 参数中的新 corpId,默认取 NEW_CORP_ID / TOKEN_CORP_ID --oldPrefix 旧前缀,默认 https://www.youcan365.com/h5/#/ --newPrefix 新前缀,默认 https://crm.gykqyy.com/gkPatientWeChat/#/ --apply --yes 真正写库;默认 dry-run @@ -432,8 +556,10 @@ async function main() { updateTeamDoc(doc, { oldPrefix: opts.oldPrefix, newPrefix: opts.newPrefix, + oldCorpId: opts.oldCorpId, + newCorpId: opts.newCorpId, }), - buildUpdate: ({ nextQrcodes }) => ({ $set: { qrcodes: nextQrcodes } }), + buildUpdate: ({ set }) => ({ $set: set }), describeDoc: (doc) => `_id=${doc._id} teamId=${doc.teamId || ""} corpId=${doc.corpId || ""}`, }); @@ -453,10 +579,10 @@ async function main() { updateStaffQrcodeDoc(doc, { oldPrefix: opts.oldPrefix, newPrefix: opts.newPrefix, + oldCorpId: opts.oldCorpId, + newCorpId: opts.newCorpId, }), - buildUpdate: ({ nextArchiveLink }) => ({ - $set: { archiveLink: nextArchiveLink }, - }), + buildUpdate: ({ set }) => ({ $set: set }), describeDoc: (doc) => `_id=${doc._id} qrcodeId=${doc.qrcodeId || ""} corpId=${doc.corpId || ""}`, });