admin_backend/model/language.go
2025-11-11 11:30:02 +08:00

215 lines
6.5 KiB
Go

package model
import (
"backend/util"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"
"time"
"github.com/xuri/excelize/v2"
)
type Language struct {
Id int `json:"Id" db:"Id"`
Key string `json:"key" db:"key"`
English string `json:"English" db:"English"`
ChineseSimplified string `json:"ChineseSimplified" db:"ChineseSimplified"`
Portuguese string `json:"Portuguese" db:"Portuguese"`
}
type LanguageOp struct {
Id int `json:"Id" db:"Id"`
LanguageId int `json:"LanguageId" db:"LanguageId"`
Field string `json:"Field" db:"Field"`
OldValue string `json:"OldValue" db:"OldValue"`
NewValue string `json:"NewValue" db:"NewValue"`
Type string `json:"Type" db:"Type"`
Update int `json:"Update" db:"Update"`
}
type LanguageMod struct {
PageSize int `json:"PageSize"`
CurrentPage int `json:"CurrentPage"`
StartTime int `json:"StartTime"`
EndTime int `json:"EndTime"`
SearchField string `json:"SearchField"`
SearchValue string `json:"SearchValue"`
}
func (l *LanguageMod) LanguageList() (map[string]interface{}, error) {
Db := util.MPool.GetGameDB()
defer Db.Close()
var languages []*Language
SearchSQL := ""
if l.SearchField != "" && l.SearchValue != "" {
escaped := strings.ReplaceAll(l.SearchValue, "'", "''")
SearchSQL = " where `" + l.SearchField + "` like '%" + escaped + "%' "
}
err := Db.Select(&languages, fmt.Sprintf("SELECT `Id`, `key`, `English`, `ChineseSimplified`, `Portuguese` FROM language %s LIMIT ?, ?", SearchSQL), (l.CurrentPage-1)*l.PageSize, l.PageSize)
if err != nil {
return nil, err
}
var languageOp []*LanguageOp
err = Db.Select(&languageOp, "SELECT `Id`, `LanguageId`, `Field`, `OldValue`, `NewValue`, `Type`, `Update` FROM language_op where `Update` >= ? and `Update` <= ? ", l.StartTime, l.EndTime)
if err != nil {
return nil, err
}
var total int
err = Db.QueryRow(fmt.Sprintf("SELECT COUNT(*) FROM language %s", SearchSQL)).Scan(&total)
if err != nil {
return nil, err
}
return map[string]interface{}{
"data": languages,
"op": languageOp,
"total": total,
}, nil
}
func (l *LanguageMod) LanguageListAll() (map[string]interface{}, error) {
Db := util.MPool.GetGameDB()
defer Db.Close()
var languages []*Language
err := Db.Select(&languages, "SELECT `Id`, `key`, `English`, `ChineseSimplified`,`Portuguese` FROM language")
if err != nil {
return nil, err
}
var total int
err = Db.QueryRow("SELECT COUNT(*) FROM language").Scan(&total)
if err != nil {
return nil, err
}
// 导出为 xlsx 文件
f := excelize.NewFile()
sheet := "Sheet1"
// 写表头
headers := []string{"Id", "key", "English", "ChineseSimplified", "Portuguese"}
cols := []string{"A", "B", "C", "D", "E"}
for i, h := range headers {
if err := f.SetCellValue(sheet, cols[i]+"1", h); err != nil {
return nil, err
}
}
headers2 := []string{"编号", "键", "英文", "简体中文", "葡萄牙语"}
for i, h := range headers2 {
if err := f.SetCellValue(sheet, cols[i]+"2", h); err != nil {
return nil, err
}
}
// 写数据行
for i, lang := range languages {
row := fmt.Sprintf("%d", i+3)
if err := f.SetCellValue(sheet, "A"+row, lang.Id); err != nil {
return nil, err
}
if err := f.SetCellValue(sheet, "B"+row, lang.Key); err != nil {
return nil, err
}
if err := f.SetCellValue(sheet, "C"+row, lang.English); err != nil {
return nil, err
}
if err := f.SetCellValue(sheet, "D"+row, lang.ChineseSimplified); err != nil {
return nil, err
}
if err := f.SetCellValue(sheet, "E"+row, lang.Portuguese); err != nil {
return nil, err
}
}
// 保存到临时文件
// 保存到指定目录
pathDir := "/data/docs/config"
if err := os.MkdirAll(pathDir, 0755); err != nil {
return nil, err
}
path := filepath.Join(pathDir, "AllLanguage.xlsx")
if err := f.SaveAs(path); err != nil {
return nil, err
}
// 在 /data/docs 仓库中添加并提交该文件
repoDir := "/data/docs"
cmd := exec.Command("git", "pull")
cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil {
return nil, fmt.Errorf("git pull failed: %v: %s", err, string(out))
}
relPath, err := filepath.Rel(repoDir, path)
if err != nil {
return nil, err
}
cmd = exec.Command("git", "add", relPath)
cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil {
return nil, fmt.Errorf("git add failed: %v: %s", err, string(out))
}
commitMsg := fmt.Sprintf("Export AllLanguage.xlsx at %s", time.Now().Format(time.RFC3339))
cmd = exec.Command("git", "commit", "-m", commitMsg)
cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil {
// 忽略 "nothing to commit" 情形
if !strings.Contains(string(out), "nothing to commit") {
return nil, fmt.Errorf("git commit failed: %v: %s", err, string(out))
}
}
cmd = exec.Command("git", "push", "origin", "main")
cmd.Dir = repoDir
if out, err := cmd.CombinedOutput(); err != nil {
return nil, fmt.Errorf("git push failed: %v: %s", err, string(out))
}
// 将文件路径返回到调用方
return map[string]interface{}{
"data": languages,
"total": total,
}, nil
}
func (l *LanguageMod) LanguageSave(langList []LanguageOp, admin string) error {
Db := util.MPool.GetGameDB()
defer Db.Close()
for _, lang := range langList {
_, err := Db.Exec("UPDATE language SET `"+lang.Field+"` = ? WHERE Id = ?", lang.NewValue, lang.LanguageId)
if err != nil {
return err
}
_, err = Db.Exec("insert into language_op (`LanguageId`, `Field`, `OldValue`, `NewValue`, `Type`, `Update`, `Role`) values (?, ?, ?, ?, ?,?,?)", lang.LanguageId, lang.Field, lang.OldValue, lang.NewValue, lang.Type, util.Now(), admin)
if err != nil {
return err
}
}
// 删除 key 包含 "obsolete" 的记录
if _, err := Db.Exec("DELETE FROM language WHERE `key` LIKE ?", "%obsolete%"); err != nil {
return err
}
return nil
}
func (l *LanguageMod) LanguageAdd(langList []Language, admin string) error {
Db := util.MPool.GetGameDB()
defer Db.Close()
for _, lang := range langList {
res, err := Db.Exec("INSERT INTO language (`key`, `English`, `ChineseSimplified`, `Portuguese`) VALUES (?, ?, ?, ?)", lang.Key, lang.English, lang.ChineseSimplified, lang.Portuguese)
if err != nil {
return err
}
lastId, err := res.LastInsertId()
if err != nil {
return err
}
lang.Id = int(lastId)
_, err = Db.Exec("insert into language_op (`LanguageId`, `Field`, `OldValue`, `NewValue`, `Type`, `Update`, `Role`) values (?, ?, ?, ?, ?,?,?)", lang.Id, "All", "", lang.English+"|"+lang.ChineseSimplified+"|"+lang.Portuguese, "Add", util.Now(), admin)
if err != nil {
return err
}
}
return nil
}