fix(tencent): detect promotional token plans

Relax the Tencent catalog plan matcher so monthly promotional plans are parsed by structure instead of a hard-coded plan-name list.

This keeps first-month promotional packages in the catalog and adds a regression sample plus parser test coverage.
This commit is contained in:
phamnazage-jpg
2026-05-15 22:41:02 +08:00
parent d5d18e987e
commit 0ee181a4a7
4 changed files with 104 additions and 49 deletions

View File

@@ -96,3 +96,33 @@ func TestRunTencentCatalogDryRunPrintsSummary(t *testing.T) {
} }
} }
} }
func TestParseTencentCatalogExtractsPromotionalPlans(t *testing.T) {
raw, err := os.ReadFile(filepath.Join("testdata", "tencent_token_plan_promo_sample.txt"))
if err != nil {
t.Fatalf("读取促销样例失败: %v", err)
}
catalog, err := parseTencentCatalog(string(raw))
if err != nil {
t.Fatalf("parseTencentCatalog 失败: %v", err)
}
if len(catalog.Plans) != 2 {
t.Fatalf("期望 2 个套餐,实际 %d", len(catalog.Plans))
}
first := catalog.Plans[0]
if first.Series != "通用 Token Plan" {
t.Fatalf("套餐系列错误: %q", first.Series)
}
if first.Tier != "首月活动版" {
t.Fatalf("促销套餐档位错误: %q", first.Tier)
}
if first.Price != "19元/月" {
t.Fatalf("促销套餐价格错误: %q", first.Price)
}
if first.Scene != "首购用户首月优惠,次月恢复标准价。" {
t.Fatalf("促销套餐说明错误: %q", first.Scene)
}
}

View File

@@ -188,22 +188,7 @@ func extractSeriesHeading(line string) string {
} }
func tryParseTencentPlan(lines []string, start int, series string) (tencentPlan, int, bool) { func tryParseTencentPlan(lines []string, start int, series string) (tencentPlan, int, bool) {
if start+4 >= len(lines) { if !looksLikeTencentPlan(lines, start) {
return tencentPlan{}, start, false
}
if !isTencentPlanName(lines[start]) {
return tencentPlan{}, start, false
}
if !isTencentPlanTier(lines[start+1]) {
return tencentPlan{}, start, false
}
if !strings.Contains(lines[start+2], "订阅月") {
return tencentPlan{}, start, false
}
if !strings.Contains(lines[start+3], "Tokens") {
return tencentPlan{}, start, false
}
if !strings.Contains(lines[start+4], "元/月") {
return tencentPlan{}, start, false return tencentPlan{}, start, false
} }
@@ -216,7 +201,7 @@ func tryParseTencentPlan(lines []string, start int, series string) (tencentPlan,
} }
nextIndex := start + 4 nextIndex := start + 4
if start+5 < len(lines) && !strings.HasPrefix(lines[start+5], "### ") && !isTencentPlanName(lines[start+5]) { if start+5 < len(lines) && !strings.HasPrefix(lines[start+5], "### ") && !looksLikeTencentPlan(lines, start+5) {
plan.Scene = lines[start+5] plan.Scene = lines[start+5]
nextIndex = start + 5 nextIndex = start + 5
} }
@@ -247,7 +232,7 @@ func tryParseTencentModel(lines []string, start int, series string) (tencentMode
if strings.HasPrefix(line, "## ") || strings.HasPrefix(line, "### ") { if strings.HasPrefix(line, "## ") || strings.HasPrefix(line, "### ") {
break break
} }
if isTencentPlanName(line) && i+1 < len(lines) && isTencentPlanTier(lines[i+1]) { if looksLikeTencentPlan(lines, i) {
break break
} }
if i+1 < len(lines) && isTencentModelID(lines[i+1]) && !isReservedTencentLine(line) { if i+1 < len(lines) && isTencentModelID(lines[i+1]) && !isReservedTencentLine(line) {
@@ -262,19 +247,32 @@ func tryParseTencentModel(lines []string, start int, series string) (tencentMode
return model, nextIndex, true return model, nextIndex, true
} }
func isTencentPlanName(line string) bool {
switch line {
case "体验套餐", "基础套餐", "进阶套餐", "专业套餐":
return true
default:
return false
}
}
func isTencentPlanTier(line string) bool { func isTencentPlanTier(line string) bool {
return strings.HasPrefix(line, "") && strings.HasSuffix(line, "") return strings.HasPrefix(line, "") && strings.HasSuffix(line, "")
} }
func looksLikeTencentPlan(lines []string, start int) bool {
if start+4 >= len(lines) {
return false
}
if isReservedTencentLine(lines[start]) {
return false
}
if isTencentModelID(lines[start]) {
return false
}
if !isTencentPlanTier(lines[start+1]) {
return false
}
if !strings.Contains(lines[start+2], "订阅月") {
return false
}
if !strings.Contains(lines[start+3], "Tokens") {
return false
}
return strings.Contains(lines[start+4], "元/月")
}
func isReservedTencentLine(line string) bool { func isReservedTencentLine(line string) bool {
if strings.HasPrefix(line, "#") { if strings.HasPrefix(line, "#") {
return true return true

View File

@@ -0,0 +1,27 @@
# Token Plan 个人版套餐概览
最近更新时间2026-05-14 09:00:00
## 通用 Token Plan 套餐
### 套餐详情
首月活动套餐
(首月活动版)
每订阅月
3500万 Tokens
19元/月
首购用户首月优惠,次月恢复标准价。
基础套餐
Standard
每订阅月
1亿 Tokens
99元/月
日常使用,高性价比。
### 可用模型
GLM-5
glm-5
深度思考、文本生成
Hunyuan-T1
hunyuan-t1
文本生成