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_')");