Files
server/app/utils/translation_helpers.go
T
2026-01-16 15:49:34 +08:00

123 lines
3.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package utils
import (
"encoding/json"
"fmt"
"os"
"path/filepath"
"github.com/goravel/framework/facades"
"goravel/lang"
)
// loadLangMessages 加载语言文件的 messages 对象(内部辅助函数)
// 优先从文件系统读取,失败时从 embed FS 读取(支持生产环境)
// 返回 messages map 和是否成功加载
func loadLangMessages(langCode string) (map[string]any, bool) {
var langData []byte
var err error
// 获取语言文件路径(使用框架配置的路径)
langPath := facades.Config().GetString("app.lang_path", "lang")
langFile := filepath.Join(langPath, fmt.Sprintf("%s.json", langCode))
// 优先尝试从文件系统读取
langData, err = os.ReadFile(langFile)
if err != nil {
// 文件系统读取失败,尝试从 embed FS 读取
embedFile := fmt.Sprintf("%s.json", langCode)
langData, err = lang.FS.ReadFile(embedFile)
if err != nil {
facades.Log().Debugf("读取语言文件失败: %s, embed: %s, error=%v", langFile, embedFile, err)
return nil, false
}
}
// 解析 JSON
var langMap map[string]any
if err := json.Unmarshal(langData, &langMap); err != nil {
facades.Log().Debugf("解析语言文件失败: lang=%s, error=%v", langCode, err)
return nil, false
}
// 获取 messages 对象(使用类型辅助函数)
messages, ok := GetMap(langMap, "messages")
if !ok {
facades.Log().Debugf("语言文件中没有 messages 对象: lang=%s", langCode)
return nil, false
}
return messages, true
}
// TranslateHeaders 翻译表头(直接读取语言文件)
// 这是一个通用函数,可以被任何需要翻译表头的 job 使用
//
// 参数:
// - headerKeys: 需要翻译的键列表(如 ["export_header_id", "export_header_order_no"]
// - lang: 语言代码(如 "cn" 或 "en"
//
// 返回:
// - []string: 翻译后的表头列表,如果翻译失败则返回原始键
//
// 示例:
//
// headerKeys := []string{"export_header_id", "export_header_order_no"}
// headers := utils.TranslateHeaders(headerKeys, "cn")
func TranslateHeaders(headerKeys []string, lang string) []string {
headers := make([]string, len(headerKeys))
// 加载语言文件的 messages 对象
messages, ok := loadLangMessages(lang)
if !ok {
// 如果读取失败,使用原始键
facades.Log().Warningf("加载语言文件失败: lang=%s, 使用原始键", lang)
return append([]string(nil), headerKeys...)
}
// 翻译每个键(使用泛型辅助函数)
for i, key := range headerKeys {
fullKey := "messages." + key
if value, ok := GetString(messages, key); ok && value != "" {
headers[i] = value
} else {
// 如果翻译失败,使用原始键
headers[i] = key
facades.Log().Debugf("翻译键未找到: %s (语言: %s)", fullKey, lang)
}
}
return headers
}
// TranslateKey 翻译单个键(从语言文件读取,支持文件系统和embed FS)
// 这是一个通用函数,可以被任何需要翻译单个键的地方使用(包括Job等无http.Context的场景)
//
// 参数:
// - key: 需要翻译的键(如 "export_order_status_pending"
// - lang: 语言代码(如 "cn" 或 "en"
// - defaultValue: 如果翻译失败时返回的默认值(通常为原始键)
//
// 返回:
// - string: 翻译后的文本,如果翻译失败则返回 defaultValue
//
// 示例:
//
// statusText := utils.TranslateKey("export_order_status_pending", "cn", "pending")
func TranslateKey(key, lang, defaultValue string) string {
// 加载语言文件的 messages 对象(支持文件系统和embed FS)
messages, ok := loadLangMessages(lang)
if !ok {
return defaultValue
}
// 尝试获取翻译值
if value, ok := GetString(messages, key); ok && value != "" {
return value
}
// 如果翻译失败,返回默认值
return defaultValue
}