fix(admin): 模板ID匹配改由后端裁决并 trim,修复"ID明明一致却报不属于该小程序"的误报

- 拉取模板列表接口在后端统一 trim 后比对,返回 mismatched 结论(含两侧空白差异场景)
- 后台改为直接展示后端结论,避免前端字符串比对误报
- 回归 87 套件/637 用例全绿
这个提交包含在:
xcbyy
2026-10-19 11:06:47 +08:00
父节点 b77827522f
当前提交 eb592dc1b9
共有 3 个文件被更改,包括 24 次插入 和 14 次删除

查看文件

@@ -1402,15 +1402,11 @@ const fetchWechatTemplates = async () => {
} }
}; };
// 后台填写的4个模板ID中,哪些不在小程序模板列表里(即为 40037 的元凶) // 后台填写的4个模板ID中,哪些不在小程序模板列表里(以后端结论为准,避免前端字符串比对误报)
const mismatchedTemplateIds = computed(() => { const mismatchedTemplateIds = computed(() => {
const t = wechatTemplates.value; const t = wechatTemplates.value;
if (!t || !Array.isArray(t.templates)) return []; if (!t || !Array.isArray(t.mismatched)) return [];
const existing = new Set(t.templates.map((x: any) => String(x.templateId))); return t.mismatched.map((m: any) => `${m.key}: ${m.templateId}`);
const cfg = t.configured || {};
return Object.entries(cfg)
.filter(([, id]) => id && !existing.has(String(id)))
.map(([key, id]) => `${key}: ${id}`);
}); });

查看文件

@@ -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 list = data && Array.isArray(data.data) ? data.data : [];
const record = await repo.getPlatformConfigByKey('message_template_rules'); const record = await repo.getPlatformConfigByKey('message_template_rules');
const rules = (record && record.valueJson) || {}; 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({ res.json({
code: 20000, code: 20000,
data: { data: {
@@ -3940,18 +3952,14 @@ app.get('/api/admin/message/templates', async (_req: Request, res: Response) =>
errmsg: (data && data.errmsg) || 'ok', errmsg: (data && data.errmsg) || 'ok',
count: list.length, count: list.length,
templates: list.map((t: any) => ({ templates: list.map((t: any) => ({
templateId: t.priTmplId, templateId: clean(t.priTmplId),
title: t.title, title: t.title,
type: t.type, type: t.type,
content: t.content, content: t.content,
example: t.example, example: t.example,
})), })),
configured: { configured,
orderStatus: String(rules.orderStatusTemplateId || ''), mismatched,
activityJoin: String(rules.activityJoinTemplateId || ''),
withdrawSuccess: String(rules.withdrawSuccessTemplateId || ''),
verifyCode: String(rules.verifyCodeTemplateId || ''),
},
}, },
}); });
} catch (err: any) { } catch (err: any) {

查看文件

@@ -44,6 +44,12 @@ describe('第七十批订阅消息原因可见与真实授权', () => {
expect(indexCode).toContain('appIdMasked'); 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('小程序真正调用订阅授权并过滤占位符', () => { it('小程序真正调用订阅授权并过滤占位符', () => {
expect(subscribeCode).toContain('requestSubscribeAll'); expect(subscribeCode).toContain('requestSubscribeAll');
expect(subscribeCode).toContain("startsWith('tmpl_')"); expect(subscribeCode).toContain("startsWith('tmpl_')");