Files
langx/langx.go
T

282 lines
5.3 KiB
Go
Raw Normal View History

2024-06-30 11:52:34 +08:00
package langx
import (
2024-07-09 20:05:53 +08:00
"context"
2024-07-11 13:47:21 +08:00
"embed"
2024-07-10 17:24:58 +08:00
"encoding/json"
2024-06-30 11:52:34 +08:00
"fmt"
2024-07-10 17:24:58 +08:00
"io/fs"
"os"
"path/filepath"
2024-06-30 11:52:34 +08:00
"strings"
2024-07-21 11:10:41 +08:00
"sync"
2024-06-30 11:52:34 +08:00
)
type langx struct {
ops *options
codeMap map[string]int
transMap map[string]map[string]string
2024-07-21 11:10:41 +08:00
mut sync.Mutex
2024-06-30 11:52:34 +08:00
}
var l *langx = &langx{}
func init() {
l = &langx{
2024-07-10 17:24:58 +08:00
ops: defaultOptions(),
2024-06-30 11:52:34 +08:00
codeMap: make(map[string]int),
transMap: make(map[string]map[string]string),
2024-07-21 11:10:41 +08:00
mut: sync.Mutex{},
2024-06-30 11:52:34 +08:00
}
}
2024-07-09 20:05:53 +08:00
// 设置
2024-06-30 11:52:34 +08:00
func InitLangx(ops ...Option) {
for _, opt := range ops {
opt(l.ops)
}
}
// 这是语言的Code
func RegisterCode(datas map[string]int) {
2024-07-21 11:10:41 +08:00
l.mut.Lock()
defer l.mut.Unlock()
2024-06-30 11:52:34 +08:00
l.codeMap = datas
}
2024-07-21 11:10:41 +08:00
// 追加覆盖Code
func AppendCode(datas map[string]int) {
l.mut.Lock()
defer l.mut.Unlock()
for k, v := range datas {
l.codeMap[k] = v
}
}
2024-06-30 11:52:34 +08:00
// 注册语言翻译
func RegisterTrans(langName string, trans map[string]string) {
2024-07-21 11:10:41 +08:00
l.mut.Lock()
defer l.mut.Unlock()
2024-06-30 11:52:34 +08:00
l.transMap[langName] = trans
}
2024-07-21 11:10:41 +08:00
// 追加覆盖翻译
func AppendTrans(langName string, trans map[string]string) {
l.mut.Lock()
defer l.mut.Unlock()
for k, v := range trans {
l.transMap[langName][k] = v
}
}
2024-07-10 17:24:58 +08:00
// 直接读取文件夹获取配置
// 要求:
2024-07-10 18:28:53 +08:00
// 1.json格式文件
2024-07-10 17:24:58 +08:00
// 2.code.json为自定义响应码 格式map[string]int{}
// 3.其他的json文件为对应语音 格式map[string]string{}
// 4.如果json解析错误将会panic
func RegisterDir(dir string) error {
// 遍历dir获取.json的文件
err := filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if strings.HasSuffix(info.Name(), ".json") {
// 读取文件
fileName := strings.Replace(info.Name(), ".json", "", 1)
by, err := os.ReadFile(path)
if err != nil {
return err
}
if fileName == "code" {
data := map[string]int{}
err = json.Unmarshal(by, &data)
if err != nil {
return err
}
RegisterCode(data)
} else {
data := map[string]string{}
err = json.Unmarshal(by, &data)
if err != nil {
return err
}
RegisterTrans(fileName, data)
}
}
return nil
})
2024-07-11 13:47:21 +08:00
// code文件为状态码,其他为对应的语言文件,文件名为语言名
return err
}
func RegisterEmbed(asset embed.FS) error {
paths, err := readEmbedAllPath(asset, "")
2024-07-10 17:24:58 +08:00
if err != nil {
2024-07-11 13:47:21 +08:00
return err
}
for _, ff := range paths {
// 获取文件的后缀
fileName := strings.Replace(ff.path, ".json", "", 1)
if fileName == "code" {
data := map[string]int{}
err = json.Unmarshal(ff.datas, &data)
if err != nil {
return err
}
RegisterCode(data)
} else {
data := map[string]string{}
err = json.Unmarshal(ff.datas, &data)
if err != nil {
return err
}
RegisterTrans(fileName, data)
}
2024-07-10 17:24:58 +08:00
}
return nil
}
2024-07-11 13:47:21 +08:00
type fileData struct {
path string
datas []byte
}
func readEmbedAllPath(asset embed.FS, path string) ([]fileData, error) {
newRoot := ""
if path == "" {
newRoot = "."
} else {
newRoot = path
}
fs, err := asset.ReadDir(newRoot)
if err != nil {
return nil, err
}
var files []fileData
for _, f := range fs {
if f.IsDir() {
chaild := ""
if newRoot == "." {
chaild = f.Name()
} else {
chaild = newRoot + "/" + f.Name()
}
df, err := readEmbedAllPath(asset, chaild)
if err != nil {
return nil, err
}
files = append(files, df...)
continue
}
by, err := asset.ReadFile(newRoot + "/" + f.Name())
if err != nil {
return nil, err
}
ff := fileData{
path: f.Name(),
datas: by,
}
files = append(files, ff)
}
return files, nil
}
2024-06-30 11:52:34 +08:00
// 获取翻译
// 包含Code和Message
2024-07-10 18:28:53 +08:00
func GetTransFormat(lang string, key string, format map[string]string) (code int, str string) {
2024-06-30 11:52:34 +08:00
code = GetCode(key)
str = GetFormat(lang, key, format)
return
}
2024-07-10 18:28:53 +08:00
func GetTrans(lang string, key string) (code int, str string) {
return GetTransFormat(lang, key, map[string]string{})
}
func GetTransCtx(ctx context.Context, key string) (code int, str string) {
return GetTrans(getLangFromCtx(ctx), key)
}
func GetTransFormatCtx(ctx context.Context, key string, format map[string]string) (code int, str string) {
return GetTransFormat(getLangFromCtx(ctx), key, format)
}
2024-06-30 11:52:34 +08:00
// 根据Key获取code
func GetCode(key string) int {
2024-07-21 11:10:41 +08:00
l.mut.Lock()
defer l.mut.Unlock()
2024-06-30 11:52:34 +08:00
code, ok := l.codeMap[key]
if !ok {
return l.ops.defaultCode
}
return code
}
2024-07-09 20:05:53 +08:00
// 获取翻译
2024-06-30 11:52:34 +08:00
func GetMsg(lang string, key string) string {
2024-07-21 11:10:41 +08:00
l.mut.Lock()
defer l.mut.Unlock()
2024-06-30 11:52:34 +08:00
// 找指定语言
str, ok := l.transMap[lang]
if ok {
val, ok := str[key]
if ok {
return val
}
}
// 找默认语言
str, ok = l.transMap[l.ops.defaultLang]
if ok {
val, ok := str[key]
if ok {
return val
}
}
return key
}
2024-07-09 20:05:53 +08:00
// 从ctx里面获取语言
func GetMsgCtx(ctx context.Context, key string) string {
2024-07-10 18:28:53 +08:00
return GetMsg(getLangFromCtx(ctx), key)
2024-07-09 20:05:53 +08:00
}
2024-06-30 11:52:34 +08:00
// 拼接回复
func GetFormat(lang string, key string, arr map[string]string) string {
str := GetMsg(lang, key)
for k, v := range arr {
str = strings.ReplaceAll(str, fmt.Sprintf(l.ops.replaceKey, k), v)
}
return str
}
2024-07-07 18:17:28 +08:00
2024-07-10 18:28:53 +08:00
func GetFormatCtx(ctx context.Context, key string, arr map[string]string) string {
return GetFormat(getLangFromCtx(ctx), key, arr)
}
2024-07-09 20:05:53 +08:00
// 获取默认Code
2024-07-07 18:17:28 +08:00
func GetDefaultCode() int {
return l.ops.defaultCode
}
2024-07-10 18:28:53 +08:00
func getLangFromCtx(ctx context.Context) string {
ctxVal := ctx.Value(l.ops.ctxLangKey)
lang := l.ops.defaultLang
if ctxVal != nil {
lang = ctxVal.(string)
}
return lang
}