diff --git a/Type/t.go b/Type/t.go
index e71021f..e44946d 100644
--- a/Type/t.go
+++ b/Type/t.go
@@ -100,6 +100,7 @@ type ServerInfo struct {
ClientVersion string `json:"ClientVersion" db:"version"`
NodeTags string `json:"-" db:"node_tags"`
Tags []string `json:"Tags" db:"-"`
+ ECS int `json:"ECS" db:"ecs"`
}
type Server struct {
@@ -162,12 +163,13 @@ type NotifyClientData struct {
}
type OrderData struct {
- UID int `db:"Date"`
- OrderId string `db:"OrderNum"`
- Product string `db:"Product"`
- ProductName string `db:"ProductName"`
- EventRecovery string `db:"EventRecovery"`
- EventAge string `db:"EventAge"`
+ UID int `json:"UID"`
+ OrderId string `json:"OrderId"`
+ Product string `json:"Product"`
+ ProductName string `json:"ProductName"`
+ EventRecovery string `json:"EventRecovery"`
+ EventAge string `json:"EventAge"`
+ TotalCharge string `json:"TotalCharge"`
}
type AlibabaUpdateCardParam struct {
diff --git a/alibaba/card.go b/alibaba/card.go
index 58dccfb..91a438f 100644
--- a/alibaba/card.go
+++ b/alibaba/card.go
@@ -141,7 +141,6 @@ func SendCard() (_err error) {
_e = r
}
}()
- fmt.Println("createAndDeliverRequest", createAndDeliverRequest)
_, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
if _err != nil {
return _err
@@ -248,7 +247,6 @@ func SendZabbixMsg(data *Type.NotifyData) (_err error) {
_e = r
}
}()
- fmt.Println("createAndDeliverRequest", createAndDeliverRequest)
_, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
if _err != nil {
return _err
@@ -344,7 +342,6 @@ func SendZabbixRecoveryMsg(data *Type.NotifyRecoveryData) (_err error) {
_e = r
}
}()
- fmt.Println("createAndDeliverRequest", createAndDeliverRequest)
_, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
if _err != nil {
return _err
@@ -439,7 +436,6 @@ func SendStandardMsg(title, content, color string) (_err error) {
_e = r
}
}()
- fmt.Println("createAndDeliverRequest", createAndDeliverRequest)
_, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
if _err != nil {
return _err
@@ -534,7 +530,6 @@ func SendAliveMsg(title, content, color string) (_err error) {
_e = r
}
}()
- fmt.Println("createAndDeliverRequest", createAndDeliverRequest)
_, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
if _err != nil {
return _err
@@ -556,3 +551,85 @@ func SendAliveMsg(title, content, color string) (_err error) {
}
return _err
}
+
+// cid64GX+2M7KehttynmDM8msQ==
+func SendOrderMsg(data *Type.OrderData) (_err error) {
+ client, _err := createCardClient()
+ if _err != nil {
+ return _err
+ }
+
+ accessToken, _ := GetToken()
+ robotCode := "dingrmgtodzxaik76jpc"
+ userId := ""
+ openConversationId := "cid64GX+2M7KehttynmDM8msQ=="
+ templateId := "843a23ff-29d2-4efc-b7f4-2dea2766d7db.schema"
+ lastMessage := "[充值]充值发货通知"
+ searchIcon := ""
+ searchDesc := ""
+
+ createAndDeliverHeaders := &dingtalkcard_1_0.CreateAndDeliverHeaders{}
+ createAndDeliverHeaders.XAcsDingtalkAccessToken = tea.String(accessToken)
+
+ imGroupOpenDeliverModel := &dingtalkcard_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
+ RobotCode: tea.String(robotCode),
+ // 卡片接收人
+ Recipients: []*string{},
+ AtUserIds: map[string]*string{},
+ }
+ imGroupOpenSpaceModelLastMessageI18n := map[string]*string{
+ "ZH_CN": tea.String(lastMessage),
+ }
+ imGroupOpenSpaceModelSearchSupport := &dingtalkcard_1_0.CreateAndDeliverRequestImGroupOpenSpaceModelSearchSupport{
+ SearchIcon: tea.String(searchIcon),
+ SearchDesc: tea.String(searchDesc),
+ }
+ imGroupOpenSpaceModel := &dingtalkcard_1_0.CreateAndDeliverRequestImGroupOpenSpaceModel{
+ SupportForward: tea.Bool(true),
+ LastMessageI18n: imGroupOpenSpaceModelLastMessageI18n,
+ SearchSupport: imGroupOpenSpaceModelSearchSupport,
+ }
+ contentStr := `
+# **充值发货通知**
+- UID:**%d**
+- 订单号:**%s**
+- 金额:**%s** 元
+- 商品描述:**%s**
+- 支付时间:**%s**
+- 发货时间:**%s**
+- 总充值金额:**%s** 元
+
+[微笑]如有任何问题,请联系在线客服处理。
+`
+ content := fmt.Sprintf(contentStr, data.UID, data.OrderId, data.Product, data.ProductName, data.EventRecovery, data.EventAge, data.TotalCharge)
+
+ // 此处使用了 MockData 作为测试数据,请结合真实场景设置卡片公有数据
+ cardDataCardParamMap := map[string]any{
+ "title": "[充值]充值发货通知",
+ "markdown": content,
+ "color": "green",
+ "config": map[string]any{
+ "autoLayout": true,
+ },
+ }
+ cardDataError := error(nil)
+ _ = cardDataError
+ cardData := &dingtalkcard_1_0.CreateAndDeliverRequestCardData{
+ CardParamMap: convertJSONValuesToString(cardDataCardParamMap),
+ }
+ createAndDeliverRequest := &dingtalkcard_1_0.CreateAndDeliverRequest{
+ UserId: tea.String(userId),
+ CardTemplateId: tea.String(templateId),
+ // 用于标识卡片的唯一 ID,业务需自行建立关联关系,用于后续的卡片更新
+ OutTrackId: tea.String(fmt.Sprintf("standard-out-track-id-%d", time.Now().Unix())),
+ CallbackType: tea.String("STREAM"),
+ CardData: cardData,
+ ImGroupOpenSpaceModel: imGroupOpenSpaceModel,
+ ImGroupOpenDeliverModel: imGroupOpenDeliverModel,
+ OpenSpaceId: tea.String(fmt.Sprintf("dtv1.card//im_group.%s", openConversationId)),
+ UserIdType: tea.Int32(1),
+ // CardAtUserIds: []*string{tea.String("all")},
+ }
+ _, _err = client.CreateAndDeliverWithOptions(createAndDeliverRequest, createAndDeliverHeaders, &util.RuntimeOptions{})
+ return _err
+}
diff --git a/conf/server.yml b/conf/server.yml
index dd321a8..426fe28 100644
--- a/conf/server.yml
+++ b/conf/server.yml
@@ -37,11 +37,11 @@ mysqls:
password: 'GWFj1cHaqjpzvcsHBWTFtLWtm8MUZKROx_wvbV6jPg=='
database: 'merge_pet_london_%d'
idleTimeout: Infinity
- - host: '47.254.83.25'
+ - host: 'rm-rj9my01442p7kpe36.mysql.rds-aliyun-america.rds.aliyuncs.com'
name: 'merge_pet_online'
port: 3306
user: 'root'
- password: 'pUf9tft9GOPjV1z855Jf2DpB5NUpGEc_'
+ password: 'ioy63iEqUA6EYmeg1GpWPh2mE8HnnBp-sVWlNR6N'
database: 'merge_pet_%d'
idleTimeout: Infinity
- host: 'rm-f8zd2030feam53n43io.mysql.rds.aliyuncs.com'
@@ -54,10 +54,10 @@ mysqls:
servers:
- name: 'server1'
- host: '1.15.182.107'
+ host: '112.124.54.243'
port: 22
username: 'root'
- password: 'r_vcLRGHPm1bEZDKU1L5TTr_-u_expNKgsCBuXNHmA=='
+ password: 'H3ukUvaLVLvWRXn9zGeAM9fspkGy6VUpMn7bEtWaTg=='
- name: 'server2'
host: '47.254.83.25'
port: 22
diff --git a/conf/translater.yml b/conf/translater.yml
index b31fb33..ae43ed1 100644
--- a/conf/translater.yml
+++ b/conf/translater.yml
@@ -8,4 +8,11 @@ user:
colunm: "key,en_US,pt_BR"
- account: "Catarina Pereira" # 账号名
keys: "MergeData, cardName, DialogData, ChapterTip, chapter_title" # 需要的键值列表,逗号分隔
- colunm: "key,en_US,pt_BR" # 需要翻译的列名
\ No newline at end of file
+ colunm: "key,en_US,pt_BR" # 需要翻译的列名
+ - account: "Príamo Jiménez" # 账号名
+ keys: "DialogData" # 需要的键值列表,逗号分隔
+ keysType: "no_include" # keysType 不包含
+ colunm: "key,en_US,es_LATAM" # 需要翻译的列名
+ - account: "Gabriela Mantellini" # 账号名
+ keys: "DialogData" # 需要的键值列表,逗号分隔
+ colunm: "key,en_US,es_LATAM" # 需要翻译的列名
\ No newline at end of file
diff --git a/controller/alibaba.go b/controller/alibaba.go
index 8a8f64f..ca789cd 100644
--- a/controller/alibaba.go
+++ b/controller/alibaba.go
@@ -4,6 +4,7 @@ import (
"backend/Type"
"backend/alibaba"
"backend/util"
+ "fmt"
"log"
"github.com/gin-gonic/gin"
@@ -47,3 +48,17 @@ func AlibabaRecovery(c *gin.Context) {
log.Printf("failed to send recovery message: %v", err)
}
}
+
+func AlibabaNotifyOrder(c *gin.Context) {
+ r := Type.OrderData{}
+ if err := c.ShouldBindJSON(&r); err != nil {
+ c.JSON(400, gin.H{"error": err.Error()})
+ return
+ }
+
+ err := alibaba.SendOrderMsg(&r)
+ if err != nil {
+ fmt.Printf("failed to send notify message: %v", err)
+ }
+ c.JSON(200, gin.H{"success": err.Error()})
+}
diff --git a/controller/operation.go b/controller/operation.go
index 83a5f0b..f624c0b 100644
--- a/controller/operation.go
+++ b/controller/operation.go
@@ -63,17 +63,20 @@ func CopyUserOperation(srcAppID, dstAppID, srcUid, dstUid int) error {
}
var auto_id int64
_ = DstDb.Get(&auto_id, "SELECT auto_id FROM t_account WHERE user_name = ?", srcData.DwUin)
- _, err = model.UserGM(dstAppID, 1, dstUid, "logout")
- time.Sleep(time.Second * 2)
- if err != nil {
- return err
- }
if auto_id == 0 {
result, err := DstDb.Exec("INSERT INTO t_account (user_name, user_password) VALUES (?, ?) ON DUPLICATE KEY UPDATE user_password = VALUES(user_password)", srcData.DwUin, "123456")
if err != nil {
return err
}
auto_id, err = result.LastInsertId()
+ } else {
+ newUid := int(auto_id) + 100000000*dstAppID + 100000
+ var node int
+ _ = DstDb.Get(&node, "SELECT node FROM t_player_baseinfo WHERE dwUin = ?", newUid)
+ if node != 0 {
+ _, err = model.UserGM(dstAppID, node, newUid, "logout")
+ time.Sleep(time.Second * 2)
+ }
}
newUid := int(auto_id) + 100000000*dstAppID + 100000
_, err = DstDb.Exec("INSERT INTO t_player_baseinfo (dwUin, user_name, start_order_id) VALUES (?, ?, 1) ON DUPLICATE KEY UPDATE user_name = VALUES(user_name)", newUid, srcData.DwUin)
diff --git a/controller/scripts.go b/controller/scripts.go
index b66e202..2b1b248 100644
--- a/controller/scripts.go
+++ b/controller/scripts.go
@@ -2,9 +2,11 @@ package controller
import (
"backend/alibaba"
+ "backend/model"
"backend/util"
"fmt"
"os/exec"
+ "strings"
"time"
"github.com/gin-gonic/gin"
@@ -226,3 +228,137 @@ func scritp_fail(c *gin.Context, err string) {
"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": "关闭QA环境服务",
+ "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 CopyOnlineStep1(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": 2,
+ "label": "复制数据库",
+ "tips": []string{},
+ "code": 0,
+ })
+}
+
+func CopyOnlineStep2(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": 3,
+ "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环境同步自动化脚本完成
+所有人
+ `
+ alibaba.SendStandardMsg("US环境同步自动化脚本完成", str, "green")
+ time.Sleep(time.Second)
+ success(c, map[string]interface{}{
+ "step": -1,
+ "label": "脚本执行成功",
+ "tips": []string{},
+ "code": 0,
+ })
+}
diff --git a/controller/user.go b/controller/user.go
index c50d28c..4e5e092 100644
--- a/controller/user.go
+++ b/controller/user.go
@@ -63,8 +63,9 @@ func UserList(c *gin.Context) {
func UserDetail(c *gin.Context) {
var request struct {
- Uid int `json:"Id"`
- Node int `json:"Node"`
+ Uid int `json:"Id"`
+ Node int `json:"Node"`
+ AppId int `json:"AppId"`
}
err := c.BindJSON(&request)
if err != nil {
@@ -72,7 +73,7 @@ func UserDetail(c *gin.Context) {
failed(c, err.Error())
return
}
- user, err := model.UserDetail(request.Uid, request.Node)
+ user, err := model.UserDetail(request.AppId, request.Uid, request.Node)
log := model.Log{
Uid: request.Uid,
}
diff --git a/go.mod b/go.mod
index ade0fb4..6f672ca 100644
--- a/go.mod
+++ b/go.mod
@@ -14,18 +14,20 @@ require (
github.com/alibabacloud-go/tea-console v1.0.0
github.com/alibabacloud-go/tea-utils/v2 v2.0.7
github.com/aliyun/credentials-go v1.4.6
+ github.com/elastic/go-elasticsearch/v8 v8.19.1
github.com/gin-gonic/gin v1.10.0
github.com/go-sql-driver/mysql v1.8.1
github.com/google/uuid v1.6.0
+ github.com/gorilla/websocket v1.5.3
github.com/jmoiron/sqlx v1.4.0
github.com/larksuite/oapi-sdk-go/v3 v3.4.9
github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
+ github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1
github.com/oschwald/geoip2-golang v1.13.0
github.com/robfig/cron/v3 v3.0.1
github.com/xuri/excelize/v2 v2.10.0
go.etcd.io/bbolt v1.4.3
golang.org/x/crypto v0.43.0
- golang.org/x/net v0.46.0
google.golang.org/protobuf v1.34.1
gopkg.in/yaml.v2 v2.4.0
)
@@ -33,7 +35,6 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
- github.com/alibabacloud-go/darabonba-openapi v0.2.1 // indirect
github.com/alibabacloud-go/debug v1.0.1 // indirect
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
github.com/alibabacloud-go/gateway-dingtalk v1.0.2 // indirect
@@ -49,14 +50,16 @@ require (
github.com/clbanning/mxj/v2 v2.7.0 // indirect
github.com/cloudwego/base64x v0.1.4 // indirect
github.com/cloudwego/iasm v0.2.0 // indirect
+ github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
+ github.com/go-logr/logr v1.4.2 // indirect
+ github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.20.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/gorilla/websocket v1.5.0 // indirect
github.com/jonboulle/clockwork v0.5.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
@@ -65,7 +68,6 @@ require (
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
- github.com/open-dingtalk/dingtalk-stream-sdk-go v0.9.1 // indirect
github.com/oschwald/maxminddb-golang v1.13.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
@@ -77,7 +79,11 @@ require (
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xuri/efp v0.0.1 // indirect
github.com/xuri/nfp v0.0.2-0.20250530014748-2ddeb826f9a9 // indirect
+ go.opentelemetry.io/otel v1.28.0 // indirect
+ go.opentelemetry.io/otel/metric v1.28.0 // indirect
+ go.opentelemetry.io/otel/trace v1.28.0 // indirect
golang.org/x/arch v0.8.0 // indirect
+ golang.org/x/net v0.46.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1 // indirect
diff --git a/go.sum b/go.sum
index 881264c..402942f 100644
--- a/go.sum
+++ b/go.sum
@@ -17,8 +17,6 @@ github.com/alibabacloud-go/darabonba-encode-util v0.0.2 h1:1uJGrbsGEVqWcWxrS9MyC
github.com/alibabacloud-go/darabonba-encode-util v0.0.2/go.mod h1:JiW9higWHYXm7F4PKuMgEUETNZasrDM6vqVr/Can7H8=
github.com/alibabacloud-go/darabonba-map v0.0.2 h1:qvPnGB4+dJbJIxOOfawxzF3hzMnIpjmafa0qOTp6udc=
github.com/alibabacloud-go/darabonba-map v0.0.2/go.mod h1:28AJaX8FOE/ym8OUFWga+MtEzBunJwQGceGQlvaPGPc=
-github.com/alibabacloud-go/darabonba-openapi v0.2.1 h1:WyzxxKvhdVDlwpAMOHgAiCJ+NXa6g5ZWPFEzaK/ewwY=
-github.com/alibabacloud-go/darabonba-openapi v0.2.1/go.mod h1:zXOqLbpIqq543oioL9IuuZYOQgHQ5B8/n5OPrnko8aY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.0/go.mod h1:5JHVmnHvGzR2wNdgaW1zDLQG8kOC4Uec8ubkMogW7OQ=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.11/go.mod h1:wHxkgZT1ClZdcwEVP/pDgYK/9HucsnCfMipmJgCz4xY=
github.com/alibabacloud-go/darabonba-openapi/v2 v2.0.12/go.mod h1:cgtLEj8i4ddXMcQgq4PnpVQvlzS+y5B+QtdSfmcLM3A=
@@ -26,7 +24,6 @@ github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.9 h1:7P0KWfed/YMtpeuW3E2iwo
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.9/go.mod h1:kgnXaV74AVjM3ZWJu1GhyXGuCtxljJ677oUfz6MyJOE=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7 h1:UzCnKvsjPFzApvODDNEYqBHMFt1w98wC7FOo0InLyxg=
github.com/alibabacloud-go/darabonba-signature-util v0.0.7/go.mod h1:oUzCYV2fcCH797xKdL6BDH8ADIHlzrtKVjeRtunBNTQ=
-github.com/alibabacloud-go/darabonba-string v1.0.0/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
github.com/alibabacloud-go/darabonba-string v1.0.2 h1:E714wms5ibdzCqGeYJ9JCFywE5nDyvIXIIQbZVFkkqo=
github.com/alibabacloud-go/darabonba-string v1.0.2/go.mod h1:93cTfV3vuPhhEwGGpKKqhVW4jLe7tDpo3LUM0i0g6mA=
github.com/alibabacloud-go/debug v0.0.0-20190504072949-9472017b5c68/go.mod h1:6pb/Qy8c+lqua8cFpEy7g39NRRqOWc3rOwAy8m5Y2BY=
@@ -68,7 +65,6 @@ github.com/alibabacloud-go/tea-oss-sdk v1.1.5/go.mod h1:5fhlKMa/kWRJNgPYRt+5qSg3
github.com/alibabacloud-go/tea-oss-utils v1.1.0 h1:y65crjjcZ2Pbb6UZtC2deuIZHDVTS3IaDWE7M9nVLRc=
github.com/alibabacloud-go/tea-oss-utils v1.1.0/go.mod h1:PFCF12e9yEKyBUIn7X1IrF/pNjvxgkHy0CgxX4+xRuY=
github.com/alibabacloud-go/tea-utils v1.3.1/go.mod h1:EI/o33aBfj3hETm4RLiAxF/ThQdSngxrpF8rKUDJjPE=
-github.com/alibabacloud-go/tea-utils v1.4.3/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
github.com/alibabacloud-go/tea-utils v1.4.5 h1:h0/6Xd2f3bPE4XHTvkpjwxowIwRCJAJOqY6Eq8f3zfA=
github.com/alibabacloud-go/tea-utils v1.4.5/go.mod h1:KNcT0oXlZZxOXINnZBs6YvgOd5aYp9U67G+E3R8fcQw=
github.com/alibabacloud-go/tea-utils/v2 v2.0.0/go.mod h1:U5MTY10WwlquGPS34DOeomUGBB0gXbLueiq5Trwu0C4=
@@ -103,6 +99,10 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo=
+github.com/elastic/elastic-transport-go/v8 v8.8.0/go.mod h1:YLHer5cj0csTzNFXoNQ8qhtGY1GTvSqPnKWKaqQE3Hk=
+github.com/elastic/go-elasticsearch/v8 v8.19.1 h1:0iEGt5/Ds9MNVxEp3hqLsXdbe6SjleaVHONg/FuR09Q=
+github.com/elastic/go-elasticsearch/v8 v8.19.1/go.mod h1:tHJQdInFa6abmDbDCEH2LJja07l/SIpaGpJcm13nt7s=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
@@ -112,6 +112,11 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU=
github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y=
+github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
+github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
+github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -148,8 +153,9 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o=
github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY=
github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
@@ -251,6 +257,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
+go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo=
+go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4=
+go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q=
+go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s=
+go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8=
+go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E=
+go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g=
+go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc=
golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
diff --git a/log/app.log b/log/app.log
deleted file mode 100644
index fc15b36..0000000
--- a/log/app.log
+++ /dev/null
@@ -1,173 +0,0 @@
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 10:25:13 | 401 | 0s | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 10:25:13 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 10:25:29 | 200 | 253.1365ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 10:25:29 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 10:25:29 | 200 | 397.7438ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 10:25:31 | 200 | 309.585ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 10:25:31 | 200 | 1.1419178s | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 10:27:09 | 200 | 347.354ms | ::1 | POST "/api/server/list"
-[GIN] 2025/12/11 - 10:27:09 | 200 | 661.8766ms | ::1 | POST "/api/log/order"
-[GIN] 2025/12/11 - 10:27:12 | 200 | 115.9295ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 10:27:13 | 200 | 711.928ms | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 10:30:23 | 200 | 444.7127ms | ::1 | POST "/api/server/list"
-[GIN] 2025/12/11 - 10:30:27 | 200 | 2.2220912s | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 10:30:29 | 200 | 5.3690768s | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 10:31:03 | 200 | 886.982ms | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 10:31:09 | 200 | 2.3555516s | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 11:33:28 | 200 | 395.5301ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:33:54 | 200 | 214.9095ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:34:30 | 200 | 305.7429ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:34:57 | 200 | 173.8177ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:35:17 | 200 | 217.7425ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:35:19 | 200 | 187.9784ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 11:35:20 | 200 | 921.4157ms | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 11:37:18 | 200 | 245.3772ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:37:45 | 200 | 517.2912ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:38:04 | 200 | 231.2394ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:38:20 | 200 | 280.0851ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:40:21 | 200 | 371.4347ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:40:23 | 200 | 518.4176ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 11:40:24 | 200 | 1.1721816s | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 11:41:08 | 200 | 132.7881ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:41:41 | 200 | 324.3031ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:43:29 | 200 | 376.0195ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:43:37 | 200 | 182.7374ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:43:48 | 200 | 203.6292ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:44:38 | 200 | 291.4693ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:44:57 | 200 | 234.8371ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:44:58 | 200 | 217.734ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 11:44:59 | 200 | 873.1764ms | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 11:45:45 | 200 | 105.532ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 11:45:47 | 200 | 890.5534ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 11:45:48 | 200 | 1.8967679s | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 11:46:17 | 200 | 253.1924ms | ::1 | POST "/api/server/list"
-[GIN] 2025/12/11 - 11:46:17 | 200 | 347.3486ms | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 11:46:57 | 200 | 498.5131ms | ::1 | POST "/api/server/list"
-[GIN] 2025/12/11 - 11:46:57 | 200 | 253.5674ms | ::1 | POST "/api/server/serverList"
-[GIN] 2025/12/11 - 11:57:22 | 200 | 296.8985ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:00:58 | 200 | 474.8772ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:01:17 | 200 | 209.8177ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:01:43 | 200 | 1.2960524s | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:04:05 | 200 | 1.2864048s | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:04:06 | 200 | 366.8252ms | ::1 | POST "/api/statistics/heat"
-[GIN] 2025/12/11 - 12:04:07 | 200 | 1.2401522s | ::1 | POST "/api/statistics/info"
-[GIN] 2025/12/11 - 12:30:05 | 200 | 636.1973ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:30:29 | 200 | 232.0374ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 12:30:39 | 200 | 315.6206ms | ::1 | GET "/api/user/info"
-2025/12/11 13:04:59 start statistics
-2025/12/11 13:05:01 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:01 remain 2025-12-11 success
-2025/12/11 13:05:03 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:03 remain 2025-12-10 success
-2025/12/11 13:05:05 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:05 remain 2025-12-09 success
-2025/12/11 13:05:06 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:06 remain 2025-12-08 success
-2025/12/11 13:05:08 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:08 remain 2025-12-07 success
-2025/12/11 13:05:10 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:10 remain 2025-12-06 success
-2025/12/11 13:05:11 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:11 remain 2025-12-05 success
-2025/12/11 13:05:13 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:13 remain 2025-12-04 success
-2025/12/11 13:05:14 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:14 remain 2025-12-03 success
-2025/12/11 13:05:17 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:17 remain 2025-12-02 success
-2025/12/11 13:05:21 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:21 remain 2025-12-01 success
-2025/12/11 13:05:24 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:24 remain 2025-11-30 success
-2025/12/11 13:05:26 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:26 remain 2025-11-29 success
-2025/12/11 13:05:29 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:29 remain 2025-11-28 success
-2025/12/11 13:05:31 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:31 remain 2025-11-27 success
-2025/12/11 13:05:33 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:33 remain 2025-11-26 success
-2025/12/11 13:05:35 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:35 remain 2025-11-25 success
-2025/12/11 13:05:37 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:37 remain 2025-11-24 success
-2025/12/11 13:05:40 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:40 remain 2025-11-23 success
-2025/12/11 13:05:42 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:42 remain 2025-11-22 success
-2025/12/11 13:05:44 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:44 remain 2025-11-21 success
-2025/12/11 13:05:46 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:46 remain 2025-11-20 success
-2025/12/11 13:05:49 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:49 remain 2025-11-19 success
-2025/12/11 13:05:51 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:51 remain 2025-11-18 success
-2025/12/11 13:05:53 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:53 remain 2025-11-17 success
-2025/12/11 13:05:55 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:55 remain 2025-11-16 success
-2025/12/11 13:05:57 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:05:57 remain 2025-11-15 success
-2025/12/11 13:06:00 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:06:00 remain 2025-11-14 success
-2025/12/11 13:06:02 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:06:02 remain 2025-11-13 success
-2025/12/11 13:06:04 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:06:04 remain 2025-11-12 success
-2025/12/11 13:06:06 failed to insert data: Error 1203 (42000): User root already has more than 'max_user_connections' active connections
-2025/12/11 13:06:06 remain 2025-11-11 success
-2025/12/11 13:06:06 end statistics
diff --git a/log/backend.2025-12-11.log b/log/backend.2025-12-11.log
deleted file mode 100644
index 812184e..0000000
--- a/log/backend.2025-12-11.log
+++ /dev/null
@@ -1,591 +0,0 @@
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 14:54:03 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 14:54:03 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 14:54:09 | 200 | 259.3216ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 14:54:10 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 14:54:10 | 200 | 227.808ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 14:54:14 | 400 | 1.4234398s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 14:55:10 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 14:55:10 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 14:55:16 | 200 | 288.3883ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 14:55:16 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 14:55:17 | 200 | 310.8601ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 14:55:20 | 400 | 1.5287218s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:00:25 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:00:25 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:00:40 | 200 | 301.712ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:00:40 | 200 | 1.0159ms | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:00:40 | 200 | 287.9144ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:00:45 | 400 | 1.2076622s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:01:18 | 401 | 511.3µs | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:01:18 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:01:25 | 200 | 274.7293ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:01:25 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:01:26 | 200 | 1.4285956s | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:04:28 | 400 | 1m13s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:05:15 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:05:15 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:05:25 | 200 | 226.7111ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:05:25 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:05:25 | 200 | 311.7222ms | ::1 | GET "/api/user/info"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:08:17 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:08:17 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:08:24 | 200 | 277.7203ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:08:24 | 200 | 533.8µs | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:08:25 | 200 | 248.5945ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:08:36 | 200 | 8.6406657s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:09:48 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:09:48 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:09:56 | 200 | 171.9066ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:09:56 | 200 | 0s | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:09:56 | 200 | 221.5967ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:26:38 | 400 | 16m40s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:26:38 | 400 | 16m28s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:28:21 | 400 | 432.899ms | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:30:41 | 400 | 3.1169586s | ::1 | POST "/api/operation/copyUser"
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
-
-[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- - using env: export GIN_MODE=release
- - using code: gin.SetMode(gin.ReleaseMode)
-
-[GIN-debug] POST /api/auth/login --> backend/controller.Login (3 handlers)
-[GIN-debug] GET /api/auth/Codes --> backend/controller.Codes (3 handlers)
-[GIN-debug] POST /api/auth/phoneCode --> backend/controller.PhoneCode (3 handlers)
-[GIN-debug] POST /api/auth/phoneLogin --> backend/controller.LoginCode (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo --> backend/controller.FeishuSendInfo (3 handlers)
-[GIN-debug] POST /api/feishu/sendInfo2 --> backend/controller.FeishuSendInfo2 (3 handlers)
-[GIN-debug] POST /api/feishu/sendWeekInfo --> backend/controller.FeishuSendWeekInfo (3 handlers)
-[GIN-debug] POST /api/feishu/updateApp --> backend/controller.FeishuUpdateApp (3 handlers)
-[GIN-debug] POST /api/feishu/serverInfo --> backend/controller.FeishuServerInfo (3 handlers)
-[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
-[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
-[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
-[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
-[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
-[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
-[GIN-debug] POST /api/log/user --> backend/controller.UserDetail (4 handlers)
-[GIN-debug] POST /api/log/asset --> backend/controller.Asset (4 handlers)
-[GIN-debug] POST /api/log/event --> backend/controller.Event (4 handlers)
-[GIN-debug] POST /api/log/order --> backend/controller.Order (4 handlers)
-[GIN-debug] POST /api/user/list --> backend/controller.UserList (4 handlers)
-[GIN-debug] GET /api/user/info --> backend/controller.UserInfo (4 handlers)
-[GIN-debug] POST /api/user/gm --> backend/controller.UserGM (4 handlers)
-[GIN-debug] POST /api/user/ban --> backend/controller.UserBan (4 handlers)
-[GIN-debug] POST /api/server/list --> backend/controller.AppList (4 handlers)
-[GIN-debug] POST /api/server/serverList --> backend/controller.ServerList (4 handlers)
-[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
-[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
-[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
-[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
-[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
-[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
-[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
-[GIN-debug] POST /api/statistics/level --> backend/controller.StatisticsLevel (4 handlers)
-[GIN-debug] POST /api/statistics/order --> backend/controller.StatisticsOrder (4 handlers)
-[GIN-debug] POST /api/statistics/info --> backend/controller.StatisticsInfo (4 handlers)
-[GIN-debug] POST /api/statistics/heat --> backend/controller.StatisticsHeat (4 handlers)
-[GIN-debug] POST /api/mail/send --> backend/controller.SendMail (4 handlers)
-[GIN-debug] POST /api/mail/list --> backend/controller.MailList (4 handlers)
-[GIN-debug] POST /api/mail/delete --> backend/controller.MailDelete (4 handlers)
-[GIN-debug] POST /api/operation/copyUser --> backend/controller.CopyUser (4 handlers)
-[GIN-debug] POST /api/language/list --> backend/controller.Language (4 handlers)
-[GIN-debug] POST /api/language/export --> backend/controller.LanguageExport (4 handlers)
-[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
-[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
-[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
-[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
-Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
-[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:51:59 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:51:59 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:52:06 | 200 | 272.8968ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:52:06 | 200 | 2.1002ms | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:52:07 | 200 | 248.6532ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:52:16 | 200 | 6.062524s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:52:43 | 200 | 11.5860106s | ::1 | POST "/api/operation/copyUser"
diff --git a/log/backend.2025-12-12.log b/log/backend.2025-12-12.log
deleted file mode 100644
index 2a2e61c..0000000
--- a/log/backend.2025-12-12.log
+++ /dev/null
@@ -1,33 +0,0 @@
-2025/12/12 08:04:59 start statistics
-2025/12/12 08:05:01 remain 2025-12-12 success
-2025/12/12 08:05:01 remain 2025-12-11 success
-2025/12/12 08:05:03 remain 2025-12-10 success
-2025/12/12 08:05:04 remain 2025-12-09 success
-2025/12/12 08:05:05 remain 2025-12-08 success
-2025/12/12 08:05:06 remain 2025-12-07 success
-2025/12/12 08:05:07 remain 2025-12-06 success
-2025/12/12 08:05:08 remain 2025-12-05 success
-2025/12/12 08:05:09 remain 2025-12-04 success
-2025/12/12 08:05:10 remain 2025-12-03 success
-2025/12/12 08:05:11 remain 2025-12-02 success
-2025/12/12 08:05:12 remain 2025-12-01 success
-2025/12/12 08:05:13 remain 2025-11-30 success
-2025/12/12 08:05:14 remain 2025-11-29 success
-2025/12/12 08:05:15 remain 2025-11-28 success
-2025/12/12 08:05:15 remain 2025-11-27 success
-2025/12/12 08:05:17 remain 2025-11-26 success
-2025/12/12 08:05:18 remain 2025-11-25 success
-2025/12/12 08:05:19 remain 2025-11-24 success
-2025/12/12 08:05:20 remain 2025-11-23 success
-2025/12/12 08:05:21 remain 2025-11-22 success
-2025/12/12 08:05:22 remain 2025-11-21 success
-2025/12/12 08:05:22 remain 2025-11-20 success
-2025/12/12 08:05:23 remain 2025-11-19 success
-2025/12/12 08:05:25 remain 2025-11-18 success
-2025/12/12 08:05:26 remain 2025-11-17 success
-2025/12/12 08:05:26 remain 2025-11-16 success
-2025/12/12 08:05:27 remain 2025-11-15 success
-2025/12/12 08:05:28 remain 2025-11-14 success
-2025/12/12 08:05:29 remain 2025-11-13 success
-2025/12/12 08:05:30 remain 2025-11-12 success
-2025/12/12 08:05:30 end statistics
diff --git a/log/backend.log b/log/backend.log
index f59cc3d..1768d3c 100644
--- a/log/backend.log
+++ b/log/backend.log
@@ -16,6 +16,10 @@
[GIN-debug] POST /api/feishu/notify --> backend/controller.FeishuNotify (3 handlers)
[GIN-debug] POST /api/feishu/notify/client --> backend/controller.FeishuNotifyClient (3 handlers)
[GIN-debug] POST /api/feishu/notify/order --> backend/controller.FeishuNotifyOrder (3 handlers)
+[GIN-debug] POST /api/alibaba/zabbix/notify --> backend/controller.AlibabaNotify (3 handlers)
+[GIN-debug] POST /api/alibaba/zabbix/recovery --> backend/controller.AlibabaRecovery (3 handlers)
+[GIN-debug] POST /api/alibaba/game/notify --> backend/controller.AlibabaGameNotify (3 handlers)
+[GIN-debug] POST /api/alibaba/notify/order --> backend/controller.AlibabaNotifyOrder (3 handlers)
[GIN-debug] POST /api/admin/list --> backend/controller.AdminList (4 handlers)
[GIN-debug] POST /api/admin/add --> backend/controller.AdminAdd (4 handlers)
[GIN-debug] POST /api/admin/log/list --> backend/controller.AdminLogList (4 handlers)
@@ -32,7 +36,9 @@
[GIN-debug] POST /api/server/addServer --> backend/controller.AddServer (4 handlers)
[GIN-debug] POST /api/server/nodeList --> backend/controller.NodeList (4 handlers)
[GIN-debug] POST /api/server/addNode --> backend/controller.AddNode (4 handlers)
+[GIN-debug] POST /api/server/editServer --> backend/controller.EditServer (4 handlers)
[GIN-debug] POST /api/server/updateApp --> backend/controller.UpdateApp (4 handlers)
+[GIN-debug] POST /api/server/updateAppReview --> backend/controller.UpdateAppReview (4 handlers)
[GIN-debug] POST /api/server/updateAppFeishu --> backend/controller.UpdateAppFeishu (4 handlers)
[GIN-debug] POST /api/server/restart --> backend/controller.RestartServer (4 handlers)
[GIN-debug] POST /api/server/reload --> backend/controller.ReloadServer (4 handlers)
@@ -49,46 +55,76 @@
[GIN-debug] POST /api/language/save --> backend/controller.LanguageSave (4 handlers)
[GIN-debug] POST /api/language/add --> backend/controller.LanguageAdd (4 handlers)
[GIN-debug] POST /api/language/delete --> backend/controller.LanguageDelete (4 handlers)
+[GIN-debug] POST /api/scripts/copywriting --> backend/controller.Copywriting (4 handlers)
+[GIN-debug] POST /api/scripts/copyonline --> backend/controller.CopyOnline (4 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Listening and serving HTTP on :5320
-[GIN] 2025/12/11 - 15:51:59 | 401 | 0s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:51:59 | 404 | 0s | ::1 | POST "/api/auth/logout"
-[GIN] 2025/12/11 - 15:52:06 | 200 | 272.8968ms | ::1 | POST "/api/auth/login"
-[GIN] 2025/12/11 - 15:52:06 | 200 | 2.1002ms | ::1 | GET "/api/auth/Codes"
-[GIN] 2025/12/11 - 15:52:07 | 200 | 248.6532ms | ::1 | GET "/api/user/info"
-[GIN] 2025/12/11 - 15:52:16 | 200 | 6.062524s | ::1 | POST "/api/operation/copyUser"
-[GIN] 2025/12/11 - 15:52:43 | 200 | 11.5860106s | ::1 | POST "/api/operation/copyUser"
-2025/12/12 08:04:59 start statistics
-2025/12/12 08:05:01 remain 2025-12-12 success
-2025/12/12 08:05:01 remain 2025-12-11 success
-2025/12/12 08:05:03 remain 2025-12-10 success
-2025/12/12 08:05:04 remain 2025-12-09 success
-2025/12/12 08:05:05 remain 2025-12-08 success
-2025/12/12 08:05:06 remain 2025-12-07 success
-2025/12/12 08:05:07 remain 2025-12-06 success
-2025/12/12 08:05:08 remain 2025-12-05 success
-2025/12/12 08:05:09 remain 2025-12-04 success
-2025/12/12 08:05:10 remain 2025-12-03 success
-2025/12/12 08:05:11 remain 2025-12-02 success
-2025/12/12 08:05:12 remain 2025-12-01 success
-2025/12/12 08:05:13 remain 2025-11-30 success
-2025/12/12 08:05:14 remain 2025-11-29 success
-2025/12/12 08:05:15 remain 2025-11-28 success
-2025/12/12 08:05:15 remain 2025-11-27 success
-2025/12/12 08:05:17 remain 2025-11-26 success
-2025/12/12 08:05:18 remain 2025-11-25 success
-2025/12/12 08:05:19 remain 2025-11-24 success
-2025/12/12 08:05:20 remain 2025-11-23 success
-2025/12/12 08:05:21 remain 2025-11-22 success
-2025/12/12 08:05:22 remain 2025-11-21 success
-2025/12/12 08:05:22 remain 2025-11-20 success
-2025/12/12 08:05:23 remain 2025-11-19 success
-2025/12/12 08:05:25 remain 2025-11-18 success
-2025/12/12 08:05:26 remain 2025-11-17 success
-2025/12/12 08:05:26 remain 2025-11-16 success
-2025/12/12 08:05:27 remain 2025-11-15 success
-2025/12/12 08:05:28 remain 2025-11-14 success
-2025/12/12 08:05:29 remain 2025-11-13 success
-2025/12/12 08:05:30 remain 2025-11-12 success
-2025/12/12 08:05:30 end statistics
+[GIN] 2026/02/06 - 11:08:08 | 200 | 283.9437ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:22:59 | 200 | 274.4469ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:24:05 | 200 | 348.2504ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:24:17 | 200 | 329.7512ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:24:27 | 200 | 345.4986ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:24:44 | 200 | 300.8164ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:35:02 | 200 | 337.9567ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:36:33 | 200 | 259.11ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:36:46 | 200 | 284.573ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:36:47 | 200 | 249.2991ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:36:59 | 200 | 67.1611ms | ::1 | GET "/api/user/info"
+[GIN] 2026/02/06 - 11:37:01 | 200 | 431.8827ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:40:34 | 200 | 309.7846ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:40:51 | 200 | 275.6383ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:41:00 | 200 | 85.64ms | ::1 | GET "/api/user/info"
+[GIN] 2026/02/06 - 11:41:01 | 200 | 499.9881ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:42:36 | 200 | 281.8592ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:45:03 | 200 | 246.0534ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:46:58 | 200 | 261.62ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:48:04 | 200 | 256.2543ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:48:54 | 200 | 330.0666ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 11:49:20 | 200 | 25.5684635s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:49:20 | 200 | 6.9455357s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:49:23 | 200 | 525.4629ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:51:09 | 200 | 310.4069ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 11:51:09 | 200 | 263.907ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:51:24 | 200 | 1.4492901s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:51:28 | 200 | 412.4035ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:51:58 | 200 | 324.8691ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 11:51:59 | 200 | 294.4355ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:52:13 | 200 | 393.9931ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 11:52:13 | 200 | 326.9202ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:54:49 | 200 | 305.8447ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:55:49 | 200 | 278.9384ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:58:55 | 200 | 330.0915ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 11:59:21 | 200 | 313.4674ms | ::1 | POST "/api/language/add"
+[GIN] 2026/02/06 - 11:59:55 | 200 | 297.1654ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:00:10 | 200 | 263.8051ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 12:00:10 | 200 | 236.9732ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:04:51 | 200 | 269.5796ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:08:14 | 200 | 275.6644ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:10:04 | 200 | 264.1296ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:10:12 | 200 | 319.581ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 12:10:12 | 200 | 281.59ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:15:14 | 200 | 280.0912ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:15:29 | 200 | 273.8402ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 12:15:33 | 200 | 314.1021ms | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 12:15:34 | 200 | 282.8297ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:06:30 | 200 | 5.3565745s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:06:39 | 200 | 527.9859ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:21:48 | 200 | 313.4629ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:21:50 | 200 | 331.8064ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:34:21 | 200 | 367.3705ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:40:44 | 200 | 297.3901ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:41:56 | 200 | 267.249ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:42:09 | 200 | 319.4952ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:47:51 | 200 | 270.7758ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:48:44 | 200 | 278.511ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:48:45 | 200 | 297.4667ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:48:49 | 200 | 1.3174404s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:48:57 | 200 | 1.4807982s | ::1 | POST "/api/language/save"
+[GIN] 2026/02/06 - 14:48:59 | 200 | 2.670194s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:49:06 | 200 | 1.2162725s | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:51:47 | 200 | 606.2702ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:56:03 | 200 | 294.684ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 14:56:56 | 200 | 306.1023ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 15:01:34 | 200 | 275.0238ms | ::1 | POST "/api/language/list"
+[GIN] 2026/02/06 - 15:18:28 | 200 | 399.0769ms | ::1 | POST "/api/language/list"
diff --git a/main.go b/main.go
index 1d18b4f..848907f 100644
--- a/main.go
+++ b/main.go
@@ -103,6 +103,7 @@ func main() {
alibabaApi.POST("/zabbix/notify", controller.AlibabaNotify) // 系统报警
alibabaApi.POST("/zabbix/recovery", controller.AlibabaRecovery) // 系统报警
alibabaApi.POST("/game/notify", controller.AlibabaGameNotify) // 游戏报警
+ alibabaApi.POST("/notify/order", controller.AlibabaNotifyOrder) // 订单通知
}
api := r.Group("/api", middleware.ValidateToken())
{
@@ -158,11 +159,12 @@ func main() {
scripts := r.Group("/api/scripts", middleware.ValidateToken())
{
scripts.POST("/copywriting", controller.Copywriting) // 下载文案文件
+ scripts.POST("/copyonline", controller.CopyOnline) // 复制线上环境到QA
}
//go util.ScheduleDailyTask()
go server.Server()
- go model.InitToken() // 初始化 Token 列表
- //go controller.USSendInfo() // 启动定时任务发送信息
+ go model.InitToken() // 初始化 Token 列表
+ go util.MonitorServerList() // 启动定时任务发送信息
go monitor.UserAliveMonitor(0) // 用户存活监控
go monitor.ServerInfoMonitor() // 服务器信息监控
defer func() {
diff --git a/model/User.go b/model/User.go
index 69fcc99..0562a31 100644
--- a/model/User.go
+++ b/model/User.go
@@ -18,18 +18,9 @@ func GetUserList(AppId, ServerId, PageSize, CurrentPage, Uid, StartTime, EndTime
}
users := []*User{}
if Uid != 0 {
- //TODO 兼容处理
- if AppId == 1 {
- err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name`, `node` FROM t_player_baseinfo WHERE dwUin = ? ", Uid)
- } else {
- err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name` FROM t_player_baseinfo WHERE dwUin = ? ", Uid)
- }
+ err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name`, `node` FROM t_player_baseinfo WHERE dwUin = ? ", Uid)
} else {
- if AppId == 1 {
- err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name`, `node` FROM t_player_baseinfo WHERE `login_time` >= ? and `login_time` <= ? Order by login_time desc limit ?, ?", StartTime, EndTime, (CurrentPage-1)*PageSize, PageSize)
- } else {
- err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name` FROM t_player_baseinfo WHERE `login_time` >= ? and `login_time` <= ? Order by login_time desc limit ?, ?", StartTime, EndTime, (CurrentPage-1)*PageSize, PageSize)
- }
+ err = db.Select(&users, "SELECT `dwUin`, `energy`, `star`, `diamond`, `level`, `exp`, `login_time`, `logout_time`, `user_name`, `nick_name`, `node` FROM t_player_baseinfo WHERE `login_time` >= ? and `login_time` <= ? Order by login_time desc limit ?, ?", StartTime, EndTime, (CurrentPage-1)*PageSize, PageSize)
}
if err != nil {
return nil, 0, fmt.Errorf("failed to get user list: %v", err)
@@ -49,14 +40,10 @@ func GetUserList(AppId, ServerId, PageSize, CurrentPage, Uid, StartTime, EndTime
return users, total, nil
}
-func UserDetail(Uid, Node int) (map[string]interface{}, error) {
+func UserDetail(AppId, Uid, Node int) (map[string]interface{}, error) {
req := &msg.ReqAdminInfo{
Uid: int64(Uid),
}
- AppId := Uid / 100000000
- if AppId != 1 {
- Node = 1
- }
ws, err := util.GetWebsocket(AppId, Node)
if err != nil {
return nil, fmt.Errorf("failed to get websocket: %v", err)
@@ -79,13 +66,8 @@ func UserGM(AppId, ServerId, Uid int, Command string) (interface{}, error) {
db := util.MPool.GetMysqlDB(App, 1)
defer db.Close()
- AppId, ServerId = util.ParseUid(Uid)
node := 0
err = db.Get(&node, "SELECT `node` FROM t_player_baseinfo WHERE dwUin = ? ", Uid)
- //TODO 兼容处理
- if AppId != 1 {
- node = 1
- }
ws, err := util.GetWebsocket(AppId, node)
if err != nil {
return nil, fmt.Errorf("failed to get websocket: %v", err)
diff --git a/model/admin.go b/model/admin.go
index 4b9f43d..686363e 100644
--- a/model/admin.go
+++ b/model/admin.go
@@ -171,7 +171,7 @@ func InitToken() {
UserName string `db:"username"`
Role int `db:"role"` // 假设有一个角色字段
}
- err := db.Select(&tokens, "SELECT username, token, expires FROM admin WHERE token IS NOT NULL")
+ err := db.Select(&tokens, "SELECT username, token, expires, role FROM admin WHERE token IS NOT NULL")
if err != nil {
return // 处理错误
}
diff --git a/model/language.go b/model/language.go
index f9ab6a6..2dbd932 100644
--- a/model/language.go
+++ b/model/language.go
@@ -14,12 +14,13 @@ import (
)
type Language struct {
- Id int `json:"Id" db:"Id"`
- Key string `json:"key" db:"key"`
- EN_US string `json:"en_US" db:"en_US"`
- ZH_CN string `json:"zh_CN" db:"zh_CN"`
- PT_BR string `json:"pt_BR" db:"pt_BR"`
- Url string `json:"url"`
+ Id int `json:"Id" db:"Id"`
+ Key string `json:"key" db:"key"`
+ EN_US string `json:"en_US" db:"en_US"`
+ ZH_CN string `json:"zh_CN" db:"zh_CN"`
+ PT_BR string `json:"pt_BR" db:"pt_BR"`
+ ES_LATAM string `json:"es_LATAM" db:"es_LATAM"`
+ Url string `json:"url"`
}
type LanguageOp struct {
@@ -79,7 +80,7 @@ func (l *LanguageMod) LanguageList(account string) (map[string]interface{}, erro
if SearchSQL != "" {
SearchSQL = " where " + SearchSQL
}
- sql := fmt.Sprintf("SELECT `Id`, `key`, `en_US`, `zh_CN`, `pt_BR` FROM language %s LIMIT ?, ?", SearchSQL)
+ sql := fmt.Sprintf("SELECT `Id`, `key`, `en_US`, `zh_CN`, `pt_BR`, `es_LATAM` FROM language %s LIMIT ?, ?", SearchSQL)
err := Db.Select(&languages, sql, (l.CurrentPage-1)*l.PageSize, l.PageSize)
if err != nil {
return nil, err
@@ -114,7 +115,7 @@ 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`, `en_US`, `zh_CN`,`pt_BR` FROM language")
+ err := Db.Select(&languages, "SELECT `Id`, `key`, `en_US`, `zh_CN`,`pt_BR`, `es_LATAM` FROM language")
if err != nil {
return nil, err
}
@@ -144,8 +145,8 @@ func (l *LanguageMod) LanguageListAll() (map[string]interface{}, error) {
}, nil
}
// 写表头(在主表和 backend 表都写一份)
- headers := []string{"Id", "key", "en_US", "zh_CN", "pt_BR"}
- cols := []string{"A", "B", "C", "D", "E"}
+ headers := []string{"Id", "key", "en_US", "zh_CN", "pt_BR", "es_LATAM"}
+ cols := []string{"A", "B", "C", "D", "E", "F"}
for i, h := range headers {
if err := f.SetCellValue(mainSheet, cols[i]+"1", h); err != nil {
return nil, err
@@ -154,7 +155,7 @@ func (l *LanguageMod) LanguageListAll() (map[string]interface{}, error) {
return nil, err
}
}
- headers2 := []string{"编号", "键", "英文", "简体中文", "葡萄牙语(巴西)"}
+ headers2 := []string{"编号", "键", "英文", "简体中文", "葡萄牙语(巴西)", "西班牙语(拉丁美洲)"}
for i, h := range headers2 {
if err := f.SetCellValue(mainSheet, cols[i]+"2", h); err != nil {
return nil, err
@@ -184,6 +185,9 @@ func (l *LanguageMod) LanguageListAll() (map[string]interface{}, error) {
if err := f.SetCellValue(backendSheet, "E"+row, lang.PT_BR); err != nil {
return nil, err
}
+ if err := f.SetCellValue(backendSheet, "F"+row, lang.ES_LATAM); err != nil {
+ return nil, err
+ }
backendRowIndex++
} else {
row := fmt.Sprintf("%d", mainRowIndex)
@@ -202,6 +206,9 @@ func (l *LanguageMod) LanguageListAll() (map[string]interface{}, error) {
if err := f.SetCellValue(mainSheet, "E"+row, lang.PT_BR); err != nil {
return nil, err
}
+ if err := f.SetCellValue(mainSheet, "F"+row, lang.ES_LATAM); err != nil {
+ return nil, err
+ }
mainRowIndex++
}
}
diff --git a/model/log.go b/model/log.go
index 29e9419..03ead45 100644
--- a/model/log.go
+++ b/model/log.go
@@ -47,8 +47,8 @@ type Order struct {
CreateTime int `db:"CreateTime"`
PayTime int `db:"PayTime"`
PayType int `db:"PayType"`
- Param string `db:"Param"`
- Timestamp int `db:"Timestamp"`
+ Param string `db:"PayChannelExtra"`
+ PayStatus int `db:"PayStatus"`
CreateTimeStr string
PayTimeStr string
}
@@ -74,7 +74,7 @@ type Event struct {
}
func (m *Log) Asset() (*ResAsset, error) {
- resutl, total, err := util.SearchAssetByUid(m.Uid, (m.CurrentPage-1)*m.PageSize, m.CurrentPage*m.PageSize, m.StartTime, m.EndTime)
+ resutl, total, err := util.SearchAssetByUid(m.AppId, m.Uid, (m.CurrentPage-1)*m.PageSize, m.CurrentPage*m.PageSize, m.StartTime, m.EndTime, m.ItemId, m.EventParam)
if err != nil {
return nil, err
}
@@ -99,7 +99,7 @@ func (m *Log) Asset() (*ResAsset, error) {
}
func (m *Log) Event() (*ResEvent, error) {
- event, total, err := util.SearchEventByUid(m.Uid, (m.CurrentPage-1)*m.PageSize, m.CurrentPage*m.PageSize, m.StartTime, m.EndTime)
+ event, total, err := util.SearchEventByUid(m.AppId, m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize, m.StartTime, m.EndTime, m.EventParam)
if err != nil {
return nil, err
}
@@ -110,31 +110,24 @@ func (m *Log) Event() (*ResEvent, error) {
}
func (m *Log) Order() (*ResOrder, error) {
+ m.AppId = m.Uid / 100000000
AppConfig, err := util.GetAppConfig(m.AppId)
if err != nil {
return nil, err
}
- Db := util.MPool.GetTopicDB(AppConfig.Topic)
+ Db := util.MPool.GetMysqlDB(AppConfig, 1)
defer Db.Close()
if Db == nil {
return nil, fmt.Errorf("failed to get mysql database")
}
assets := []*Order{}
- if m.Uid == 0 {
- err = Db.Select(&assets, "SELECT * FROM log_order where `PayTime` > 0 ORDER BY Timestamp DESC LIMIT ?, ?", (m.CurrentPage-1)*m.PageSize, m.PageSize)
- } else {
- err = Db.Select(&assets, "SELECT * FROM log_order WHERE Uid = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
- }
+ err = Db.Select(&assets, "SELECT `id`, `Uid`, `ProductId`, `Price`, `PayTime`, `PayStatus`, `PayChannelOrderId`, `OrderId`, `PayChannelExtra` FROM t_player_charge WHERE Uid = ? and PayTime > 0 ORDER BY PayTime DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize)
if err != nil {
return nil, fmt.Errorf("failed to get asset list: %v", err)
}
var total int
- if m.Uid == 0 {
- err = Db.QueryRow("SELECT COUNT(*) FROM log_order").Scan(&total)
- } else {
- err = Db.QueryRow("SELECT COUNT(*) FROM log_order WHERE Uid = ? ", m.Uid).Scan(&total)
- }
+ err = Db.QueryRow("SELECT COUNT(*) FROM t_player_charge WHERE Uid = ? and PayTime > 0 ", m.Uid).Scan(&total)
for _, asset := range assets {
asset.CreateTimeStr = util.TimestampToDateTime(int64(asset.CreateTime), AppConfig.Tz)
asset.PayTimeStr = util.TimestampToDateTime(int64(asset.PayTime), AppConfig.Tz)
diff --git a/model/mail.go b/model/mail.go
index 5b376df..73eee8d 100644
--- a/model/mail.go
+++ b/model/mail.go
@@ -26,6 +26,10 @@ type Mail struct {
SubTitlePtBr string `json:"subtitle_ptbr" db:"subTitle_ptbr"`
ContentPtBr string `json:"content_ptbr" db:"content_ptbr"`
+ TitleEsLatam string `json:"title_es_latam" db:"title_es_latam"`
+ SubTitleEsLatam string `json:"subtitle_es_latam" db:"subTitle_es_latam"`
+ ContentEsLatam string `json:"content_es_latam" db:"content_es_latam"`
+
StartTime int64 `json:"start_time" db:"start_time"`
EndTime int64 `json:"end_time" db:"end_time"`
Items string `json:"items" db:"items"`
@@ -51,7 +55,7 @@ func (m *Mail) MailList() (*Result, error) {
Db := util.MPool.GetMysqlDB(AppCfg, m.ServerId)
defer Db.Close()
var mail []*Mail
- err = Db.Select(&mail, "SELECT `mail_id`, `title`, `content`, `start_time`, `end_time`, `items`, `register_time`, `mail_type`,`send_type`, `to_uids`, `create_time`, `subTitle`, `subTitle_en`, `content_en`, `title_en`, `title_ptbr`,`subTitle_ptbr`, `content_ptbr` FROM system_mail_info")
+ err = Db.Select(&mail, "SELECT `mail_id`, `title`, `content`, `start_time`, `end_time`, `items`, `register_time`, `mail_type`,`send_type`, `to_uids`, `create_time`, `subTitle`, `subTitle_en`, `content_en`, `title_en`, `title_ptbr`,`subTitle_ptbr`, `content_ptbr`, `title_es_latam`, `subtitle_es_latam`, `content_es_latam` FROM system_mail_info")
if err != nil {
return nil, fmt.Errorf("failed to scan rows: %v", err)
}
diff --git a/model/server.go b/model/server.go
index 29e3c8c..5cfc61b 100644
--- a/model/server.go
+++ b/model/server.go
@@ -100,12 +100,15 @@ func (s *Server) UpdateApp() (string, error) {
if err != nil {
return "", fmt.Errorf("failed to git pull: %v", err)
}
+ resp, err := SshClient.RunCommand(`export PATH="$PATH:$(go env GOPATH)/bin"`)
+ fmt.Print(resp)
+
now := util.Now()
- cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
+ cmd := fmt.Sprintf(`source /etc/profile && export PATH="$PATH:$(go env GOPATH)/bin"`+"&& ansible-playbook /data/devops/playbook/%s.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
output, err := SshClient.RunCommand(cmd)
param.UpdateTime = util.NowFormat()
param.Duration = fmt.Sprintf("%d 秒", util.Now()-now)
- param.Server = AppConfig.AppName
+ param.Server = util.GetAppName(s.AppId)
if err != nil {
param.SrcGitLog = fmt.Sprintf("- 更新失败: %v\n", err)
@@ -121,9 +124,10 @@ func (s *Server) UpdateApp() (string, error) {
log.Printf("警告: 无法获取源码 git head (目录或git命令可能不存在): %v", err)
// 继续执行,不中断流程
} else {
+ src_git_key := fmt.Sprintf("src_%d", s.AppId)
srcHead = strings.TrimSpace(srcHead)
- oldSrcHead, _ := util.GetGitHead("src")
- util.SaveGitHead("src", srcHead)
+ oldSrcHead, _ := util.GetGitHead(src_git_key)
+ util.SaveGitHead(src_git_key, srcHead)
if oldSrcHead != "" && oldSrcHead != srcHead {
cmd = fmt.Sprintf("cd /codes/pet_home_server && git log %s..%s --pretty=format:'%%h-%%s'", oldSrcHead, srcHead)
commitMsg, _ := SshClient.RunCommand(cmd)
@@ -139,9 +143,10 @@ func (s *Server) UpdateApp() (string, error) {
log.Printf("警告: 无法获取文档 git head (目录或git命令可能不存在): %v", err)
// 继续执行,不中断流程
} else {
+ docs_git_key := fmt.Sprintf("docs_%d", s.AppId)
docHead = strings.TrimSpace(docHead)
- oldDocHead, _ := util.GetGitHead("doc")
- util.SaveGitHead("doc", docHead)
+ oldDocHead, _ := util.GetGitHead(docs_git_key)
+ util.SaveGitHead(docs_git_key, docHead)
if oldDocHead != "" && oldDocHead != docHead {
cmd = fmt.Sprintf("cd /data/docs && git log %s..%s --pretty=format:'%%h-%%s'", oldDocHead, docHead)
commitMsg, _ := SshClient.RunCommand(cmd)
@@ -178,11 +183,11 @@ func (s *Server) UpdateAppReview() (string, error) {
return "", fmt.Errorf("failed to git pull: %v", err)
}
now := util.Now()
- cmd := fmt.Sprintf("ansible-playbook /data/devops/playbook/%s-review.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
+ cmd := fmt.Sprintf(`source /etc/profile && export PATH="$PATH:$(go env GOPATH)/bin"`+"&& ansible-playbook /data/devops/playbook/%s-review.yml -i /data/devops/playbook/hosts", AppConfig.AppName)
output, err := SshClient.RunCommand(cmd)
param.UpdateTime = util.NowFormat()
param.Duration = fmt.Sprintf("%d 秒", util.Now()-now)
- param.Server = AppConfig.AppName
+ param.Server = util.GetAppName(s.AppId) + " review"
if err != nil {
param.SrcGitLog = fmt.Sprintf("- 更新失败: %v\n", err)
@@ -268,10 +273,6 @@ func (s *Server) UpdateAppFeishu() (string, error) {
func (s *Server) RestartServer() (string, error) {
serverInfo := util.GetServer(s.AppId, s.ServerId)
nodeInfo := util.GetNodeById(serverInfo.Ecs)
- AppConfig, err := util.GetAppConfig(s.AppId)
- if err != nil {
- return "", err
- }
SshClient, err := util.NewSshClient(nodeInfo)
if err != nil {
return "", err
@@ -279,11 +280,83 @@ func (s *Server) RestartServer() (string, error) {
defer SshClient.Close()
workDir := serverInfo.WorkDir
cmd := fmt.Sprintf("cd %s && ./tool/tool restart node %d", workDir, s.ServerId)
+ if serverInfo.NodeType == 0 {
+ cmd = fmt.Sprintf("cd %s && ./tool/tool restart center %d", workDir, s.ServerId)
+ }
output, err := SshClient.RunCommand(cmd)
if err != nil {
return "", err
}
- feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
+ // feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
+ str := `
+# 游戏服务重启
+* 游戏环境:**%s**
+* 节点:%s
+------------------
+重启完成[鼓掌]
+所有人
+ `
+ alibaba.SendStandardMsg("游戏服务器重启完成", fmt.Sprintf(str, util.GetAppName(s.AppId), serverInfo.Name), "green")
+ return output, nil
+}
+
+func (s *Server) StopServer() (string, error) {
+ serverInfo := util.GetServer(s.AppId, s.ServerId)
+ nodeInfo := util.GetNodeById(serverInfo.Ecs)
+ SshClient, err := util.NewSshClient(nodeInfo)
+ if err != nil {
+ return "", err
+ }
+ defer SshClient.Close()
+ workDir := serverInfo.WorkDir
+ cmd := fmt.Sprintf("cd %s && ./tool/tool stop node %d", workDir, s.ServerId)
+ if serverInfo.NodeType == 0 {
+ cmd = fmt.Sprintf("cd %s && ./tool/tool stop center %d", workDir, s.ServerId)
+ }
+ output, err := SshClient.RunCommand(cmd)
+ if err != nil {
+ return output, err
+ }
+ // feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
+ // str := `
+ // # 游戏服务关闭
+ // * 游戏环境:**%s**
+ // * 节点:%s
+ // ------------------
+ // 关闭完成[鼓掌]
+ // 所有人
+ // `
+ // alibaba.SendStandardMsg("游戏服务器关闭完成", fmt.Sprintf(str, util.GetAppName(s.AppId), serverInfo.Name), "green")
+ return output, nil
+}
+
+func (s *Server) StartServer() (string, error) {
+ serverInfo := util.GetServer(s.AppId, s.ServerId)
+ nodeInfo := util.GetNodeById(serverInfo.Ecs)
+ SshClient, err := util.NewSshClient(nodeInfo)
+ if err != nil {
+ return "", err
+ }
+ defer SshClient.Close()
+ workDir := serverInfo.WorkDir
+ cmd := fmt.Sprintf("cd %s && ./tool/tool start node %d", workDir, s.ServerId)
+ if serverInfo.NodeType == 0 {
+ cmd = fmt.Sprintf("cd %s && ./tool/tool start center %d", workDir, s.ServerId)
+ }
+ output, err := SshClient.RunCommand(cmd)
+ if err != nil {
+ return "", err
+ }
+ // feishu.SendFeishuMsg(fmt.Sprintf("AppName: %s, ServerName: %s, 重启完成", AppConfig.AppName, s.ServerName))
+ // str := `
+ // # 游戏服务启动
+ // * 游戏环境:**%s**
+ // * 节点:%s
+ // ------------------
+ // 启动完成[鼓掌]
+ // 所有人
+ // `
+ // alibaba.SendStandardMsg("游戏服务器启动完成", fmt.Sprintf(str, util.GetAppName(s.AppId), serverInfo.Name), "green")
return output, nil
}
diff --git a/monitor/Monitor.go b/monitor/Monitor.go
index e6b5822..eb8793f 100644
--- a/monitor/Monitor.go
+++ b/monitor/Monitor.go
@@ -79,7 +79,7 @@ func monitorServerInfo() {
defer tmpDb.Close()
res, err := model.GetServerInfo(v.AppId, v.ServerId)
if err != nil {
- // tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", v.AppId, v.ServerId)
+ tmpDb.Exec("update server set Status=0 where AppId=? and ServerId=?", v.AppId, v.ServerId)
return
}
serverInfo := res.(map[string]interface{})
diff --git a/msg/Gameapi.pb.go b/msg/Gameapi.pb.go
index 1322506..29eb92c 100644
--- a/msg/Gameapi.pb.go
+++ b/msg/Gameapi.pb.go
@@ -866,9 +866,10 @@ func (CHESS_EX_TYPE) EnumDescriptor() ([]byte, []int) {
type LANG_TYPE int32
const (
- LANG_TYPE_LANG_CN LANG_TYPE = 0 // 中文
- LANG_TYPE_LANG_EN LANG_TYPE = 1 // 英文
- LANG_TYPE_LANG_PTBR LANG_TYPE = 2 // 葡萄牙语
+ LANG_TYPE_LANG_CN LANG_TYPE = 0 // 中文
+ LANG_TYPE_LANG_EN LANG_TYPE = 1 // 英文
+ LANG_TYPE_LANG_PTBR LANG_TYPE = 2 // 葡萄牙语
+ LANG_TYPE_LANG_ES_LATAM LANG_TYPE = 3 // 西班牙语-拉丁美洲
)
// Enum value maps for LANG_TYPE.
@@ -877,11 +878,13 @@ var (
0: "LANG_CN",
1: "LANG_EN",
2: "LANG_PTBR",
+ 3: "LANG_ES_LATAM",
}
LANG_TYPE_value = map[string]int32{
- "LANG_CN": 0,
- "LANG_EN": 1,
- "LANG_PTBR": 2,
+ "LANG_CN": 0,
+ "LANG_EN": 1,
+ "LANG_PTBR": 2,
+ "LANG_ES_LATAM": 3,
}
)
@@ -16457,6 +16460,9 @@ type MailInfo struct {
TitlePtBr string `protobuf:"bytes,12,opt,name=TitlePtBr,proto3" json:"TitlePtBr,omitempty"` // 葡萄牙标题
ContentPtBr string `protobuf:"bytes,13,opt,name=ContentPtBr,proto3" json:"ContentPtBr,omitempty"` // 葡萄牙内容
SubTitlePtBr string `protobuf:"bytes,14,opt,name=SubTitlePtBr,proto3" json:"SubTitlePtBr,omitempty"` // 葡萄牙子标题
+ TitleEsLa string `protobuf:"bytes,15,opt,name=TitleEsLa,proto3" json:"TitleEsLa,omitempty"` // 西班牙语标题
+ SubTitleEsLa string `protobuf:"bytes,16,opt,name=SubTitleEsLa,proto3" json:"SubTitleEsLa,omitempty"` // 西班牙语子标题
+ ContentEsLa string `protobuf:"bytes,17,opt,name=ContentEsLa,proto3" json:"ContentEsLa,omitempty"` // 西班牙语内容
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -16589,6 +16595,27 @@ func (x *MailInfo) GetSubTitlePtBr() string {
return ""
}
+func (x *MailInfo) GetTitleEsLa() string {
+ if x != nil {
+ return x.TitleEsLa
+ }
+ return ""
+}
+
+func (x *MailInfo) GetSubTitleEsLa() string {
+ if x != nil {
+ return x.SubTitleEsLa
+ }
+ return ""
+}
+
+func (x *MailInfo) GetContentEsLa() string {
+ if x != nil {
+ return x.ContentEsLa
+ }
+ return ""
+}
+
type MailNotify struct {
state protoimpl.MessageState `protogen:"open.v1"`
Info *MailInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"`
@@ -24168,7 +24195,7 @@ func (x *ReqPlayroomGameShowReward) GetSelectId() int32 {
type ResPlayroomGameShowReward struct {
state protoimpl.MessageState `protogen:"open.v1"`
- Items []*ItemInfo `protobuf:"bytes,5,rep,name=Items,proto3" json:"Items,omitempty"` // 奖励道具
+ Items []*ItemInfo `protobuf:"bytes,1,rep,name=Items,proto3" json:"Items,omitempty"` // 奖励道具
unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
}
@@ -28782,7 +28809,7 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"\bMailList\x18\x01 \x03(\v2#.tutorial.ResMailList.MailListEntryR\bMailList\x1aO\n" +
"\rMailListEntry\x12\x10\n" +
"\x03key\x18\x01 \x01(\x05R\x03key\x12(\n" +
- "\x05value\x18\x02 \x01(\v2\x12.tutorial.MailInfoR\x05value:\x028\x01\"\x8c\x03\n" +
+ "\x05value\x18\x02 \x01(\v2\x12.tutorial.MailInfoR\x05value:\x028\x01\"\xf0\x03\n" +
"\bMailInfo\x12\x0e\n" +
"\x02Id\x18\x01 \x01(\x05R\x02Id\x12\x14\n" +
"\x05Title\x18\x02 \x01(\tR\x05Title\x12\x18\n" +
@@ -28800,7 +28827,10 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"SubTitleEn\x12\x1c\n" +
"\tTitlePtBr\x18\f \x01(\tR\tTitlePtBr\x12 \n" +
"\vContentPtBr\x18\r \x01(\tR\vContentPtBr\x12\"\n" +
- "\fSubTitlePtBr\x18\x0e \x01(\tR\fSubTitlePtBr\"4\n" +
+ "\fSubTitlePtBr\x18\x0e \x01(\tR\fSubTitlePtBr\x12\x1c\n" +
+ "\tTitleEsLa\x18\x0f \x01(\tR\tTitleEsLa\x12\"\n" +
+ "\fSubTitleEsLa\x18\x10 \x01(\tR\fSubTitleEsLa\x12 \n" +
+ "\vContentEsLa\x18\x11 \x01(\tR\vContentEsLa\"4\n" +
"\n" +
"MailNotify\x12&\n" +
"\x04Info\x18\x01 \x01(\v2\x12.tutorial.MailInfoR\x04Info\"\x1d\n" +
@@ -29415,7 +29445,7 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"\x04Type\x18\x01 \x01(\x05R\x04Type\x12\x1a\n" +
"\bSelectId\x18\x02 \x01(\x05R\bSelectId\"E\n" +
"\x19ResPlayroomGameShowReward\x12(\n" +
- "\x05Items\x18\x05 \x03(\v2\x12.tutorial.ItemInfoR\x05Items\"9\n" +
+ "\x05Items\x18\x01 \x03(\v2\x12.tutorial.ItemInfoR\x05Items\"9\n" +
"\x13ReqPlayroomInteract\x12\x0e\n" +
"\x02Id\x18\x01 \x01(\x05R\x02Id\x12\x12\n" +
"\x04Type\x18\x02 \x01(\x05R\x04Type\"q\n" +
@@ -29808,11 +29838,12 @@ const file_proto_Gameapi_proto_rawDesc = "" +
"\fCHESS_EX_BOX\x10\x02\x12\x16\n" +
"\x12CHESS_EX_QUICK_BUY\x10\x03\x12\x12\n" +
"\x0eCHESS_EX_EVENT\x10\x04\x12$\n" +
- " CHESS_EX_EVENT_LITTLE_APPRENTICE\x10\x05*4\n" +
+ " CHESS_EX_EVENT_LITTLE_APPRENTICE\x10\x05*G\n" +
"\tLANG_TYPE\x12\v\n" +
"\aLANG_CN\x10\x00\x12\v\n" +
"\aLANG_EN\x10\x01\x12\r\n" +
- "\tLANG_PTBR\x10\x02*x\n" +
+ "\tLANG_PTBR\x10\x02\x12\x11\n" +
+ "\rLANG_ES_LATAM\x10\x03*x\n" +
"\x0fLimitEventParam\x12\f\n" +
"\bLEP_NONE\x10\x00\x12\x14\n" +
"\x10CAT_TRICK_ENERGY\x10\x01\x12\x12\n" +
diff --git a/release/backend b/release/backend
index 41d7f5c..64cdc57 100644
Binary files a/release/backend and b/release/backend differ
diff --git a/release/start.sh b/release/start.sh
index 66c47a5..2582ee6 100644
--- a/release/start.sh
+++ b/release/start.sh
@@ -15,16 +15,16 @@ if [ $1 == "start" ]; then
echo "backend started."
elif [ $1 == "stop" ]; then
echo "Stopping backend..."
- PID=$(ps -ef | grep backend | grep -v "grep" | awk '{print $2}')
+ PID=$(ps -ef | grep “./backend” | grep -v "grep" | awk '{print $2}')
if [ -z $PID ]; then
echo "backend is not running."
exit 1
fi
- ps -ef | grep backend | grep -v grep | awk '{print $2}' | xargs kill
+ ps -ef | grep “./backend” | grep -v grep | awk '{print $2}' | xargs kill
echo "backend stopped."
elif [ $1 == "status" ]; then
echo "backend status:"
- PID=$(ps -ef | grep backend | grep -v "grep" | awk '{print $2}')
+ PID=$(ps -ef | grep “./backend” | grep -v "grep" | awk '{print $2}')
if [ -z $PID ]; then
echo "backend is not running."
else
@@ -32,14 +32,14 @@ elif [ $1 == "status" ]; then
fi
elif [ $1 == "restart" ]; then
echo "Restarting backend..."
- PID=$(ps -ef | grep backend | grep -v "grep" | awk '{print $2}')
+ PID=$(ps -ef | grep “./backend” | grep -v "grep" | awk '{print $2}')
if [ -n "$PID" ]; then
echo "backend stoping."
kill $PID
fi
while [ -n "$PID" ]; do
sleep 1
- PID=$(ps -ef | grep backend | grep -v "grep" | awk '{print $2}')
+ PID=$(ps -ef | grep “./backend” | grep -v "grep" | awk '{print $2}')
done
echo "backend stoped."
> log/backend.log # 清空 logs 文件
diff --git a/scripts/zabbix/main.go b/scripts/zabbix/main.go
index bdfac37..152afd1 100644
--- a/scripts/zabbix/main.go
+++ b/scripts/zabbix/main.go
@@ -4,11 +4,12 @@ import (
"backend/msg"
"backend/util"
"fmt"
+ "net/http"
"os"
"strconv"
"time"
- "golang.org/x/net/websocket"
+ "github.com/gorilla/websocket"
)
func main() {
@@ -44,17 +45,13 @@ func main() {
}
func getwebsocket(Host string, Port int) (*websocket.Conn, error) {
- origin := "http://localhost/"
url := fmt.Sprintf("ws://%s:%d/", Host, Port)
- config, err := websocket.NewConfig(url, origin)
- if err != nil {
- return nil, fmt.Errorf("failed to create websocket config: %v", err)
+ dialer := &websocket.Dialer{
+ HandshakeTimeout: 5 * time.Second,
}
- // config.Dialer = &net.Dialer{
- // Timeout: 5 * time.Second,
- // }
-
- ws, err := websocket.DialConfig(config)
+ header := http.Header{}
+ header.Set("Origin", "http://localhost/")
+ ws, _, err := dialer.Dial(url, header)
if err != nil {
return nil, fmt.Errorf("failed to connect to websocket: %v", err)
}
diff --git a/sdk/login/conf/server.yml b/sdk/login/conf/server.yml
index b424eae..6844ed8 100644
--- a/sdk/login/conf/server.yml
+++ b/sdk/login/conf/server.yml
@@ -36,7 +36,7 @@ mysqls:
password: 'GWFj1cHaqjpzvcsHBWTFtLWtm8MUZKROx_wvbV6jPg=='
database: 'merge_pet_london_%d'
idleTimeout: Infinity
- - host: '127.0.0.1'
+ - host: 'rm-rj9my01442p7kpe36.mysql.rds-aliyun-america.rds.aliyuncs.com'
name: 'merge_pet_online'
port: 3306
user: 'root'
@@ -47,7 +47,7 @@ mysqls:
name: 'log'
port: 3306
user: 'root'
- password: 'GWFj1cHaqjpzvcsHBWTFtLWtm8MUZKROx_wvbV6jPg=='
+ password: 'ioy63iEqUA6EYmeg1GpWPh2mE8HnnBp-sVWlNR6N'
database: 'game'
idleTimeout: Infinity
diff --git a/sdk/ship/main.go b/sdk/ship/main.go
index 7b6aa1e..20a3c8d 100644
--- a/sdk/ship/main.go
+++ b/sdk/ship/main.go
@@ -72,6 +72,7 @@ func main() {
// 充值发货
ChargeApi.POST("test/charge", test.Charge)
ChargeApi.POST("tuyou/charge", tuyou.Charge)
+ ChargeApi.GET("tuyou/charge", tuyou.Charge)
}
log.Printf("Ship SDK started on port %d", shipcommon.AppConf.Port)
r.Run(fmt.Sprintf(":%d", shipcommon.AppConf.Port))
diff --git a/sdk/ship/model/base/base.go b/sdk/ship/model/base/base.go
index 356e132..f2f7864 100644
--- a/sdk/ship/model/base/base.go
+++ b/sdk/ship/model/base/base.go
@@ -2,6 +2,7 @@ package base
import (
"backend/util"
+ "fmt"
"time"
"github.com/gin-gonic/gin"
@@ -20,7 +21,7 @@ type Param struct {
ChannelOrderId string
}
-func (p *Param) ChangeOrderStatus(Platform string) error {
+func (p *Param) ChangeOrderStatus(Platform string, prodprice string) error {
// 校验成功 修改订单状态为已支付
AppConf, err := util.GetAppConfig(p.AppId)
if err != nil {
@@ -28,6 +29,28 @@ func (p *Param) ChangeOrderStatus(Platform string) error {
}
Db := util.MPool.GetMysqlDB(AppConf, 1)
defer Db.Close()
+ var chargeId int
+ var price float64
+ var paystatus int
+ err = Db.QueryRow("SELECT `ProductId`, `Price`, `PayStatus` FROM `t_player_charge` WHERE `OrderId`=?", p.OrderId).Scan(&chargeId, &price, &paystatus)
+ if err != nil {
+ return err
+ }
+ if fmt.Sprintf("%.2f", price) != prodprice {
+ // str := `
+ // # 订单金额不匹配报警
+ // - 项目名称: %s
+ // - 订单ID: %s
+ // - 数据库金额: %.2f
+ // - 回调金额: %s
+ // - 渠道订单ID: %s
+ // - 充值ID: %d
+ // `
+ return fmt.Errorf("订单金额不匹配,数据库金额:%.2f,回调金额:%s; 订单id:%s, chargeid:%d", price, prodprice, p.OrderId, chargeId)
+ }
+ if paystatus != 0 {
+ return fmt.Errorf("订单已支付,无法重复发货; 订单id:%s, chargeid:%d", p.OrderId, chargeId)
+ }
_, err = Db.Exec("UPDATE `t_player_charge` SET `PayStatus`=1, `PayTime`=?, `PayChannelOrderId` = ? , `PayPlatform` =? WHERE `OrderId`=? AND `PayStatus`=0", time.Now().Unix(), p.ChannelOrderId, Platform, p.OrderId)
return err
}
diff --git a/sdk/ship/model/test/test.go b/sdk/ship/model/test/test.go
index 10ebb5b..6125deb 100644
--- a/sdk/ship/model/test/test.go
+++ b/sdk/ship/model/test/test.go
@@ -105,7 +105,7 @@ func Charge(c *gin.Context) {
return
}
AppInfo.ChannelOrderId = req.ProductID
- err := AppInfo.ChangeOrderStatus("test")
+ err := AppInfo.ChangeOrderStatus("test", req.ProductID)
if err != nil {
log.Print("change order status error:", err)
c.JSON(500, gin.H{"error": "failed to change order status"})
diff --git a/sdk/ship/model/tuyou/tuyou.go b/sdk/ship/model/tuyou/tuyou.go
index 4fd464a..acbc8b9 100644
--- a/sdk/ship/model/tuyou/tuyou.go
+++ b/sdk/ship/model/tuyou/tuyou.go
@@ -2,6 +2,7 @@ package tuyou
import (
"backend/Type"
+ "backend/alibaba"
"backend/feishu"
"backend/msg"
"backend/sdk/ship/model/base"
@@ -118,9 +119,9 @@ func Charge(c *gin.Context) {
return
}
AppInfo.ChannelOrderId = req.PlatformOrder
- err := AppInfo.ChangeOrderStatus("tuyou")
+ err := AppInfo.ChangeOrderStatus("tuyou", req.ProdPrice)
if err != nil {
- FeishuNotify(fmt.Sprintf("change order status error: %v", err))
+ alibaba.SendStandardMsg("途游充值发货错误-测试", err.Error(), "red")
log.Print("change order status error:", err)
c.JSON(500, gin.H{"error": "failed to change order status"})
return
diff --git a/unit_test.go b/unit_test.go
index fbc5e63..4214e00 100644
--- a/unit_test.go
+++ b/unit_test.go
@@ -7,7 +7,12 @@ import (
"backend/model"
"backend/sdk/ship/model/tuyou"
"backend/util"
+ "bytes"
+ "context"
+ "encoding/json"
"fmt"
+ "sort"
+ "strings"
"testing"
"time"
)
@@ -85,7 +90,7 @@ func TestLogin(t *testing.T) {
}
func TestEncrypt(t *testing.T) {
- str := "usSdkMysql*1133"
+ str := "3L1Ogjy4J8&EErK"
enc, _ := util.Encrypt(str)
fmt.Println(enc)
}
@@ -127,14 +132,15 @@ func TestAlibabaRobot(t *testing.T) {
}
func TestAlibabaCard(t *testing.T) {
- r := Type.NotifyData{
- NotifyMsg: "测试报警消息内容",
- Host: "测试主机",
- EventName: "测试事件名称",
- Severity: "High",
- AlarmTime: time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04:05"),
+ r := Type.OrderData{
+ UID: 106622,
+ OrderId: "e50b32601160423c7f",
+ Product: "0.99",
+ ProductName: "100钻石",
+ EventRecovery: "2026-01-15 18:22:12",
+ EventAge: "2026-01-15 18:22:15",
}
- err := alibaba.SendZabbixMsg(&r)
+ err := alibaba.SendOrderMsg(&r)
if err != nil {
fmt.Println("err:", err)
} else {
@@ -143,9 +149,88 @@ func TestAlibabaCard(t *testing.T) {
}
func TestServerUpdateApp(t *testing.T) {
-
+ log := model.Log{
+ AppId: 0,
+ Uid: 105372,
+ CurrentPage: 1,
+ PageSize: 20,
+ }
+ r, e := log.Order()
+ if e != nil {
+ fmt.Print(e)
+ }
+ fmt.Print(r)
}
func TestXxxx(t *testing.T) {
- util.SaveGitHead("src", "7d6a040cec2841c728fc798d720bac30c5084ceb")
+ ctx := context.Background()
+ client, _ := util.GetEsClient()
+ var buf bytes.Buffer
+ query := map[string]interface{}{
+ "query": map[string]interface{}{
+ "wildcard": map[string]interface{}{
+ "log_message": map[string]interface{}{
+ "value": "*set kv key 100*",
+ },
+ },
+ },
+ "size": 10000,
+ }
+ if err := json.NewEncoder(&buf).Encode(query); err != nil {
+ return
+ }
+ res, err := client.Search(
+ client.Search.WithContext(ctx),
+ client.Search.WithIndex(".ds-game-node-log*"),
+ client.Search.WithBody(&buf),
+ )
+ if err != nil {
+ fmt.Print(err)
+ }
+ defer res.Body.Close()
+
+ var result map[string]interface{}
+ if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
+ return
+ }
+ // player 106910 set kv key 48 value
+ hits := result["hits"].(map[string]interface{})["hits"].([]interface{})
+ tmap := make(map[string]int)
+ for _, hit := range hits {
+ source := hit.(map[string]interface{})["_source"]
+ log_message := source.(map[string]interface{})["log_message"]
+ fmt.Println(log_message)
+ a := strings.Split(log_message.(string), " ")[1]
+ tmap[a]++
+ }
+ // 将 map 转换为切片进行排序
+ type kv struct {
+ Key string
+ Value int
+ }
+ var sorted []kv
+ for k, v := range tmap {
+ sorted = append(sorted, kv{k, v})
+ }
+ // 按值降序排序
+ sort.Slice(sorted, func(i, j int) bool {
+ return sorted[i].Value > sorted[j].Value
+ })
+
+ for _, item := range sorted {
+ if item.Value < 100 {
+ //continue
+ }
+ fmt.Printf("msg type:%s, 次数:%d\n", item.Key, item.Value)
+ }
+}
+
+func TestEs2(t *testing.T) {
+ s := &model.Server{AppId: 2, ServerId: 1}
+ _, err := s.StartServer()
+ if err != nil {
+ fmt.Println("err:", err)
+ } else {
+ fmt.Println("服务器启动成功")
+ }
}
diff --git a/util/Mysql.go b/util/Mysql.go
index 5bb794e..67e6020 100644
--- a/util/Mysql.go
+++ b/util/Mysql.go
@@ -240,7 +240,7 @@ func GetServerConfig(AppId, ServerId int) (*Type.ServerInfo, error) {
Db := MPool.GetTopicDB("game")
defer Db.Close()
var server Type.ServerInfo
- err := Db.Get(&server, "SELECT `AppId`,`ServerId`,`Host`,`Status`,`ws_port` FROM server WHERE `AppId` = ? AND `ServerId` = ?", AppId, ServerId)
+ err := Db.Get(&server, "SELECT `AppId`,`ServerId`,`Host`,`Status`,`ws_port`,`ecs` FROM server WHERE `AppId` = ? AND `ServerId` = ?", AppId, ServerId)
if err != nil {
return nil, fmt.Errorf("failed to scan rows: %v", err)
}
diff --git a/util/es.go b/util/es.go
index d2a27c3..9f2acea 100644
--- a/util/es.go
+++ b/util/es.go
@@ -111,7 +111,7 @@ func TermSearch(ctx context.Context, index, field, value string, from, size int)
return DSlSearch(ctx, index, query, from, size, nil)
}
-func SearchAssetByUid(_uid int, from, size int, start, end int64) ([]*Type.AssetData, int64, error) {
+func SearchAssetByUid(app, _uid int, from, size int, start, end int64, itemid int, param string) ([]*Type.AssetData, int64, error) {
defer func() {
if r := recover(); r != nil {
log.Printf("SearchAssetByUid panic: %v", r)
@@ -119,30 +119,51 @@ func SearchAssetByUid(_uid int, from, size int, start, end int64) ([]*Type.Asset
}()
uid := Int(_uid)
ctx := context.Background()
- query := map[string]interface{}{
- "bool": map[string]interface{}{
- "must": []map[string]interface{}{
- {
- "term": map[string]interface{}{
- "game.#distinct_id.keyword": uid,
- },
- },
- {
- "term": map[string]interface{}{
- "game.#event_name": "asset_change",
- },
- },
- {
- "range": map[string]interface{}{
- "game.#timestamp": map[string]interface{}{
- "gte": start,
- "lte": end,
- },
- },
+ region := GetAppRegion(app)
+ mustCondition := []map[string]interface{}{
+ {
+ "term": map[string]interface{}{
+ "game.#distinct_id": uid,
+ },
+ },
+ {
+ "term": map[string]interface{}{
+ "fields.region": region,
+ },
+ },
+ {
+ "term": map[string]interface{}{
+ "game.#event_name": "asset_change",
+ },
+ },
+ {
+ "range": map[string]interface{}{
+ "game.#timestamp": map[string]interface{}{
+ "gte": start,
+ "lte": end,
},
},
},
}
+ if itemid != 0 {
+ mustCondition = append(mustCondition, map[string]interface{}{
+ "term": map[string]interface{}{
+ "game.properties.item_id": itemid,
+ },
+ })
+ }
+ if param != "" {
+ mustCondition = append(mustCondition, map[string]interface{}{
+ "match": map[string]interface{}{
+ "game.properties.change_type": param,
+ },
+ })
+ }
+ query := map[string]interface{}{
+ "bool": map[string]interface{}{
+ "must": mustCondition,
+ },
+ }
// 添加降序排序
sort := []map[string]interface{}{
@@ -153,7 +174,7 @@ func SearchAssetByUid(_uid int, from, size int, start, end int64) ([]*Type.Asset
},
}
- result, err := DSlSearch(ctx, "game-user-log", query, from, size, sort)
+ result, err := DSlSearch(ctx, "game-user-log*", query, from, size, sort)
if err != nil {
return nil, 0, err
}
@@ -185,7 +206,7 @@ func SearchAssetByUid(_uid int, from, size int, start, end int64) ([]*Type.Asset
return assets, total, nil
}
-func SearchEventByUid(_uid int, from, size int, start, end int64) ([]*Type.EventData, int64, error) {
+func SearchEventByUid(app, _uid int, from, size int, start, end int64, event_name string) ([]*Type.EventData, int64, error) {
defer func() {
if r := recover(); r != nil {
log.Println("Recovered in SearchEventByUid", r)
@@ -193,23 +214,39 @@ func SearchEventByUid(_uid int, from, size int, start, end int64) ([]*Type.Event
}()
uid := Int(_uid)
ctx := context.Background()
- query := map[string]interface{}{
- "bool": map[string]interface{}{
- "must": []map[string]interface{}{
- {
- "term": map[string]interface{}{
- "game.#distinct_id.keyword": uid,
- },
- },
- {
- "range": map[string]interface{}{
- "game.#timestamp": map[string]interface{}{
- "gte": start,
- "lte": end,
- },
- },
+ region := GetAppRegion(app)
+ mustConditions := []map[string]interface{}{
+ {
+ "term": map[string]interface{}{
+ "game.#distinct_id": uid,
+ },
+ },
+ {
+ "term": map[string]interface{}{
+ "fields.region": region,
+ },
+ },
+ {
+ "range": map[string]interface{}{
+ "game.#timestamp": map[string]interface{}{
+ "gte": start,
+ "lte": end,
},
},
+ },
+ }
+
+ if event_name != "" {
+ mustConditions = append(mustConditions, map[string]interface{}{
+ "term": map[string]interface{}{
+ "game.#event_name": event_name,
+ },
+ })
+ }
+
+ query := map[string]interface{}{
+ "bool": map[string]interface{}{
+ "must": mustConditions,
"must_not": []map[string]interface{}{
{
"term": map[string]interface{}{
@@ -229,7 +266,7 @@ func SearchEventByUid(_uid int, from, size int, start, end int64) ([]*Type.Event
},
}
- result, err := DSlSearch(ctx, "game-user-log", query, from, size, sort)
+ result, err := DSlSearch(ctx, "game-user-log*", query, from, size, sort)
if err != nil {
return nil, 0, err
}
@@ -291,7 +328,7 @@ func CountDistinctUidLastHour() (int64, int64, error) {
"must": []map[string]interface{}{
{
"term": map[string]interface{}{
- "fields.region.keyword": "us-newyork",
+ "fields.region": "us-newyork",
},
},
},
@@ -316,7 +353,6 @@ func CountDistinctUidLastHour() (int64, int64, error) {
"minimum_should_match": 1,
},
},
- "size": 0,
"from": 0,
"aggs": map[string]interface{}{
"current_hour": map[string]interface{}{
@@ -331,7 +367,7 @@ func CountDistinctUidLastHour() (int64, int64, error) {
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
- "field": "game.#distinct_id.keyword",
+ "field": "game.#distinct_id",
},
},
},
@@ -348,7 +384,7 @@ func CountDistinctUidLastHour() (int64, int64, error) {
"aggs": map[string]interface{}{
"unique_users": map[string]interface{}{
"cardinality": map[string]interface{}{
- "field": "game.#distinct_id.keyword",
+ "field": "game.#distinct_id",
},
},
},
@@ -360,10 +396,9 @@ func CountDistinctUidLastHour() (int64, int64, error) {
if err := json.NewEncoder(&buf).Encode(query); err != nil {
return 0, 0, fmt.Errorf("编码查询失败: %w", err)
}
-
res, err := client.Search(
client.Search.WithContext(ctx),
- client.Search.WithIndex("game-user-log"),
+ client.Search.WithIndex("game-user-log*"),
client.Search.WithBody(&buf),
)
if err != nil {
@@ -508,7 +543,7 @@ func CountDistinctUidLastHourTest() interface{} {
res, err := client.Search(
client.Search.WithContext(ctx),
- client.Search.WithIndex("game-user-log"),
+ client.Search.WithIndex(".ds-game-user-log*"),
client.Search.WithBody(&buf),
client.Search.WithTrackTotalHits(true),
)
diff --git a/util/login.go b/util/login.go
index d16b5d0..176620f 100644
--- a/util/login.go
+++ b/util/login.go
@@ -23,6 +23,7 @@ type ServerConfig struct {
Ecs int `db:"ecs"`
Name string `db:"ServerName"`
AppId int `db:"AppId"`
+ NodeType int `db:"node_type"`
}
var serverList map[int][]ServerConfig
@@ -202,7 +203,7 @@ func GetServer(AppId, ServerId int) ServerConfig {
Db := MPool.GetGameDB()
defer Db.Close()
var server ServerConfig
- err := Db.Get(&server, "SELECT ServerId, Status, Host, Port, MaxOnline, Online, version, ecs, work_dir FROM server WHERE AppId = ? AND ServerId = ?", AppId, ServerId)
+ err := Db.Get(&server, "SELECT ServerId, ServerName, Status, Host, Port, MaxOnline, Online, version, ecs, work_dir, node_type FROM server WHERE AppId = ? AND ServerId = ?", AppId, ServerId)
if err != nil {
return ServerConfig{}
}
@@ -271,3 +272,22 @@ func _initServerList() {
}
serverList = tempServerList
}
+
+func GetAllServersByAppId(appid int) []ServerConfig {
+ Db := MPool.GetGameDB()
+ defer Db.Close()
+ rows, err := Db.Query("SELECT ServerId, ServerName, Status, Host, Port, MaxOnline, Online, version, ecs, work_dir, node_type FROM server WHERE AppId = ? ORDER BY ServerId", appid)
+ if err != nil {
+ return nil
+ }
+ defer rows.Close()
+ var servers []ServerConfig
+ for rows.Next() {
+ var server ServerConfig
+ if err := rows.Scan(&server.ServerId, &server.Name, &server.Status, &server.Host, &server.Port, &server.MaxOnline, &server.Online, &server.Version, &server.Ecs, &server.WorkDir, &server.NodeType); err != nil {
+ continue
+ }
+ servers = append(servers, server)
+ }
+ return servers
+}
diff --git a/util/ssh.go b/util/ssh.go
index 4293a15..e7fb09c 100644
--- a/util/ssh.go
+++ b/util/ssh.go
@@ -69,8 +69,9 @@ func (s *SshClient) RunCommand(cmd string) (string, error) {
defer session.Close()
output, err := session.CombinedOutput(cmd)
+ // 即使命令失败也返回输出,这样可以看到错误信息
if err != nil {
- return "", err
+ return string(output), err
}
return string(output), nil
diff --git a/util/util.go b/util/util.go
index 68ed6ba..19194f4 100644
--- a/util/util.go
+++ b/util/util.go
@@ -24,7 +24,7 @@ import (
"time"
"github.com/gin-gonic/gin"
- "golang.org/x/net/websocket"
+ "github.com/gorilla/websocket"
"google.golang.org/protobuf/proto"
)
@@ -117,10 +117,16 @@ func PackMsg(m proto.Message) []byte {
}
func UnpackMsg(buf []byte, n int) (string, error) {
+ // 检查数据长度
+ if n < 2 {
+ return "", fmt.Errorf("message too short: got %d bytes, need at least 2", n)
+ }
res := &msg.AdminRes{}
err := proto.Unmarshal(buf[2:n], res)
if err != nil {
- return "", err
+ // 记录更详细的错误信息
+ log.Printf("UnpackMsg error: %v, data length: %d, hex: %x", err, n-2, buf[2:n])
+ return "", fmt.Errorf("proto unmarshal error: %v", err)
}
return res.Info, nil
}
@@ -215,20 +221,22 @@ func NowFormat() string {
func SendAdminMsg(ws *websocket.Conn, req proto.Message) (map[string]interface{}, error) {
reqBuf := PackMsg(req)
- _, err := ws.Write(reqBuf)
+ err := ws.WriteMessage(websocket.BinaryMessage, reqBuf)
if err != nil {
return nil, fmt.Errorf("failed to write to websocket: %v", err)
}
- readbuf := make([]byte, 4096)
- n, err := ws.Read(readbuf)
+ _, readbuf, err := ws.ReadMessage()
if err != nil {
return nil, fmt.Errorf("failed to read from websocket: %v", err)
}
+ n := len(readbuf)
+
resBuf, err := UnpackMsg(readbuf, n)
if err != nil {
return nil, fmt.Errorf("failed to unpack message: %v", err)
}
+
r := make(map[string]interface{})
err = json.Unmarshal([]byte(resBuf), &r)
if err != nil {
@@ -699,3 +707,25 @@ func ParseNodeTags(tags string) []string {
}
return strings.Split(tags, ",")
}
+
+func GetAppName(AppId int) string {
+ switch AppId {
+ case 0:
+ return "正式服"
+ case 1:
+ return "测试服"
+ case 2:
+ return "QA服"
+ default:
+ return "未知服"
+ }
+}
+
+func GetAppRegion(AppId int) string {
+ switch AppId {
+ case 0:
+ return "us-newyork"
+ default:
+ return "cn-shanghai"
+ }
+}
diff --git a/util/websocket.go b/util/websocket.go
index 8309157..6523583 100644
--- a/util/websocket.go
+++ b/util/websocket.go
@@ -2,29 +2,35 @@ package util
import (
"fmt"
- "net"
+ "net/http"
"time"
- "golang.org/x/net/websocket"
+ "github.com/gorilla/websocket"
)
func GetWebsocket(AppId, ServerId int) (*websocket.Conn, error) {
- ServerConfig, _ := GetServerConfig(AppId, ServerId)
- origin := "http://localhost/"
- if AppId == 0 {
- ServerConfig.Host = "google.bywaystudios.com"
- }
- url := fmt.Sprintf("ws://%s:%d/", ServerConfig.Host, ServerConfig.WsPort)
-
- config, err := websocket.NewConfig(url, origin)
+ ServerConfig, err := GetServerConfig(AppId, ServerId)
if err != nil {
- return nil, fmt.Errorf("failed to create websocket config: %v", err)
+ return nil, fmt.Errorf("failed to get server config: %v", err)
}
- config.Dialer = &net.Dialer{
- Timeout: 5 * time.Second,
+ if ServerConfig == nil {
+ return nil, fmt.Errorf("server config not found for AppId %d and ServerId %d", AppId, ServerId)
}
- ws, err := websocket.DialConfig(config)
+ // if AppId == 0 {
+ // ServerConfig.Host = "google.bywaystudios.com"
+ // }
+ nodeConfig := GetNodeById(ServerConfig.ECS)
+ url := fmt.Sprintf("ws://%s:%d/", nodeConfig.Host, ServerConfig.WsPort)
+
+ dialer := &websocket.Dialer{
+ HandshakeTimeout: 5 * time.Second,
+ }
+
+ header := http.Header{}
+ header.Set("Origin", "http://localhost/")
+
+ ws, _, err := dialer.Dial(url, header)
if err != nil {
return nil, fmt.Errorf("failed to connect to websocket: %v", err)
}