From eb592dc1b95655f26ed25591b430820034471657 Mon Sep 17 00:00:00 2001 From: xcbyy <2578898740@qq.com> Date: Mon, 19 Oct 2026 11:06:47 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20=E6=A8=A1=E6=9D=BFID=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E6=94=B9=E7=94=B1=E5=90=8E=E7=AB=AF=E8=A3=81=E5=86=B3?= =?UTF-8?q?=E5=B9=B6=20trim=EF=BC=8C=E4=BF=AE=E5=A4=8D"ID=E6=98=8E?= =?UTF-8?q?=E6=98=8E=E4=B8=80=E8=87=B4=E5=8D=B4=E6=8A=A5=E4=B8=8D=E5=B1=9E?= =?UTF-8?q?=E4=BA=8E=E8=AF=A5=E5=B0=8F=E7=A8=8B=E5=BA=8F"=E7=9A=84?= =?UTF-8?q?=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 拉取模板列表接口在后端统一 trim 后比对,返回 mismatched 结论(含两侧空白差异场景) - 后台改为直接展示后端结论,避免前端字符串比对误报 - 回归 87 套件/637 用例全绿 --- .../views/safety/platform-config/index.vue | 10 +++------ server/src/index.ts | 22 +++++++++++++------ .../subscription-message-diagnose.spec.ts | 6 +++++ 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue b/admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue index 68a7eed..5c7f0ef 100644 --- a/admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue +++ b/admin/arco-design-pro-vite/src/views/safety/platform-config/index.vue @@ -1402,15 +1402,11 @@ const fetchWechatTemplates = async () => { } }; -// 后台填写的4个模板ID中,哪些不在小程序模板列表里(即为 40037 的元凶) +// 后台填写的4个模板ID中,哪些不在小程序模板列表里(以后端结论为准,避免前端字符串比对误报) const mismatchedTemplateIds = computed(() => { const t = wechatTemplates.value; - if (!t || !Array.isArray(t.templates)) return []; - const existing = new Set(t.templates.map((x: any) => String(x.templateId))); - const cfg = t.configured || {}; - return Object.entries(cfg) - .filter(([, id]) => id && !existing.has(String(id))) - .map(([key, id]) => `${key}: ${id}`); + if (!t || !Array.isArray(t.mismatched)) return []; + return t.mismatched.map((m: any) => `${m.key}: ${m.templateId}`); }); diff --git a/server/src/index.ts b/server/src/index.ts index 6662500..0d05c33 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -3932,6 +3932,18 @@ app.get('/api/admin/message/templates', async (_req: Request, res: Response) => const list = data && Array.isArray(data.data) ? data.data : []; const record = await repo.getPlatformConfigByKey('message_template_rules'); const rules = (record && record.valueJson) || {}; + const clean = (v: any) => String(v == null ? '' : v).trim(); + const configured = { + orderStatus: clean(rules.orderStatusTemplateId), + activityJoin: clean(rules.activityJoinTemplateId), + withdrawSuccess: clean(rules.withdrawSuccessTemplateId), + verifyCode: clean(rules.verifyCodeTemplateId), + }; + // 以服务端为准做匹配:两侧均 trim,避免因末尾空白/换行导致的误报 + const existing = new Set(list.map((t: any) => clean(t.priTmplId))); + const mismatched = Object.entries(configured) + .filter(([, id]) => Boolean(id) && !existing.has(id)) + .map(([key, id]) => ({ key, templateId: id })); res.json({ code: 20000, data: { @@ -3940,18 +3952,14 @@ app.get('/api/admin/message/templates', async (_req: Request, res: Response) => errmsg: (data && data.errmsg) || 'ok', count: list.length, templates: list.map((t: any) => ({ - templateId: t.priTmplId, + templateId: clean(t.priTmplId), title: t.title, type: t.type, content: t.content, example: t.example, })), - configured: { - orderStatus: String(rules.orderStatusTemplateId || ''), - activityJoin: String(rules.activityJoinTemplateId || ''), - withdrawSuccess: String(rules.withdrawSuccessTemplateId || ''), - verifyCode: String(rules.verifyCodeTemplateId || ''), - }, + configured, + mismatched, }, }); } catch (err: any) { diff --git a/server/tests/subscription-message-diagnose.spec.ts b/server/tests/subscription-message-diagnose.spec.ts index 77af789..ee3d821 100644 --- a/server/tests/subscription-message-diagnose.spec.ts +++ b/server/tests/subscription-message-diagnose.spec.ts @@ -44,6 +44,12 @@ describe('第七十批订阅消息原因可见与真实授权', () => { expect(indexCode).toContain('appIdMasked'); }); + it('模板ID匹配以后端为准并做 trim,避免误报不匹配', () => { + expect(indexCode).toContain('const mismatched = Object.entries(configured)'); + expect(indexCode).toContain('const clean = (v: any) => String(v == null'); + expect(adminCode).toContain('t.mismatched'); + }); + it('小程序真正调用订阅授权并过滤占位符', () => { expect(subscribeCode).toContain('requestSubscribeAll'); expect(subscribeCode).toContain("startsWith('tmpl_')");