feat(subscribe): 新增拉取小程序真实模板列表诊断(定位40037)
- 新增 GET /api/admin/message/templates:调用 wxaapi/newtmpl/gettemplate 返回当前 appId(脱敏) 下真实模板列表,并标出后台已填但不在列表中的ID - 测试推送 diagnostics 增加 appIdMasked,便于核对 appId - 后台新增「拉取小程序模板列表(核对ID)」按钮与不匹配高亮提示 - 文档补充 40037 排查步骤;回归 86 套件/632 用例全绿
这个提交包含在:
@@ -650,9 +650,44 @@
|
||||
</a-row>
|
||||
|
||||
<div style="margin-top: 16px">
|
||||
<a-button type="primary" :loading="saving" @click="saveMessageTemplateConfig">
|
||||
保存微信模板消息配置
|
||||
</a-button>
|
||||
<a-space>
|
||||
<a-button type="primary" :loading="saving" @click="saveMessageTemplateConfig">
|
||||
保存微信模板消息配置
|
||||
</a-button>
|
||||
<a-button :loading="loadingTemplates" @click="fetchWechatTemplates">
|
||||
拉取小程序模板列表(核对ID)
|
||||
</a-button>
|
||||
</a-space>
|
||||
</div>
|
||||
|
||||
<div v-if="wechatTemplates" style="margin-top: 16px">
|
||||
<a-alert
|
||||
:type="mismatchedTemplateIds.length > 0 ? 'error' : 'success'"
|
||||
:title="mismatchedTemplateIds.length > 0
|
||||
? `有 ${mismatchedTemplateIds.length} 个已填模板ID不属于该小程序(会导致 40037 invalid template_id)`
|
||||
: `已填模板ID均匹配该小程序(appId: ${wechatTemplates.appIdMasked || '-'})`"
|
||||
>
|
||||
<div>小程序模板总数:{{ wechatTemplates.count ?? 0 }}</div>
|
||||
<div v-if="mismatchedTemplateIds.length > 0">
|
||||
不在列表中的已填ID:{{ mismatchedTemplateIds.join(';') }}
|
||||
</div>
|
||||
<div v-if="wechatTemplates.errcode">微信返回:[{{ wechatTemplates.errcode }}] {{ wechatTemplates.errmsg }}</div>
|
||||
</a-alert>
|
||||
|
||||
<a-table
|
||||
v-if="Array.isArray(wechatTemplates.templates) && wechatTemplates.templates.length"
|
||||
style="margin-top: 12px"
|
||||
:data="wechatTemplates.templates"
|
||||
:pagination="false"
|
||||
size="small"
|
||||
:scroll="{ y: 260 }"
|
||||
>
|
||||
<template #columns>
|
||||
<a-table-column title="模板标题" data-index="title" :width="180" />
|
||||
<a-table-column title="模板ID" data-index="templateId" :width="320" />
|
||||
<a-table-column title="类型" data-index="type" :width="90" />
|
||||
</template>
|
||||
</a-table>
|
||||
</div>
|
||||
</a-form>
|
||||
</a-card>
|
||||
@@ -1031,7 +1066,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { ref, reactive, computed, onMounted } from 'vue';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import axios from 'axios';
|
||||
|
||||
@@ -1339,6 +1374,8 @@ const messageTemplateForm = reactive({
|
||||
|
||||
const testSending = ref(false);
|
||||
const testResult = ref<any>(null);
|
||||
const loadingTemplates = ref(false);
|
||||
const wechatTemplates = ref<any>(null);
|
||||
const testMsgForm = reactive({
|
||||
templateType: 'order_status',
|
||||
targetUserId: 1001,
|
||||
@@ -1346,6 +1383,37 @@ const testMsgForm = reactive({
|
||||
previewDetail: '您的同城生活陪伴订单已开始服务,请出示4位核销码完成现场确认。'
|
||||
});
|
||||
|
||||
// 拉取当前小程序真实存在的订阅消息模板,用于核对后台填写的模板ID是否属于该 appId
|
||||
const fetchWechatTemplates = async () => {
|
||||
loadingTemplates.value = true;
|
||||
try {
|
||||
const res: any = await axios.get('/api/admin/message/templates');
|
||||
const data = res?.data?.data || res?.data || res;
|
||||
wechatTemplates.value = data;
|
||||
if (data?.errcode && data.errcode !== 0) {
|
||||
Message.error(`微信返回 [${data.errcode}] ${data.errmsg}`);
|
||||
} else {
|
||||
Message.success(`已拉取到 ${data?.count ?? 0} 个模板(appId: ${data?.appIdMasked || '-'})`);
|
||||
}
|
||||
} catch (err: any) {
|
||||
Message.error(err.response?.data?.message || err.message || '拉取模板列表失败');
|
||||
} finally {
|
||||
loadingTemplates.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 后台填写的4个模板ID中,哪些不在小程序模板列表里(即为 40037 的元凶)
|
||||
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}`);
|
||||
});
|
||||
|
||||
|
||||
const saveMessageTemplateConfig = () => {
|
||||
saveConfig('message_template_rules', messageTemplateForm);
|
||||
};
|
||||
|
||||
在新工单中引用
屏蔽一个用户