merge gamelog
This commit is contained in:
commit
4c2afbf5d5
62
admin/apps/game/domain/gamelog.go
Normal file
62
admin/apps/game/domain/gamelog.go
Normal file
@ -0,0 +1,62 @@
|
||||
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/jmoiron/sqlx"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GameLogService struct {
|
||||
projectRepo repo.IProjectRepo
|
||||
repo repo.IGameLogRepo
|
||||
}
|
||||
|
||||
func NewGameLogSvc(db *gorm.DB, metaDb *gorm.DB, clickHouseSqlx *sqlx.DB) *GameLogService {
|
||||
return &GameLogService{projectRepo: repo.NewProjectRepo(db), repo: repo.NewGameLogRepo(metaDb, clickHouseSqlx)}
|
||||
}
|
||||
|
||||
func (svc *GameLogService) QueryEventList(projectId 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)
|
||||
}
|
||||
appId := projectEt.Po.BiAdminAppId
|
||||
|
||||
if appId == 0 {
|
||||
return 0, make([]*dto.GameLogFieldInfo, 0), make([][]any, 0), nil
|
||||
}
|
||||
|
||||
var attrList []*repo.AttrInfo
|
||||
attrList, err = svc.repo.QueryAttrListByEvent(appId, eventName)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
querier := svc.repo.NewEventListQuerier("xwl_event"+strconv.Itoa(appId), 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 {
|
||||
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_WhiteList: &smdl.WhitelistHook{}, // 所有角色走神魔大陆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 {
|
||||
ServerId string `json:"server_id"`
|
||||
AccountId string `json:"account_id"`
|
||||
RoleId string `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
Sn string `json:"sn"`
|
||||
ProductId string `json:"product_id"`
|
||||
Price int `json:"price"`
|
||||
PurchaseType string `json:"purchase_type"`
|
||||
PurchaseAt int64 `json:"purchase_at"`
|
||||
ServerId string `json:"server_id"`
|
||||
AccountId string `json:"account_id"`
|
||||
RoleId string `json:"role_id"`
|
||||
RoleName string `json:"role_name"`
|
||||
Sn string `json:"sn"`
|
||||
ProductId string `json:"product_id"`
|
||||
Price int `json:"price"`
|
||||
PurchaseType string `json:"purchase_type"`
|
||||
PurchasePlatform string `json:"purchasePlatform"`
|
||||
PurchaseAt int64 `json:"purchase_at"`
|
||||
}
|
||||
|
||||
func (info *AccountDetailOrderInfo) toDto() *dto2.AccountDetailOrderInfo {
|
||||
@ -120,7 +121,7 @@ func (info *AccountDetailOrderInfo) toDto() *dto2.AccountDetailOrderInfo {
|
||||
Sn: info.Sn,
|
||||
ProductId: info.ProductId,
|
||||
Price: info.Price,
|
||||
PurchaseType: info.PurchaseType,
|
||||
PurchaseType: info.PurchasePlatform,
|
||||
PurchaseAt: utils.ParseUnixTimestamp2LocalTime(info.PurchaseAt).Format(time.DateTime),
|
||||
}
|
||||
}
|
||||
@ -149,6 +150,7 @@ func (info *AccountDetailRoleInfo) toDto() *dto2.AccountDetailRoleInfo {
|
||||
CurrencyItems: info.CurrencyItems,
|
||||
CreatedAt: utils.ParseUnixTimestamp2LocalTime(info.CreatedAt).Format(time.DateTime),
|
||||
LastLoginTime: utils.ParseUnixTimestamp2LocalTime(info.LastLoginTime).Format(time.DateTime),
|
||||
OrderList: make([]*dto2.AccountDetailOrderInfo, 0),
|
||||
}
|
||||
totalPayAmount := 0
|
||||
for _, order := range info.OrderList {
|
||||
|
290
admin/apps/game/domain/projects/smdl/gamelog.go
Normal file
290
admin/apps/game/domain/projects/smdl/gamelog.go
Normal file
@ -0,0 +1,290 @@
|
||||
package smdl
|
||||
|
||||
import (
|
||||
"admin/apps/game/domain/entity"
|
||||
dto2 "admin/internal/model/dto"
|
||||
"admin/lib/xlog"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type GameLogHook struct {
|
||||
}
|
||||
|
||||
var removeFields = map[string]struct{}{
|
||||
"pub_mediaid": {},
|
||||
"pub_role_name": {},
|
||||
"pub_udid": {},
|
||||
}
|
||||
|
||||
var fieldsAlias = 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 rowI, row := range rows {
|
||||
row = append(row[:i], row[i+1:]...)
|
||||
rows[rowI] = row
|
||||
}
|
||||
} else {
|
||||
// 查找要不要把value做base64解码
|
||||
if _, find := base64decodeFields[field.Name]; find {
|
||||
for _, row := range rows {
|
||||
newValue, err := base64.StdEncoding.DecodeString(row[i].(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++
|
||||
}
|
||||
}
|
||||
|
||||
//fBin, _ := json.Marshal(&fieldsDescInfo)
|
||||
//rBin, _ := json.Marshal(&rows)
|
||||
//xlog.Tracef("gamelog1 query result:%v, rows:%v", string(fBin), string(rBin))
|
||||
|
||||
fieldsDescInfo, rows = (&queryResultInfo{fields: fieldsDescInfo, rows: rows}).tidyByEventDescInfo(eventName)
|
||||
|
||||
//fBin, _ = json.Marshal(&fieldsDescInfo)
|
||||
//rBin, _ = json.Marshal(&rows)
|
||||
//xlog.Tracef("gamelog1 query result:%v, rows:%v", string(fBin), string(rBin))
|
||||
|
||||
for i, f := range fieldsDescInfo {
|
||||
// 修改每一行日志别名
|
||||
if f.Name == "xwl_part_event" {
|
||||
for j := range rows {
|
||||
opEventName := rows[j][i].(string)
|
||||
descInfo, find := globEventList[opEventName]
|
||||
if find {
|
||||
rows[j][i] = descInfo.Alias
|
||||
}
|
||||
}
|
||||
} else if f.Name == "xwl_part_date" {
|
||||
for j := range rows {
|
||||
eventDate := rows[j][i].(time.Time)
|
||||
//eventDate, err := time.Parse("2006-01-02T15:04:05+07:00", eventDateString)
|
||||
rows[j][i] = eventDate.Format(time.DateTime)
|
||||
}
|
||||
}
|
||||
// 修改每一行公共属性别名
|
||||
alias, find := fieldsAlias[f.Name]
|
||||
if find && f.Name == f.Alias {
|
||||
f.Alias = alias
|
||||
}
|
||||
}
|
||||
|
||||
fBin, _ := json.Marshal(&fieldsDescInfo)
|
||||
rBin, _ := json.Marshal(&rows)
|
||||
xlog.Tracef("gamelog2 query result:%v, rows:%v", string(fBin), string(rBin))
|
||||
|
||||
i = 0
|
||||
for {
|
||||
if i >= len(fieldsDescInfo) {
|
||||
break
|
||||
}
|
||||
f := fieldsDescInfo[i]
|
||||
swapI := 2
|
||||
if f.Name == "pub_serverid" || f.Name == "pub_roleid" || f.Name == "pub_rolename" {
|
||||
pubF := fieldsDescInfo[i]
|
||||
for moveI := i; moveI > swapI; moveI-- {
|
||||
fieldsDescInfo[moveI] = fieldsDescInfo[moveI-1]
|
||||
}
|
||||
fieldsDescInfo[swapI] = pubF
|
||||
|
||||
for _, row := range rows {
|
||||
pubValue := row[i]
|
||||
for moveI := i; moveI > swapI; moveI-- {
|
||||
row[moveI] = row[moveI-1]
|
||||
}
|
||||
row[swapI] = pubValue
|
||||
}
|
||||
swapI++
|
||||
}
|
||||
i++
|
||||
}
|
||||
|
||||
return totalCount, fieldsDescInfo, rows
|
||||
}
|
||||
|
||||
type queryResultInfo struct {
|
||||
fields []*dto2.GameLogFieldInfo
|
||||
rows [][]any
|
||||
}
|
||||
|
||||
func (info *queryResultInfo) tidyByEventDescInfo(eventNameList []string) ([]*dto2.GameLogFieldInfo, [][]any) {
|
||||
if len(eventNameList) == 0 {
|
||||
return info.fields, info.rows
|
||||
}
|
||||
if len(eventNameList) == 1 {
|
||||
en := eventNameList[0]
|
||||
enDescInfo, find := globEventList[en]
|
||||
if !find {
|
||||
panic(en)
|
||||
}
|
||||
for _, f := range info.fields {
|
||||
for _, df := range enDescInfo.fields {
|
||||
fName := removeFieldEventName(en, f.Name)
|
||||
if fName == df.Name && f.Name == f.Alias {
|
||||
f.Alias = df.Alias
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return info.fields, info.rows
|
||||
}
|
||||
|
||||
// 神魔的埋点里字段名是日志名_字段名,所以如果一次游戏日志查询包含多个事件名,会查出稀疏数据,
|
||||
// 例如gainitem,loseitem两个日志,都会存在gainitem_itemid,loseitem_itemid,需要把对应
|
||||
// 为0的稀疏字段去掉
|
||||
|
||||
// 具体方案:
|
||||
// 1.创建新的行数据,将自己日志的字段值先追加进来,然后前面补上日志名,后面补上公共字段,
|
||||
// 2.字段描述信息直接全部去重
|
||||
|
||||
newRows := make([][]any, len(info.rows))
|
||||
for rowI, row := range info.rows {
|
||||
curRowEventName := row[0].(string)
|
||||
enDescInfo, find := globEventList[curRowEventName]
|
||||
if !find {
|
||||
// 不存在描述信息,先崩溃下
|
||||
panic(curRowEventName)
|
||||
}
|
||||
|
||||
for _, fieldDesc := range enDescInfo.fields {
|
||||
for i, field := range info.fields {
|
||||
fName := removeFieldEventName(curRowEventName, field.Name)
|
||||
if fName == fieldDesc.Name {
|
||||
newRows[rowI] = append(newRows[rowI], row[i])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 上面步骤走完,newRows每一行都是各自日志的字段值了,但是每一行长度可能不一样,例如gainitem就比loseitem多一个字段
|
||||
// 下面步骤会把字段描述信息通过事件名具有的所有字段去重追加,例如gainitem就是全量的字段,loseitem就是子集
|
||||
newFieldsDescInfo := make([]*dto2.GameLogFieldInfo, 0, len(info.fields))
|
||||
for _, en := range eventNameList {
|
||||
enDescInfo, find := globEventList[en]
|
||||
if !find {
|
||||
panic(en)
|
||||
}
|
||||
find = false
|
||||
for _, fd := range enDescInfo.fields {
|
||||
for _, newFd := range newFieldsDescInfo {
|
||||
if fd.Name == newFd.Name {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
// 追加
|
||||
for _, oldFd := range info.fields {
|
||||
fName := removeFieldEventName(en, oldFd.Name)
|
||||
if fName == fd.Name {
|
||||
newFieldInfo := &dto2.GameLogFieldInfo{
|
||||
Name: fName,
|
||||
Alias: oldFd.Alias,
|
||||
IsPublicField: oldFd.IsPublicField,
|
||||
FieldType: oldFd.FieldType,
|
||||
}
|
||||
if oldFd.Name == oldFd.Alias {
|
||||
newFieldInfo.Alias = fd.Alias
|
||||
}
|
||||
newFieldsDescInfo = append(newFieldsDescInfo, newFieldInfo)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 走完上面这一步,newFieldsDescInfo就是事件列表具有的所有去重字段了
|
||||
allEventFieldsLen := len(newFieldsDescInfo)
|
||||
|
||||
// 给newRows和newFieldsDescInfo前追加公共字段了
|
||||
// 追加前面的日志名、时间
|
||||
tmpFields := make([]*dto2.GameLogFieldInfo, 2)
|
||||
copy(tmpFields, info.fields[:2])
|
||||
newFieldsDescInfo = append(tmpFields, newFieldsDescInfo...)
|
||||
for i, newRow := range newRows {
|
||||
if len(newRow) < allEventFieldsLen {
|
||||
rowCols := len(newRow)
|
||||
for j := 0; j < allEventFieldsLen-rowCols; j++ {
|
||||
// 补充这一行日志没有的字段
|
||||
newRow = append(newRow, "\\")
|
||||
}
|
||||
} else if len(newRow) > allEventFieldsLen {
|
||||
panic(fmt.Sprintf("%v,%v", len(newRow), allEventFieldsLen))
|
||||
}
|
||||
tmpCols := make([]any, 2)
|
||||
copy(tmpCols, info.rows[i][:2])
|
||||
newRow = append(tmpCols, newRow...)
|
||||
newRows[i] = newRow
|
||||
}
|
||||
|
||||
// 给newRows和newFieldsDescInfo后追加公共字段了
|
||||
for i, f := range info.fields {
|
||||
if len(f.Name) >= 4 && f.Name[:4] == "pub_" {
|
||||
newFieldsDescInfo = append(newFieldsDescInfo, info.fields[i:]...)
|
||||
for rowI, newRow := range newRows {
|
||||
newRow = append(newRow, info.rows[rowI][i:]...)
|
||||
newRows[rowI] = newRow
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return newFieldsDescInfo, newRows
|
||||
}
|
||||
|
||||
// 因为推送到clickhouse的字段名都是日志名_字段名的格式,放置不同日志出现同名字段冲突,这里直接去掉一下日志名
|
||||
func removeFieldEventName(eventName, fieldName string) string {
|
||||
return strings.ReplaceAll(fieldName, eventName+"_", "")
|
||||
}
|
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
146
admin/apps/game/domain/repo/gamelog.go
Normal file
146
admin/apps/game/domain/repo/gamelog.go
Normal file
@ -0,0 +1,146 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"admin/apps/game/model"
|
||||
"admin/internal/errcode"
|
||||
"admin/lib/utils"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type IGameLogRepo interface {
|
||||
QueryAttrListByEvent(appId int, eventName []string) ([]*AttrInfo, error)
|
||||
NewEventListQuerier(tableName string, eventName []string, attrList []*AttrInfo) *EventListQuerier
|
||||
}
|
||||
|
||||
func NewGameLogRepo(metaDb *gorm.DB, clickHouseSqlx *sqlx.DB) IGameLogRepo {
|
||||
return &gameLogRepoImpl{metaDb: metaDb, clickHouseSqlx: clickHouseSqlx}
|
||||
}
|
||||
|
||||
type gameLogRepoImpl struct {
|
||||
metaDb *gorm.DB
|
||||
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)
|
||||
}
|
||||
|
||||
normalAttrList := make([]*AttrInfo, 0)
|
||||
publicAttrList := make([]*AttrInfo, 0)
|
||||
|
||||
var eventNameAttr *AttrInfo
|
||||
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" && attr.AttrName != "xwl_part_event" {
|
||||
continue
|
||||
}
|
||||
if attr.AttrName == "xwl_part_date" {
|
||||
timeAttr = &AttrInfo{
|
||||
Name: attr.AttrName,
|
||||
Alias: "时间",
|
||||
DataType: attr.AttrFieldType,
|
||||
IsUserAttr: true,
|
||||
}
|
||||
} else if attr.AttrName == "xwl_part_event" {
|
||||
eventNameAttr = &AttrInfo{
|
||||
Name: attr.AttrName,
|
||||
Alias: "操作类型",
|
||||
DataType: attr.AttrFieldType,
|
||||
IsUserAttr: true,
|
||||
}
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
find := false
|
||||
for _, oldAttr := range normalAttrList {
|
||||
if oldAttr.Name == attr.AttrName {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
for _, oldAttr := range publicAttrList {
|
||||
if oldAttr.Name == attr.AttrName {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !find {
|
||||
var isPublicField bool
|
||||
if len(attr.AttrName) >= 4 {
|
||||
isPublicField = attr.AttrName[:4] == "pub_"
|
||||
}
|
||||
attrInfo := &AttrInfo{
|
||||
Name: attr.AttrName,
|
||||
Alias: attr.AttrAlias,
|
||||
DataType: attr.AttrFieldType,
|
||||
IsUserAttr: isPublicField,
|
||||
}
|
||||
if isPublicField {
|
||||
publicAttrList = append(publicAttrList, attrInfo)
|
||||
} else {
|
||||
normalAttrList = append(normalAttrList, attrInfo)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if timeAttr != nil {
|
||||
normalAttrList = append([]*AttrInfo{timeAttr}, normalAttrList...)
|
||||
}
|
||||
if eventNameAttr != nil {
|
||||
normalAttrList = append([]*AttrInfo{eventNameAttr}, normalAttrList...)
|
||||
}
|
||||
|
||||
return append(normalAttrList, publicAttrList...), 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.clickHouseSqlx = impl.clickHouseSqlx
|
||||
querier.tableName = tableName
|
||||
querier.eventName = eventName
|
||||
querier.attrList = attrList
|
||||
return querier
|
||||
}
|
221
admin/apps/game/domain/repo/gamelog_querier.go
Normal file
221
admin/apps/game/domain/repo/gamelog_querier.go
Normal file
@ -0,0 +1,221 @@
|
||||
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
|
||||
}
|
||||
|
||||
if xlog.GetLogLevel() <= xlog.LogLevelDebug {
|
||||
argsBin, _ := json.Marshal(&sqlArgs)
|
||||
rowsBin, _ := json.Marshal(&rows)
|
||||
xlog.Debugf("query sql:%v with args:%v, rows result:%v", sql, string(argsBin), string(rowsBin))
|
||||
}
|
||||
|
||||
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 {
|
||||
if len(querier.eventName) == 1 {
|
||||
whereList = append(whereList, "`xwl_part_event`=?")
|
||||
whereArgs = append(whereArgs, querier.eventName[0])
|
||||
} else {
|
||||
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(" order by xwl_part_date desc 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,
|
||||
FieldType: field.DataType,
|
||||
}
|
||||
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)
|
||||
}
|
||||
if xlog.GetLogLevel() <= xlog.LogLevelTrace {
|
||||
argsBin, _ := json.Marshal(&args)
|
||||
cacheRowBin, _ := json.Marshal(&readCacheRow)
|
||||
xlog.Tracef("query sql:%v with args:%+v result row:%v", sql, string(argsBin), string(cacheRowBin))
|
||||
}
|
||||
|
||||
parsedRow := make([]any, len(readCacheRow))
|
||||
for i := range readCacheRow {
|
||||
parsedRow[i] = *(readCacheRow[i].(*interface{}))
|
||||
}
|
||||
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"
|
||||
}
|
@ -25,13 +25,14 @@ type Project struct {
|
||||
// 不为空就代表项目要实现一个自己统一对外暴露的gm调用服务对内聚合、分发指令执行,本后台执行指令只调用一次;
|
||||
// 为空就代表command_list实现在各个逻辑服,由本后台系统在执行指令时聚合、分发指令
|
||||
// 调用各个逻辑服执行,本后台执行指令需要根据逻辑服数量调用;
|
||||
ApiAddr string `name:"游戏api地址" desc:"api服务器地址,例如神魔大陆就是alisrv服务器地址,用于后台调用gm"`
|
||||
DfsBucket string `name:"分布式存储桶名" desc:"上传服务器列表分布式存储的桶名"`
|
||||
DfsRegion string `name:"分布式存储区域" desc:"上传服务器列表分布式存储的桶区域例如ap-chengdu"`
|
||||
CdnPath string `name:"cdn地址" desc:"拉取服务器列表文件的cdn"`
|
||||
SortWeight int `name:"菜单排序" desc:"越大越靠前"`
|
||||
CreatedAt time.Time `readonly:"true"`
|
||||
UpdatedAt time.Time `readonly:"true"`
|
||||
ApiAddr string `name:"游戏api地址" desc:"api服务器地址,例如神魔大陆就是alisrv服务器地址,用于后台调用gm"`
|
||||
DfsBucket string `name:"分布式存储桶名" desc:"上传服务器列表分布式存储的桶名"`
|
||||
DfsRegion string `name:"分布式存储区域" desc:"上传服务器列表分布式存储的桶区域例如ap-chengdu"`
|
||||
CdnPath string `name:"cdn地址" desc:"拉取服务器列表文件的cdn"`
|
||||
BiAdminAppId int `name:"bi后台appid" desc:"用于查找所属游戏日志"`
|
||||
SortWeight int `name:"菜单排序" desc:"越大越靠前"`
|
||||
CreatedAt time.Time `readonly:"true"`
|
||||
UpdatedAt time.Time `readonly:"true"`
|
||||
}
|
||||
|
||||
func (lm *Project) TableName() string {
|
||||
|
@ -3,11 +3,13 @@ package server
|
||||
import (
|
||||
"admin/internal/consts"
|
||||
"admin/internal/context"
|
||||
"admin/internal/errcode"
|
||||
"admin/internal/model/dto"
|
||||
"admin/lib/httpclient"
|
||||
"admin/lib/xlog"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func (ctl *controller) CommandList(ctx *context.WebContext, params *dto.CommandListReq, rsp *dto.CommandListRsp) error {
|
||||
@ -65,6 +67,35 @@ func (ctl *controller) ProjectResourceDelete(ctx *context.WebContext, params *dt
|
||||
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)
|
||||
}
|
||||
|
||||
var eventList []string
|
||||
if params.EventName != "" {
|
||||
eventList = strings.Split(params.EventName, ",")
|
||||
for _, en := range eventList {
|
||||
if en == "" {
|
||||
return errcode.New(errcode.ParamsInvalid, "event name invalid:[%v]", params.EventName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
rsp.TotalCount, rsp.FieldsDescInfo, rsp.Rows, err =
|
||||
ctl.svc.GameLogSvc.QueryEventList(projectId,
|
||||
eventList, params.ServerId, params.Account, params.RoleId, params.PageNo, params.PageLen, ds, de)
|
||||
return err
|
||||
}
|
||||
|
||||
func (ctl *controller) getProjectResourceCommandApiAddr(ctx *context.WebContext) ([]string, error) {
|
||||
projectId := getCtxURIProjectId(ctx)
|
||||
//resouce := getCtxURIResource(ctx)
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
func (srv *Server) Route(engine *web.Engine, sdkEngine *web.Engine) {
|
||||
|
||||
{ // gm后台内部路由
|
||||
engine.Use(srv.CheckToken)
|
||||
|
||||
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.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.Get("/detail", "角色详情查看", consts.WebPathPermit_Write, srv.ctl.GetRoleDetail)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
{ // gm后台作为sdk,供内部其它游戏调用的路由
|
||||
|
@ -4,12 +4,19 @@ import (
|
||||
"admin/apps/game/api"
|
||||
"admin/apps/game/domain"
|
||||
"admin/internal/consts"
|
||||
dbLib "admin/internal/db"
|
||||
"admin/internal/errcode"
|
||||
"admin/internal/event"
|
||||
"admin/internal/global"
|
||||
dto2 "admin/internal/model/dto"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
_ "github.com/ClickHouse/clickhouse-go/v2"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"gorm.io/gorm"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
@ -18,15 +25,43 @@ type Service struct {
|
||||
projectSvc *domain.ProjectService
|
||||
cdkeySvc *domain.CDKeyService
|
||||
accountSvc *domain.AccountService
|
||||
GameLogSvc *domain.GameLogService
|
||||
}
|
||||
|
||||
func New(db *gorm.DB) (*Service, error) {
|
||||
var metaDb *gorm.DB
|
||||
var clickHouseSqlx *sqlx.DB
|
||||
var err error
|
||||
|
||||
if global.GLOB_BOOT_FLAGS.BiMysqlAddr != "" {
|
||||
metaDb, err = dbLib.NewDBNoMigrate("mysql",
|
||||
global.GLOB_BOOT_FLAGS.BiMysqlAddr,
|
||||
global.GLOB_BOOT_FLAGS.BiMysqlDb,
|
||||
global.GLOB_BOOT_FLAGS.BiMysqlUser,
|
||||
global.GLOB_BOOT_FLAGS.BiMysqlPass)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dbSource := fmt.Sprintf(
|
||||
"tcp://%s?username=%s&password=%s&compress=true&database=%s",
|
||||
global.GLOB_BOOT_FLAGS.BiCkAddr,
|
||||
global.GLOB_BOOT_FLAGS.BiCkUser,
|
||||
global.GLOB_BOOT_FLAGS.BiCkPass,
|
||||
global.GLOB_BOOT_FLAGS.BiCkDb)
|
||||
clickHouseSqlx, err = NewCkDb("clickhouse", dbSource, 5, 20)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
//"192.168.6.83", "9000", "root", "dev123", "databi")
|
||||
}
|
||||
|
||||
svc := &Service{
|
||||
db: db,
|
||||
resourceSvc: domain.NewCommonResourceService(db),
|
||||
projectSvc: domain.NewProjectService(db),
|
||||
cdkeySvc: domain.NewCDKeyService(db),
|
||||
accountSvc: domain.NewAccountService(db),
|
||||
GameLogSvc: domain.NewGameLogSvc(db, metaDb, clickHouseSqlx),
|
||||
}
|
||||
api.RegisterGameApi(svc)
|
||||
//err := svc.ensureProjectsDBData()
|
||||
@ -36,6 +71,38 @@ func New(db *gorm.DB) (*Service, error) {
|
||||
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) {
|
||||
|
||||
params.ParsedWhereConditions = &dto2.ListWhereConditionInfo{}
|
||||
|
@ -7,12 +7,12 @@ import (
|
||||
|
||||
func (srv *Server) Route(engine *web.Engine) {
|
||||
|
||||
engine.Use(srv.CheckToken)
|
||||
|
||||
apiGroup := engine.Group("/api", "")
|
||||
|
||||
{
|
||||
userGroup := apiGroup.Group("/user", "用户操作组")
|
||||
userGroup.Use(srv.CheckToken)
|
||||
|
||||
userGroup.Post("/login", "登录", consts.WebPathPermit_Write, srv.ctl.Login)
|
||||
userGroup.Get("/info", "获取用户信息,里面包含用户权限信息,用于前端生成动态菜单", consts.WebPathPermit_Read, srv.ctl.GetUserInfo)
|
||||
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.Use(srv.CheckToken)
|
||||
|
||||
userResourceGroup.Get("", "查看列表", consts.WebPathPermit_Read, srv.ctl.CommonList)
|
||||
userResourceGroup.Post("", "新增", consts.WebPathPermit_Read, srv.ctl.CommonPost)
|
||||
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
|
||||
|
||||
require (
|
||||
github.com/ClickHouse/clickhouse-go/v2 v2.37.2
|
||||
github.com/gin-contrib/pprof v1.5.3
|
||||
github.com/gin-gonic/gin v1.10.0
|
||||
github.com/glebarez/sqlite v1.11.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/jmoiron/sqlx v1.4.0
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/redis/go-redis/v9 v9.8.0
|
||||
github.com/rpcxio/rpcx-gateway v0.0.0-20230602022101-74ed729109fd
|
||||
github.com/rpcxio/rpcx-redis v0.0.0-20250107024620-f10ac7d956cb
|
||||
github.com/rs/zerolog v1.34.0
|
||||
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
|
||||
golang.org/x/crypto v0.38.0
|
||||
golang.org/x/sync v0.14.0
|
||||
golang.org/x/crypto v0.39.0
|
||||
golang.org/x/sync v0.15.0
|
||||
golang.org/x/telemetry v0.0.0-20250507143331-155ddd5254aa
|
||||
golang.org/x/tools v0.33.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
@ -26,8 +29,11 @@ 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/alitto/pond v1.9.2 // indirect
|
||||
github.com/andybalholm/brotli v1.1.1 // indirect
|
||||
github.com/apache/thrift v0.21.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // 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/gin-contrib/sse v1.0.0 // 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-playground/locales v0.14.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/julienschmidt/httprouter v1.3.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/reedsolomon v1.12.4 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // 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/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/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
@ -94,12 +105,13 @@ require (
|
||||
github.com/rpcxio/libkv v0.5.1 // indirect
|
||||
github.com/rs/cors v1.11.1 // 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/rsocket v0.0.0-20241130031020-4a72eb6ff62a // indirect
|
||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // 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/tinylib/msgp v1.2.5 // 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/tagparser/v2 v2.0.0 // 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
|
||||
golang.org/x/arch v0.16.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.40.0 // indirect
|
||||
golang.org/x/mod v0.25.0 // indirect
|
||||
golang.org/x/net v0.41.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
|
||||
modernc.org/libc v1.22.5 // 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/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=
|
||||
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=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
|
||||
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/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/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/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=
|
||||
@ -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/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-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.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
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.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
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.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-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=
|
||||
@ -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.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.1/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/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/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
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/json-iterator/go v1.1.5/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.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
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/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
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-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/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/go.mod h1:5NxulaB17yJ07IpzRIleys4un0PJ7WLWgMDLBBWrGw8=
|
||||
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.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
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/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
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.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
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.4.0 h1:aBn6aRXtFzyDLZ4VIRLsZbbJloagQfMnCiYgOq6hK4w=
|
||||
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/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/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.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M=
|
||||
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/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/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/errors v0.8.0/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-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/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/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/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=
|
||||
@ -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/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/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/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
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/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/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/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-20200209145036-adba10fffc37 h1:EWU6Pktpas0n8lLQwDsRyZfmkPeRbdgPtW609es+/9E=
|
||||
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.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
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/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.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.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
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 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/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 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/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
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-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-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
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.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
|
||||
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
|
||||
golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM=
|
||||
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-20250128144449-3edf0e91c1ae h1:COZdc9Ut6wLq7MO9GIYxfZl4n4ScmgqQLoHocKXrxco=
|
||||
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.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.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
|
||||
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-20180826012351-8a410e7b638d/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-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-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.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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
|
||||
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
|
||||
golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
|
||||
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-20181017192945-9dcd33a902f4/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-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.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
|
||||
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
|
||||
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-20180830151530-49385e6e1522/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-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-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-20220520151302-bc2c85ada10a/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.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.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.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
||||
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
|
||||
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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
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.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.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.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
|
@ -1,10 +1,18 @@
|
||||
package config
|
||||
|
||||
type CommonBootFlags struct {
|
||||
ApiPort string `env:"api_port" default:"8080" desc:"api端口,客户端请求的地址端口"`
|
||||
DBType string `env:"db_type" default:"sqlite" desc:"数据库类型,默认sqlite,可选:sqlite|mysql|pg"`
|
||||
DBAddr string `env:"db_addr" default:"localhost" desc:"数据库地址"`
|
||||
DBName string `env:"db_name" default:"uniugm" desc:"数据库名字"`
|
||||
DBUser string `env:"db_user" default:"root" desc:"数据库用户名"`
|
||||
DBPass string `env:"db_pass" default:"" desc:"数据库密码"`
|
||||
ApiPort string `env:"api_port" default:"8080" desc:"api端口,客户端请求的地址端口"`
|
||||
DBType string `env:"db_type" default:"sqlite" desc:"数据库类型,默认sqlite,可选:sqlite|mysql|pg"`
|
||||
DBAddr string `env:"db_addr" default:"localhost" desc:"数据库地址"`
|
||||
DBName string `env:"db_name" default:"uniugm" desc:"数据库名字"`
|
||||
DBUser string `env:"db_user" default:"root" desc:"数据库用户名"`
|
||||
DBPass string `env:"db_pass" default:"" desc:"数据库密码"`
|
||||
BiCkAddr string `env:"bi_ck_addr" desc:"clickhouse分析数据库地址"`
|
||||
BiCkDb string `env:"bi_ck_db" desc:"clickhouse数据库"`
|
||||
BiCkUser string `env:"bi_ck_user" desc:"clickhouse用户名"`
|
||||
BiCkPass string `env:"bi_ck_pass" desc:"clickhouse密码"`
|
||||
BiMysqlAddr string `env:"bi_mysql_addr" desc:"mysql分析数据库地址"`
|
||||
BiMysqlDb string `env:"bi_mysql_db" desc:"mysql数据库"`
|
||||
BiMysqlUser string `env:"bi_mysql_user" desc:"mysql用户名"`
|
||||
BiMysqlPass string `env:"bi_mysql_pass" desc:"mysql密码"`
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ const (
|
||||
ResourcesName_DevicePush = "device_push"
|
||||
ResourcesName_ItemBag = "item_bag"
|
||||
ResourcesName_GenAccount = "gen_account"
|
||||
ResourcesName_GameLog = "gamelog"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -39,6 +39,36 @@ func NewDB(dbType, dbAddr, dbName, dbUser, dbPass string) (db *gorm.DB, err erro
|
||||
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) {
|
||||
mysqlDriverConf, err := mysqlDriver.ParseDSN(dsn)
|
||||
if err != nil {
|
||||
|
@ -152,3 +152,10 @@ type WhiteListInfo struct {
|
||||
WType string `json:"w_type"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type GameLogFieldInfo struct {
|
||||
Name string `json:"name"`
|
||||
Alias string `json:"alias"`
|
||||
IsPublicField bool `json:"isPublicField"`
|
||||
FieldType int `json:"fieldType"`
|
||||
}
|
||||
|
@ -135,3 +135,20 @@ type GetRoleDetailReq struct {
|
||||
type GetRoleDetailRsp struct {
|
||||
RoleInfo *RoleDetailInfo `json:"role_info"`
|
||||
}
|
||||
|
||||
type GameLogEventListReq struct {
|
||||
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
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Vite App</title>
|
||||
<script type="module" crossorigin src="/static/js/index-hOIgOejC.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/static/js/vendor-B2m3dX6z.js">
|
||||
<script type="module" crossorigin src="/static/js/index-1btxRZkB.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/static/js/vendor-BRRlSJxx.js">
|
||||
<link rel="stylesheet" crossorigin href="/static/css/vendor-DnLjZ1mj.css">
|
||||
<link rel="stylesheet" crossorigin href="/static/css/index-BqAGgcXq.css">
|
||||
</head>
|
||||
|
1
admin/ui/static/static/css/table-Dwi5aXVw.css
Normal file
1
admin/ui/static/static/css/table-Dwi5aXVw.css
Normal file
@ -0,0 +1 @@
|
||||
.roleDetailList[data-v-5a8d8958] .el-table__header-wrapper th{word-break:break-word;background-color:#f8f8f9!important;color:#515a6e;height:40px!important;font-size:13px}.roleDetailList[data-v-5a8d8958] .el-table__header .el-table-column--selection .cell{width:60px!important}.roleDetailList[data-v-5a8d8958] .el-table .fixed-width .el-button--small{padding-left:0;padding-right:0;width:20px!important}.roleDetailList[data-v-5a8d8958] .el-table__header{background:#f5f7fa!important}.roleDetailList[data-v-5a8d8958] .el-table__row td{border-color:#ebeef5}.app-content[data-v-6117fd7c]{height:calc(100vh - 100px);display:flex}.app-content .table-content[data-v-6117fd7c]{display:flex;flex-direction:column;justify-content:space-between;height:100%;overflow:auto}.app-content .table-content .table[data-v-6117fd7c]{flex:1;position:relative}.app-content .table-content .table[data-v-6117fd7c] .el-table{flex:1;position:absolute}.app-content .table-content .table[data-v-6117fd7c] .el-popper{max-width:640px;word-break:break-all}.pagination-container .el-pagination[data-v-6117fd7c]{right:0;position:absolute;height:25px;margin-bottom:50px;margin-top:0;padding:10px 30px!important;z-index:2}.pagination-container.hidden[data-v-6117fd7c]{display:none}@media (max-width: 768px){.pagination-container .el-pagination>.el-pagination__jump[data-v-6117fd7c]{display:none!important}.pagination-container .el-pagination>.el-pagination__sizes[data-v-6117fd7c]{display:none!important}}
|
1
admin/ui/static/static/js/Login-C5AapNRS.js
Normal file
1
admin/ui/static/static/js/Login-C5AapNRS.js
Normal file
@ -0,0 +1 @@
|
||||
import{r as e,ab as a,a as s,o,d as r,b as l,w as n,a0 as t,a3 as u,ac as d,W as i,v as p,$ as c,a9 as m,I as v}from"./vendor-BRRlSJxx.js";import{_ as f,u as _,r as g}from"./index-1btxRZkB.js";const y={class:"login-box"},h={class:m({container:!0,animate__animated:!0,animate__flipInX:!0})},w={class:"form-container sign-in-container"},b=f({__name:"Login",setup(m){e(void 0);const{proxy:f}=a(),b=e({user:"",password:""}),V={user:[{required:!0,trigger:"blur",message:"请输入您的账号"}],password:[{required:!0,trigger:"blur",message:"请输入您的密码"}]},x=e=>{e&&f.$refs.ruleFormRef.validate((e=>{if(!e)return console.log("error submit!"),!1;_().login(b.value.user,b.value.password).then((()=>{console.log("登录成功,推送首页。。"),g.push({path:"/welcome"})}),(e=>{})).catch((()=>{v.error("login response error")}))}))};return(e,a)=>{const m=u,v=t,f=i,_=c;return o(),s("div",y,[r("div",h,[r("div",w,[l(_,{ref:"ruleFormRef",model:b.value,"status-icon":"",rules:V,class:"form"},{default:n((()=>[l(v,{class:"form-item",prop:"username"},{default:n((()=>[l(m,{modelValue:b.value.user,"onUpdate:modelValue":a[0]||(a[0]=e=>b.value.user=e),placeholder:"用户名",autocomplete:"off",onKeyup:a[1]||(a[1]=d((e=>x(b.value)),["enter"]))},null,8,["modelValue"])])),_:1}),l(v,{class:"form-item",prop:"password"},{default:n((()=>[l(m,{modelValue:b.value.password,"onUpdate:modelValue":a[2]||(a[2]=e=>b.value.password=e),placeholder:"密码",type:"password",autocomplete:"off",onKeyup:a[3]||(a[3]=d((e=>x(b.value)),["enter"]))},null,8,["modelValue"])])),_:1}),l(f,{class:"theme-button",type:"primary",onClick:a[4]||(a[4]=e=>x(b.value)),onKeydown:a[5]||(a[5]=d((e=>{var a;13!==a.keyCode&&100!==a.keyCode||x(b.value)}),["enter"]))},{default:n((()=>a[6]||(a[6]=[p("登 陆 ")]))),_:1})])),_:1},8,["model"])]),a[7]||(a[7]=r("div",{class:"overlay_container"},[r("div",{class:"overlay"},[r("div",{class:"overlay_panel overlay_right_container"},[r("h2",{class:"container-title"},"hello friend!"),r("p",null,"输入您的个人信息,以便使用后台管理系统")])])],-1))])])}}},[["__scopeId","data-v-68d4afe9"]]);export{b as default};
|
1
admin/ui/static/static/js/character--9gw0-Ov.js
Normal file
1
admin/ui/static/static/js/character--9gw0-Ov.js
Normal file
@ -0,0 +1 @@
|
||||
import{t as e}from"./tableUser-BT_id_R-.js";import{u as r,L as t}from"./index-1btxRZkB.js";import{a as s,o as a,c as o,B as c}from"./vendor-BRRlSJxx.js";import"./resource-ebhyDeUm.js";import"./empty-DuTaDG5U.js";const m={__name:"character",setup(m){let u={meta:{desc:"character",resource:"character",resource_url:"/resource/character",methods:{get:!0,post:!0,put:!0,delete:!0}}};return"admin"!==r().userInfo.character&&(u.meta.methods={}),t.setCache("resource",u),(r,t)=>(a(),s("div",null,[(a(),o(c(e)))]))}};export{m as default};
|
1
admin/ui/static/static/js/empty-DuTaDG5U.js
Normal file
1
admin/ui/static/static/js/empty-DuTaDG5U.js
Normal file
@ -0,0 +1 @@
|
||||
import{c as o,o as r,ai as s}from"./vendor-BRRlSJxx.js";import{_ as n}from"./index-1btxRZkB.js";const e=n({},[["render",function(n,e){const t=s;return r(),o(t,{description:"没有权限!请联系管理员添加权限!"})}]]);export{e};
|
1
admin/ui/static/static/js/history-C3Pvxh4X.js
Normal file
1
admin/ui/static/static/js/history-C3Pvxh4X.js
Normal file
@ -0,0 +1 @@
|
||||
import{r as e,T as a,a as l,o as t,c as o,u,B as n,F as s,U as p,w as r,b as d,V as i,a7 as v,a3 as m,a8 as c,W as g,v as h,C as y,d as f,X as V,Y as b,Z as x,D as w,a9 as I}from"./vendor-BRRlSJxx.js";import{_ as k,u as _,a as C}from"./index-1btxRZkB.js";import{e as U}from"./empty-DuTaDG5U.js";const z={class:"table-content"},j={class:"table"},D={class:"pagination-container"},R=k({__name:"history",props:{rowInfo:{},disableConditionInput:!0},setup(k){const R=k;let S=!0;!1===R.disableConditionInput&&(S=!1);const T="admin"===_().userInfo.character,A=e(T),B=e(1),F=e(20),G=e(R.userId);R.rowInfo&&void 0!==R.rowInfo.ID&&(G.value=R.rowInfo.ID);const K=e(""),N=e(""),P=e(""),W=e(""),X=e(!1),Y=[20,50,100],Z=e(0),q=e([]),E=()=>{C(B.value,F.value,G.value,K.value,N.value,P.value,W.value).then((e=>{q.value=e.data.list,Z.value=e.data.totalCount,X.value=!0}),(e=>{}))};a((()=>{E()}));const H=()=>{G.value="",K.value="",N.value="",P.value="",W.value=""},J=e=>{Z.value<=0||F.value*B.value>Z.value&&q.value.length>=Z.value||E()},L=e=>{E()};return(e,a)=>{const k=m,_=g,C=v,R=i,T=b,M=V,O=x,Q=y,$=w;return t(),l("div",{class:I(u(S)?"app-content1":"app-content")},[u(A)?(t(),l(s,{key:1},[u(X)?(t(),o($,{key:0},{default:r((()=>[d(R,{style:{"margin-bottom":"10px"}},{default:r((()=>[d(C,null,{default:r((()=>[!1===u(S)?(t(),o(k,{key:0,modelValue:u(G),"onUpdate:modelValue":a[0]||(a[0]=e=>c(G)?G.value=e:null),placeholder:"用户id",style:{width:"150px","margin-right":"10px"}},null,8,["modelValue"])):p("",!0),!1===u(S)?(t(),o(k,{key:1,modelValue:u(K),"onUpdate:modelValue":a[1]||(a[1]=e=>c(K)?K.value=e:null),placeholder:"操作资源类型",style:{width:"150px","margin-right":"10px"}},null,8,["modelValue"])):p("",!0),!1===u(S)?(t(),o(k,{key:2,modelValue:u(N),"onUpdate:modelValue":a[2]||(a[2]=e=>c(N)?N.value=e:null),placeholder:"操作资源组",style:{width:"150px","margin-right":"10px"}},null,8,["modelValue"])):p("",!0),!1===u(S)?(t(),o(k,{key:3,modelValue:u(P),"onUpdate:modelValue":a[3]||(a[3]=e=>c(P)?P.value=e:null),placeholder:"操作对象",style:{width:"150px","margin-right":"10px"}},null,8,["modelValue"])):p("",!0),!1===u(S)?(t(),o(k,{key:4,modelValue:u(W),"onUpdate:modelValue":a[4]||(a[4]=e=>c(W)?W.value=e:null),placeholder:"操作方法",style:{width:"150px","margin-right":"10px"}},null,8,["modelValue"])):p("",!0),!1===u(S)?(t(),o(_,{key:5,onClick:E,type:"primary",style:{"margin-right":"10px"}},{default:r((()=>a[7]||(a[7]=[h("条件搜索 ")]))),_:1})):p("",!0),!1===u(S)?(t(),o(_,{key:6,onClick:H},{default:r((()=>a[8]||(a[8]=[h("清空条件")]))),_:1})):p("",!0)])),_:1})])),_:1}),d(Q,null,{default:r((()=>[f("div",z,[f("div",j,[d(M,{data:u(q),style:{width:"100%"},"table-layout":"auto",stripe:"","tooltip-effect":"light"},{default:r((()=>[d(T,{prop:"userId",label:"用户id"}),d(T,{prop:"userName",label:"用户名"}),d(T,{prop:"opResourceType",label:"操作资源类型"}),d(T,{prop:"opResourceGroup",label:"操作资源组"}),d(T,{prop:"opResourceKey",label:"操作对象"}),d(T,{prop:"method",label:"操作方法"}),d(T,{prop:"createdAt",label:"创建时间"}),d(T,{prop:"detailInfo",label:"详情数据","show-overflow-tooltip":""})])),_:1},8,["data"])]),f("div",D,[d(O,{"current-page":u(B),"onUpdate:currentPage":a[5]||(a[5]=e=>c(B)?B.value=e:null),"page-size":u(F),"onUpdate:pageSize":a[6]||(a[6]=e=>c(F)?F.value=e:null),"page-sizes":Y,layout:"total, sizes, prev, pager, next, jumper",total:u(Z),onSizeChange:J,onCurrentChange:L},null,8,["current-page","page-size","total"])])])])),_:1})])),_:1})):p("",!0)],64)):(t(),o(n(U),{key:0}))],2)}}},[["__scopeId","data-v-926d7759"]]);export{R as t};
|
1
admin/ui/static/static/js/history-zzIzXglC.js
Normal file
1
admin/ui/static/static/js/history-zzIzXglC.js
Normal file
@ -0,0 +1 @@
|
||||
import{t as s}from"./history-C3Pvxh4X.js";import{c as o,o as t,B as e}from"./vendor-BRRlSJxx.js";import"./index-1btxRZkB.js";import"./empty-DuTaDG5U.js";const i={__name:"history",setup:i=>(i,r)=>(t(),o(e(s),{disableConditionInput:false}))};export{i as default};
|
2
admin/ui/static/static/js/index-1btxRZkB.js
Normal file
2
admin/ui/static/static/js/index-1btxRZkB.js
Normal file
File diff suppressed because one or more lines are too long
1
admin/ui/static/static/js/project-BRalbG0E.js
Normal file
1
admin/ui/static/static/js/project-BRalbG0E.js
Normal file
@ -0,0 +1 @@
|
||||
import{t as e}from"./table-BhmTKySX.js";import{L as s,u as a,c as r}from"./index-1btxRZkB.js";import{i as t,a as o,o as m,c,B as p}from"./vendor-BRRlSJxx.js";import"./resource-ebhyDeUm.js";import"./empty-DuTaDG5U.js";const i={__name:"project",setup(i){s.setCache("project",{}),t();let n=r;return"admin"!==a().userInfo.character&&(n.meta.methods={}),s.setCache("resource",n),(s,a)=>(m(),o("div",null,[(m(),c(p(e)))]))}};export{i as default};
|
1
admin/ui/static/static/js/project_op-DR6paW88.js
Normal file
1
admin/ui/static/static/js/project_op-DR6paW88.js
Normal file
File diff suppressed because one or more lines are too long
1
admin/ui/static/static/js/resource-ebhyDeUm.js
Normal file
1
admin/ui/static/static/js/resource-ebhyDeUm.js
Normal file
@ -0,0 +1 @@
|
||||
import{s as t}from"./index-1btxRZkB.js";function r(r,e){return t({url:r,method:"get",params:e})}function e(r,e){return t({url:r,method:"post",data:{dto:e}})}function o(r,e){return t({url:r,method:"put",data:{dto:e}})}function n(r,e){return t({url:r,method:"delete",data:e})}function u(r,e){return t({url:r+"/selection",method:"post",data:e})}function a(r){return t({url:"/project/"+r.toString()+"/items",method:"get"})}export{n as a,e as b,o as c,a as d,u as e,r};
|
1
admin/ui/static/static/js/table-BhmTKySX.js
Normal file
1
admin/ui/static/static/js/table-BhmTKySX.js
Normal file
File diff suppressed because one or more lines are too long
1
admin/ui/static/static/js/tableUser-BT_id_R-.js
Normal file
1
admin/ui/static/static/js/tableUser-BT_id_R-.js
Normal file
File diff suppressed because one or more lines are too long
1
admin/ui/static/static/js/user-CSxKKefZ.js
Normal file
1
admin/ui/static/static/js/user-CSxKKefZ.js
Normal file
@ -0,0 +1 @@
|
||||
import{t as e}from"./tableUser-BT_id_R-.js";import{u as s,L as r}from"./index-1btxRZkB.js";import{t}from"./history-C3Pvxh4X.js";import{a as o,o as a,c,B as m}from"./vendor-BRRlSJxx.js";import"./resource-ebhyDeUm.js";import"./empty-DuTaDG5U.js";const u={__name:"user",setup(u){let n={meta:{desc:"user",resource:"user",resource_url:"/resource/user",methods:{get:!0,post:!0,put:!0,delete:!0}}};"admin"!==s().userInfo.character&&(n.meta.methods={}),r.setCache("resource",n);const p=[];return p.push({key:"user:exec:history",name:"执行记录",btn_color_type:"info",btn_type:1,btn_callback_component:t}),(s,r)=>(a(),o("div",null,[(a(),c(m(e),{rowClickDialogBtns:p}))]))}};export{u as default};
|
96
admin/ui/static/static/js/vendor-BRRlSJxx.js
Normal file
96
admin/ui/static/static/js/vendor-BRRlSJxx.js
Normal file
File diff suppressed because one or more lines are too long
1
admin/ui/static/static/js/welcome-DSoGychw.js
Normal file
1
admin/ui/static/static/js/welcome-DSoGychw.js
Normal file
@ -0,0 +1 @@
|
||||
import{a as s,o as a,d as e,b as n,v as t,t as o,u as r,aa as p,F as l}from"./vendor-BRRlSJxx.js";import{u}from"./index-1btxRZkB.js";const f={style:{"font-size":"40px"}},i={style:{color:"darkslategrey","font-size":"50px"}},m={__name:"welcome",setup(m){const c=u().userInfo;return(u,m)=>{const d=p;return a(),s(l,null,[e("span",f,[m[0]||(m[0]=t("亲爱的")),e("span",i,o(r(c).nick_name),1),m[1]||(m[1]=t("!欢迎使用本公司后台管理系统!"))]),n(d),m[2]||(m[2]=e("span",{style:{"font-size":"40px"}},"硬盘有价,数据无价,操作不规范,亲人两行泪。",-1))],64)}}};export{m as default};
|
BIN
admin/uniugm.db
Normal file
BIN
admin/uniugm.db
Normal file
Binary file not shown.
8
ui/package-lock.json
generated
8
ui/package-lock.json
generated
@ -11,8 +11,10 @@
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"ant-design-vue": "^4.0.0-rc.6",
|
||||
"axios": "^1.8.4",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.9.7",
|
||||
"js-base64": "^3.7.7",
|
||||
"pinia": "^3.0.1",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"splitpanes": "^4.0.4",
|
||||
@ -3607,6 +3609,12 @@
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
|
@ -12,8 +12,10 @@
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"ant-design-vue": "^4.0.0-rc.6",
|
||||
"axios": "^1.8.4",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.9.7",
|
||||
"js-base64": "^3.7.7",
|
||||
"pinia": "^3.0.1",
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"splitpanes": "^4.0.4",
|
||||
|
@ -15,4 +15,12 @@ export function roleGetDetail(baseUrl, params) {
|
||||
method: 'get',
|
||||
params: params,
|
||||
})
|
||||
}
|
||||
|
||||
export function gameLogEventList(baseUrl, params) {
|
||||
return request({
|
||||
url: baseUrl + '/special/event_list',
|
||||
method: 'get',
|
||||
params: params,
|
||||
})
|
||||
}
|
259
ui/src/components/game/gamelogList.vue
Normal file
259
ui/src/components/game/gamelogList.vue
Normal file
@ -0,0 +1,259 @@
|
||||
<script setup>
|
||||
|
||||
import {gameLogEventList} from "@/api/account.js";
|
||||
import LocalCache from "@/stores/localCache.js";
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const props = defineProps({
|
||||
eventName: "",
|
||||
serverId: "",
|
||||
account: "",
|
||||
roleId: "",
|
||||
})
|
||||
|
||||
const eventList = ref({
|
||||
totalCount: 0,
|
||||
fieldsDescInfo: [],
|
||||
rows: [],
|
||||
})
|
||||
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
|
||||
|
||||
const todayStart = new Date()
|
||||
const todayEnd = new Date()
|
||||
todayStart.setHours(0)
|
||||
todayStart.setMinutes(0)
|
||||
todayStart.setSeconds(0)
|
||||
|
||||
const dateTimeValue = ref([todayStart, todayEnd])
|
||||
|
||||
const getPageNo = ref(1)
|
||||
const getPageLen = ref(10)
|
||||
const pageSizes = [10, 20, 50, 100, 200]
|
||||
|
||||
const eventNameList = props.eventName.split(",")
|
||||
const selectedEventName = ref('')
|
||||
const roleIdFilters = ref([])
|
||||
|
||||
const getEventList = () => {
|
||||
let listParams = {
|
||||
"AppId": 41,
|
||||
"EventName": props.eventName,
|
||||
"ServerId": props.serverId,
|
||||
"Account": props.account,
|
||||
"RoleId": props.roleId,
|
||||
"PageNo": getPageNo.value,
|
||||
"PageLen": getPageLen.value,
|
||||
}
|
||||
console.log("select name:", selectedEventName.value)
|
||||
if (selectedEventName.value !== undefined && selectedEventName.value !== '' && selectedEventName.value !== ' ') {
|
||||
listParams.EventName = selectedEventName.value
|
||||
}
|
||||
if (dateTimeValue.value.length === 2) {
|
||||
console.log("select date time:", dateTimeValue.value)
|
||||
listParams.DateStart = dayjs(dateTimeValue.value[0]).format('YYYY-MM-DD HH:mm:ss')
|
||||
listParams.DateEnd = dayjs(dateTimeValue.value[1]).format('YYYY-MM-DD HH:mm:ss')
|
||||
}
|
||||
gameLogEventList(resource_url, listParams).then(res => {
|
||||
// console.log("获取账户聊天记录返回:", res.data)
|
||||
eventList.value = res.data
|
||||
|
||||
roleIdFilters.value = []
|
||||
eventList.value.rows.forEach(row => {
|
||||
let find = false
|
||||
for (let i = 0; i < roleIdFilters.value.length; i++) {
|
||||
if (row[4] === roleIdFilters.value[i].value) {
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
roleIdFilters.value.push({
|
||||
text: row[4],
|
||||
value: row[4],
|
||||
})
|
||||
}
|
||||
})
|
||||
// console.log("roleidfilter:", roleIdFilters.value)
|
||||
}, err => {
|
||||
|
||||
})
|
||||
};
|
||||
|
||||
const onDateTimeChange = () => {
|
||||
// getEventList()
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
getEventList
|
||||
});
|
||||
|
||||
const handlePaginationSizeChange = () => {
|
||||
getEventList()
|
||||
}
|
||||
const handlePaginationCurChange = () => {
|
||||
getEventList()
|
||||
}
|
||||
|
||||
const onClickResetParams = () => {
|
||||
selectedEventName.value = ''
|
||||
dateTimeValue.value = [todayStart, todayEnd]
|
||||
}
|
||||
|
||||
const filterRoleIdHandler = (
|
||||
value,
|
||||
row,
|
||||
column
|
||||
) => {
|
||||
// console.log("filter:", value, row, column)
|
||||
return row[4] === value
|
||||
}
|
||||
|
||||
onUnmounted(() => {
|
||||
console.log('用户列表组件已销毁');
|
||||
// 这里可以清理资源
|
||||
});
|
||||
|
||||
const dateTimeShortcuts = [
|
||||
{
|
||||
text: '今天',
|
||||
value: () => {
|
||||
return [todayStart, todayEnd]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '昨天',
|
||||
value: () => {
|
||||
const end = new Date()
|
||||
end.setHours(0)
|
||||
end.setMinutes(0)
|
||||
end.setSeconds(0)
|
||||
const start = new Date()
|
||||
start.setHours(0)
|
||||
start.setMinutes(0)
|
||||
start.setSeconds(0)
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 1)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '最近7天',
|
||||
value: () => {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '上周',
|
||||
value: () => {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '上个月',
|
||||
value: () => {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
{
|
||||
text: '最近1个月',
|
||||
value: () => {
|
||||
const end = new Date()
|
||||
const start = new Date()
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
|
||||
return [start, end]
|
||||
},
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-row align="middle">
|
||||
<div style="margin-right: 20px">
|
||||
<el-select v-model="selectedEventName"
|
||||
placeholder="选择事件"
|
||||
clearable
|
||||
style="width: 150px;margin-right: 10px">
|
||||
<el-option v-for="choice in eventNameList" :key="choice" :label="choice"
|
||||
:value="choice"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
<span>选择时间范围:</span>
|
||||
<div style="width: 400px;margin-right: 10px">
|
||||
<el-date-picker
|
||||
v-model="dateTimeValue"
|
||||
type="datetimerange"
|
||||
format="YYYY/MM/DD HH:mm:ss"
|
||||
range-separator="到"
|
||||
placeholder="选个一个时间范围"
|
||||
start-placeholder="开始时间"
|
||||
end-placeholder="结束时间"
|
||||
:shortcuts="dateTimeShortcuts"
|
||||
@change="onDateTimeChange"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<el-button type="primary" @click="getEventList">
|
||||
查询
|
||||
</el-button>
|
||||
|
||||
<el-button @click="onClickResetParams">
|
||||
重置
|
||||
</el-button>
|
||||
|
||||
<div style="width:100%;height:0px;border: 1px solid #ebeef5;margin:8px 0 8px 0"/>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-table :data="eventList.rows" max-height="500px" style="width: 100%" table-layout="auto" border
|
||||
:show-header="true">
|
||||
<template v-for="(field, i) in eventList.fieldsDescInfo">
|
||||
<el-table-column :prop="field.name" :label="field.alias" width="100px" v-if="field.name === 'pub_roleid'"
|
||||
:filters="roleIdFilters" :filter-method="filterRoleIdHandler">
|
||||
<template #default="scope">
|
||||
<span>
|
||||
{{ scope.row[i] }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :prop="field.name" :label="field.alias" width="100px" v-else>
|
||||
<template #default="scope">
|
||||
<span>
|
||||
{{ scope.row[i] }}
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table>
|
||||
|
||||
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 10px; margin-right: 10px" justify="end">
|
||||
<el-pagination
|
||||
v-model:current-page="getPageNo"
|
||||
v-model:page-size="getPageLen"
|
||||
:page-sizes="pageSizes"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="eventList.totalCount"
|
||||
@size-change="handlePaginationSizeChange"
|
||||
@current-change="handlePaginationCurChange"
|
||||
/>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -2,7 +2,8 @@
|
||||
|
||||
import userDetailAccount from '@/components/game/userDetailAccount.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";
|
||||
|
||||
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) => {
|
||||
// console.log("tab info:", tab)
|
||||
switch (tab.props.name) {
|
||||
@ -40,6 +45,15 @@ const handleClick = (tab, event) => {
|
||||
case 'order':
|
||||
console.log("点击了充值订单记录")
|
||||
break
|
||||
case 'chat':
|
||||
gamelogChatChildRef.value.getEventList()
|
||||
break
|
||||
case 'currencyChange':
|
||||
gamelogCurrencyChildRef.value.getEventList()
|
||||
break
|
||||
case 'itemChange':
|
||||
gamelogItemChangeChildRef.value.getEventList()
|
||||
break
|
||||
case 'currency':
|
||||
console.log("点击了货币记录")
|
||||
}
|
||||
@ -48,13 +62,28 @@ const handleClick = (tab, event) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div style="width: 1000px">
|
||||
<el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick" v-if="loadAccountOk">
|
||||
<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 label="充值订单记录" name="order" v-if="loadAccountOk" :accountInfo="accountInfo">
|
||||
<component :is="userDetailOrder" v-if="loadAccountOk" :accountInfo="accountInfo"/>
|
||||
<el-tab-pane label="充值订单记录" name="order">
|
||||
<component v-if="activeName === 'order'" :is="userDetailOrder" :accountInfo="accountInfo"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane key="tab-chat" label="聊天记录" name="chat">
|
||||
<gamelogList key="tab-chat" :ref="(el) => gamelogChatChildRef = el"
|
||||
:serverId="serverId" :account="account"
|
||||
eventName="chatlog"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane key="tab-currency" label="货币变动" name="currencyChange">
|
||||
<gamelogList key="tab-currency" :ref="(el) => gamelogCurrencyChildRef = el"
|
||||
:serverId="serverId" :account="account"
|
||||
eventName="addcoin,costcoin"/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane key="tab-item" label="道具变动" name="itemChange">
|
||||
<gamelogList key="tab-item" :ref="(el) => gamelogItemChangeChildRef = el"
|
||||
:serverId="serverId" :account="account"
|
||||
eventName="gainitem,loseitem"/>
|
||||
</el-tab-pane>
|
||||
<!-- <el-tab-pane label="货币记录" name="currency" v-if="accountInfo !== null">货币记录子页面</el-tab-pane>-->
|
||||
</el-tabs>
|
||||
|
@ -582,7 +582,7 @@ const handleGenRandAccount = () => {
|
||||
for (let i = 0; i < genRandAccountNum.value; i++) {
|
||||
let randStr = ""
|
||||
for (let j = 0; j < genRandAccountCharBitNum.value; j++) {
|
||||
randStr += randCharArray[Math.floor(Math.random() * 1000000) %randCharArray.length]
|
||||
randStr += randCharArray[Math.floor(Math.random() * 1000000) % randCharArray.length]
|
||||
}
|
||||
const accountName = genRandAccountPrefix.value + randStr + genRandAccountSuffix.value
|
||||
// console.log("rand account name:", Math.random())
|
||||
@ -727,7 +727,7 @@ const handleGenRandAccount = () => {
|
||||
@click="tableSelectRows2(btn, scope.$index, scope.row)"
|
||||
v-if="scope.row['ReviewNeedCharacters'].includes(curCharacter) &&
|
||||
scope.row['ReviewCheckStatus'] === 'pending'">
|
||||
{{ btn.name }}
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
<div v-else/>
|
||||
</template>
|
||||
@ -775,7 +775,7 @@ const handleGenRandAccount = () => {
|
||||
<template v-for="(btn, index) in rowClickBtns">
|
||||
<el-dialog v-model="rowClickBtnVisibleList[index]" :title="btn.name"
|
||||
@close="rowClickBtnVisibleList[index]=false"
|
||||
destroy-on-close>
|
||||
destroy-on-close style="width: 1020px">
|
||||
<component :is="btn.btn_callback_component" :rowInfo="rowClickBtnSelectRow"
|
||||
:fieldsDescInfo="fieldsDescInfo"/>
|
||||
</el-dialog>
|
||||
@ -864,18 +864,24 @@ const handleGenRandAccount = () => {
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-row style="margin-bottom: 10px">
|
||||
<span>随机数量:</span>
|
||||
<el-tooltip effect="light" placement="top-start" content="输入生成账号的数量,数量范围[1-1000],数量太大了后台短时间生成不完,注意多等几分钟会再发放账号">
|
||||
<el-input type="number" v-model="genRandAccountNum" placeholder="账号数量" style="width: 90px"/>
|
||||
<el-tooltip effect="light" placement="top-start"
|
||||
content="输入生成账号的数量,数量范围[1-1000],数量太大了后台短时间生成不完,注意多等几分钟会再发放账号">
|
||||
<el-input type="number" v-model="genRandAccountNum" placeholder="账号数量"
|
||||
style="width: 90px"/>
|
||||
</el-tooltip>
|
||||
<span style="margin-left: 10px">随机模板:</span>
|
||||
<el-tooltip effect="light" placement="top" content="前缀、后缀必填至少一个">
|
||||
<el-input v-model="genRandAccountPrefix" placeholder="前缀" style="width: 100px;margin-right: 5px"></el-input>
|
||||
<el-input v-model="genRandAccountPrefix" placeholder="前缀"
|
||||
style="width: 100px;margin-right: 5px"></el-input>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="light" placement="top" content="账号随机混淆字串的位数,范围[3-20],与前缀、后缀一起组成账号">
|
||||
<el-input type="number" v-model="genRandAccountCharBitNum" placeholder="随机串数量" style="width: 80px;margin-right: 5px"/>
|
||||
<el-tooltip effect="light" placement="top"
|
||||
content="账号随机混淆字串的位数,范围[3-20],与前缀、后缀一起组成账号">
|
||||
<el-input type="number" v-model="genRandAccountCharBitNum" placeholder="随机串数量"
|
||||
style="width: 80px;margin-right: 5px"/>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="light" placement="top" content="前缀、后缀必填至少一个">
|
||||
<el-input v-model="genRandAccountSuffix" placeholder="后缀" style="width: 100px;margin-right: 5px"></el-input>
|
||||
<el-input v-model="genRandAccountSuffix" placeholder="后缀"
|
||||
style="width: 100px;margin-right: 5px"></el-input>
|
||||
</el-tooltip>
|
||||
<el-button type="success" @click="handleGenRandAccount">生成</el-button>
|
||||
</el-row>
|
||||
@ -918,41 +924,44 @@ const handleGenRandAccount = () => {
|
||||
<!--如果是items类型,就是物品下拉框+道具组合-->
|
||||
<template v-if="(fieldDescInfo.type === 'items')">
|
||||
<el-row>
|
||||
<el-form :inline="true" :model="selectedItem" label-position="right"
|
||||
label-width="130px">
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top-start">
|
||||
<el-select placeholder="--搜索道具--" v-model="selectedItem" style="width: 200px"
|
||||
filterable remote :remote-method="handleQueryItem"
|
||||
:loading="loadingRemoteItems"
|
||||
value-key="value"
|
||||
>
|
||||
<el-option v-for="info in itemChoices" :key="info.value" :label="info.desc+'('+info.value+')'"
|
||||
:value="info"></el-option>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<el-form :inline="true" :model="selectedItem" label-position="right"
|
||||
label-width="130px">
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top-start">
|
||||
<el-select placeholder="--搜索道具--" v-model="selectedItem" style="width: 200px"
|
||||
filterable remote :remote-method="handleQueryItem"
|
||||
:loading="loadingRemoteItems"
|
||||
value-key="value"
|
||||
>
|
||||
<el-option v-for="info in itemChoices" :key="info.value"
|
||||
:label="info.desc+'('+info.value+')'"
|
||||
:value="info"></el-option>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="数量" prop="number" label-width="40px">
|
||||
<el-input type="number" v-model="selectedItemNum" placeholder="请输入数量" style="width: 100px"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="数量" prop="number" label-width="40px">
|
||||
<el-input type="number" v-model="selectedItemNum" placeholder="请输入数量"
|
||||
style="width: 100px"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="addItem(fieldDescInfo)">添加</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 选择礼包 -->
|
||||
<el-form-item v-if="cachedResource.meta.resource !== 'item_bag'">
|
||||
<el-tooltip effect="light" content="选择礼包,点击添加到奖励列表">
|
||||
<el-select placeholder="--礼包--" v-model="selectedItemBag" clearable style="width: 150px"
|
||||
value-key="name" multiple @blur="itemBagSelectChange">
|
||||
<el-option v-for="bag in itemBags" :key="bag.name" :label="bag.name" :value="bag"></el-option>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
<!-- 选择礼包 -->
|
||||
<el-form-item v-if="cachedResource.meta.resource !== 'item_bag'">
|
||||
<el-tooltip effect="light" content="选择礼包,点击添加到奖励列表">
|
||||
<el-select placeholder="--礼包--" v-model="selectedItemBag" clearable style="width: 150px"
|
||||
value-key="name" multiple @blur="itemBagSelectChange">
|
||||
<el-option v-for="bag in itemBags" :key="bag.name" :label="bag.name"
|
||||
:value="bag"></el-option>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-form-item label="奖励列表" prop="Attach">
|
||||
<el-table :data="dialogObjectForm.Attach" border>
|
||||
<el-table-column label="道具id" prop="id"/>
|
||||
@ -1054,6 +1063,7 @@ const handleGenRandAccount = () => {
|
||||
}
|
||||
|
||||
/*控制表格tooltip宽度*/
|
||||
|
||||
::v-deep(.el-popper) {
|
||||
max-width: 640px;
|
||||
word-break: break-all;
|
||||
@ -1080,6 +1090,7 @@ const handleGenRandAccount = () => {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination > .el-pagination__sizes {
|
||||
display: none !important;
|
||||
}
|
||||
|
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