From 5f9156137fc424f2f9cde6d87a3a3c3c619a5b6e Mon Sep 17 00:00:00 2001 From: likun <906102152@qq.com> Date: Wed, 14 May 2025 18:09:20 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=A5=BD=E5=A4=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/apps/game/domain/comm_resource.go | 1 + .../apps/game/domain/projects/smdl/account.go | 129 +++++++++++++++-- admin/apps/game/domain/projects/smdl/ban.go | 4 +- .../game/domain/projects/smdl/mail_global.go | 2 +- .../game/domain/projects/smdl/mail_role.go | 2 +- .../game/domain/projects/smdl/whitelist.go | 60 ++++++-- admin/apps/game/domain/repo/comm_resource.go | 21 ++- admin/apps/game/model/ban.go | 12 +- admin/apps/game/model/cdkey.go | 2 +- admin/apps/game/model/globalmail.go | 2 +- admin/apps/game/model/item_bag.go | 40 ++++++ admin/apps/game/model/rolemail.go | 2 +- admin/apps/game/model/whitelist.go | 10 +- admin/apps/game/server/middleware.go | 1 + admin/apps/user/domain/user.go | 2 +- admin/apps/user/model/token.go | 2 +- admin/apps/user/service/service_user.go | 3 + admin/internal/consts/consts.go | 1 + admin/lib/utils/time.go | 5 +- ui/src/components/game/userDetail.vue | 16 ++- ui/src/components/game/userDetailAccount.vue | 134 +++++++++++++++++- ui/src/components/game/userDetailOrder.vue | 23 ++- ui/src/components/restful/table.vue | 29 +++- ui/src/components/restful/tableCDKey.vue | 58 +++++++- ui/src/permission.js | 1 + ui/src/router/index.js | 3 +- ui/src/views/project/project_op.vue | 54 ++++++- 27 files changed, 561 insertions(+), 58 deletions(-) create mode 100644 admin/apps/game/model/item_bag.go diff --git a/admin/apps/game/domain/comm_resource.go b/admin/apps/game/domain/comm_resource.go index df43e6d..870117e 100644 --- a/admin/apps/game/domain/comm_resource.go +++ b/admin/apps/game/domain/comm_resource.go @@ -42,6 +42,7 @@ func initCommonResourcesRepo(db *gorm.DB) { r(consts.ResourcesName_MailRole, "个人邮件", repo.NewCommonResourceRepo(db, &model.RoleMail{}), ShowMethod_Get|ShowMethod_Post) // 个人邮件发放就没法撤回? r(consts.ResourcesName_MailGlobal, "全服邮件", repo.NewCommonResourceRepo(db, &model.GlobalMail{}), ShowMethod_Get|ShowMethod_Post) // 直接删除,别修改了,玩家收到的更乱 r(consts.ResourcesName_CDKey, "礼包码", repo.NewCommonResourceRepo(db, &model.CDKey{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) + r(consts.ResourcesName_ItemBag, "道具礼包", repo.NewCommonResourceRepo(db, &model.ItemBag{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) r(consts.ResourcesName_Notice, "公告(暂无)", repo.NewCommonResourceRepo(db, &model.Notice{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) r(consts.ResourcesName_DevicePush, "设备推送(暂无)", repo.NewCommonResourceRepo(db, &model.DevicePush{}), ShowMethod_Get) } diff --git a/admin/apps/game/domain/projects/smdl/account.go b/admin/apps/game/domain/projects/smdl/account.go index 342cdb8..3d9134a 100644 --- a/admin/apps/game/domain/projects/smdl/account.go +++ b/admin/apps/game/domain/projects/smdl/account.go @@ -11,6 +11,7 @@ import ( "math" "net/url" "strconv" + "time" ) type AccountHook struct { @@ -98,16 +99,125 @@ func (hook *AccountHook) List(projectInfo *entity.Project, resource string, para return totalCount, fields, rows, nil } +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"` +} + +func (info *AccountDetailOrderInfo) toDto() *dto.AccountDetailOrderInfo { + return &dto.AccountDetailOrderInfo{ + ServerId: info.ServerId, + AccountId: info.AccountId, + RoleId: info.RoleId, + RoleName: info.RoleName, + Sn: info.Sn, + ProductId: info.ProductId, + Price: info.Price, + PurchaseType: info.PurchaseType, + PurchaseAt: utils.ParseUnixTimestamp2LocalTime(info.PurchaseAt).Format(time.DateTime), + } +} + +type AccountDetailRoleInfo struct { + Platform string `json:"platform"` // ios ad + ServerId string `json:"serverId"` + Name string `json:"name"` + RoleId string `json:"roleId"` + Level int `json:"level"` + CurrencyItems []*dto.ItemInfo `json:"item_list"` + Ip string `json:"ip"` + Channel string `json:"channel"` + CreatedAt int64 `json:"created_at"` + LastLoginTime int64 `json:"last_login_time"` + OrderList []*AccountDetailOrderInfo `json:"order_list"` +} + +func (info *AccountDetailRoleInfo) toDto() *dto.AccountDetailRoleInfo { + retInfo := &dto.AccountDetailRoleInfo{ + Platform: info.Platform, + ServerId: info.ServerId, + Name: info.Name, + RoleId: info.RoleId, + Level: info.Level, + CurrencyItems: info.CurrencyItems, + CreatedAt: utils.ParseUnixTimestamp2LocalTime(info.CreatedAt).Format(time.DateTime), + LastLoginTime: utils.ParseUnixTimestamp2LocalTime(info.LastLoginTime).Format(time.DateTime), + } + totalPayAmount := 0 + for _, order := range info.OrderList { + totalPayAmount += order.Price + retInfo.OrderList = append(retInfo.OrderList, order.toDto()) + } + retInfo.TotalPayAmount = totalPayAmount + retInfo.TotalPayTimes = len(info.OrderList) + return retInfo +} + +type AccountDetailInfo struct { + AccountId string `json:"account_id"` + LoginDeviceCount int `json:"login_device_count"` + RoleList []*AccountDetailRoleInfo `json:"role_list"` +} + +func (info *AccountDetailInfo) toDto() *dto.AccountDetailInfo { + retInfo := &dto.AccountDetailInfo{ + AccountId: info.AccountId, + } + var earliestRole *AccountDetailRoleInfo + var totalPayAmount int + var totalPayCount int + var firstPayAt int64 = math.MaxInt64 + var lastPayAt int64 = 0 + var lastLoginTime int64 = 0 + for _, r := range info.RoleList { + if earliestRole == nil || earliestRole.CreatedAt > r.CreatedAt { + earliestRole = r + } + retInfo.RoleList = append(retInfo.RoleList, r.toDto()) + if lastLoginTime < r.LastLoginTime { + lastLoginTime = r.LastLoginTime + } + for _, o := range r.OrderList { + if firstPayAt > o.PurchaseAt { + firstPayAt = o.PurchaseAt + } + if lastPayAt < o.PurchaseAt { + lastPayAt = o.PurchaseAt + } + } + } + retInfo.TotalPayAmount = totalPayAmount + retInfo.TotalPayTimes = totalPayCount + retInfo.FirstPayAt = utils.ParseUnixTimestamp2LocalTime(firstPayAt).Format(time.DateTime) + retInfo.LastPayAt = utils.ParseUnixTimestamp2LocalTime(lastPayAt).Format(time.DateTime) + retInfo.LastLoginTime = utils.ParseUnixTimestamp2LocalTime(lastLoginTime).Format(time.DateTime) + if earliestRole != nil { + retInfo.Platform = earliestRole.Platform + retInfo.Channel = earliestRole.Channel + retInfo.CreatedAt = utils.ParseUnixTimestamp2LocalTime(earliestRole.CreatedAt).Format(time.DateTime) + retInfo.CreatedIp = earliestRole.Ip + retInfo.Platform = earliestRole.Platform + retInfo.Platform = earliestRole.Platform + retInfo.Platform = earliestRole.Platform + retInfo.Platform = earliestRole.Platform + } + + return retInfo +} + func (hook *AccountHook) GetDetail(projectInfo *entity.Project, account string) (*dto.GetAccountDetailRsp, error) { accountId := account if accountId == "" { return nil, errcode.New(errcode.ParamsInvalid, "not found account id:%v", accountId) } - rsp := &dto.GetAccountDetailRsp{ - AccountInfo: &dto.AccountDetailInfo{}, - } - params := &url.Values{} allRunningServers, err := getAllRunningServers(projectInfo) @@ -115,7 +225,7 @@ func (hook *AccountHook) GetDetail(projectInfo *entity.Project, account string) return nil, err } - roleList := make([]*dto.AccountDetailRoleInfo, 0) + roleList := make([]*AccountDetailRoleInfo, 0) for _, runningServer := range allRunningServers { params.Set("serverid", runningServer.ServerId) params.Set("userId", accountId) @@ -127,7 +237,7 @@ func (hook *AccountHook) GetDetail(projectInfo *entity.Project, account string) Msg string `json:"msg"` } `json:"state"` - Data *dto.AccountDetailInfo `json:"data"` + Data *AccountDetailInfo `json:"data"` } detailRsp := &RspData{} @@ -140,14 +250,11 @@ func (hook *AccountHook) GetDetail(projectInfo *entity.Project, account string) continue } - rsp.AccountInfo = detailRsp.Data roleList = append(roleList, detailRsp.Data.RoleList...) } - rsp.AccountInfo.RoleCount = len(roleList) - rsp.AccountInfo.RoleList = roleList - - return rsp, nil + accountDetailTotal := &AccountDetailInfo{AccountId: accountId, RoleList: roleList} + return &dto.GetAccountDetailRsp{AccountInfo: accountDetailTotal.toDto()}, nil } func getPaginationServerReqList(projectInfo *entity.Project, serverInfoList internal.ServerInfoList, diff --git a/admin/apps/game/domain/projects/smdl/ban.go b/admin/apps/game/domain/projects/smdl/ban.go index 8e4beb5..65cda30 100644 --- a/admin/apps/game/domain/projects/smdl/ban.go +++ b/admin/apps/game/domain/projects/smdl/ban.go @@ -107,7 +107,9 @@ func (hook *BanHook) Edit(projectInfo *entity.Project, resource string, dtoObj d dura := int64(expireAt.Time.Sub(time.Now()).Minutes()) // 神魔大陆封禁是分钟 if dura <= 0 { // 解封 - params.Add("forbidtime", "0") + params.Add("forbidtime", "-1") + params.Add("desc", "") + params.Add("notifytouser", "") } else { params.Add("forbidtime", strconv.FormatInt(int64(dura), 10)) params.Add("desc", banInfo.BanReason) diff --git a/admin/apps/game/domain/projects/smdl/mail_global.go b/admin/apps/game/domain/projects/smdl/mail_global.go index 534dc75..9ead47f 100644 --- a/admin/apps/game/domain/projects/smdl/mail_global.go +++ b/admin/apps/game/domain/projects/smdl/mail_global.go @@ -39,7 +39,7 @@ func (hook *MailGlobalHook) Create(projectInfo *entity.Project, resource string, itemIdStr = strings.Join(itemWordList, "@") itemNumStr = "-1" } else { - itemIdStr = "0" + itemNumStr = "0" } var serverIds []string diff --git a/admin/apps/game/domain/projects/smdl/mail_role.go b/admin/apps/game/domain/projects/smdl/mail_role.go index 5f73e56..a96028e 100644 --- a/admin/apps/game/domain/projects/smdl/mail_role.go +++ b/admin/apps/game/domain/projects/smdl/mail_role.go @@ -38,7 +38,7 @@ func (hook *MailRoleHook) Create(projectInfo *entity.Project, resource string, d itemIdStr = strings.Join(itemWordList, "@") itemNumStr = "-1" } else { - itemIdStr = "0" + itemNumStr = "0" } params := &url.Values{} diff --git a/admin/apps/game/domain/projects/smdl/whitelist.go b/admin/apps/game/domain/projects/smdl/whitelist.go index fbbb880..7f62ef9 100644 --- a/admin/apps/game/domain/projects/smdl/whitelist.go +++ b/admin/apps/game/domain/projects/smdl/whitelist.go @@ -26,12 +26,31 @@ func (hook *WhitelistHook) Create(projectInfo *entity.Project, resource string, params.Add("type", whiteInfo.WType) params.Add("value", whiteInfo.Value) params.Add("op", "add") - params.Add("server", whiteInfo.ServerConfID) - rsp := make(map[string]any) - err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) - if err != nil { - return errcode.New(errcode.ServerError, "发送新增白名单请求:%+v错误:%v", whiteInfo, err) + if len(whiteInfo.ServerConfID) == 0 { + // 所有区服 + serverList, err := getAllRunningServers(projectInfo) + if err != nil { + return err + } + for _, v := range serverList { + params.Set("server", v.ServerId) + rsp := make(map[string]any) + err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) + if err != nil { + return errcode.New(errcode.ServerError, "发送新增白名单请求:%+v错误:%v", whiteInfo, err) + } + } + } else { + // 指定区服 + for _, v := range whiteInfo.ServerConfID { + params.Set("server", v) + rsp := make(map[string]any) + err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) + if err != nil { + return errcode.New(errcode.ServerError, "发送新增白名单请求:%+v错误:%v", whiteInfo, err) + } + } } return nil @@ -51,13 +70,32 @@ func (hook *WhitelistHook) Delete(projectInfo *entity.Project, resource string, params.Add("type", whiteInfo.WType) params.Add("value", whiteInfo.Value) params.Add("op", "remove") - params.Add("server", whiteInfo.ServerConfID) - rsp := make(map[string]any) - err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) - if err != nil { - return errcode.New(errcode.ServerError, "发送删除白名单请求:%+v错误:%v", whiteInfo, err) + if len(whiteInfo.ServerConfID) == 0 { + // 所有区服 + serverList, err := getAllRunningServers(projectInfo) + if err != nil { + return err + } + for _, v := range serverList { + params.Set("server", v.ServerId) + rsp := make(map[string]any) + err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) + if err != nil { + return errcode.New(errcode.ServerError, "发送新增白名单请求:%+v错误:%v", whiteInfo, err) + } + } + } else { + // 指定区服 + for _, v := range whiteInfo.ServerConfID { + params.Set("server", v) + rsp := make(map[string]any) + err := httpclient.Request(alisrvAddr+"/gm", "get", params, &rsp) + if err != nil { + return errcode.New(errcode.ServerError, "发送新增白名单请求:%+v错误:%v", whiteInfo, err) + } + } } - + return nil } diff --git a/admin/apps/game/domain/repo/comm_resource.go b/admin/apps/game/domain/repo/comm_resource.go index 92a4553..a19a945 100644 --- a/admin/apps/game/domain/repo/comm_resource.go +++ b/admin/apps/game/domain/repo/comm_resource.go @@ -114,7 +114,7 @@ func (repo *commonResourceRepoImpl) Create(projectEt *entity.Project, resource s return et, err } } - + err := repo.db.Create(et.Po).Error if err != nil { if strings.Contains(err.Error(), "Duplicate entry") || strings.Contains(err.Error(), "UNIQUE constraint") { @@ -191,8 +191,23 @@ func (repo *commonResourceRepoImpl) parseWhereConditions2Sql(conditions []*dto.G whereClause = append(whereClause, fmt.Sprintf("`%v` like ?", dbFieldName)) whereArgs = append(whereArgs, cond.Value1) case "range": - whereClause = append(whereClause, fmt.Sprintf("`%v` >= ? and `%v` <= ?", dbFieldName, dbFieldName)) - whereArgs = append(whereArgs, cond.Value1, cond.Value2) + + if t1, ok1 := cond.Value1.(time.Time); ok1 { + t2, _ := cond.Value2.(time.Time) + if t1.IsZero() && t2.IsZero() { + whereClause = append(whereClause, fmt.Sprintf("`%v` >= ? and `%v` <= ?", dbFieldName, dbFieldName)) + whereArgs = append(whereArgs, cond.Value1, cond.Value2) + } else if !t1.IsZero() { + whereClause = append(whereClause, fmt.Sprintf("`%v` >= ? ", dbFieldName)) + whereArgs = append(whereArgs, cond.Value1) + } else { + whereClause = append(whereClause, fmt.Sprintf("`%v` <= ? ", dbFieldName)) + whereArgs = append(whereArgs, cond.Value2) + } + } else { + whereClause = append(whereClause, fmt.Sprintf("`%v` >= ? and `%v` <= ?", dbFieldName, dbFieldName)) + whereArgs = append(whereArgs, cond.Value1, cond.Value2) + } case "": default: panic(fmt.Errorf("unsupport where tag %v", field.Tag)) diff --git a/admin/apps/game/model/ban.go b/admin/apps/game/model/ban.go index 7d9fa55..fccdee1 100644 --- a/admin/apps/game/model/ban.go +++ b/admin/apps/game/model/ban.go @@ -41,8 +41,16 @@ func (m *Ban) GetBanTypeChoices(project *Project) []*dto.CommonDtoFieldChoice { switch project.ProjectType { case consts.RegisteredProjectId_shenmodalu: return []*dto.CommonDtoFieldChoice{ + //{ + // Desc: "账号", + // Value: consts.BanType_Account, + //}, + //{ + // Desc: "IP", + // Value: consts.BanType_Ip, + //}, { - Desc: "角色", + Desc: "角色登录", Value: consts.BanType_Role, }, { @@ -57,7 +65,7 @@ func (m *Ban) GetBanTypeChoices(project *Project) []*dto.CommonDtoFieldChoice { Value: consts.BanType_Account, }, { - Desc: "角色", + Desc: "角色登录", Value: consts.BanType_Role, }, { diff --git a/admin/apps/game/model/cdkey.go b/admin/apps/game/model/cdkey.go index fb0db54..eae4c6f 100644 --- a/admin/apps/game/model/cdkey.go +++ b/admin/apps/game/model/cdkey.go @@ -15,8 +15,8 @@ func init() { type CDKey struct { ID int `gorm:"primarykey" readonly:"true"` ProjectId int `gorm:"index:idx_project_id"` - Name string `gorm:"type:varchar(100);unique" name:"礼包说明" required:"true" uneditable:"true"` ServerIDs []string `gorm:"type:json;serializer:json" name:"区服" desc:"不选就是全服通用" type:"[]string" choices:"GetChoiceServers" multi_choice:"true" uneditable:"true""` + Name string `gorm:"type:varchar(100);unique" name:"礼包说明" required:"true" uneditable:"true"` CodeType int `name:"礼包类型" required:"true" choices:"GetCodeTypeChoices" uneditable:"true"` Code string `gorm:"type:VARCHAR(50);index" name:"礼包码" desc:"一码通用才配置" uneditable:"true"` CodeNum int `name:"礼包数量" desc:"一码一用才配置"` diff --git a/admin/apps/game/model/globalmail.go b/admin/apps/game/model/globalmail.go index 577251f..dd63664 100644 --- a/admin/apps/game/model/globalmail.go +++ b/admin/apps/game/model/globalmail.go @@ -13,7 +13,7 @@ func init() { type GlobalMail struct { ID int `gorm:"primarykey" readonly:"true"` ProjectId int `gorm:"index:idx_project_id"` - ServerIDs []string `gorm:"type:json;serializer:json" name:"区服" type:"[]string" choices:"GetChoiceServers" multi_choice:"true"` + ServerIDs []string `gorm:"type:json;serializer:json" desc:"不选就是默认所有区服" name:"区服" type:"[]string" choices:"GetChoiceServers" multi_choice:"true"` Title string `name:"邮件标题" required:"true"` Content string `name:"邮件内容" required:"true"` Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" desc:"搜索道具并点击添加"` diff --git a/admin/apps/game/model/item_bag.go b/admin/apps/game/model/item_bag.go new file mode 100644 index 0000000..0d9512d --- /dev/null +++ b/admin/apps/game/model/item_bag.go @@ -0,0 +1,40 @@ +package model + +import ( + "admin/apps/game/model/dto" + "admin/internal/db" + "time" +) + +func init() { + db.RegisterTableModels(ItemBag{}) +} + +// 道具包,配置一系列道具,供邮件、礼包码填写使用 +type ItemBag struct { + ID int `gorm:"primarykey" readonly:"true"` + ProjectId int `gorm:"uniqueIndex:idx_whitelist"` + Name string `gorm:"type:varchar(255);uniqu" name:"礼包名称" desc:"请输入礼包名称,全项目唯一" required:"true" where:"eq"` + Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" desc:"搜索道具并点击添加"` + + CreatedAt time.Time `readonly:"true" where:"range"` +} + +func (lm *ItemBag) TableName() string { + return "item_bag" +} + +func (m *ItemBag) GetId() int { + return m.ID +} + +func (m *ItemBag) GetChoiceServers(project *Project) []*dto.CommonDtoFieldChoice { + return getChoiceServers(project) +} + +func (m *ItemBag) GetWhitelistTypeChoices(project *Project) []*dto.CommonDtoFieldChoice { + return []*dto.CommonDtoFieldChoice{ + {Desc: "IP", Value: "ip"}, + {Desc: "账号", Value: "account"}, + } +} diff --git a/admin/apps/game/model/rolemail.go b/admin/apps/game/model/rolemail.go index 9c22805..0d2d5a0 100644 --- a/admin/apps/game/model/rolemail.go +++ b/admin/apps/game/model/rolemail.go @@ -20,8 +20,8 @@ type MailAttachItem struct { type RoleMail struct { ID int `gorm:"primarykey" readonly:"true"` ProjectId int `gorm:"index:idx_project_id"` - RoleIDs []string `gorm:"type:json;serializer:json" name:"生效的角色id" desc:"生效的角色id,逗号分隔多个" required:"true"` ServerID string `name:"所属区服" choices:"GetChoiceServers" required:"true" where:"eq"` + RoleIDs []string `gorm:"type:json;serializer:json" name:"生效的角色id" desc:"生效的角色id,逗号分隔多个" required:"true"` Title string `name:"邮件标题" required:"true"` Content string `name:"邮件内容" required:"true"` Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" desc:"搜索道具并点击添加"` diff --git a/admin/apps/game/model/whitelist.go b/admin/apps/game/model/whitelist.go index ace7379..ae855c3 100644 --- a/admin/apps/game/model/whitelist.go +++ b/admin/apps/game/model/whitelist.go @@ -11,11 +11,11 @@ func init() { } type WhiteList struct { - ID int `gorm:"primarykey" readonly:"true"` - ProjectId int `gorm:"uniqueIndex:idx_whitelist"` - ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_whitelist;index:idx_server" name:"区服id" required:"true" choices:"GetChoiceServers" multi_choices:"true" where:"eq"` - WType string `name:"白名单类型" desc:"账号或者ip" required:"true" choices:"GetWhitelistTypeChoices"` - Value string `gorm:"type:varchar(128);uniqueIndex:idx_whitelist" name:"账号或者ip等值" required:"true"` + ID int `gorm:"primarykey" readonly:"true"` + ProjectId int `gorm:"uniqueIndex:idx_whitelist"` + ServerConfID []string `gorm:"type:json;serializer:json" type:"[]string" name:"区服id" desc:"不选就是默认所有区服" choices:"GetChoiceServers" multi_choice:"true" where:"eq"` + WType string `name:"白名单类型" desc:"账号或者ip" required:"true" choices:"GetWhitelistTypeChoices"` + Value string `gorm:"type:varchar(128);uniqueIndex:idx_whitelist" name:"账号或者ip等值" required:"true"` CreatedAt time.Time `readonly:"true" where:"range"` } diff --git a/admin/apps/game/server/middleware.go b/admin/apps/game/server/middleware.go index 2c9ce71..08d6d8d 100644 --- a/admin/apps/game/server/middleware.go +++ b/admin/apps/game/server/middleware.go @@ -31,6 +31,7 @@ func (srv *Server) CheckToken(ctx *context.WebContext) { ctx.Header.UserName = authRsp.User.NickName ctx.GinCtx().Set("userInfo", authRsp) + ctx.GinCtx().Next() return } diff --git a/admin/apps/user/domain/user.go b/admin/apps/user/domain/user.go index e2bb2a8..77db72c 100644 --- a/admin/apps/user/domain/user.go +++ b/admin/apps/user/domain/user.go @@ -46,7 +46,7 @@ func (svc *CommonResourceService) GetOrCreateToken(userId int) (*model.Token, er if err != nil { return nil, err } - if !find { + if !find || tokenInfo.ExpireAt.Before(time.Now()) { tokenInfo, err = svc.tokenRepo.CreateToken(userId, time.Hour*24*15) // 15天过期的token,可以使用中加上token刷新功能 if err != nil { return nil, err diff --git a/admin/apps/user/model/token.go b/admin/apps/user/model/token.go index 738caef..b4574d8 100644 --- a/admin/apps/user/model/token.go +++ b/admin/apps/user/model/token.go @@ -17,7 +17,7 @@ func init() { type Token struct { ID int `gorm:"primarykey" readonly:"true"` Token string `gorm:"type:varchar(256);unique" required:"true"` - UserId int `name:"用户id" readonly:"true"` + UserId int `gorm:"type:int(20);unique" name:"用户id" readonly:"true"` ExpireAt time.Time `name:"到期时间" readonly:"true"` CreatedAt time.Time `readonly:"true"` } diff --git a/admin/apps/user/service/service_user.go b/admin/apps/user/service/service_user.go index 2b194b9..61e04a0 100644 --- a/admin/apps/user/service/service_user.go +++ b/admin/apps/user/service/service_user.go @@ -8,6 +8,7 @@ import ( "admin/apps/user/model/dto" "admin/internal/errcode" "admin/lib/tokenlib" + "admin/lib/xlog" "context" ) @@ -22,6 +23,8 @@ func (svc *Service) CheckToken(token string, userId int) error { return err } if token != dbToken.Token { + xlog.Infof("user:%v token invalid:(%v)(%v)", + dbToken.UserId, token, dbToken.Token) return errcode.New(errcode.TokenInvalid, "token not equal:%v,%v", token, dbToken.Token) } return nil diff --git a/admin/internal/consts/consts.go b/admin/internal/consts/consts.go index b0d2e17..d0e95dd 100644 --- a/admin/internal/consts/consts.go +++ b/admin/internal/consts/consts.go @@ -35,6 +35,7 @@ const ( ResourcesName_Notice = "notice" ResourcesName_CDKey = "cdkey" ResourcesName_DevicePush = "device_push" + ResourcesName_ItemBag = "item_bag" ) const ( diff --git a/admin/lib/utils/time.go b/admin/lib/utils/time.go index c51da94..079210d 100644 --- a/admin/lib/utils/time.go +++ b/admin/lib/utils/time.go @@ -1,7 +1,7 @@ package utils import ( - "fmt" + "admin/lib/xlog" "time" ) @@ -22,7 +22,8 @@ func ParseUnixTimestamp2LocalTime(ts int64) (local time.Time) { sec = ts nsec = 0 default: - panic(fmt.Errorf("ts:%v invalid parse to local time", ts)) + xlog.Warnf("ParseUnixTimestamp2LocalTime:%v invalid", ts) + sec = int64((time.Time{}).Second()) } t := time.Unix(sec, nsec) diff --git a/ui/src/components/game/userDetail.vue b/ui/src/components/game/userDetail.vue index 35b8822..f4a40e0 100644 --- a/ui/src/components/game/userDetail.vue +++ b/ui/src/components/game/userDetail.vue @@ -1,6 +1,7 @@ \ No newline at end of file diff --git a/ui/src/components/game/userDetailOrder.vue b/ui/src/components/game/userDetailOrder.vue index 4802a0d..0f3457f 100644 --- a/ui/src/components/game/userDetailOrder.vue +++ b/ui/src/components/game/userDetailOrder.vue @@ -1,10 +1,31 @@ diff --git a/ui/src/components/restful/table.vue b/ui/src/components/restful/table.vue index 9dbb518..9a76bdc 100644 --- a/ui/src/components/restful/table.vue +++ b/ui/src/components/restful/table.vue @@ -32,8 +32,8 @@ rowClickBtns.push(...props.rowClickDialogBtns) const rowClickBtnVisibleList = reactive(rowClickBtns.map(() => false)) const rowClickBtnSelectRow = ref(null) -console.log("global btns:", globalClickBtns) -console.log("row btns:", rowClickBtns) +// console.log("global btns:", globalClickBtns) +// console.log("row btns:", rowClickBtns) const resource_url = cachedResource.meta.resource_url; const fieldsDescInfo = ref([]) @@ -62,7 +62,7 @@ const listData = async () => { where_conditions: "", } - console.log(`查询页:${listParams.page_no},查询页大小:${listParams.page_len}`) + // console.log(`查询页:${listParams.page_no},查询页大小:${listParams.page_len}`) let whereReqConditions = { conditions: [] @@ -88,7 +88,7 @@ const listData = async () => { for (let i = 0; i < fieldsDescInfo.value.length; i++) { var field = fieldsDescInfo.value[i] - dialogObjectForm.value[field.key] = '' + // dialogObjectForm.value[field.key] = '' if (field.required == true) { rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}] @@ -159,6 +159,21 @@ const dialogObjectForm = ref({ Attach: [], }) +const route = useRoute() +if (route.query.from != undefined && route.query.from != "") { + Object.keys((route.query)).forEach(key => { + const value = route.query[key] + if (key === "from") { + return + } + dialogObjectForm.value[key] = value + console.log("进入页面,来自查询参数的数据:", key, value) + }) + console.log("进入页面,来自查询参数的数据:", route.query) + dialogAddVisible.value = true +} + + const tableSelectRows = ref([]) const handleTableSelectRowsSendToServer = (btnInfo, rows) => { @@ -206,6 +221,10 @@ const tableSelectRow3 = (i, row) => { rowClickBtnVisibleList[i] = true console.log("点击按钮:", rowClickBtnSelectRow) } +const tableSelectRow4 = (btnInfo, row) => { + btnInfo.click_handler(row) + // console.log("点击按钮:", row) +} const submitAdd = async () => { try { @@ -489,7 +508,7 @@ const handlePaginationCurChange = (val) => { diff --git a/ui/src/components/restful/tableCDKey.vue b/ui/src/components/restful/tableCDKey.vue index 3e11890..f0ed299 100644 --- a/ui/src/components/restful/tableCDKey.vue +++ b/ui/src/components/restful/tableCDKey.vue @@ -81,6 +81,18 @@ const listData = async () => { for (let j = 0; j < rows.value.length; j++) { rows.value[j].jsonValue = JSON.stringify(rows.value[j][field.key]) } + rules.value[field.key] = [{ + required: true, + validator: (rule, value, callback) => { + console.log("触发校验道具列表规则:", dialogObjectForm.value) + if (dialogObjectForm.value.Attach === undefined || dialogObjectForm.value.Attach.length === 0) { + callback(new Error("请至少填写一个奖励道具!")) + } else { + callback() + } + }, + trigger: "blur", + }] } if (field.where !== "") { @@ -149,6 +161,7 @@ const submitAdd = async () => { await dialogAddFormRef.value.validate(valid => { if (valid) { console.log("commit add form:", dialogObjectForm.value) + return resourcePost(resource_url, dialogObjectForm.value).then((res) => { ElNotification({ title: "添加结果通知", @@ -243,6 +256,8 @@ const handleEdit = (index, row) => { dialogObjectForm.value = row dialogObjectForm.value.oldData = row dialogObjectForm.value.oldIndex = index + rules.value["Code"] = [] + rules.value["CodeNum"] = [] console.log("edit data:", row) dialogEditVisible.value = true } @@ -284,12 +299,15 @@ function addItem() { dialogObjectForm.value.Attach = []; } dialogObjectForm.value.Attach.push(d); + console.log("校验规则:", rules.value) + dialogAddFormRef.value.validateField("Attach"); } function deleteItem(row) { // 移除该对象 let number = dialogObjectForm.value.Attach.findIndex(item => item === row); dialogObjectForm.value.Attach.splice(number, 1); + dialogAddFormRef.value.validateField("Attach"); } const handleCloseDialog = () => { @@ -311,6 +329,24 @@ const handleItemOnSelect = (itemOption) => { item.value.id = itemOption.value item.value.desc = itemOption.desc } + +const cdkeyCodeInputDisabled = ref(true) +const cdkeyCodeNumInputDisabled = ref(true) +const handleCodeTypeOnSelect = (codeType) => { + console.log("选中:", codeType) + if (codeType === 0) { + cdkeyCodeInputDisabled.value = false + cdkeyCodeNumInputDisabled.value = true + rules.value["Code"] = [{required: true, message: "礼包码不能为空", trigger: "blur"}] + rules.value["CodeNum"] = [] + } else { + cdkeyCodeInputDisabled.value = true + cdkeyCodeNumInputDisabled.value = false + rules.value["Code"] = [] + rules.value["CodeNum"] = [{required: true, message: "礼包数量不能为空", trigger: "blur"}] + } +} + const handleQueryItem = (itemQueryStr) => { if (!itemQueryStr) { itemChoices.value = [] @@ -520,11 +556,24 @@ const handlePaginationCurChange = (val) => { + :multiple="(fieldDescInfo.multi_choice === true)" + v-if="fieldDescInfo.key === 'CodeType'" + @change="handleCodeTypeOnSelect" + > + + + + + @@ -540,8 +589,13 @@ const handlePaginationCurChange = (val) => { diff --git a/ui/src/permission.js b/ui/src/permission.js index df709ff..904ad52 100644 --- a/ui/src/permission.js +++ b/ui/src/permission.js @@ -6,6 +6,7 @@ import ExpireCache from "@/stores/expireCache.js"; router.beforeEach((to, from, next) => { if (to.path === '/login') { + console.log("进入登录页面") next() } else { const token = ExpireCache.getCache("token"); diff --git a/ui/src/router/index.js b/ui/src/router/index.js index 9a21596..96b8a91 100644 --- a/ui/src/router/index.js +++ b/ui/src/router/index.js @@ -85,7 +85,7 @@ const router = createRouter({ export default router export function setProjectOperationRoutes(projectList) { - console.log("resourceList:", projectList) + // console.log("resourceList:", projectList) isGetUserInfo.value = true projectOpTreeRoutes.value = [] @@ -150,5 +150,6 @@ export function setProjectOperationRoutes(projectList) { } LocalCache.setCache("projectsRoute", projectList) + LocalCache.setCache("homeRoute", homeRoute) // console.log("重新获取了用户数据,刷新路由表:", router.getRoutes()) } diff --git a/ui/src/views/project/project_op.vue b/ui/src/views/project/project_op.vue index 128a307..3e9bf5e 100644 --- a/ui/src/views/project/project_op.vue +++ b/ui/src/views/project/project_op.vue @@ -3,8 +3,11 @@ import tableView from "@/components/restful/table.vue"; import LocalCache from "@/stores/localCache.js"; import userDetail from "@/components/game/userDetail.vue"; +import router, {projectOpTreeRoutes} from '@/router/index.js' const cachedResource = LocalCache.getCache("resource"); +const homeRoutes = LocalCache.getCache("homeRoute"); +const projectId = cachedResource.meta.projectId const rowClickDialogBtns = [] @@ -23,13 +26,60 @@ switch (cachedResource.meta.resource) { }, { key: "account:detail", name: "白名单", - btn_color_type: "success", + btn_color_type: "default", btn_type: 2, - }, { + click_handler: (row) => { + for (let i = 0; i < homeRoutes.children.length; i++) { + const curRecourseRoute = homeRoutes.children[i] + if (curRecourseRoute.meta === undefined) { + continue + } + if (curRecourseRoute.meta.projectId === projectId && curRecourseRoute.meta.resource === "whitelist") { + // 跳转路由 + console.log("角色页面点击:", row, "跳转快速封禁") + LocalCache.setCache("resource", curRecourseRoute) + router.push({ + path: curRecourseRoute.path, query: { + from: "account", + WType: "account", + Value: row.Account, + } + }) + } + } + } + },) + break + case "role": + // 给账号页面添加按钮 + if (rowClickDialogBtns.length > 0) { + break + } + rowClickDialogBtns.push({ key: "account:detail", name: "封禁", btn_color_type: "info", btn_type: 2, + click_handler: (row) => { + for (let i = 0; i < homeRoutes.children.length; i++) { + const curRecourseRoute = homeRoutes.children[i] + if (curRecourseRoute.meta === undefined) { + continue + } + if (curRecourseRoute.meta.projectId === projectId && curRecourseRoute.meta.resource === "ban") { + // 跳转路由 + console.log("角色页面点击:", row, "跳转快速封禁") + LocalCache.setCache("resource", curRecourseRoute) + router.push({ + path: curRecourseRoute.path, query: { + from: "role", + ServerConfID: row.ServerConfId, + Value: row.RoleId, + } + }) + } + } + } },) break }