temp commit
This commit is contained in:
		
							parent
							
								
									f5bf3b9c77
								
							
						
					
					
						commit
						166812abf4
					
				
							
								
								
									
										57
									
								
								admin/apps/game/domain/gamelog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								admin/apps/game/domain/gamelog.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					package domain
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"admin/apps/game/domain/projects"
 | 
				
			||||||
 | 
						"admin/apps/game/domain/repo"
 | 
				
			||||||
 | 
						"admin/internal/consts"
 | 
				
			||||||
 | 
						"admin/internal/errcode"
 | 
				
			||||||
 | 
						"admin/internal/model/dto"
 | 
				
			||||||
 | 
						"admin/lib/xlog"
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
 | 
				
			||||||
 | 
						"github.com/jmoiron/sqlx"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GameLogService struct {
 | 
				
			||||||
 | 
						projectRepo repo.IProjectRepo
 | 
				
			||||||
 | 
						repo        repo.IGameLogRepo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewGameLogSvc(db *gorm.DB, metaDb *gorm.DB, ckDb driver.Conn, clickHouseSqlx *sqlx.DB) *GameLogService {
 | 
				
			||||||
 | 
						return &GameLogService{projectRepo: repo.NewProjectRepo(db), repo: repo.NewGameLogRepo(metaDb, ckDb, clickHouseSqlx)}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (svc *GameLogService) QueryEventList(projectId, appId int, eventName []string, serverId int, account, roleId string,
 | 
				
			||||||
 | 
						pageNo, pageLen int, dateStart, dateEnd time.Time) (totalCount int, fieldsDescInfo []*dto.GameLogFieldInfo, rows [][]any, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, projectEt, find, err := svc.projectRepo.GetById(projectId)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, nil, nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if !find {
 | 
				
			||||||
 | 
							return 0, nil, nil, errcode.New(errcode.ServerError, "not found project %v db data", projectId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var attrList []*repo.AttrInfo
 | 
				
			||||||
 | 
						attrList, err = svc.repo.QueryAttrListByEvent(appId, eventName)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						querier := svc.repo.NewEventListQuerier("xwl_event41", eventName, attrList)
 | 
				
			||||||
 | 
						totalCount, fieldsDescInfo, rows, err = querier.CondRoleId(serverId, roleId).CondAccount(serverId, account).
 | 
				
			||||||
 | 
							Go(context.Background(), pageNo, pageLen, dateStart, dateEnd)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							xlog.Warnf("event list error:%v", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						hook := projects.GetProjectResourceHook(projectEt, consts.ResourcesName_GameLog)
 | 
				
			||||||
 | 
						if h, ok := hook.(projects.IGameLogEventListHook); ok {
 | 
				
			||||||
 | 
							totalCount, fieldsDescInfo, rows = h.Trim(projectEt, eventName, totalCount, fieldsDescInfo, rows)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -44,3 +44,8 @@ type IGetAllValueChoiceHook interface {
 | 
				
			|||||||
type IServerInfoHook interface {
 | 
					type IServerInfoHook interface {
 | 
				
			||||||
	IsServerDownStatus(projectInfo *entity.Project, serverInfo *model.Server) bool
 | 
						IsServerDownStatus(projectInfo *entity.Project, serverInfo *model.Server) bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IGameLogEventListHook interface {
 | 
				
			||||||
 | 
						Trim(projectInfo *entity.Project, eventName []string, totalCount int, fieldsDescInfo []*dto2.GameLogFieldInfo, rows [][]any) (
 | 
				
			||||||
 | 
							int, []*dto2.GameLogFieldInfo, [][]any)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -21,6 +21,7 @@ var projectsResourceHookMgr = map[string]map[string]any{
 | 
				
			|||||||
		consts.ResourcesName_MailRole:   &smdl.MailRoleHook{},   // 所有角色走神魔大陆api直接获取
 | 
							consts.ResourcesName_MailRole:   &smdl.MailRoleHook{},   // 所有角色走神魔大陆api直接获取
 | 
				
			||||||
		consts.ResourcesName_WhiteList:  &smdl.WhitelistHook{},  // 所有角色走神魔大陆api直接获取
 | 
							consts.ResourcesName_WhiteList:  &smdl.WhitelistHook{},  // 所有角色走神魔大陆api直接获取
 | 
				
			||||||
		consts.ResourcesName_GenAccount: &smdl.GenAccountHook{}, // 所有角色走神魔大陆api直接获取
 | 
							consts.ResourcesName_GenAccount: &smdl.GenAccountHook{}, // 所有角色走神魔大陆api直接获取
 | 
				
			||||||
 | 
							consts.ResourcesName_GameLog:    &smdl.GameLogHook{},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -100,15 +100,16 @@ func (hook *AccountHook) List(projectInfo *entity.Project, resource string, para
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AccountDetailOrderInfo struct {
 | 
					type AccountDetailOrderInfo struct {
 | 
				
			||||||
	ServerId     string `json:"server_id"`
 | 
						ServerId         string `json:"server_id"`
 | 
				
			||||||
	AccountId    string `json:"account_id"`
 | 
						AccountId        string `json:"account_id"`
 | 
				
			||||||
	RoleId       string `json:"role_id"`
 | 
						RoleId           string `json:"role_id"`
 | 
				
			||||||
	RoleName     string `json:"role_name"`
 | 
						RoleName         string `json:"role_name"`
 | 
				
			||||||
	Sn           string `json:"sn"`
 | 
						Sn               string `json:"sn"`
 | 
				
			||||||
	ProductId    string `json:"product_id"`
 | 
						ProductId        string `json:"product_id"`
 | 
				
			||||||
	Price        int    `json:"price"`
 | 
						Price            int    `json:"price"`
 | 
				
			||||||
	PurchaseType string `json:"purchase_type"`
 | 
						PurchaseType     string `json:"purchase_type"`
 | 
				
			||||||
	PurchaseAt   int64  `json:"purchase_at"`
 | 
						PurchasePlatform string `json:"purchasePlatform"`
 | 
				
			||||||
 | 
						PurchaseAt       int64  `json:"purchase_at"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (info *AccountDetailOrderInfo) toDto() *dto2.AccountDetailOrderInfo {
 | 
					func (info *AccountDetailOrderInfo) toDto() *dto2.AccountDetailOrderInfo {
 | 
				
			||||||
@ -120,7 +121,7 @@ func (info *AccountDetailOrderInfo) toDto() *dto2.AccountDetailOrderInfo {
 | 
				
			|||||||
		Sn:           info.Sn,
 | 
							Sn:           info.Sn,
 | 
				
			||||||
		ProductId:    info.ProductId,
 | 
							ProductId:    info.ProductId,
 | 
				
			||||||
		Price:        info.Price,
 | 
							Price:        info.Price,
 | 
				
			||||||
		PurchaseType: info.PurchaseType,
 | 
							PurchaseType: info.PurchasePlatform,
 | 
				
			||||||
		PurchaseAt:   utils.ParseUnixTimestamp2LocalTime(info.PurchaseAt).Format(time.DateTime),
 | 
							PurchaseAt:   utils.ParseUnixTimestamp2LocalTime(info.PurchaseAt).Format(time.DateTime),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -149,6 +150,7 @@ func (info *AccountDetailRoleInfo) toDto() *dto2.AccountDetailRoleInfo {
 | 
				
			|||||||
		CurrencyItems: info.CurrencyItems,
 | 
							CurrencyItems: info.CurrencyItems,
 | 
				
			||||||
		CreatedAt:     utils.ParseUnixTimestamp2LocalTime(info.CreatedAt).Format(time.DateTime),
 | 
							CreatedAt:     utils.ParseUnixTimestamp2LocalTime(info.CreatedAt).Format(time.DateTime),
 | 
				
			||||||
		LastLoginTime: utils.ParseUnixTimestamp2LocalTime(info.LastLoginTime).Format(time.DateTime),
 | 
							LastLoginTime: utils.ParseUnixTimestamp2LocalTime(info.LastLoginTime).Format(time.DateTime),
 | 
				
			||||||
 | 
							OrderList:     make([]*dto2.AccountDetailOrderInfo, 0),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	totalPayAmount := 0
 | 
						totalPayAmount := 0
 | 
				
			||||||
	for _, order := range info.OrderList {
 | 
						for _, order := range info.OrderList {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										110
									
								
								admin/apps/game/domain/projects/smdl/gamelog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								admin/apps/game/domain/projects/smdl/gamelog.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
				
			|||||||
 | 
					package smdl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"admin/apps/game/domain/entity"
 | 
				
			||||||
 | 
						dto2 "admin/internal/model/dto"
 | 
				
			||||||
 | 
						"admin/lib/xlog"
 | 
				
			||||||
 | 
						"encoding/base64"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GameLogHook struct {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var removeFields = map[string]struct{}{
 | 
				
			||||||
 | 
						"pub_mediaid":   {},
 | 
				
			||||||
 | 
						"pub_role_name": {},
 | 
				
			||||||
 | 
						"pub_udid":      {},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var alias = map[string]string{
 | 
				
			||||||
 | 
						"pub_viplev":    "vip等级",
 | 
				
			||||||
 | 
						"pub_userid":    "账号",
 | 
				
			||||||
 | 
						"pub_totalcash": "总充值金额",
 | 
				
			||||||
 | 
						"pub_serverid":  "服务器id",
 | 
				
			||||||
 | 
						"pub_rolename":  "角色名",
 | 
				
			||||||
 | 
						"pub_roleid":    "角色id",
 | 
				
			||||||
 | 
						"pub_lev":       "等级",
 | 
				
			||||||
 | 
						"pub_language":  "语言",
 | 
				
			||||||
 | 
						"pub_ip":        "IP",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var base64decodeFields = map[string]struct{}{
 | 
				
			||||||
 | 
						"pub_rolename": {},
 | 
				
			||||||
 | 
						"chatlog_msg":  {},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						for i := 0; i < 15; i++ {
 | 
				
			||||||
 | 
							removeFields["chatlog_score"] = struct{}{}
 | 
				
			||||||
 | 
							removeFields["chatlog_score"+strconv.Itoa(i)] = struct{}{}
 | 
				
			||||||
 | 
							removeFields["chatlog_label"] = struct{}{}
 | 
				
			||||||
 | 
							removeFields["chatlog_label"+strconv.Itoa(i)] = struct{}{}
 | 
				
			||||||
 | 
							removeFields["chatlog_checklevel"] = struct{}{}
 | 
				
			||||||
 | 
							removeFields["chatlog_checklevel"+strconv.Itoa(i)] = struct{}{}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						removeFields["chatlog_code"] = struct{}{}
 | 
				
			||||||
 | 
						removeFields["chatlog_checkresult"] = struct{}{}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (hook *GameLogHook) Trim(projectInfo *entity.Project, eventName []string, totalCount int, fieldsDescInfo []*dto2.GameLogFieldInfo, rows [][]any) (
 | 
				
			||||||
 | 
						int, []*dto2.GameLogFieldInfo, [][]any) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 删除不需要的字段
 | 
				
			||||||
 | 
						i := 0
 | 
				
			||||||
 | 
						for {
 | 
				
			||||||
 | 
							if i >= len(fieldsDescInfo) {
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							field := fieldsDescInfo[i]
 | 
				
			||||||
 | 
							if _, find := removeFields[field.Name]; find {
 | 
				
			||||||
 | 
								// 找到这个字段在去掉的列表里
 | 
				
			||||||
 | 
								fieldsDescInfo = append(fieldsDescInfo[:i], fieldsDescInfo[i+1:]...)
 | 
				
			||||||
 | 
								// 对应所有数据行里也删除这个值
 | 
				
			||||||
 | 
								for _, row := range rows {
 | 
				
			||||||
 | 
									row = append(row[:i], row[i+1:]...)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								// 查找要不要把value做base64解码
 | 
				
			||||||
 | 
								if _, find := base64decodeFields[field.Name]; find {
 | 
				
			||||||
 | 
									for _, row := range rows {
 | 
				
			||||||
 | 
										newValue, err := base64.StdEncoding.DecodeString((*(row[i].(*interface{}))).(string))
 | 
				
			||||||
 | 
										if err != nil {
 | 
				
			||||||
 | 
											xlog.Warnf("base64 decode field:%v value:%v error:%v", field.Name, row[i], err)
 | 
				
			||||||
 | 
										} else {
 | 
				
			||||||
 | 
											row[i] = string(newValue)
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								i++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 查找别名
 | 
				
			||||||
 | 
						for _, en := range eventName {
 | 
				
			||||||
 | 
							// 查找全局eventName描述表信息,对里面没有别的字段名改为表里的名字
 | 
				
			||||||
 | 
							descInfo, find := globEventList[en]
 | 
				
			||||||
 | 
							if find {
 | 
				
			||||||
 | 
								for _, f := range fieldsDescInfo {
 | 
				
			||||||
 | 
									find := false
 | 
				
			||||||
 | 
									for _, f1 := range descInfo.fields {
 | 
				
			||||||
 | 
										if f.Name == f1.Name && f1.Alias != "" {
 | 
				
			||||||
 | 
											if f.Name == f.Alias {
 | 
				
			||||||
 | 
												f.Alias = f1.Alias
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											find = true
 | 
				
			||||||
 | 
											break
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if !find {
 | 
				
			||||||
 | 
										aliasName, find1 := alias[f.Name]
 | 
				
			||||||
 | 
										if find1 && f.Name == f.Alias && f.Alias != "" {
 | 
				
			||||||
 | 
											f.Alias = aliasName
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return totalCount, fieldsDescInfo, rows
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										52
									
								
								admin/apps/game/domain/projects/smdl/gamelog_desc.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								admin/apps/game/domain/projects/smdl/gamelog_desc.go
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										134
									
								
								admin/apps/game/domain/repo/gamelog.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								admin/apps/game/domain/repo/gamelog.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,134 @@
 | 
				
			|||||||
 | 
					package repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"admin/apps/game/model"
 | 
				
			||||||
 | 
						"admin/internal/errcode"
 | 
				
			||||||
 | 
						"admin/lib/utils"
 | 
				
			||||||
 | 
						"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
 | 
				
			||||||
 | 
						"github.com/jmoiron/sqlx"
 | 
				
			||||||
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type IGameLogRepo interface {
 | 
				
			||||||
 | 
						QueryAttrListByEvent(appId int, eventName []string) ([]*AttrInfo, error)
 | 
				
			||||||
 | 
						NewEventListQuerier(tableName string, eventName []string, attrList []*AttrInfo) *EventListQuerier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewGameLogRepo(metaDb *gorm.DB, ckDb driver.Conn, clickHouseSqlx *sqlx.DB) IGameLogRepo {
 | 
				
			||||||
 | 
						return &gameLogRepoImpl{metaDb: metaDb, db: ckDb, clickHouseSqlx: clickHouseSqlx}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type gameLogRepoImpl struct {
 | 
				
			||||||
 | 
						metaDb         *gorm.DB
 | 
				
			||||||
 | 
						db             driver.Conn
 | 
				
			||||||
 | 
						clickHouseSqlx *sqlx.DB
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GetEventAttrResult struct {
 | 
				
			||||||
 | 
						AppId             int
 | 
				
			||||||
 | 
						EventName         string
 | 
				
			||||||
 | 
						EventAlias        string
 | 
				
			||||||
 | 
						AttrName          string
 | 
				
			||||||
 | 
						AttrAlias         string
 | 
				
			||||||
 | 
						AttrFieldType     int
 | 
				
			||||||
 | 
						AttrIsPublicField int
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (impl *gameLogRepoImpl) QueryAttrListByEvent(appId int, eventName []string) ([]*AttrInfo, error) {
 | 
				
			||||||
 | 
						resultList := make([]*GetEventAttrResult, 0)
 | 
				
			||||||
 | 
						err := impl.metaDb.Model(&model.EventAttribute{}).Select("meta_attr_relation.app_id,"+
 | 
				
			||||||
 | 
							"meta_event.event_name as event_name,"+
 | 
				
			||||||
 | 
							"meta_event.show_name as event_alias,"+
 | 
				
			||||||
 | 
							"attribute.attribute_name as attr_name,"+
 | 
				
			||||||
 | 
							"attribute.show_name as attr_alias,"+
 | 
				
			||||||
 | 
							"attribute.data_type as attr_field_type,"+
 | 
				
			||||||
 | 
							"attribute.attribute_type as attr_is_public_field",
 | 
				
			||||||
 | 
						).
 | 
				
			||||||
 | 
							Joins("inner join meta_event on "+
 | 
				
			||||||
 | 
								"meta_event.event_name=meta_attr_relation.event_name and "+
 | 
				
			||||||
 | 
								"meta_event.appid=? and meta_attr_relation.app_id=?", appId, appId).
 | 
				
			||||||
 | 
							Joins("inner join attribute on "+
 | 
				
			||||||
 | 
								"attribute.attribute_name=meta_attr_relation.event_attr and "+
 | 
				
			||||||
 | 
								"attribute.app_id=?", appId).
 | 
				
			||||||
 | 
							Scan(&resultList).Error
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errcode.New(errcode.DBError, "join tables get event list error:%v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						attrList := make([]*AttrInfo, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var timeAttr *AttrInfo
 | 
				
			||||||
 | 
						for _, attr := range resultList {
 | 
				
			||||||
 | 
							if len(eventName) == 0 || utils.IsInSlice(eventName, attr.EventName) {
 | 
				
			||||||
 | 
								if len(attr.AttrName) >= 4 && attr.AttrName[:4] == "xwl_" {
 | 
				
			||||||
 | 
									if attr.AttrName != "xwl_part_date" {
 | 
				
			||||||
 | 
										continue
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									timeAttr = &AttrInfo{
 | 
				
			||||||
 | 
										Name:       attr.AttrName,
 | 
				
			||||||
 | 
										Alias:      "时间",
 | 
				
			||||||
 | 
										DataType:   attr.AttrFieldType,
 | 
				
			||||||
 | 
										IsUserAttr: attr.AttrIsPublicField != 2,
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									continue
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								attrList = append(attrList, &AttrInfo{
 | 
				
			||||||
 | 
									Name:       attr.AttrName,
 | 
				
			||||||
 | 
									Alias:      attr.AttrAlias,
 | 
				
			||||||
 | 
									DataType:   attr.AttrFieldType,
 | 
				
			||||||
 | 
									IsUserAttr: attr.AttrIsPublicField != 2,
 | 
				
			||||||
 | 
								})
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sort.SliceStable(attrList, func(i, j int) bool {
 | 
				
			||||||
 | 
							if attrList[i].IsUserAttr && !attrList[j].IsUserAttr {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if attrList[i].IsUserAttr && attrList[j].IsUserAttr {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if attrList[i].IsUserAttr && attrList[j].IsUserAttr {
 | 
				
			||||||
 | 
								return false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if timeAttr != nil {
 | 
				
			||||||
 | 
							attrList = append([]*AttrInfo{timeAttr}, attrList...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//retList := make(map[string][]*AttrInfo)
 | 
				
			||||||
 | 
						//for _, attr := range resultList {
 | 
				
			||||||
 | 
						//	attrList, find := retList[attr.EventName]
 | 
				
			||||||
 | 
						//	if !find {
 | 
				
			||||||
 | 
						//		attrList = make([]*AttrInfo, 0, 1)
 | 
				
			||||||
 | 
						//	}
 | 
				
			||||||
 | 
						//	attrList = append(attrList, &AttrInfo{
 | 
				
			||||||
 | 
						//		Name:       attr.AttrName,
 | 
				
			||||||
 | 
						//		Alias:      attr.AttrAlias,
 | 
				
			||||||
 | 
						//		DataType:   attr.AttrFieldType,
 | 
				
			||||||
 | 
						//		IsUserAttr: attr.AttrIsPublicField != 2,
 | 
				
			||||||
 | 
						//	})
 | 
				
			||||||
 | 
						//	retList[attr.EventName] = attrList
 | 
				
			||||||
 | 
						//}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return attrList, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AttrInfo struct {
 | 
				
			||||||
 | 
						Name       string
 | 
				
			||||||
 | 
						Alias      string
 | 
				
			||||||
 | 
						DataType   int // 1:number 3:string 4:time
 | 
				
			||||||
 | 
						IsUserAttr bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (impl *gameLogRepoImpl) NewEventListQuerier(tableName string, eventName []string, attrList []*AttrInfo) *EventListQuerier {
 | 
				
			||||||
 | 
						querier := new(EventListQuerier)
 | 
				
			||||||
 | 
						querier.db = impl.db
 | 
				
			||||||
 | 
						querier.clickHouseSqlx = impl.clickHouseSqlx
 | 
				
			||||||
 | 
						querier.tableName = tableName
 | 
				
			||||||
 | 
						querier.eventName = eventName
 | 
				
			||||||
 | 
						querier.attrList = attrList
 | 
				
			||||||
 | 
						return querier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										200
									
								
								admin/apps/game/domain/repo/gamelog_querier.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										200
									
								
								admin/apps/game/domain/repo/gamelog_querier.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,200 @@
 | 
				
			|||||||
 | 
					package repo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"admin/internal/errcode"
 | 
				
			||||||
 | 
						"admin/internal/model/dto"
 | 
				
			||||||
 | 
						"admin/lib/xlog"
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
 | 
				
			||||||
 | 
						"github.com/jmoiron/sqlx"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EventListQuerier struct {
 | 
				
			||||||
 | 
						db             driver.Conn
 | 
				
			||||||
 | 
						clickHouseSqlx *sqlx.DB
 | 
				
			||||||
 | 
						tableName      string
 | 
				
			||||||
 | 
						eventName      []string
 | 
				
			||||||
 | 
						attrList       []*AttrInfo
 | 
				
			||||||
 | 
						serverId       int
 | 
				
			||||||
 | 
						roleId         string
 | 
				
			||||||
 | 
						account        string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CondRoleId 添加角色信息查询条件
 | 
				
			||||||
 | 
					func (querier *EventListQuerier) CondRoleId(serverId int, roleId string) *EventListQuerier {
 | 
				
			||||||
 | 
						querier.serverId = serverId
 | 
				
			||||||
 | 
						querier.roleId = roleId
 | 
				
			||||||
 | 
						return querier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (querier *EventListQuerier) CondAccount(serverId int, account string) *EventListQuerier {
 | 
				
			||||||
 | 
						querier.serverId = serverId
 | 
				
			||||||
 | 
						querier.account = account
 | 
				
			||||||
 | 
						return querier
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const (
 | 
				
			||||||
 | 
						TypeUnknown = iota
 | 
				
			||||||
 | 
						Int
 | 
				
			||||||
 | 
						Float
 | 
				
			||||||
 | 
						String
 | 
				
			||||||
 | 
						DateTime
 | 
				
			||||||
 | 
						ElasticDateTime
 | 
				
			||||||
 | 
						IntArray
 | 
				
			||||||
 | 
						FloatArray
 | 
				
			||||||
 | 
						StringArray
 | 
				
			||||||
 | 
						DateTimeArray
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (querier *EventListQuerier) Go(ctx context.Context, pageNo int, pageLen int, dateStart, dateEnd time.Time) (
 | 
				
			||||||
 | 
						totalCount int, fieldsDescInfo []*dto.GameLogFieldInfo, rows [][]any, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 生成sql
 | 
				
			||||||
 | 
						sql, countSql, sqlArgs := querier.genSql(querier.tableName, pageNo, pageLen, dateStart, dateEnd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 查询总数量和数据
 | 
				
			||||||
 | 
						totalCount, fieldsDescInfo, rows, err = querier.query(sql, countSql, sqlArgs)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (querier *EventListQuerier) genSql(tableName string, pageNo int, pageLen int, dateStart, dateEnd time.Time) (
 | 
				
			||||||
 | 
						string, string, []any) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						querier.tableName = tableName
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sql := "select "
 | 
				
			||||||
 | 
						countSql := "select count(1) "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cols := make([]string, 0, len(querier.attrList))
 | 
				
			||||||
 | 
						for _, attr := range querier.attrList {
 | 
				
			||||||
 | 
							cols = append(cols, attr.Name)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						sql += strings.Join(cols, ",")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sql += " from " + querier.tableName + " where "
 | 
				
			||||||
 | 
						countSql += " from " + querier.tableName + " where "
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						whereList := make([]string, 0)
 | 
				
			||||||
 | 
						whereArgs := make([]any, 0)
 | 
				
			||||||
 | 
						if len(querier.eventName) != 0 {
 | 
				
			||||||
 | 
							eventNameWhereSql := make([]string, 0, len(querier.eventName))
 | 
				
			||||||
 | 
							for _, v := range querier.eventName {
 | 
				
			||||||
 | 
								eventNameWhereSql = append(eventNameWhereSql, "`xwl_part_event`=?")
 | 
				
			||||||
 | 
								whereArgs = append(whereArgs, v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							whereList = append(whereList, "("+strings.Join(eventNameWhereSql, " or ")+")")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if querier.serverId != 0 {
 | 
				
			||||||
 | 
							whereList = append(whereList, "`pub_serverid`=?")
 | 
				
			||||||
 | 
							whereArgs = append(whereArgs, querier.serverId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if querier.roleId != "" {
 | 
				
			||||||
 | 
							whereList = append(whereList, "`xwl_distinct_id`=?")
 | 
				
			||||||
 | 
							whereArgs = append(whereArgs, strconv.Itoa(querier.serverId)+"-"+querier.roleId)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if querier.account != "" {
 | 
				
			||||||
 | 
							whereList = append(whereList, "`pub_userid`=?")
 | 
				
			||||||
 | 
							whereArgs = append(whereArgs, querier.account)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						whereList = append(whereList, "xwl_part_date >= toDateTime(?)")
 | 
				
			||||||
 | 
						whereList = append(whereList, "xwl_part_date <= toDateTime(?)")
 | 
				
			||||||
 | 
						whereArgs = append(whereArgs, dateStart.Format("2006-01-02 15:04:05"))
 | 
				
			||||||
 | 
						whereArgs = append(whereArgs, dateEnd.Format("2006-01-02 15:04:05"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sql += strings.Join(whereList, " and ")
 | 
				
			||||||
 | 
						countSql += strings.Join(whereList, " and ")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						limitStart := (pageNo - 1) * pageLen
 | 
				
			||||||
 | 
						limitLen := pageLen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sql += fmt.Sprintf(" limit %v,%v", limitStart, limitLen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return sql, countSql, whereArgs
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (querier *EventListQuerier) query(sql string, countSql string, args []any) (
 | 
				
			||||||
 | 
						totalCount int, fieldsDescInfo []*dto.GameLogFieldInfo, rows [][]any, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rawRows, err := querier.clickHouseSqlx.Query(sql, args...)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							argsBin, _ := json.Marshal(&args)
 | 
				
			||||||
 | 
							return 0, nil, nil, errcode.New(errcode.DBError, "query sql:%v args:%v, error:%v",
 | 
				
			||||||
 | 
								sql, string(argsBin), err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer rawRows.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						columns, err := rawRows.Columns()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, nil, nil, errcode.New(errcode.DBError, "query sql:%v read rows columns error:%v", sql, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						columnLength := len(columns)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						readCacheRow := make([]any, 0, columnLength)
 | 
				
			||||||
 | 
						if columnLength != len(querier.attrList) {
 | 
				
			||||||
 | 
							colsBin, _ := json.Marshal(&columns)
 | 
				
			||||||
 | 
							selectColsBin, _ := json.Marshal(&querier.attrList)
 | 
				
			||||||
 | 
							xlog.Warnf("queyr table %v with sql:%v, args:%+v, result cols len:%v not equal to select:%v",
 | 
				
			||||||
 | 
								querier.tableName, sql, args, string(colsBin), string(selectColsBin))
 | 
				
			||||||
 | 
							// 修正一下查询结果,以数据库实际读取为准
 | 
				
			||||||
 | 
							for _, field := range columns {
 | 
				
			||||||
 | 
								for _, selectField := range querier.attrList {
 | 
				
			||||||
 | 
									if field == selectField.Name {
 | 
				
			||||||
 | 
										fieldDesc := &dto.GameLogFieldInfo{
 | 
				
			||||||
 | 
											Name:          selectField.Name,
 | 
				
			||||||
 | 
											Alias:         selectField.Name,
 | 
				
			||||||
 | 
											IsPublicField: false,
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if selectField.Alias != "" {
 | 
				
			||||||
 | 
											fieldDesc.Alias = selectField.Alias
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										fieldsDescInfo = append(fieldsDescInfo, fieldDesc)
 | 
				
			||||||
 | 
										var v any
 | 
				
			||||||
 | 
										readCacheRow = append(readCacheRow, &v)
 | 
				
			||||||
 | 
										break
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							for _, field := range querier.attrList {
 | 
				
			||||||
 | 
								fieldDesc := &dto.GameLogFieldInfo{
 | 
				
			||||||
 | 
									Name:          field.Name,
 | 
				
			||||||
 | 
									Alias:         field.Name,
 | 
				
			||||||
 | 
									IsPublicField: false,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if field.Alias != "" {
 | 
				
			||||||
 | 
									fieldDesc.Alias = field.Alias
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								fieldsDescInfo = append(fieldsDescInfo, fieldDesc)
 | 
				
			||||||
 | 
								var v any
 | 
				
			||||||
 | 
								readCacheRow = append(readCacheRow, &v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for rawRows.Next() {
 | 
				
			||||||
 | 
							err = rawRows.Scan(readCacheRow...)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return 0, nil, nil, errcode.New(errcode.DBError, "sql:%v result scan row error:%v", sql, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							parsedRow := make([]any, len(readCacheRow))
 | 
				
			||||||
 | 
							copy(parsedRow, readCacheRow)
 | 
				
			||||||
 | 
							rows = append(rows, parsedRow)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						count := 0
 | 
				
			||||||
 | 
						err = querier.clickHouseSqlx.QueryRow(countSql, args...).Scan(&count)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return 0, nil, nil, errcode.New(errcode.DBError, "query count sql:%v error:%v", countSql, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return count, fieldsDescInfo, rows, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								admin/apps/game/model/bi_all_attr.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								admin/apps/game/model/bi_all_attr.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					package model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Attribute struct {
 | 
				
			||||||
 | 
						ID              int `gorm:"primarykey" readonly:"true"`
 | 
				
			||||||
 | 
						AppId           int
 | 
				
			||||||
 | 
						Status          int // 是否显示 0为不显示 1为显示 默认不显示
 | 
				
			||||||
 | 
						AttributeName   string
 | 
				
			||||||
 | 
						ShowName        string
 | 
				
			||||||
 | 
						DataType        string
 | 
				
			||||||
 | 
						AttributeType   int
 | 
				
			||||||
 | 
						AttributeSource int
 | 
				
			||||||
 | 
						CreateTime      time.Time
 | 
				
			||||||
 | 
						UpdateTime      time.Time
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Attribute) TableName() string {
 | 
				
			||||||
 | 
						return "attribute"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								admin/apps/game/model/bi_event.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								admin/apps/game/model/bi_event.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Event struct {
 | 
				
			||||||
 | 
						ID             int `gorm:"primarykey" readonly:"true"`
 | 
				
			||||||
 | 
						Appid          int
 | 
				
			||||||
 | 
						EventName      string
 | 
				
			||||||
 | 
						ShowName       string
 | 
				
			||||||
 | 
						YesterdayCount int
 | 
				
			||||||
 | 
						CreateTime     time.Time
 | 
				
			||||||
 | 
						UpdateTime     time.Time
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *Event) TableName() string {
 | 
				
			||||||
 | 
						return "mata_event"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								admin/apps/game/model/bi_event_attr.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								admin/apps/game/model/bi_event_attr.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
				
			|||||||
 | 
					package model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EventAttribute struct {
 | 
				
			||||||
 | 
						ID        int `gorm:"primarykey" readonly:"true"`
 | 
				
			||||||
 | 
						AppId     int
 | 
				
			||||||
 | 
						EventName string
 | 
				
			||||||
 | 
						EventAttr string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (m *EventAttribute) TableName() string {
 | 
				
			||||||
 | 
						return "meta_attr_relation"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -8,6 +8,7 @@ import (
 | 
				
			|||||||
	"admin/lib/xlog"
 | 
						"admin/lib/xlog"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ctl *controller) CommandList(ctx *context.WebContext, params *dto.CommandListReq, rsp *dto.CommandListRsp) error {
 | 
					func (ctl *controller) CommandList(ctx *context.WebContext, params *dto.CommandListReq, rsp *dto.CommandListRsp) error {
 | 
				
			||||||
@ -65,6 +66,27 @@ func (ctl *controller) ProjectResourceDelete(ctx *context.WebContext, params *dt
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (ctl *controller) GameLogEventList(ctx *context.WebContext, params *dto.GameLogEventListReq, rsp *dto.GameLogEventListRsp) error {
 | 
				
			||||||
 | 
						projectId := getCtxURIProjectId(ctx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ds, _ := time.ParseInLocation("2006-01-02 15:04:05", params.DateStart, time.Local)
 | 
				
			||||||
 | 
						de, _ := time.ParseInLocation("2006-01-02 15:04:05", params.DateEnd, time.Local)
 | 
				
			||||||
 | 
						if ds.IsZero() {
 | 
				
			||||||
 | 
							ds = time.Now().Add(-time.Hour * 24 * 7)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if de.IsZero() {
 | 
				
			||||||
 | 
							de = time.Now().Add(time.Hour)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						eventList := strings.Split(params.EventName, ",")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var err error
 | 
				
			||||||
 | 
						rsp.TotalCount, rsp.FieldsDescInfo, rsp.Rows, err =
 | 
				
			||||||
 | 
							ctl.svc.GameLogSvc.QueryEventList(projectId, params.AppId,
 | 
				
			||||||
 | 
								eventList, params.ServerId, params.Account, params.RoleId, params.PageNo, params.PageLen, ds, de)
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (ctl *controller) getProjectResourceCommandApiAddr(ctx *context.WebContext) ([]string, error) {
 | 
					func (ctl *controller) getProjectResourceCommandApiAddr(ctx *context.WebContext) ([]string, error) {
 | 
				
			||||||
	projectId := getCtxURIProjectId(ctx)
 | 
						projectId := getCtxURIProjectId(ctx)
 | 
				
			||||||
	//resouce := getCtxURIResource(ctx)
 | 
						//resouce := getCtxURIResource(ctx)
 | 
				
			||||||
 | 
				
			|||||||
@ -8,9 +8,9 @@ import (
 | 
				
			|||||||
func (srv *Server) Route(engine *web.Engine, sdkEngine *web.Engine) {
 | 
					func (srv *Server) Route(engine *web.Engine, sdkEngine *web.Engine) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ // gm后台内部路由
 | 
						{ // gm后台内部路由
 | 
				
			||||||
		engine.Use(srv.CheckToken)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		apiGroup := engine.Group("/api", "")
 | 
							apiGroup := engine.Group("/api", "")
 | 
				
			||||||
 | 
							apiGroup.Use(srv.CheckToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// 注册项目增删改查接口
 | 
								// 注册项目增删改查接口
 | 
				
			||||||
@ -44,11 +44,13 @@ func (srv *Server) Route(engine *web.Engine, sdkEngine *web.Engine) {
 | 
				
			|||||||
				// 特殊接口
 | 
									// 特殊接口
 | 
				
			||||||
				accountGroup := projectGroup.Group("/:projectId/account/special", "")
 | 
									accountGroup := projectGroup.Group("/:projectId/account/special", "")
 | 
				
			||||||
				accountGroup.Get("/detail", "账号详情查看", consts.WebPathPermit_Write, srv.ctl.GetAccountDetail)
 | 
									accountGroup.Get("/detail", "账号详情查看", consts.WebPathPermit_Write, srv.ctl.GetAccountDetail)
 | 
				
			||||||
 | 
									accountGroup.Get("/event_list", "查询事件详细列表", consts.WebPathPermit_Write, srv.ctl.GameLogEventList)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				roleGroup := projectGroup.Group("/:projectId/role/special", "")
 | 
									roleGroup := projectGroup.Group("/:projectId/role/special", "")
 | 
				
			||||||
				roleGroup.Get("/detail", "角色详情查看", consts.WebPathPermit_Write, srv.ctl.GetRoleDetail)
 | 
									roleGroup.Get("/detail", "角色详情查看", consts.WebPathPermit_Write, srv.ctl.GetRoleDetail)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{ // gm后台作为sdk,供内部其它游戏调用的路由
 | 
						{ // gm后台作为sdk,供内部其它游戏调用的路由
 | 
				
			||||||
 | 
				
			|||||||
@ -4,12 +4,18 @@ import (
 | 
				
			|||||||
	"admin/apps/game/api"
 | 
						"admin/apps/game/api"
 | 
				
			||||||
	"admin/apps/game/domain"
 | 
						"admin/apps/game/domain"
 | 
				
			||||||
	"admin/internal/consts"
 | 
						"admin/internal/consts"
 | 
				
			||||||
 | 
						dbLib "admin/internal/db"
 | 
				
			||||||
	"admin/internal/errcode"
 | 
						"admin/internal/errcode"
 | 
				
			||||||
	"admin/internal/event"
 | 
						"admin/internal/event"
 | 
				
			||||||
	dto2 "admin/internal/model/dto"
 | 
						dto2 "admin/internal/model/dto"
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"github.com/ClickHouse/clickhouse-go/v2"
 | 
				
			||||||
 | 
						"github.com/jmoiron/sqlx"
 | 
				
			||||||
	"gorm.io/gorm"
 | 
						"gorm.io/gorm"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Service struct {
 | 
					type Service struct {
 | 
				
			||||||
@ -18,15 +24,43 @@ type Service struct {
 | 
				
			|||||||
	projectSvc  *domain.ProjectService
 | 
						projectSvc  *domain.ProjectService
 | 
				
			||||||
	cdkeySvc    *domain.CDKeyService
 | 
						cdkeySvc    *domain.CDKeyService
 | 
				
			||||||
	accountSvc  *domain.AccountService
 | 
						accountSvc  *domain.AccountService
 | 
				
			||||||
 | 
						GameLogSvc  *domain.GameLogService
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func New(db *gorm.DB) (*Service, error) {
 | 
					func New(db *gorm.DB) (*Service, error) {
 | 
				
			||||||
 | 
						metaDb, err := dbLib.NewDBNoMigrate("mysql", "192.168.6.83:13306", "databi", "root", "dev123")
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dbSource := fmt.Sprintf(
 | 
				
			||||||
 | 
							"tcp://%s:%s?username=%s&password=%s&compress=true&database=%s",
 | 
				
			||||||
 | 
							"192.168.6.83", "9000", "root", "dev123", "databi")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						clickHouseSqlx, err := NewCkDb("clickhouse", dbSource, 5, 20)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						conn, err := clickhouse.Open(&clickhouse.Options{
 | 
				
			||||||
 | 
							Addr: []string{"192.168.78.128:9000"},
 | 
				
			||||||
 | 
							Auth: clickhouse.Auth{
 | 
				
			||||||
 | 
								Database: "databi_prod",
 | 
				
			||||||
 | 
								Username: "root",
 | 
				
			||||||
 | 
								Password: "dev123",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, errcode.New(errcode.DBError, "open clickhouse %v error:%v", "databi_prod", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	svc := &Service{
 | 
						svc := &Service{
 | 
				
			||||||
		db:          db,
 | 
							db:          db,
 | 
				
			||||||
		resourceSvc: domain.NewCommonResourceService(db),
 | 
							resourceSvc: domain.NewCommonResourceService(db),
 | 
				
			||||||
		projectSvc:  domain.NewProjectService(db),
 | 
							projectSvc:  domain.NewProjectService(db),
 | 
				
			||||||
		cdkeySvc:    domain.NewCDKeyService(db),
 | 
							cdkeySvc:    domain.NewCDKeyService(db),
 | 
				
			||||||
		accountSvc:  domain.NewAccountService(db),
 | 
							accountSvc:  domain.NewAccountService(db),
 | 
				
			||||||
 | 
							GameLogSvc:  domain.NewGameLogSvc(db, metaDb, conn, clickHouseSqlx),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	api.RegisterGameApi(svc)
 | 
						api.RegisterGameApi(svc)
 | 
				
			||||||
	//err := svc.ensureProjectsDBData()
 | 
						//err := svc.ensureProjectsDBData()
 | 
				
			||||||
@ -36,6 +70,38 @@ func New(db *gorm.DB) (*Service, error) {
 | 
				
			|||||||
	return svc, nil
 | 
						return svc, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// NewMySQL 创建一个连接MySQL的实体池
 | 
				
			||||||
 | 
					func NewCkDb(driverName, dbSource string, maxOpenConns, maxIdleConns int) (db *sqlx.DB, err error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						db, err = sqlx.Open(driverName, dbSource)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("sqlx open driver %v source %v error:%v", driverName, dbSource, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if maxOpenConns > 0 {
 | 
				
			||||||
 | 
							db.SetMaxOpenConns(maxOpenConns)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if maxIdleConns > 0 {
 | 
				
			||||||
 | 
							db.SetMaxIdleConns(maxIdleConns)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = db.Ping()
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("sqlx ping driver %v source %v error:%v", driverName, dbSource, err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						go func() {
 | 
				
			||||||
 | 
							for {
 | 
				
			||||||
 | 
								err = db.Ping()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									log.Printf("mysql db can't connect!:%v", err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								time.Sleep(time.Minute)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (svc *Service) CommonList(ctx context.Context, projectId int, resourceName string, params *dto2.CommonListReq) (*dto2.CommonDtoList, error) {
 | 
					func (svc *Service) CommonList(ctx context.Context, projectId int, resourceName string, params *dto2.CommonListReq) (*dto2.CommonDtoList, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	params.ParsedWhereConditions = &dto2.ListWhereConditionInfo{}
 | 
						params.ParsedWhereConditions = &dto2.ListWhereConditionInfo{}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,12 +7,12 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func (srv *Server) Route(engine *web.Engine) {
 | 
					func (srv *Server) Route(engine *web.Engine) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	engine.Use(srv.CheckToken)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	apiGroup := engine.Group("/api", "")
 | 
						apiGroup := engine.Group("/api", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		userGroup := apiGroup.Group("/user", "用户操作组")
 | 
							userGroup := apiGroup.Group("/user", "用户操作组")
 | 
				
			||||||
 | 
							userGroup.Use(srv.CheckToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		userGroup.Post("/login", "登录", consts.WebPathPermit_Write, srv.ctl.Login)
 | 
							userGroup.Post("/login", "登录", consts.WebPathPermit_Write, srv.ctl.Login)
 | 
				
			||||||
		userGroup.Get("/info", "获取用户信息,里面包含用户权限信息,用于前端生成动态菜单", consts.WebPathPermit_Read, srv.ctl.GetUserInfo)
 | 
							userGroup.Get("/info", "获取用户信息,里面包含用户权限信息,用于前端生成动态菜单", consts.WebPathPermit_Read, srv.ctl.GetUserInfo)
 | 
				
			||||||
		userGroup.Get("/history", "获取用户执行历史记录,按各种条件检索", consts.WebPathPermit_Read, srv.ctl.GetUserExecHistory)
 | 
							userGroup.Get("/history", "获取用户执行历史记录,按各种条件检索", consts.WebPathPermit_Read, srv.ctl.GetUserExecHistory)
 | 
				
			||||||
@ -21,6 +21,8 @@ func (srv *Server) Route(engine *web.Engine) {
 | 
				
			|||||||
	{
 | 
						{
 | 
				
			||||||
		// 操作所有资源增删改查的接口
 | 
							// 操作所有资源增删改查的接口
 | 
				
			||||||
		userResourceGroup := apiGroup.Group("/resource/:resource", "用户管理")
 | 
							userResourceGroup := apiGroup.Group("/resource/:resource", "用户管理")
 | 
				
			||||||
 | 
							userResourceGroup.Use(srv.CheckToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		userResourceGroup.Get("", "查看列表", consts.WebPathPermit_Read, srv.ctl.CommonList)
 | 
							userResourceGroup.Get("", "查看列表", consts.WebPathPermit_Read, srv.ctl.CommonList)
 | 
				
			||||||
		userResourceGroup.Post("", "新增", consts.WebPathPermit_Read, srv.ctl.CommonPost)
 | 
							userResourceGroup.Post("", "新增", consts.WebPathPermit_Read, srv.ctl.CommonPost)
 | 
				
			||||||
		userResourceGroup.Put("", "编辑", consts.WebPathPermit_Read, srv.ctl.CommonPut)
 | 
							userResourceGroup.Put("", "编辑", consts.WebPathPermit_Read, srv.ctl.CommonPut)
 | 
				
			||||||
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										28
									
								
								admin/go.mod
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								admin/go.mod
									
									
									
									
									
								
							@ -3,21 +3,24 @@ module admin
 | 
				
			|||||||
go 1.24.2
 | 
					go 1.24.2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
 | 
						github.com/ClickHouse/clickhouse-go/v2 v2.37.2
 | 
				
			||||||
	github.com/gin-contrib/pprof v1.5.3
 | 
						github.com/gin-contrib/pprof v1.5.3
 | 
				
			||||||
	github.com/gin-gonic/gin v1.10.0
 | 
						github.com/gin-gonic/gin v1.10.0
 | 
				
			||||||
	github.com/glebarez/sqlite v1.11.0
 | 
						github.com/glebarez/sqlite v1.11.0
 | 
				
			||||||
	github.com/go-playground/assert/v2 v2.2.0
 | 
						github.com/go-playground/assert/v2 v2.2.0
 | 
				
			||||||
	github.com/go-sql-driver/mysql v1.7.0
 | 
						github.com/go-sql-driver/mysql v1.8.1
 | 
				
			||||||
	github.com/golang-jwt/jwt/v5 v5.2.2
 | 
						github.com/golang-jwt/jwt/v5 v5.2.2
 | 
				
			||||||
 | 
						github.com/jmoiron/sqlx v1.4.0
 | 
				
			||||||
	github.com/prometheus/client_golang v1.22.0
 | 
						github.com/prometheus/client_golang v1.22.0
 | 
				
			||||||
	github.com/redis/go-redis/v9 v9.8.0
 | 
						github.com/redis/go-redis/v9 v9.8.0
 | 
				
			||||||
	github.com/rpcxio/rpcx-gateway v0.0.0-20230602022101-74ed729109fd
 | 
						github.com/rpcxio/rpcx-gateway v0.0.0-20230602022101-74ed729109fd
 | 
				
			||||||
	github.com/rpcxio/rpcx-redis v0.0.0-20250107024620-f10ac7d956cb
 | 
						github.com/rpcxio/rpcx-redis v0.0.0-20250107024620-f10ac7d956cb
 | 
				
			||||||
	github.com/rs/zerolog v1.34.0
 | 
						github.com/rs/zerolog v1.34.0
 | 
				
			||||||
	github.com/smallnest/rpcx v1.9.1
 | 
						github.com/smallnest/rpcx v1.9.1
 | 
				
			||||||
 | 
						github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1200
 | 
				
			||||||
	github.com/tencentyun/cos-go-sdk-v5 v0.7.66
 | 
						github.com/tencentyun/cos-go-sdk-v5 v0.7.66
 | 
				
			||||||
	golang.org/x/crypto v0.38.0
 | 
						golang.org/x/crypto v0.39.0
 | 
				
			||||||
	golang.org/x/sync v0.14.0
 | 
						golang.org/x/sync v0.15.0
 | 
				
			||||||
	golang.org/x/telemetry v0.0.0-20250507143331-155ddd5254aa
 | 
						golang.org/x/telemetry v0.0.0-20250507143331-155ddd5254aa
 | 
				
			||||||
	golang.org/x/tools v0.33.0
 | 
						golang.org/x/tools v0.33.0
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1
 | 
						gopkg.in/yaml.v3 v3.0.1
 | 
				
			||||||
@ -26,8 +29,11 @@ require (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
 | 
						filippo.io/edwards25519 v1.1.0 // indirect
 | 
				
			||||||
 | 
						github.com/ClickHouse/ch-go v0.66.1 // indirect
 | 
				
			||||||
	github.com/akutz/memconn v0.1.0 // indirect
 | 
						github.com/akutz/memconn v0.1.0 // indirect
 | 
				
			||||||
	github.com/alitto/pond v1.9.2 // indirect
 | 
						github.com/alitto/pond v1.9.2 // indirect
 | 
				
			||||||
 | 
						github.com/andybalholm/brotli v1.1.1 // indirect
 | 
				
			||||||
	github.com/apache/thrift v0.21.0 // indirect
 | 
						github.com/apache/thrift v0.21.0 // indirect
 | 
				
			||||||
	github.com/beorn7/perks v1.0.1 // indirect
 | 
						github.com/beorn7/perks v1.0.1 // indirect
 | 
				
			||||||
	github.com/bytedance/sonic v1.13.2 // indirect
 | 
						github.com/bytedance/sonic v1.13.2 // indirect
 | 
				
			||||||
@ -46,6 +52,8 @@ require (
 | 
				
			|||||||
	github.com/gabriel-vasile/mimetype v1.4.8 // indirect
 | 
						github.com/gabriel-vasile/mimetype v1.4.8 // indirect
 | 
				
			||||||
	github.com/gin-contrib/sse v1.0.0 // indirect
 | 
						github.com/gin-contrib/sse v1.0.0 // indirect
 | 
				
			||||||
	github.com/glebarez/go-sqlite v1.21.2 // indirect
 | 
						github.com/glebarez/go-sqlite v1.21.2 // indirect
 | 
				
			||||||
 | 
						github.com/go-faster/city v1.0.1 // indirect
 | 
				
			||||||
 | 
						github.com/go-faster/errors v0.7.1 // indirect
 | 
				
			||||||
	github.com/go-ping/ping v1.2.0 // indirect
 | 
						github.com/go-ping/ping v1.2.0 // indirect
 | 
				
			||||||
	github.com/go-playground/locales v0.14.1 // indirect
 | 
						github.com/go-playground/locales v0.14.1 // indirect
 | 
				
			||||||
	github.com/go-playground/universal-translator v0.18.1 // indirect
 | 
						github.com/go-playground/universal-translator v0.18.1 // indirect
 | 
				
			||||||
@ -69,6 +77,7 @@ require (
 | 
				
			|||||||
	github.com/juju/ratelimit v1.0.2 // indirect
 | 
						github.com/juju/ratelimit v1.0.2 // indirect
 | 
				
			||||||
	github.com/julienschmidt/httprouter v1.3.0 // indirect
 | 
						github.com/julienschmidt/httprouter v1.3.0 // indirect
 | 
				
			||||||
	github.com/kavu/go_reuseport v1.5.0 // indirect
 | 
						github.com/kavu/go_reuseport v1.5.0 // indirect
 | 
				
			||||||
 | 
						github.com/klauspost/compress v1.18.0 // indirect
 | 
				
			||||||
	github.com/klauspost/cpuid/v2 v2.2.10 // indirect
 | 
						github.com/klauspost/cpuid/v2 v2.2.10 // indirect
 | 
				
			||||||
	github.com/klauspost/reedsolomon v1.12.4 // indirect
 | 
						github.com/klauspost/reedsolomon v1.12.4 // indirect
 | 
				
			||||||
	github.com/leodido/go-urn v1.4.0 // indirect
 | 
						github.com/leodido/go-urn v1.4.0 // indirect
 | 
				
			||||||
@ -82,8 +91,10 @@ require (
 | 
				
			|||||||
	github.com/mozillazg/go-httpheader v0.4.0 // indirect
 | 
						github.com/mozillazg/go-httpheader v0.4.0 // indirect
 | 
				
			||||||
	github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 | 
						github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 | 
				
			||||||
	github.com/onsi/ginkgo/v2 v2.22.2 // indirect
 | 
						github.com/onsi/ginkgo/v2 v2.22.2 // indirect
 | 
				
			||||||
 | 
						github.com/paulmach/orb v0.11.1 // indirect
 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
 | 
						github.com/pelletier/go-toml/v2 v2.2.3 // indirect
 | 
				
			||||||
	github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
 | 
						github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
 | 
				
			||||||
 | 
						github.com/pierrec/lz4/v4 v4.1.22 // indirect
 | 
				
			||||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
						github.com/pkg/errors v0.9.1 // indirect
 | 
				
			||||||
	github.com/prometheus/client_model v0.6.1 // indirect
 | 
						github.com/prometheus/client_model v0.6.1 // indirect
 | 
				
			||||||
	github.com/prometheus/common v0.62.0 // indirect
 | 
						github.com/prometheus/common v0.62.0 // indirect
 | 
				
			||||||
@ -94,12 +105,13 @@ require (
 | 
				
			|||||||
	github.com/rpcxio/libkv v0.5.1 // indirect
 | 
						github.com/rpcxio/libkv v0.5.1 // indirect
 | 
				
			||||||
	github.com/rs/cors v1.11.1 // indirect
 | 
						github.com/rs/cors v1.11.1 // indirect
 | 
				
			||||||
	github.com/rubyist/circuitbreaker v2.2.1+incompatible // indirect
 | 
						github.com/rubyist/circuitbreaker v2.2.1+incompatible // indirect
 | 
				
			||||||
 | 
						github.com/segmentio/asm v1.2.0 // indirect
 | 
				
			||||||
 | 
						github.com/shopspring/decimal v1.4.0 // indirect
 | 
				
			||||||
	github.com/smallnest/quick v0.2.0 // indirect
 | 
						github.com/smallnest/quick v0.2.0 // indirect
 | 
				
			||||||
	github.com/smallnest/rsocket v0.0.0-20241130031020-4a72eb6ff62a // indirect
 | 
						github.com/smallnest/rsocket v0.0.0-20241130031020-4a72eb6ff62a // indirect
 | 
				
			||||||
	github.com/soheilhy/cmux v0.1.5 // indirect
 | 
						github.com/soheilhy/cmux v0.1.5 // indirect
 | 
				
			||||||
	github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
 | 
						github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
 | 
				
			||||||
	github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
 | 
						github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
 | 
				
			||||||
	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdn v1.0.1200 // indirect
 | 
					 | 
				
			||||||
	github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1201 // indirect
 | 
						github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1201 // indirect
 | 
				
			||||||
	github.com/tinylib/msgp v1.2.5 // indirect
 | 
						github.com/tinylib/msgp v1.2.5 // indirect
 | 
				
			||||||
	github.com/tjfoc/gmsm v1.4.1 // indirect
 | 
						github.com/tjfoc/gmsm v1.4.1 // indirect
 | 
				
			||||||
@ -109,13 +121,15 @@ require (
 | 
				
			|||||||
	github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
 | 
						github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
 | 
				
			||||||
	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 | 
						github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
 | 
				
			||||||
	github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
 | 
						github.com/xtaci/kcp-go v5.4.20+incompatible // indirect
 | 
				
			||||||
 | 
						go.opentelemetry.io/otel v1.36.0 // indirect
 | 
				
			||||||
 | 
						go.opentelemetry.io/otel/trace v1.36.0 // indirect
 | 
				
			||||||
	go.uber.org/mock v0.5.0 // indirect
 | 
						go.uber.org/mock v0.5.0 // indirect
 | 
				
			||||||
	golang.org/x/arch v0.16.0 // indirect
 | 
						golang.org/x/arch v0.16.0 // indirect
 | 
				
			||||||
	golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae // indirect
 | 
						golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae // indirect
 | 
				
			||||||
	golang.org/x/mod v0.24.0 // indirect
 | 
						golang.org/x/mod v0.25.0 // indirect
 | 
				
			||||||
	golang.org/x/net v0.40.0 // indirect
 | 
						golang.org/x/net v0.41.0 // indirect
 | 
				
			||||||
	golang.org/x/sys v0.33.0 // indirect
 | 
						golang.org/x/sys v0.33.0 // indirect
 | 
				
			||||||
	golang.org/x/text v0.25.0 // indirect
 | 
						golang.org/x/text v0.26.0 // indirect
 | 
				
			||||||
	google.golang.org/protobuf v1.36.6 // indirect
 | 
						google.golang.org/protobuf v1.36.6 // indirect
 | 
				
			||||||
	modernc.org/libc v1.22.5 // indirect
 | 
						modernc.org/libc v1.22.5 // indirect
 | 
				
			||||||
	modernc.org/mathutil v1.5.0 // indirect
 | 
						modernc.org/mathutil v1.5.0 // indirect
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										70
									
								
								admin/go.sum
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								admin/go.sum
									
									
									
									
									
								
							@ -6,9 +6,15 @@ dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl
 | 
				
			|||||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
 | 
					dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
 | 
				
			||||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
 | 
					dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
 | 
				
			||||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
 | 
					dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
 | 
				
			||||||
 | 
					filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
 | 
				
			||||||
 | 
					filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
 | 
				
			||||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
 | 
					git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
 | 
				
			||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
					github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
				
			||||||
github.com/ChimeraCoder/gojson v1.1.0/go.mod h1:nYbTQlu6hv8PETM15J927yM0zGj3njIldp72UT1MqSw=
 | 
					github.com/ChimeraCoder/gojson v1.1.0/go.mod h1:nYbTQlu6hv8PETM15J927yM0zGj3njIldp72UT1MqSw=
 | 
				
			||||||
 | 
					github.com/ClickHouse/ch-go v0.66.1 h1:LQHFslfVYZsISOY0dnOYOXGkOUvpv376CCm8g7W74A4=
 | 
				
			||||||
 | 
					github.com/ClickHouse/ch-go v0.66.1/go.mod h1:NEYcg3aOFv2EmTJfo4m2WF7sHB/YFbLUuIWv9iq76xY=
 | 
				
			||||||
 | 
					github.com/ClickHouse/clickhouse-go/v2 v2.37.2 h1:wRLNKoynvHQEN4znnVHNLaYnrqVc9sGJmGYg+GGCfto=
 | 
				
			||||||
 | 
					github.com/ClickHouse/clickhouse-go/v2 v2.37.2/go.mod h1:pH2zrBGp5Y438DMwAxXMm1neSXPPjSI7tD4MURVULw8=
 | 
				
			||||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 | 
					github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
 | 
				
			||||||
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
 | 
					github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
 | 
				
			||||||
github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A=
 | 
					github.com/akutz/memconn v0.1.0 h1:NawI0TORU4hcOMsMr11g7vwlCdkYeLKXBcxWu2W/P8A=
 | 
				
			||||||
@ -21,6 +27,8 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
 | 
				
			|||||||
github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
 | 
					github.com/alitto/pond v1.9.2 h1:9Qb75z/scEZVCoSU+osVmQ0I0JOeLfdTDafrbcJ8CLs=
 | 
				
			||||||
github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
 | 
					github.com/alitto/pond v1.9.2/go.mod h1:xQn3P/sHTYcU/1BR3i86IGIrilcrGC2LiS+E2+CJWsI=
 | 
				
			||||||
github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
 | 
					github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk=
 | 
				
			||||||
 | 
					github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
 | 
				
			||||||
 | 
					github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
 | 
				
			||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 | 
					github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
 | 
				
			||||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 | 
					github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
 | 
				
			||||||
github.com/apache/thrift v0.14.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 | 
					github.com/apache/thrift v0.14.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
 | 
				
			||||||
@ -125,6 +133,10 @@ github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GM
 | 
				
			|||||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
 | 
					github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
 | 
				
			||||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 | 
					github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 | 
				
			||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 | 
					github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 | 
				
			||||||
 | 
					github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
 | 
				
			||||||
 | 
					github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
 | 
				
			||||||
 | 
					github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
 | 
				
			||||||
 | 
					github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
 | 
				
			||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 | 
					github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 | 
				
			||||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 | 
					github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 | 
				
			||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 | 
					github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 | 
				
			||||||
@ -147,8 +159,9 @@ github.com/go-redis/redis/v8 v8.4.0/go.mod h1:A1tbYoHSa1fXwN+//ljcCYYJeLmVrwL9hb
 | 
				
			|||||||
github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
 | 
					github.com/go-redis/redis/v8 v8.8.2/go.mod h1:F7resOH5Kdug49Otu24RjHWwgK7u9AmtqWMnCV1iP5Y=
 | 
				
			||||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
 | 
					github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
 | 
				
			||||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
 | 
					github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
 | 
				
			||||||
github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc=
 | 
					 | 
				
			||||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 | 
					github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 | 
				
			||||||
 | 
					github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
 | 
				
			||||||
 | 
					github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
 | 
				
			||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 | 
					github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 | 
				
			||||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 | 
					github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
 | 
				
			||||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 | 
					github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
 | 
				
			||||||
@ -191,6 +204,7 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
 | 
				
			|||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 | 
					github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 | 
				
			||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 | 
					github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
 | 
				
			||||||
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
					github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
				
			||||||
 | 
					github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
				
			||||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
					github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
				
			||||||
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 | 
					github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
 | 
				
			||||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
					github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
 | 
				
			||||||
@ -272,6 +286,8 @@ github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkr
 | 
				
			|||||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
					github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
 | 
				
			||||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
					github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 | 
				
			||||||
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 | 
					github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 | 
				
			||||||
 | 
					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.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 | 
					github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 | 
				
			||||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
					github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
				
			||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
					github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
 | 
				
			||||||
@ -292,6 +308,7 @@ github.com/kavu/go_reuseport v1.5.0/go.mod h1:CG8Ee7ceMFSMnx/xr25Vm0qXaj2Z4i5PWo
 | 
				
			|||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 | 
					github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 | 
				
			||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 | 
					github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 | 
				
			||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 | 
					github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 | 
				
			||||||
 | 
					github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
				
			||||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
 | 
					github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
 | 
				
			||||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 | 
					github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
 | 
				
			||||||
github.com/klauspost/cpuid/v2 v2.0.2/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 | 
					github.com/klauspost/cpuid/v2 v2.0.2/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
 | 
				
			||||||
@ -327,6 +344,8 @@ github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjS
 | 
				
			|||||||
github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
 | 
					github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570/go.mod h1:BLt8L9ld7wVsvEWQbuLrUZnCMnUmLZ+CGDzKtclrTlE=
 | 
				
			||||||
github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
 | 
					github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f/go.mod h1:UGmTpUd3rjbtfIpwAPrcfmGf/Z1HS95TATB+m57TPB8=
 | 
				
			||||||
github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
 | 
					github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042/go.mod h1:TPpsiPUEh0zFL1Snz4crhMlBe60PYxRHr5oFF3rRYg0=
 | 
				
			||||||
 | 
					github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
 | 
				
			||||||
 | 
					github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 | 
				
			||||||
github.com/libp2p/go-sockaddr v0.2.0 h1:Alhhj6lGxVAon9O32tOO89T601EugSx6YiGjy5BVjWk=
 | 
					github.com/libp2p/go-sockaddr v0.2.0 h1:Alhhj6lGxVAon9O32tOO89T601EugSx6YiGjy5BVjWk=
 | 
				
			||||||
github.com/libp2p/go-sockaddr v0.2.0/go.mod h1:5NxulaB17yJ07IpzRIleys4un0PJ7WLWgMDLBBWrGw8=
 | 
					github.com/libp2p/go-sockaddr v0.2.0/go.mod h1:5NxulaB17yJ07IpzRIleys4un0PJ7WLWgMDLBBWrGw8=
 | 
				
			||||||
github.com/lucas-clemente/quic-go v0.15.5/go.mod h1:Myi1OyS0FOjL3not4BxT7KN29bRkcMUV5JVVFLKtDp8=
 | 
					github.com/lucas-clemente/quic-go v0.15.5/go.mod h1:Myi1OyS0FOjL3not4BxT7KN29bRkcMUV5JVVFLKtDp8=
 | 
				
			||||||
@ -359,6 +378,8 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
 | 
				
			|||||||
github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
					github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
				
			||||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
					github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
 | 
				
			||||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 | 
					github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
 | 
				
			||||||
 | 
					github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
 | 
				
			||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 | 
					github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 | 
				
			||||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
 | 
					github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
 | 
				
			||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 | 
					github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 | 
				
			||||||
@ -382,6 +403,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
 | 
				
			|||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
					github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 | 
					github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 | 
				
			||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 | 
					github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 | 
				
			||||||
 | 
					github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
 | 
				
			||||||
github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
 | 
					github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60=
 | 
				
			||||||
github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
 | 
					github.com/mozillazg/go-httpheader v0.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
 | 
				
			||||||
github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
 | 
					github.com/mozillazg/go-httpheader v0.4.0/go.mod h1:PuT8h0pw6efvp8ZeUec1Rs7dwjK08bt6gKSReGMqtdA=
 | 
				
			||||||
@ -419,6 +441,9 @@ github.com/opentracing/opentracing-go v1.1.1-0.20190913142402-a7454ce5950e/go.mo
 | 
				
			|||||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 | 
					github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 | 
				
			||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 | 
					github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 | 
				
			||||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 | 
					github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 | 
				
			||||||
 | 
					github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
 | 
				
			||||||
 | 
					github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
 | 
				
			||||||
 | 
					github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
 | 
				
			||||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 | 
					github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 | 
				
			||||||
github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
 | 
					github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
 | 
				
			||||||
github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
 | 
					github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc=
 | 
				
			||||||
@ -426,6 +451,8 @@ github.com/peterbourgon/g2s v0.0.0-20140925154142-ec76db4c1ac1 h1:5Dl+ADmsGerAqH
 | 
				
			|||||||
github.com/peterbourgon/g2s v0.0.0-20140925154142-ec76db4c1ac1/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg=
 | 
					github.com/peterbourgon/g2s v0.0.0-20140925154142-ec76db4c1ac1/go.mod h1:1VcHEd3ro4QMoHfiNl/j7Jkln9+KQuorp0PItHMJYNg=
 | 
				
			||||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
 | 
					github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c h1:dAMKvw0MlJT1GshSTtih8C2gDs04w8dReiOGXrGLNoY=
 | 
				
			||||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
 | 
					github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
 | 
				
			||||||
 | 
					github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU=
 | 
				
			||||||
 | 
					github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 | 
				
			||||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 | 
					github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
 | 
				
			||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
					github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
					github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 | 
				
			||||||
@ -500,8 +527,12 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
 | 
				
			|||||||
github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 | 
					github.com/samuel/go-zookeeper v0.0.0-20200724154423-2164a8ac840e/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 | 
				
			||||||
github.com/samuel/go-zookeeper v0.0.0-20201211165307-7117e9ea2414/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 | 
					github.com/samuel/go-zookeeper v0.0.0-20201211165307-7117e9ea2414/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
 | 
				
			||||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 | 
					github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 | 
				
			||||||
 | 
					github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
 | 
				
			||||||
 | 
					github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
 | 
				
			||||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 | 
					github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 | 
				
			||||||
github.com/serialx/hashring v0.0.0-20180504054112-49a4782e9908/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
 | 
					github.com/serialx/hashring v0.0.0-20180504054112-49a4782e9908/go.mod h1:/yeG0My1xr/u+HZrFQ1tOQQQQrOawfyMUH13ai5brBc=
 | 
				
			||||||
 | 
					github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
 | 
				
			||||||
 | 
					github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
 | 
				
			||||||
github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
 | 
					github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY=
 | 
				
			||||||
github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
 | 
					github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM=
 | 
				
			||||||
github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
 | 
					github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0=
 | 
				
			||||||
@ -579,6 +610,7 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1201/go.mod
 | 
				
			|||||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
 | 
					github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0=
 | 
				
			||||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.66 h1:O4O6EsozBoDjxWbltr3iULgkI7WPj/BFNlYTXDuE64E=
 | 
					github.com/tencentyun/cos-go-sdk-v5 v0.7.66 h1:O4O6EsozBoDjxWbltr3iULgkI7WPj/BFNlYTXDuE64E=
 | 
				
			||||||
github.com/tencentyun/cos-go-sdk-v5 v0.7.66/go.mod h1:8+hG+mQMuRP/OIS9d83syAvXvrMj9HhkND6Q1fLghw0=
 | 
					github.com/tencentyun/cos-go-sdk-v5 v0.7.66/go.mod h1:8+hG+mQMuRP/OIS9d83syAvXvrMj9HhkND6Q1fLghw0=
 | 
				
			||||||
 | 
					github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 | 
				
			||||||
github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
 | 
					github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
 | 
				
			||||||
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
 | 
					github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
 | 
				
			||||||
github.com/tjfoc/gmsm v1.4.0/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
 | 
					github.com/tjfoc/gmsm v1.4.0/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
 | 
				
			||||||
@ -603,11 +635,17 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU
 | 
				
			|||||||
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
 | 
					github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
 | 
				
			||||||
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
 | 
					github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
 | 
				
			||||||
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
 | 
					github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
 | 
				
			||||||
 | 
					github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
 | 
				
			||||||
 | 
					github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
 | 
				
			||||||
 | 
					github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
 | 
				
			||||||
github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
 | 
					github.com/xtaci/kcp-go v5.4.20+incompatible h1:TN1uey3Raw0sTz0Fg8GkfM0uH3YwzhnZWQ1bABv5xAg=
 | 
				
			||||||
github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
 | 
					github.com/xtaci/kcp-go v5.4.20+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE=
 | 
				
			||||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
 | 
					github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
 | 
				
			||||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
 | 
					github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
 | 
				
			||||||
github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
 | 
					github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
 | 
				
			||||||
 | 
					github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
 | 
				
			||||||
 | 
					github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
 | 
				
			||||||
 | 
					github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 | 
				
			||||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
					github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
				
			||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
					github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 | 
				
			||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 | 
					github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 | 
				
			||||||
@ -615,13 +653,18 @@ go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r7
 | 
				
			|||||||
go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU=
 | 
					go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU=
 | 
				
			||||||
go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8=
 | 
					go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8=
 | 
				
			||||||
go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY=
 | 
					go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY=
 | 
				
			||||||
 | 
					go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
 | 
				
			||||||
go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
 | 
					go.opencensus.io v0.18.0/go.mod h1:vKdFvxhtzZ9onBp9VKHK8z/sRpBMnKAsufL7wlDrCOA=
 | 
				
			||||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 | 
					go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
 | 
				
			||||||
go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
 | 
					go.opentelemetry.io/otel v0.14.0/go.mod h1:vH5xEuwy7Rts0GNtsCW3HYQoZDY+OmBJ6t1bFGGlxgw=
 | 
				
			||||||
go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
 | 
					go.opentelemetry.io/otel v0.19.0/go.mod h1:j9bF567N9EfomkSidSfmMwIwIBuP37AMAIzVW85OxSg=
 | 
				
			||||||
 | 
					go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
 | 
				
			||||||
 | 
					go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
 | 
				
			||||||
go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
 | 
					go.opentelemetry.io/otel/metric v0.19.0/go.mod h1:8f9fglJPRnXuskQmKpnad31lcLJ2VmNNqIsx/uIwBSc=
 | 
				
			||||||
go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
 | 
					go.opentelemetry.io/otel/oteltest v0.19.0/go.mod h1:tI4yxwh8U21v7JD6R3BcA/2+RBoTKFexE/PJ/nSO7IA=
 | 
				
			||||||
go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
 | 
					go.opentelemetry.io/otel/trace v0.19.0/go.mod h1:4IXiNextNOpPnRlI4ryK69mn5iC84bjBWZQA5DXz/qg=
 | 
				
			||||||
 | 
					go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
 | 
				
			||||||
 | 
					go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
 | 
				
			||||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
					go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
 | 
				
			||||||
go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
 | 
					go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
 | 
				
			||||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
 | 
					go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
 | 
				
			||||||
@ -648,10 +691,11 @@ golang.org/x/crypto v0.0.0-20200423211502-4bdfaf469ed5/go.mod h1:LzIPMQfyMNhhGPh
 | 
				
			|||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
					golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
					golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 | 
				
			||||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
					golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
				
			||||||
 | 
					golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 | 
				
			||||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 | 
					golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
 | 
				
			||||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 | 
					golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
 | 
				
			||||||
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
 | 
					golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
 | 
				
			||||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
 | 
					golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U=
 | 
				
			||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
					golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 | 
				
			||||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae h1:COZdc9Ut6wLq7MO9GIYxfZl4n4ScmgqQLoHocKXrxco=
 | 
					golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae h1:COZdc9Ut6wLq7MO9GIYxfZl4n4ScmgqQLoHocKXrxco=
 | 
				
			||||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
 | 
					golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
 | 
				
			||||||
@ -666,8 +710,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
				
			|||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
					golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 | 
				
			||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 | 
					golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 | 
				
			||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 | 
					golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 | 
				
			||||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
 | 
					golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
 | 
				
			||||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
 | 
					golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
 | 
				
			||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
					golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
				
			||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
					golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
				
			||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
					golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 | 
				
			||||||
@ -696,12 +740,13 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
 | 
				
			|||||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 | 
					golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 | 
				
			||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 | 
					golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 | 
				
			||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 | 
					golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
 | 
				
			||||||
 | 
					golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 | 
				
			||||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
					golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 | 
				
			||||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 | 
					golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 | 
				
			||||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 | 
					golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
 | 
				
			||||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 | 
					golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
 | 
				
			||||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
 | 
					golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
 | 
				
			||||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
 | 
					golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
 | 
				
			||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
					golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
				
			||||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
					golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
				
			||||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
					golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 | 
				
			||||||
@ -718,8 +763,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 | 
				
			|||||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
					golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 | 
				
			||||||
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
 | 
					golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
 | 
				
			||||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 | 
					golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
					golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 | 
				
			||||||
@ -754,6 +799,7 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
 | 
				
			|||||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
					golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
 | 
					golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
					golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 | 
				
			||||||
@ -777,13 +823,14 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
				
			|||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
					golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 | 
				
			||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
					golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 | 
				
			||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
					golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
				
			||||||
 | 
					golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 | 
				
			||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
					golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 | 
				
			||||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 | 
					golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 | 
				
			||||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 | 
					golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 | 
				
			||||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 | 
					golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 | 
				
			||||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 | 
					golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 | 
				
			||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
 | 
					golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
 | 
				
			||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
 | 
					golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
 | 
				
			||||||
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
					golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
					golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 | 
				
			||||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
 | 
					golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
 | 
				
			||||||
@ -855,6 +902,7 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
 | 
				
			|||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 | 
					google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
 | 
				
			||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 | 
					google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
 | 
				
			||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
					google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 | 
				
			||||||
 | 
					google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
 | 
				
			||||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 | 
					google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
 | 
				
			||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
 | 
					google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
 | 
				
			||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
 | 
					google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ const (
 | 
				
			|||||||
	ResourcesName_DevicePush     = "device_push"
 | 
						ResourcesName_DevicePush     = "device_push"
 | 
				
			||||||
	ResourcesName_ItemBag        = "item_bag"
 | 
						ResourcesName_ItemBag        = "item_bag"
 | 
				
			||||||
	ResourcesName_GenAccount     = "gen_account"
 | 
						ResourcesName_GenAccount     = "gen_account"
 | 
				
			||||||
 | 
						ResourcesName_GameLog        = "gamelog"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
 | 
				
			|||||||
@ -36,6 +36,36 @@ func NewDB(dbType, dbAddr, dbName, dbUser, dbPass string) (db *gorm.DB, err erro
 | 
				
			|||||||
	return db, nil
 | 
						return db, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewDBNoMigrate(dbType, dbAddr, dbName, dbUser, dbPass string) (db *gorm.DB, err error) {
 | 
				
			||||||
 | 
						dsn := fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPass, dbAddr, dbName)
 | 
				
			||||||
 | 
						var dialector gorm.Dialector
 | 
				
			||||||
 | 
						switch dbType {
 | 
				
			||||||
 | 
						case "sqlite":
 | 
				
			||||||
 | 
							dialector = sqlite.Open(dbName + ".db")
 | 
				
			||||||
 | 
						case "mysql":
 | 
				
			||||||
 | 
							dialector = mysql.Open(dsn)
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							panic(fmt.Errorf("unsupported db type: %v", dbType))
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						db, err = gorm.Open(dialector, &gorm.Config{
 | 
				
			||||||
 | 
							Logger:      &gormLogger{},
 | 
				
			||||||
 | 
							PrepareStmt: false, // 关闭缓存sql语句功能,因为后续use db会报错,这个缓存会无限存储可能导致内存泄露
 | 
				
			||||||
 | 
							//SkipDefaultTransaction: true, // 跳过默认事务
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("failed to connect to mysql:%v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sqlDB, _ := db.DB()
 | 
				
			||||||
 | 
						sqlDB.SetMaxIdleConns(10)
 | 
				
			||||||
 | 
						sqlDB.SetMaxOpenConns(50)
 | 
				
			||||||
 | 
						sqlDB.SetConnMaxIdleTime(time.Minute * 5)
 | 
				
			||||||
 | 
						sqlDB.SetConnMaxLifetime(time.Minute * 10)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return db, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func createDBAndGuaranteeMigrate(dbType string, dsnWithoutDb, dsn string, tables []any) (*gorm.DB, error) {
 | 
					func createDBAndGuaranteeMigrate(dbType string, dsnWithoutDb, dsn string, tables []any) (*gorm.DB, error) {
 | 
				
			||||||
	mysqlDriverConf, err := mysqlDriver.ParseDSN(dsn)
 | 
						mysqlDriverConf, err := mysqlDriver.ParseDSN(dsn)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -152,3 +152,9 @@ type WhiteListInfo struct {
 | 
				
			|||||||
	WType string `json:"w_type"`
 | 
						WType string `json:"w_type"`
 | 
				
			||||||
	Value string `json:"value"`
 | 
						Value string `json:"value"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GameLogFieldInfo struct {
 | 
				
			||||||
 | 
						Name          string `json:"name"`
 | 
				
			||||||
 | 
						Alias         string `json:"alias"`
 | 
				
			||||||
 | 
						IsPublicField bool   `json:"isPublicField"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -135,3 +135,21 @@ type GetRoleDetailReq struct {
 | 
				
			|||||||
type GetRoleDetailRsp struct {
 | 
					type GetRoleDetailRsp struct {
 | 
				
			||||||
	RoleInfo *RoleDetailInfo `json:"role_info"`
 | 
						RoleInfo *RoleDetailInfo `json:"role_info"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GameLogEventListReq struct {
 | 
				
			||||||
 | 
						AppId     int
 | 
				
			||||||
 | 
						EventName string
 | 
				
			||||||
 | 
						ServerId  int
 | 
				
			||||||
 | 
						Account   string
 | 
				
			||||||
 | 
						RoleId    string
 | 
				
			||||||
 | 
						PageNo    int
 | 
				
			||||||
 | 
						PageLen   int
 | 
				
			||||||
 | 
						DateStart string
 | 
				
			||||||
 | 
						DateEnd   string
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GameLogEventListRsp struct {
 | 
				
			||||||
 | 
						TotalCount     int                 `json:"totalCount"`
 | 
				
			||||||
 | 
						FieldsDescInfo []*GameLogFieldInfo `json:"fieldsDescInfo"`
 | 
				
			||||||
 | 
						Rows           [][]any             `json:"rows"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										10
									
								
								admin/lib/utils/slice.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								admin/lib/utils/slice.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					package utils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func IsInSlice[T comparable](slice []T, elem T) bool {
 | 
				
			||||||
 | 
						for _, v := range slice {
 | 
				
			||||||
 | 
							if v == elem {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								admin/uniugm.db
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								admin/uniugm.db
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										7
									
								
								ui/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								ui/package-lock.json
									
									
									
										generated
									
									
									
								
							@ -13,6 +13,7 @@
 | 
				
			|||||||
        "axios": "^1.8.4",
 | 
					        "axios": "^1.8.4",
 | 
				
			||||||
        "echarts": "^5.6.0",
 | 
					        "echarts": "^5.6.0",
 | 
				
			||||||
        "element-plus": "^2.9.7",
 | 
					        "element-plus": "^2.9.7",
 | 
				
			||||||
 | 
					        "js-base64": "^3.7.7",
 | 
				
			||||||
        "pinia": "^3.0.1",
 | 
					        "pinia": "^3.0.1",
 | 
				
			||||||
        "pinia-plugin-persistedstate": "^4.2.0",
 | 
					        "pinia-plugin-persistedstate": "^4.2.0",
 | 
				
			||||||
        "splitpanes": "^4.0.4",
 | 
					        "splitpanes": "^4.0.4",
 | 
				
			||||||
@ -3607,6 +3608,12 @@
 | 
				
			|||||||
        "jiti": "lib/jiti-cli.mjs"
 | 
					        "jiti": "lib/jiti-cli.mjs"
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "node_modules/js-base64": {
 | 
				
			||||||
 | 
					      "version": "3.7.7",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.7.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==",
 | 
				
			||||||
 | 
					      "license": "BSD-3-Clause"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "node_modules/js-tokens": {
 | 
					    "node_modules/js-tokens": {
 | 
				
			||||||
      "version": "4.0.0",
 | 
					      "version": "4.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
 | 
					      "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
 | 
				
			||||||
 | 
				
			|||||||
@ -14,6 +14,7 @@
 | 
				
			|||||||
    "axios": "^1.8.4",
 | 
					    "axios": "^1.8.4",
 | 
				
			||||||
    "echarts": "^5.6.0",
 | 
					    "echarts": "^5.6.0",
 | 
				
			||||||
    "element-plus": "^2.9.7",
 | 
					    "element-plus": "^2.9.7",
 | 
				
			||||||
 | 
					    "js-base64": "^3.7.7",
 | 
				
			||||||
    "pinia": "^3.0.1",
 | 
					    "pinia": "^3.0.1",
 | 
				
			||||||
    "pinia-plugin-persistedstate": "^4.2.0",
 | 
					    "pinia-plugin-persistedstate": "^4.2.0",
 | 
				
			||||||
    "splitpanes": "^4.0.4",
 | 
					    "splitpanes": "^4.0.4",
 | 
				
			||||||
 | 
				
			|||||||
@ -15,4 +15,12 @@ export function roleGetDetail(baseUrl, params) {
 | 
				
			|||||||
        method: 'get',
 | 
					        method: 'get',
 | 
				
			||||||
        params: params,
 | 
					        params: params,
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function gameLogEventList(baseUrl, params) {
 | 
				
			||||||
 | 
					    return request({
 | 
				
			||||||
 | 
					        url: baseUrl + '/special/event_list',
 | 
				
			||||||
 | 
					        method: 'get',
 | 
				
			||||||
 | 
					        params: params,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										71
									
								
								ui/src/components/game/gamelogList.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								ui/src/components/game/gamelogList.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {gameLogEventList} from "@/api/account.js";
 | 
				
			||||||
 | 
					import LocalCache from "@/stores/localCache.js";
 | 
				
			||||||
 | 
					import {Base64} from 'js-base64'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const props = defineProps({
 | 
				
			||||||
 | 
					  eventNames: [],
 | 
				
			||||||
 | 
					  serverId: "",
 | 
				
			||||||
 | 
					  account: "",
 | 
				
			||||||
 | 
					  roleId: "",
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const eventList = ref({
 | 
				
			||||||
 | 
					  totalCount: 0,
 | 
				
			||||||
 | 
					  fieldsDescInfo: [],
 | 
				
			||||||
 | 
					  rows: [],
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const cachedResource = LocalCache.getCache("resource");
 | 
				
			||||||
 | 
					const resource_url = cachedResource.meta.resource_url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getPageNo = ref(1)
 | 
				
			||||||
 | 
					const getPageLen = ref(20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getEventList = () => {
 | 
				
			||||||
 | 
					  gameLogEventList(resource_url, {
 | 
				
			||||||
 | 
					    "AppId": 41,
 | 
				
			||||||
 | 
					    "EventName": props.eventNames,
 | 
				
			||||||
 | 
					    "ServerId": props.serverId,
 | 
				
			||||||
 | 
					    "Account": props.account,
 | 
				
			||||||
 | 
					    "RoleId": props.roleId,
 | 
				
			||||||
 | 
					    "PageNo": getPageNo.value,
 | 
				
			||||||
 | 
					    "PageLen": getPageLen.value,
 | 
				
			||||||
 | 
					  }).then(res => {
 | 
				
			||||||
 | 
					    // console.log("获取账户聊天记录返回:", res.data)
 | 
				
			||||||
 | 
					    eventList.value = res.data
 | 
				
			||||||
 | 
					  }, err => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					defineExpose({
 | 
				
			||||||
 | 
					  getEventList
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function b64Decode(str) {
 | 
				
			||||||
 | 
					  return Base64.decode(str)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <div>
 | 
				
			||||||
 | 
					    <span>
 | 
				
			||||||
 | 
					       <el-table :data="eventList.rows" max-height="500px" style="width: 100%" table-layout="auto" border :show-header="true">
 | 
				
			||||||
 | 
					         <el-table-column v-for="(field, i) in eventList.fieldsDescInfo" :prop="field.name" :label="field.alias" width="100px">
 | 
				
			||||||
 | 
					           <template #default="scope">
 | 
				
			||||||
 | 
					             <span>
 | 
				
			||||||
 | 
					               {{scope.row[i]}}
 | 
				
			||||||
 | 
					             </span>
 | 
				
			||||||
 | 
					           </template>
 | 
				
			||||||
 | 
					         </el-table-column>
 | 
				
			||||||
 | 
					        </el-table>
 | 
				
			||||||
 | 
					    </span>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@ -2,7 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import userDetailAccount from '@/components/game/userDetailAccount.vue';
 | 
					import userDetailAccount from '@/components/game/userDetailAccount.vue';
 | 
				
			||||||
import userDetailOrder from '@/components/game/userDetailOrder.vue';
 | 
					import userDetailOrder from '@/components/game/userDetailOrder.vue';
 | 
				
			||||||
import {accountGetDetail} from "@/api/account.js";
 | 
					import gamelogList from '@/components/game/gamelogList.vue';
 | 
				
			||||||
 | 
					import {accountGetDetail, gameLogEventList} from "@/api/account.js";
 | 
				
			||||||
import LocalCache from "@/stores/localCache.js";
 | 
					import LocalCache from "@/stores/localCache.js";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = defineProps({
 | 
					const props = defineProps({
 | 
				
			||||||
@ -31,6 +32,10 @@ accountGetDetail(resource_url, props.rowInfo).then((res) => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const gamelogChatChildRef = ref(null);
 | 
				
			||||||
 | 
					const gamelogCurrencyChildRef = ref(null);
 | 
				
			||||||
 | 
					const gamelogItemChangeChildRef = ref(null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handleClick = (tab, event) => {
 | 
					const handleClick = (tab, event) => {
 | 
				
			||||||
  // console.log("tab info:", tab)
 | 
					  // console.log("tab info:", tab)
 | 
				
			||||||
  switch (tab.props.name) {
 | 
					  switch (tab.props.name) {
 | 
				
			||||||
@ -40,6 +45,15 @@ const handleClick = (tab, event) => {
 | 
				
			|||||||
    case 'order':
 | 
					    case 'order':
 | 
				
			||||||
      console.log("点击了充值订单记录")
 | 
					      console.log("点击了充值订单记录")
 | 
				
			||||||
      break
 | 
					      break
 | 
				
			||||||
 | 
					    case 'chat':
 | 
				
			||||||
 | 
					      gamelogChatChildRef.value.getEventList()
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    case 'currencyChange':
 | 
				
			||||||
 | 
					      gamelogCurrencyChildRef.value.getEventList()
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
 | 
					    case 'itemChange':
 | 
				
			||||||
 | 
					      gamelogItemChangeChildRef.value.getEventList()
 | 
				
			||||||
 | 
					      break
 | 
				
			||||||
    case 'currency':
 | 
					    case 'currency':
 | 
				
			||||||
      console.log("点击了货币记录")
 | 
					      console.log("点击了货币记录")
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -51,10 +65,19 @@ const handleClick = (tab, event) => {
 | 
				
			|||||||
  <div>
 | 
					  <div>
 | 
				
			||||||
    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" v-if="loadAccountOk">
 | 
					    <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" v-if="loadAccountOk">
 | 
				
			||||||
      <el-tab-pane label="账号详情" name="detail">
 | 
					      <el-tab-pane label="账号详情" name="detail">
 | 
				
			||||||
        <component :is="userDetailAccount" v-if="loadAccountOk" :accountInfo="accountInfo"/>
 | 
					        <component :is="userDetailAccount" :accountInfo="accountInfo"/>
 | 
				
			||||||
      </el-tab-pane>
 | 
					      </el-tab-pane>
 | 
				
			||||||
      <el-tab-pane label="充值订单记录" name="order" v-if="loadAccountOk" :accountInfo="accountInfo">
 | 
					      <el-tab-pane label="充值订单记录" name="order">
 | 
				
			||||||
        <component :is="userDetailOrder" v-if="loadAccountOk" :accountInfo="accountInfo"/>
 | 
					        <component :is="userDetailOrder" :accountInfo="accountInfo"/>
 | 
				
			||||||
 | 
					      </el-tab-pane>
 | 
				
			||||||
 | 
					      <el-tab-pane label="聊天记录" name="chat">
 | 
				
			||||||
 | 
					        <gamelogList ref="gamelogChatChildRef" :serverId="serverId" :account="account" :eventName="chatlog"/>
 | 
				
			||||||
 | 
					      </el-tab-pane>
 | 
				
			||||||
 | 
					      <el-tab-pane label="货币变动" name="currencyChange">
 | 
				
			||||||
 | 
					        <gamelogList ref="gamelogCurrencyChildRef"  :serverId="serverId" :account="account" :eventName="addcoin,costcoin"/>
 | 
				
			||||||
 | 
					      </el-tab-pane>
 | 
				
			||||||
 | 
					      <el-tab-pane label="道具变动" name="itemChange">
 | 
				
			||||||
 | 
					        <gamelogList ref="gamelogItemChangeChildRef"  :serverId="serverId" :account="account" :eventName="gainitem,costitem"/>
 | 
				
			||||||
      </el-tab-pane>
 | 
					      </el-tab-pane>
 | 
				
			||||||
      <!--      <el-tab-pane label="货币记录" name="currency" v-if="accountInfo !== null">货币记录子页面</el-tab-pane>-->
 | 
					      <!--      <el-tab-pane label="货币记录" name="currency" v-if="accountInfo !== null">货币记录子页面</el-tab-pane>-->
 | 
				
			||||||
    </el-tabs>
 | 
					    </el-tabs>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								ui/src/views/gamelog/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ui/src/views/gamelog/index.vue
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					<script setup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user