180 lines
6.0 KiB
Go
180 lines
6.0 KiB
Go
|
|
//go:build llm_script
|
|||
|
|
|
|||
|
|
package main
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"fmt"
|
|||
|
|
"regexp"
|
|||
|
|
"strings"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
const (
|
|||
|
|
defaultAliyunTokenPlanURL = "https://help.aliyun.com/zh/model-studio/token-plan-overview"
|
|||
|
|
defaultAliyunCodingPlanURL = "https://help.aliyun.com/zh/model-studio/coding-plan-quickstart"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
func parseAliyunSubscriptionCatalog(tokenRaw string, codingRaw string) ([]subscriptionImportRecord, error) {
|
|||
|
|
publishedAt, known := publishedAtFromText(firstNonEmptyText(tokenRaw, codingRaw))
|
|||
|
|
|
|||
|
|
tokenRecords, err := parseAliyunTokenPlan(tokenRaw, publishedAt)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
codingRecords, err := parseAliyunCodingPlan(codingRaw, publishedAt)
|
|||
|
|
if err != nil {
|
|||
|
|
return nil, err
|
|||
|
|
}
|
|||
|
|
records := append(tokenRecords, codingRecords...)
|
|||
|
|
for i := range records {
|
|||
|
|
records[i].PublishedAtKnown = known
|
|||
|
|
}
|
|||
|
|
return records, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func parseAliyunTokenPlan(raw string, publishedAt string) ([]subscriptionImportRecord, error) {
|
|||
|
|
seatPattern := regexp.MustCompile(`(?s)(标准坐席|高级坐席|尊享坐席)\s+¥([\d,]+)(?:/坐席/月)?\s+([\d,]+)\s*Credits/坐席/月\s+([^\n]+)`)
|
|||
|
|
matches := seatPattern.FindAllStringSubmatch(raw, -1)
|
|||
|
|
if len(matches) != 3 {
|
|||
|
|
return nil, fmt.Errorf("unexpected aliyun token seat count: %d", len(matches))
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
tierCodes := map[string]string{
|
|||
|
|
"标准坐席": "standard-seat",
|
|||
|
|
"高级坐席": "advanced-seat",
|
|||
|
|
"尊享坐席": "premium-seat",
|
|||
|
|
}
|
|||
|
|
tierNames := map[string]string{
|
|||
|
|
"标准坐席": "Standard",
|
|||
|
|
"高级坐席": "Advanced",
|
|||
|
|
"尊享坐席": "Premium",
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
records := make([]subscriptionImportRecord, 0, 4)
|
|||
|
|
for _, match := range matches {
|
|||
|
|
records = append(records, subscriptionImportRecord{
|
|||
|
|
ProviderName: "Alibaba",
|
|||
|
|
ProviderNameCn: "阿里巴巴",
|
|||
|
|
ProviderCountry: "CN",
|
|||
|
|
ProviderWebsite: "https://www.aliyun.com",
|
|||
|
|
OperatorName: "Alibaba Bailian",
|
|||
|
|
OperatorNameCn: "阿里云百炼",
|
|||
|
|
OperatorCountry: "CN",
|
|||
|
|
OperatorWebsite: "https://help.aliyun.com/zh/model-studio/",
|
|||
|
|
OperatorType: "cloud",
|
|||
|
|
PlanFamily: "token_plan",
|
|||
|
|
PlanCode: "aliyun-token-plan-" + tierCodes[match[1]],
|
|||
|
|
PlanName: "Token Plan 团队版 " + match[1],
|
|||
|
|
Tier: tierNames[match[1]],
|
|||
|
|
BillingCycle: "monthly",
|
|||
|
|
Currency: "CNY",
|
|||
|
|
ListPrice: mustParseSubscriptionPrice(match[2]),
|
|||
|
|
PriceUnit: "CNY/month",
|
|||
|
|
QuotaValue: mustParseSubscriptionInt64(match[3]),
|
|||
|
|
QuotaUnit: "credits/month",
|
|||
|
|
PlanScope: "Token Plan 团队版",
|
|||
|
|
SourceURL: defaultAliyunTokenPlanURL,
|
|||
|
|
PublishedAt: publishedAt,
|
|||
|
|
EffectiveDate: effectiveDateFromPublishedAt(publishedAt),
|
|||
|
|
Notes: strings.TrimSpace(match[4]),
|
|||
|
|
})
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
sharedPattern := regexp.MustCompile(`共享用量包\s+¥([\d,]+)(?:/个)?\s+([\d,]+)\s*Credits/个`)
|
|||
|
|
shared := sharedPattern.FindStringSubmatch(raw)
|
|||
|
|
if len(shared) != 3 {
|
|||
|
|
return nil, fmt.Errorf("aliyun shared pack not found")
|
|||
|
|
}
|
|||
|
|
records = append(records, subscriptionImportRecord{
|
|||
|
|
ProviderName: "Alibaba",
|
|||
|
|
ProviderNameCn: "阿里巴巴",
|
|||
|
|
ProviderCountry: "CN",
|
|||
|
|
ProviderWebsite: "https://www.aliyun.com",
|
|||
|
|
OperatorName: "Alibaba Bailian",
|
|||
|
|
OperatorNameCn: "阿里云百炼",
|
|||
|
|
OperatorCountry: "CN",
|
|||
|
|
OperatorWebsite: "https://help.aliyun.com/zh/model-studio/",
|
|||
|
|
OperatorType: "cloud",
|
|||
|
|
PlanFamily: "token_plan",
|
|||
|
|
PlanCode: "aliyun-token-plan-shared-pack",
|
|||
|
|
PlanName: "Token Plan 团队版 共享用量包",
|
|||
|
|
Tier: "SharedPack",
|
|||
|
|
BillingCycle: "monthly",
|
|||
|
|
Currency: "CNY",
|
|||
|
|
ListPrice: mustParseSubscriptionPrice(shared[1]),
|
|||
|
|
PriceUnit: "CNY/pack",
|
|||
|
|
QuotaValue: mustParseSubscriptionInt64(shared[2]),
|
|||
|
|
QuotaUnit: "credits/pack",
|
|||
|
|
PlanScope: "Token Plan 团队版",
|
|||
|
|
SourceURL: defaultAliyunTokenPlanURL,
|
|||
|
|
PublishedAt: publishedAt,
|
|||
|
|
EffectiveDate: effectiveDateFromPublishedAt(publishedAt),
|
|||
|
|
Notes: "跨坐席共享的弹性用量包,有效期 1 个月。",
|
|||
|
|
})
|
|||
|
|
return records, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
func parseAliyunCodingPlan(raw string, publishedAt string) ([]subscriptionImportRecord, error) {
|
|||
|
|
pricePattern := regexp.MustCompile(`价格\s+¥\s*([\d,]+)\s*/月`)
|
|||
|
|
priceMatch := pricePattern.FindStringSubmatch(raw)
|
|||
|
|
if len(priceMatch) != 2 {
|
|||
|
|
return nil, fmt.Errorf("aliyun coding plan price not found")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
modelsPattern := regexp.MustCompile(`支持的模型\s+\|\s+推荐模型:([^\n]+)`)
|
|||
|
|
modelsMatch := modelsPattern.FindStringSubmatch(raw)
|
|||
|
|
modelScope := []string{}
|
|||
|
|
if len(modelsMatch) == 2 {
|
|||
|
|
for _, item := range strings.Split(modelsMatch[1], "、") {
|
|||
|
|
item = strings.TrimSpace(item)
|
|||
|
|
if item != "" {
|
|||
|
|
modelScope = append(modelScope, item)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
limitPattern := regexp.MustCompile(`每月\s*([\d,]+)\s*次请求`)
|
|||
|
|
limitMatch := limitPattern.FindStringSubmatch(raw)
|
|||
|
|
quotaValue := int64(0)
|
|||
|
|
if len(limitMatch) == 2 {
|
|||
|
|
quotaValue = mustParseSubscriptionInt64(limitMatch[1])
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
notes := []string{}
|
|||
|
|
for _, fragment := range []string{
|
|||
|
|
"Lite 套餐自 2026 年 3 月 20 日 00:00:00(UTC+08:00)起停止新购",
|
|||
|
|
"活动已结束",
|
|||
|
|
} {
|
|||
|
|
if strings.Contains(raw, fragment) {
|
|||
|
|
notes = append(notes, fragment)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return []subscriptionImportRecord{{
|
|||
|
|
ProviderName: "Alibaba",
|
|||
|
|
ProviderNameCn: "阿里巴巴",
|
|||
|
|
ProviderCountry: "CN",
|
|||
|
|
ProviderWebsite: "https://www.aliyun.com",
|
|||
|
|
OperatorName: "Alibaba Bailian",
|
|||
|
|
OperatorNameCn: "阿里云百炼",
|
|||
|
|
OperatorCountry: "CN",
|
|||
|
|
OperatorWebsite: "https://help.aliyun.com/zh/model-studio/",
|
|||
|
|
OperatorType: "cloud",
|
|||
|
|
PlanFamily: "coding_plan",
|
|||
|
|
PlanCode: "aliyun-coding-plan-pro",
|
|||
|
|
PlanName: "百炼 Coding Plan Pro",
|
|||
|
|
Tier: "Pro",
|
|||
|
|
BillingCycle: "monthly",
|
|||
|
|
Currency: "CNY",
|
|||
|
|
ListPrice: mustParseSubscriptionPrice(priceMatch[1]),
|
|||
|
|
PriceUnit: "CNY/month",
|
|||
|
|
QuotaValue: quotaValue,
|
|||
|
|
QuotaUnit: "requests/month",
|
|||
|
|
PlanScope: "Coding Plan",
|
|||
|
|
ModelScope: modelScope,
|
|||
|
|
SourceURL: defaultAliyunCodingPlanURL,
|
|||
|
|
PublishedAt: publishedAt,
|
|||
|
|
EffectiveDate: effectiveDateFromPublishedAt(publishedAt),
|
|||
|
|
Notes: strings.Join(notes, ";"),
|
|||
|
|
}}, nil
|
|||
|
|
}
|