feat(admin): 模板列表支持「一键按标题填入槽位」,避免手抄长模板ID出错

- 列表每行新增「填入」按钮,按标题(订单/提现/活动报名/核销)自动写入对应槽位
- 顶部新增「一键按标题填入槽位」,批量填入后提示保存落库
- 回归 87 套件/639 用例全绿
这个提交包含在:
xcbyy
2026-10-19 11:27:12 +08:00
父节点 c58449ddae
当前提交 c17afd20d5
共有 2 个文件被更改,包括 57 次插入 和 0 次删除

查看文件

@@ -660,6 +660,13 @@
<a-button :loading="loadingTemplates" @click="fetchWechatTemplates">
拉取小程序模板列表(核对ID)
</a-button>
<a-button
v-if="wechatTemplates && Array.isArray(wechatTemplates.templates) && wechatTemplates.templates.length"
type="outline"
@click="applyWechatTemplates"
>
一键按标题填入槽位
</a-button>
</a-space>
</div>
@@ -690,6 +697,11 @@
<a-table-column title="模板ID" data-index="templateId" :width="300" />
<a-table-column title="类型" data-index="type" :width="80" />
<a-table-column title="模板内容(关键词)" data-index="content" :ellipsis="true" :tooltip="true" />
<a-table-column title="操作" :width="80">
<template #cell="{ record }">
<a-button type="text" size="mini" @click="applyOneTemplate(record)">填入</a-button>
</template>
</a-table-column>
</template>
</a-table>
</div>
@@ -1413,6 +1425,45 @@ const mismatchedTemplateIds = computed(() => {
return t.mismatched.map((m: any) => `${m.key}: ${m.templateId}`);
});
// 按模板标题推断应填入的后台槽位,避免手抄长ID出错
const resolveSlotByTitle = (title: string): string => {
const t = String(title || '');
if (/订单/.test(t)) return 'orderStatusTemplateId';
if (/提现/.test(t)) return 'withdrawSuccessTemplateId';
if (/活动|报名|组局|搭子/.test(t)) return 'activityJoinTemplateId';
if (/核销|签到/.test(t)) return 'verifyCodeTemplateId';
return '';
};
const applyOneTemplate = (record: any) => {
const slot = resolveSlotByTitle(record?.title);
const id = String(record?.templateId || '');
if (!slot || !id) {
Message.warning('无法按标题判断槽位,请手动复制该模板ID');
return;
}
(messageTemplateForm.valueJson as any)[slot] = id;
Message.success('已填入对应槽位,请点「保存微信模板消息配置」落库');
};
const applyWechatTemplates = () => {
const t = wechatTemplates.value;
if (!t || !Array.isArray(t.templates)) return;
let filled = 0;
for (const tpl of t.templates) {
const slot = resolveSlotByTitle(tpl?.title);
if (slot && tpl?.templateId) {
(messageTemplateForm.valueJson as any)[slot] = String(tpl.templateId);
filled += 1;
}
}
if (filled > 0) {
Message.success(`已按标题填入 ${filled} 个模板ID,请点「保存微信模板消息配置」落库`);
} else {
Message.warning('未能按标题自动匹配,请手动复制列表中的模板ID');
}
};
const saveMessageTemplateConfig = () => {
saveConfig('message_template_rules', messageTemplateForm);

查看文件

@@ -56,6 +56,12 @@ describe('第七十批订阅消息原因可见与真实授权', () => {
expect(indexCode).toContain('const normId = (v: any)');
});
it('提供「一键填入槽位」,避免手抄长模板ID出错', () => {
expect(adminCode).toContain('applyWechatTemplates');
expect(adminCode).toContain('resolveSlotByTitle');
expect(adminCode).toContain('applyOneTemplate');
});
it('小程序真正调用订阅授权并过滤占位符', () => {
expect(subscribeCode).toContain('requestSubscribeAll');
expect(subscribeCode).toContain("startsWith('tmpl_')");