feat: 将竞品报告和数据报告的title针对不同的语言翻译

This commit is contained in:
cjy 2026-04-10 09:41:55 +08:00
parent f1362a6502
commit a95fdcb2d2
4 changed files with 260 additions and 0 deletions

1
go.mod
View File

@ -176,6 +176,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mozillazg/go-pinyin v0.21.0 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect github.com/nwaples/rardecode v1.1.3 // indirect
github.com/nxadm/tail v1.4.11 // indirect github.com/nxadm/tail v1.4.11 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect github.com/onsi/ginkgo v1.16.5 // indirect

2
go.sum
View File

@ -678,6 +678,8 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mozillazg/go-pinyin v0.21.0 h1:Wo8/NT45z7P3er/9YSLHA3/kjZzbLz5hR7i+jGeIGao=
github.com/mozillazg/go-pinyin v0.21.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM= github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw= github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=

120
pkg/utils/reportname.go Normal file
View File

@ -0,0 +1,120 @@
package utils
import (
"fmt"
"strings"
"github.com/mozillazg/go-pinyin"
)
// reportTypeTranslations locale 到 数据报告/竞品报告 翻译的映射
var reportTypeTranslations = map[string]map[string]string{
"zh-CN": {
"数据报告": "数据报告",
"竞品报告": "竞品报告",
},
"zh-TW": {
"数据报告": "數據報告",
"竞品报告": "競合報告",
},
"EN": {
"数据报告": "Data Report",
"竞品报告": "Competitor Report",
},
"de-DE": {
"数据报告": "Datenbericht",
"竞品报告": "Wettbewerbsanalyse",
},
"ja-JP": {
"数据报告": "データレポート",
"竞品报告": "競合分析レポート",
},
}
// pinyinTitles 中文称谓"老师"对应的拼音形式(用于检测)
var pinyinTitles = []string{"lao shi", "laoshi"}
// ConvertNameToPinyin 将中文姓名转换为拼音,单词首字母大写,单词间用空格分隔。
// 对于非中文 locale会去除"老师"称谓。
// 示例:"王旗老师" -> "Wang Qi"
func ConvertNameToPinyin(name string) string {
args := pinyin.NewArgs()
slices := pinyin.Pinyin(name, args)
var result []string
for _, s := range slices {
if len(s) > 0 {
// 首字母大写
runes := []rune(s[0])
if len(runes) > 0 {
uppered := string([]rune{runes[0] - 32}) + string(runes[1:])
result = append(result, uppered)
}
}
}
pinyinName := joinWithSpace(result)
// 对于非中文 locale去除拼音 "Lao Shi"
lowerName := strings.ToLower(pinyinName)
for _, pt := range pinyinTitles {
if strings.HasSuffix(lowerName, pt) {
// 提取去掉称谓后的姓名部分
nameWithoutTitle := strings.TrimSuffix(pinyinName, " Lao Shi")
nameWithoutTitle = strings.TrimSuffix(nameWithoutTitle, " Laoshi")
return nameWithoutTitle
}
}
return pinyinName
}
// joinWithSpace 用空格连接字符串,过滤空字符串
func joinWithSpace(parts []string) string {
var nonEmpty []string
for _, p := range parts {
if p != "" {
nonEmpty = append(nonEmpty, p)
}
}
if len(nonEmpty) == 0 {
return ""
}
result := nonEmpty[0]
for i := 1; i < len(nonEmpty); i++ {
result += " " + nonEmpty[i]
}
return result
}
// ConvertReportName 将报告名转换为指定语言版本。
// prefix: YYYY-MM 格式,如 "2026-03"
// personName: 中文姓名,如 "王旗老师"
// reportType: "数据报告" 或 "竞品报告"
// locale: "zh-CN", "zh-TW", "EN", "de-DE", 或 "ja-JP"
func ConvertReportName(prefix, personName, reportType, locale string) string {
reportTypeTrans, ok := reportTypeTranslations[locale]
if !ok {
reportTypeTrans = reportTypeTranslations["zh-CN"]
}
translatedReportType, ok := reportTypeTrans[reportType]
if !ok {
translatedReportType = reportType
}
// 对于中文 localezh-CN, zh-TW保持原样
if locale == "zh-CN" || locale == "zh-TW" {
displayName := personName
if locale == "zh-TW" {
// zh-TW 去掉"老师",繁体报告类型已通过 translatedReportType 获取
displayName = strings.ReplaceAll(personName, "老师", "")
}
return fmt.Sprintf("%s%s%s", prefix, displayName, translatedReportType)
}
// 对于其他 locale转换为拼音
pinyinName := ConvertNameToPinyin(personName)
return fmt.Sprintf("%s %s %s", prefix, pinyinName, translatedReportType)
}

View File

@ -0,0 +1,137 @@
package utils
import "testing"
func TestConvertReportName(t *testing.T) {
tests := []struct {
name string
prefix string // YYYY-MM
personName string // 中文姓名
reportType string // 数据报告 或 竞品报告
locale string
expected string
}{
{
name: "EN Data Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "数据报告",
locale: "EN",
expected: "2026-03 Wang Qi Data Report",
},
{
name: "EN Competitor Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "竞品报告",
locale: "EN",
expected: "2026-03 Wang Qi Competitor Report",
},
{
name: "zh-TW Data Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "数据报告",
locale: "zh-TW",
expected: "2026-03王旗數據報告",
},
{
name: "zh-TW Competitor Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "竞品报告",
locale: "zh-TW",
expected: "2026-03王旗競合報告",
},
{
name: "de-DE Data Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "数据报告",
locale: "de-DE",
expected: "2026-03 Wang Qi Datenbericht",
},
{
name: "de-DE Competitor Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "竞品报告",
locale: "de-DE",
expected: "2026-03 Wang Qi Wettbewerbsanalyse",
},
{
name: "ja-JP Data Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "数据报告",
locale: "ja-JP",
expected: "2026-03 Wang Qi データレポート",
},
{
name: "ja-JP Competitor Report",
prefix: "2026-03",
personName: "王旗老师",
reportType: "竞品报告",
locale: "ja-JP",
expected: "2026-03 Wang Qi 競合分析レポート",
},
{
name: "zh-CN Data Report (no conversion)",
prefix: "2026-03",
personName: "王旗老师",
reportType: "数据报告",
locale: "zh-CN",
expected: "2026-03王旗老师数据报告",
},
{
name: "zh-CN Competitor Report (no conversion)",
prefix: "2026-03",
personName: "王旗老师",
reportType: "竞品报告",
locale: "zh-CN",
expected: "2026-03王旗老师竞品报告",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConvertReportName(tt.prefix, tt.personName, tt.reportType, tt.locale)
if result != tt.expected {
t.Errorf("ConvertReportName() = %v, want %v", result, tt.expected)
}
})
}
}
func TestConvertNameToPinyin(t *testing.T) {
tests := []struct {
name string
input string
expected string
}{
{
name: "simple name",
input: "王旗",
expected: "Wang Qi",
},
{
name: "name with title",
input: "王旗老师",
expected: "Wang Qi",
},
{
name: "two word name with title",
input: "王小明老师",
expected: "Wang Xiao Ming",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ConvertNameToPinyin(tt.input)
if result != tt.expected {
t.Errorf("ConvertNameToPinyin() = %v, want %v", result, tt.expected)
}
})
}
}