admin_backend/controller/scripts.go
2026-04-15 14:48:13 +08:00

378 lines
9.3 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 controller
import (
"backend/middleware/alibaba"
"backend/model"
"backend/util"
"fmt"
"os/exec"
"strings"
"time"
"github.com/gin-gonic/gin"
"github.com/xuri/excelize/v2"
)
func Copywriting(c *gin.Context) {
request := struct {
Step int `json:"step"`
}{}
if err := c.BindJSON(&request); err != nil {
failed(c, "参数绑定失败: "+err.Error())
return
}
switch request.Step {
case 0:
success(c, map[string]interface{}{
"step": 1,
"label": "下载文案文件",
"tips": []string{},
"code": 0,
})
case 1:
CopywritingStep1(c)
case 2:
CopywritingStep2(c)
case 3:
CopywritingStep3(c)
default:
failed(c, "无效的步骤")
}
util.AddAdminLog(c, "文案自动化脚本", request)
}
func CopywritingStep1(c *gin.Context) {
repoDir := `/data/docs`
// git fetch all
if out, err := exec.Command("git", "-C", repoDir, "fetch", "--all").CombinedOutput(); err != nil {
scritp_fail(c, "git fetch all 失败: "+err.Error()+": "+string(out))
return
}
// git reset --hard origin/main
if out, err := exec.Command("git", "-C", repoDir, "reset", "--hard", "origin/main").CombinedOutput(); err != nil {
scritp_fail(c, "git reset 失败: "+err.Error()+": "+string(out))
return
}
// git pull
if out, err := exec.Command("git", "-C", repoDir, "pull").CombinedOutput(); err != nil {
scritp_fail(c, "git pull 失败: "+err.Error()+": "+string(out))
return
}
err := alibaba.DownloadFile()
if err != nil {
success(c, map[string]interface{}{
"step": 2,
"label": "提交git",
"tips": []string{
err.Error(),
},
"code": 1,
})
return
}
// 执行脚本的逻辑
success(c, map[string]interface{}{
"step": 2,
"label": "提交git",
"tips": []string{
"下载文案文件DialogueData.xlsx成功",
},
"code": 0,
})
}
func CopywritingStep2(c *gin.Context) {
time.Sleep(time.Second)
code := 0
repoDir := `/data/docs`
file := `config/DialogueData.xlsx`
// git add
if out, err := exec.Command("git", "-C", repoDir, "add", file).CombinedOutput(); err != nil {
scritp_fail(c, "git add 失败: "+err.Error()+": "+string(out))
return
}
// git commit (ignore non-fatal commit output/errors like "nothing to commit")
exec.Command("git", "-C", repoDir, "commit", "-m", "Update DialogueData.xlsx").Run()
// git push
if out, err := exec.Command("git", "-C", repoDir, "push").CombinedOutput(); err != nil {
scritp_fail(c, "git push 失败: "+err.Error()+": "+string(out))
return
}
_ = code
// 执行脚本的逻辑
success(c, map[string]interface{}{
"step": 3,
"label": "修改翻译表",
"tips": []string{},
"code": 0,
})
}
func CopywritingStep3(c *gin.Context) {
file := `/data/docs/config/DialogueData.xlsx`
f, err := excelize.OpenFile(file)
if err != nil {
failed(c, "打开文件失败: "+err.Error())
return
}
defer f.Close()
rows, err := f.GetRows("DialogueData")
if err != nil {
failed(c, "读取sheet失败: "+err.Error())
return
}
type Dialogue struct {
Id int
Key string
Dialogue string
}
dialogueMap := make(map[string]Dialogue)
for i, row := range rows {
// 跳过标题行(如果有)
if i < 2 {
continue
}
var dVal, iVal string
if len(row) > 3 {
dVal = row[3] // D列0-based 索引 3
}
if len(row) > 8 {
iVal = row[8] // I列0-based 索引 8
}
var lVal string
if len(row) > 11 {
lVal = row[11] // L列0-based 索引 11
}
if lVal != "" {
continue
}
if dVal == "" || iVal == "" {
continue
}
dialogueMap[dVal] = Dialogue{
Key: dVal,
Dialogue: iVal,
Id: i - 2, // 减去标题行
}
}
type db_data struct {
Id int `db:"Id"`
Key string `db:"key"`
EnUs string `db:"en_us"`
OldValue string
}
var dbDatas []db_data
db := util.MPool.GetGameDB()
defer db.Close()
if db == nil {
scritp_fail(c, "获取数据库连接失败")
return
}
err = db.Select(&dbDatas, "SELECT `Id`, `key`, `en_us` FROM `language`")
if err != nil {
scritp_fail(c, "查询语言表失败: "+err.Error())
return
}
updateData := []db_data{}
for _, item := range dbDatas {
if val, ok := dialogueMap[item.Key]; ok {
if val.Dialogue != item.EnUs {
item.OldValue = item.EnUs
item.EnUs = val.Dialogue
updateData = append(updateData, item)
}
delete(dialogueMap, item.Key)
}
}
for _, item := range updateData {
_, err := db.Exec("UPDATE `language` SET `en_us` = ? WHERE `key` = ?", item.EnUs, item.Key)
if err != nil {
scritp_fail(c, "更新语言表失败: "+err.Error())
return
}
_, err = db.Exec("insert into language_op (`LanguageId`, `Field`, `OldValue`, `NewValue`, `Type`, `Update`, `Role`) values (?, ?, ?, ?, ?,?,?)", item.Id, "en_us", item.OldValue, item.EnUs, "Edit", util.Now(), "scripts")
}
for _, v := range dialogueMap {
result, err := db.Exec("INSERT INTO `language` (`key`, `en_us`) VALUES (?, ?)", v.Key, v.Dialogue)
if err != nil {
scritp_fail(c, "插入语言表失败: "+err.Error())
return
}
id, _ := result.LastInsertId()
_, err = db.Exec("insert into language_op (`LanguageId`, `Field`, `OldValue`, `NewValue`, `Type`, `Update`, `Role`) values (?, ?, ?, ?, ?,?,?)", id, "All", "", v.Dialogue, "Add", util.Now(), "scripts")
}
// 将结果放到 gin 上下文,供后续使用
c.Set("DialogueMap", dialogueMap)
tips := []string{}
if len(updateData) > 0 {
tips = append(tips, fmt.Sprintf("更新了 %d 条翻译内容", len(updateData)))
for _, v := range updateData {
tips = append(tips, fmt.Sprintf("Key: %s", v.Key))
}
}
if len(dialogueMap) > 0 {
tips = append(tips, fmt.Sprintf("新增了 %d 条翻译内容", len(dialogueMap)))
for _, v := range dialogueMap {
tips = append(tips, fmt.Sprintf("Key: %s", v.Key))
}
}
languageMod := &model.LanguageMod{}
go languageMod.LanguageListAll()
// 执行脚本的逻辑
success(c, map[string]interface{}{
"step": -1,
"label": "脚本执行成功",
"tips": tips,
"code": 0,
})
}
func scritp_fail(c *gin.Context, err string) {
success(c, map[string]interface{}{
"step": -1,
"label": "",
"tips": []string{
err,
},
"code": 1,
})
}
func CopyOnline(c *gin.Context) {
request := struct {
Step int `json:"step"`
}{}
if err := c.BindJSON(&request); err != nil {
failed(c, "参数绑定失败: "+err.Error())
return
}
switch request.Step {
case 0:
success(c, map[string]interface{}{
"step": 1,
"label": "复制数据库",
"tips": []string{},
"code": 0,
})
case 1:
CopyOnlineStep1(c)
case 2:
CopyOnlineStep2(c)
case 3:
CopyOnlineStep3(c)
case 4:
CopyOnlineStep4(c)
default:
failed(c, "无效的步骤")
}
util.AddAdminLog(c, "文案自动化脚本", request)
}
func CopyOnlineStep2(c *gin.Context) {
// 关闭QA环境服务
time.Sleep(time.Second)
servers := util.GetAllServersByAppId(2) // AppId=2 QA环境
for _, server := range servers {
if server.Status != 1 {
continue
}
s := &model.Server{AppId: 2, ServerId: server.ServerId}
output, err := s.StopServer()
if err != nil {
// 如果错误信息包含"未启动",则忽略该错误
if !strings.Contains(output, "未启动") {
scritp_fail(c, "停止QA环境服务失败: "+err.Error())
return
}
}
}
success(c, map[string]interface{}{
"step": 3,
"label": "写入数据到QA环境",
"tips": []string{},
"code": 0,
})
}
func CopyOnlineStep1(c *gin.Context) {
// mysqldump 复制数据库
// nodeInfo := util.GetNodeByName("devops")
// SshClient, err := util.NewSshClient(nodeInfo)
// if err != nil {
// scritp_fail(c, "连接devops节点失败: "+err.Error())
// return
// }
// defer SshClient.Close()
// cmd := "ansible-playbook /data/devops/playbook/script_copy_us_step_1.yml -i /data/devops/playbook/hosts"
// output, err := SshClient.RunCommand(cmd)
// if err != nil {
// scritp_fail(c, "执行复制数据库脚本step1失败: "+err.Error()+": "+output)
// return
// }
time.Sleep(time.Second)
success(c, map[string]interface{}{
"step": 2,
"label": "关闭QA环境服务",
"tips": []string{},
"code": 0,
})
}
func CopyOnlineStep3(c *gin.Context) {
// 写入数据到QA环境
nodeInfo := util.GetNodeByName("devops")
SshClient, err := util.NewSshClient(nodeInfo)
if err != nil {
scritp_fail(c, "连接devops节点失败: "+err.Error())
return
}
defer SshClient.Close()
cmd := "ansible-playbook /data/devops/playbook/script_copy_us_step_2.yml -i /data/devops/playbook/hosts"
output, err := SshClient.RunCommand(cmd)
if err != nil {
scritp_fail(c, "执行复制数据库脚本step1失败: "+err.Error()+": "+output)
return
}
time.Sleep(time.Second)
success(c, map[string]interface{}{
"step": 4,
"label": "启动QA环境服务",
"tips": []string{},
"code": 0,
})
}
func CopyOnlineStep4(c *gin.Context) {
// 启动QA环境服务
servers := util.GetAllServersByAppId(2) // AppId=2 QA环境
for _, server := range servers {
if server.Status == 1 {
continue
}
s := &model.Server{AppId: 2, ServerId: server.ServerId}
_, err := s.StartServer()
if err != nil {
scritp_fail(c, "启动QA环境服务失败: "+err.Error())
return
}
}
str := `
# US环境同步自动化脚本完成
<a>所有人</a>
`
alibaba.SendStandardMsg("US环境同步自动化脚本完成", str, "green")
time.Sleep(time.Second)
success(c, map[string]interface{}{
"step": -1,
"label": "脚本执行成功",
"tips": []string{},
"code": 0,
})
}