fix(微信订阅): 字段名按微信真实模板校准,不再靠猜编号;phrase 只截断不补齐

This commit is contained in:
2026-10-24 10:18:57 +08:00
parent c51b7c660a
commit dc2565da34
8 changed files with 701 additions and 49 deletions
+7 -11
View File
@@ -7,8 +7,7 @@
*
* 各类型限制(公众平台模板字段名后缀就是类型):
* thing 20 字
* phrase 5 个以内纯汉字(官方文档的写法;社区反馈**恰好 5 个汉字**在部分模板上会报
* `47003 data.phraseN.value invalid`,实测 4 个汉字正常)
* phrase 5 个以内纯汉字(**只截断不补齐**:补齐会塞进非汉字字符,更容易 47003)
* time 必须是 'YYYY-MM-DD HH:mm'
* date 必须是 'YYYY-MM-DD'
* character_string 32 字(只能数字、字母)
@@ -50,16 +49,13 @@ export function clampField(key: string, value: unknown): string {
}
if (type === 'phrase') {
/*
* phrase = 5 个以内纯汉字。官方文档是「5个以内」,但社区反馈**恰好 5 个汉字**在部分模板上
* 会被判 47003 invalid(4 个正常,见 wxopen.club/topic/61daa41e947eea50368f28ec),所以
* 按最保守的写法统一补到 5 个字:短了补全角空格,长到 5 个字保持原样,超了截断。
* “已排期”只有 3 个字 —— 真发出去不是被拒就是显示得莫名其妙,这里补齐后不会超长。
* phrase = 5 个以内纯汉字。**只截断、不补齐**。
*
* 早先的版本为了绕开「社区反馈恰好 5 个汉字会报 47003」,把短词用全角空格补到 5 个字 ——
* 结果补进去的 U+3000 不是汉字,反而更容易被判「不是纯汉字」。现在按官方文档字面执行:
* 汉字数 ≤ 5 就原样发(「已排期」3 个字完全合规),超了才截。
*/
const chars = Array.from(text)
if (chars.length >= 5) return chars.slice(0, 5).join('')
let padded = text
while (Array.from(padded).length < 5) padded += ' '
return padded
return Array.from(text).slice(0, 5).join('')
}
const max = FIELD_MAX_LEN[type] || 32
return text.slice(0, max)