diff --git a/admin/apps/game/api/api.go b/admin/apps/game/api/api.go index 996ee5c..98c4959 100644 --- a/admin/apps/game/api/api.go +++ b/admin/apps/game/api/api.go @@ -14,11 +14,19 @@ func RegisterGameApi(handler IGameApi) { gameApiInstance = handler } +type ResourceBtnInfo struct { + Key string `json:"key"` // 按钮关键词,用于后端判断点击按钮 + Name string `json:"name"` // 按钮中文名 + BtnType string `json:"btn_type"` // primary warn等 +} + type ResourceInitInfo struct { - Resource string `json:"resource"` - Desc string `json:"desc"` - ShowMethods []string `json:"show_methods"` // 资源权限列表 - MethodsPermissionStr []string `json:"methods_permission"` // 资源权限字符串 + Resource string `json:"resource"` + Desc string `json:"desc"` + ShowMethods []string `json:"show_methods"` // 资源权限列表 + MethodsPermissionStr []string `json:"methods_permission"` // 资源权限字符串 + GlobalBtns []*ResourceBtnInfo `json:"global_btns"` // 页面全局按钮,放在新增后面 + RowBtns []*ResourceBtnInfo `json:"row_btns"` // 页面每一行的功能按钮 } type ProjectInitInfo struct { diff --git a/admin/apps/game/domain/comm_resource.go b/admin/apps/game/domain/comm_resource.go index 7fed316..18ff253 100644 --- a/admin/apps/game/domain/comm_resource.go +++ b/admin/apps/game/domain/comm_resource.go @@ -21,7 +21,19 @@ type CommonResourceService struct { func initCommonResourcesRepo(db *gorm.DB) { r(consts.ResourcesName_Project, "项目管理", repo.NewCommonResourceRepo(db, &model.Project{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) - r(consts.ResourcesName_Server, "服务器管理", repo.NewCommonResourceRepo(db, &model.Server{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) + + { + serverRepo := r(consts.ResourcesName_Server, "服务器管理", repo.NewCommonResourceRepo(db, &model.Server{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) + serverRepo.GlobalBtns = []*api.ResourceBtnInfo{ + {Key: consts.BtnKeyGlobal_Server_DownAll, Name: "一键停服", BtnType: "info"}, + {Key: consts.BtnKeyGlobal_Server_UpAll, Name: "一键起服", BtnType: "warning"}, + } + serverRepo.RowBtns = []*api.ResourceBtnInfo{ + {Key: consts.BtnKeyRow_Server_Down, Name: "停服", BtnType: "info"}, + {Key: consts.BtnKeyRow_Server_Up, Name: "起服", BtnType: "warning"}, + } + } + r(consts.ResourcesName_Account, "账号列表", repo.NewCommonResourceRepo(db, &model.Account{}), ShowMethod_Get) // 账号管理不需要在后台读写数据,都是通过项目api拉 r(consts.ResourcesName_SupportAccount, "扶持账号", repo.NewCommonResourceRepo(db, &model.SupportAccount{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Delete) // 扶持账号,只是标记哪些账号是扶持好 r(consts.ResourcesName_Role, "角色列表", repo.NewCommonResourceRepo(db, &model.Role{}), ShowMethod_Get) // 角色管理不需要在后台读写数据,都是通过项目api拉 @@ -29,8 +41,8 @@ func initCommonResourcesRepo(db *gorm.DB) { r(consts.ResourcesName_Ban, "封禁管理", repo.NewCommonResourceRepo(db, &model.Ban{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) 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_Notice, "公告", repo.NewCommonResourceRepo(db, &model.Notice{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete) r(consts.ResourcesName_CDKey, "礼包码", repo.NewCommonResourceRepo(db, &model.CDKey{}), 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) } @@ -101,7 +113,7 @@ func (svc *CommonResourceService) Create(projectId int, resource string, dtoObj } createOne := func(obj dto.CommonDtoValues) (dto.CommonDtoValues, error) { - et, err := findCommResourceRepo(resource).Create(projectEt, obj) + et, err := findCommResourceRepo(resource).Create(projectEt, resource, obj) if err != nil { return nil, err } @@ -200,6 +212,20 @@ func (svc *CommonResourceService) Delete(projectId int, resource string, id int) return oldEt, nil } +func (svc *CommonResourceService) RowsSelection(projectId int, resourceName string, params *dto.CommonRowsSelectionReq) (*dto.CommonRowsSelectionRsp, error) { + _, projectEt, find, err := svc.projectRepo.GetById(projectId) + if err != nil { + return nil, err + } + if resourceName != consts.ResourcesName_Project && !find { + return nil, errcode.New(errcode.ServerError, "not found project %v db data", projectId) + } + if hook, ok := projects.GetProjectResourceHook(projectEt, resourceName).(projects.IPostResourceOpRowsHook); ok { + return hook.RowsSelection(projectEt, resourceName, params.BtnKey, params.Rows) + } + return nil, nil +} + func (svc *CommonResourceService) GetSupportResourcesList(permissions []string) []*api.ResourceInitInfo { list := make([]*api.ResourceInitInfo, 0, len(commResourcesRepo)) for _, v := range commResourcesRepo { @@ -207,6 +233,8 @@ func (svc *CommonResourceService) GetSupportResourcesList(permissions []string) Resource: v.Resource, Desc: v.Desc, ShowMethods: v.ShowMethods, + GlobalBtns: v.GlobalBtns, + RowBtns: v.RowBtns, }) } return list @@ -225,11 +253,13 @@ type resourceRepoInfo struct { Repo repo.ICommonResourceRepo ShowMethods []string showMethods int + GlobalBtns []*api.ResourceBtnInfo + RowBtns []*api.ResourceBtnInfo } var commResourcesRepo = make([]*resourceRepoInfo, 0) -func r(resource, desc string, repo repo.ICommonResourceRepo, showMethods int) { +func r(resource, desc string, repo repo.ICommonResourceRepo, showMethods int) *resourceRepoInfo { curRepo := &resourceRepoInfo{ Resource: resource, Desc: desc, @@ -251,6 +281,8 @@ func r(resource, desc string, repo repo.ICommonResourceRepo, showMethods int) { } commResourcesRepo = append(commResourcesRepo, curRepo) + + return curRepo } func findCommResourceRepo(resource string) repo.ICommonResourceRepo { diff --git a/admin/apps/game/domain/projects/ihook.go b/admin/apps/game/domain/projects/ihook.go index 4e00ada..9b89d3d 100644 --- a/admin/apps/game/domain/projects/ihook.go +++ b/admin/apps/game/domain/projects/ihook.go @@ -23,6 +23,10 @@ type IPostResourceOpDeleteHook interface { Delete(projectInfo *entity.Project, resource string, dtoObj dto.CommonDtoValues) error } +type IPostResourceOpRowsHook interface { + RowsSelection(projectInfo *entity.Project, resource string, btnKey string, dtoObjs []dto.CommonDtoValues) (*dto.CommonRowsSelectionRsp, error) +} + type IGetAllValueChoicesHook interface { // 获取所有道具,可以用于前端页面做下拉选择等 GetItems(projectInfo *entity.Project) ([]*dto.CommonDtoFieldChoice, error) diff --git a/admin/apps/game/domain/projects/smdl/ban.go b/admin/apps/game/domain/projects/smdl/ban.go index 5578846..8e4beb5 100644 --- a/admin/apps/game/domain/projects/smdl/ban.go +++ b/admin/apps/game/domain/projects/smdl/ban.go @@ -42,20 +42,20 @@ func (hook *BanHook) Create(projectInfo *entity.Project, resource string, dtoObj params.Add("server", banInfo.ServerConfID) params.Add("roleid", roleId) - expireAt := banInfo.ExpireAt.Unix() + expireAt := banInfo.ExpireAt - if expireAt <= 0 { + if !expireAt.Valid { // 解封 params.Add("forbidtime", "0") params.Add("desc", banInfo.BanReason) params.Add("notifytouser", banInfo.BanNotifyReason) } else { - dura := (expireAt - time.Now().Unix()) / 60 // 神魔大陆封禁是分钟 + dura := int64(expireAt.Time.Sub(time.Now()).Minutes()) // 神魔大陆封禁是分钟 if dura <= 0 { // 解封 params.Add("forbidtime", "0") } else { - params.Add("forbidtime", strconv.FormatInt(dura, 10)) + params.Add("forbidtime", strconv.FormatInt(int64(dura), 10)) params.Add("desc", banInfo.BanReason) params.Add("notifytouser", banInfo.BanNotifyReason) } @@ -70,6 +70,59 @@ func (hook *BanHook) Create(projectInfo *entity.Project, resource string, dtoObj return nil } +func (hook *BanHook) Edit(projectInfo *entity.Project, resource string, dtoObj dto.CommonDtoValues) error { + alisrvAddr := projectInfo.GetApiAddr() + if alisrvAddr == "" { + return errcode.New(errcode.ServerError, "项目%v没有配置api服务器地址", projectInfo.Po.Name) + } + + et := (&entity.CommonResource{}).FromPo(&model.Ban{}).FromDto(dtoObj) + banInfo := et.ToPo().(*model.Ban) + + banApi := "" + switch banInfo.BanType { + case consts.BanType_Role: + banApi = "banrole" + case consts.BanType_RoleChat: + banApi = "banroletalk" + default: + xlog.Warnf("神魔大陆不支持此类型的封禁:%v", banInfo.BanType) + return nil + } + + roleId := banInfo.Value + + params := &url.Values{} + params.Add("server", banInfo.ServerConfID) + params.Add("roleid", roleId) + + expireAt := banInfo.ExpireAt + + if !expireAt.Valid { + // 解封 + params.Add("forbidtime", "0") + params.Add("desc", banInfo.BanReason) + params.Add("notifytouser", banInfo.BanNotifyReason) + } else { + dura := int64(expireAt.Time.Sub(time.Now()).Minutes()) // 神魔大陆封禁是分钟 + if dura <= 0 { + // 解封 + params.Add("forbidtime", "0") + } else { + params.Add("forbidtime", strconv.FormatInt(int64(dura), 10)) + params.Add("desc", banInfo.BanReason) + params.Add("notifytouser", banInfo.BanNotifyReason) + } + } + + rsp := make(map[string]any) + err := httpclient.Request(alisrvAddr+"/"+banApi, "get", params, &rsp) + if err != nil { + return err + } + return nil +} + func (hook *BanHook) Delete(projectInfo *entity.Project, resource string, dtoObj dto.CommonDtoValues) error { alisrvAddr := projectInfo.GetApiAddr() if alisrvAddr == "" { diff --git a/admin/apps/game/domain/projects/smdl/notice.go b/admin/apps/game/domain/projects/smdl/notice.go index 46c81ad..99fa519 100644 --- a/admin/apps/game/domain/projects/smdl/notice.go +++ b/admin/apps/game/domain/projects/smdl/notice.go @@ -9,8 +9,6 @@ import ( "admin/lib/httpclient" "admin/lib/xlog" "net/url" - "strconv" - "time" ) type NoticeHook struct { @@ -22,55 +20,57 @@ func (hook *NoticeHook) Create(projectInfo *entity.Project, resource string, dto return errcode.New(errcode.ServerError, "项目%v没有配置api服务器地址", projectInfo.Po.Name) } - et := (&entity.CommonResource{}).FromPo(&model.Ban{}).FromDto(dtoObj) - banInfo := et.ToPo().(*model.Ban) - - banApi := "" - switch banInfo.BanType { - case consts.BanType_Role: - banApi = "banrole" - case consts.BanType_RoleChat: - banApi = "banroletalk" - default: - xlog.Warnf("神魔大陆不支持此类型的封禁:%v", banInfo.BanType) - return nil - } - - roleId := banInfo.Value - - params := &url.Values{} - params.Add("server", banInfo.ServerConfID) - params.Add("roleid", roleId) - - expireAt := banInfo.ExpireAt.Unix() - - if expireAt <= 0 { - // 解封 - params.Add("forbidtime", "0") - params.Add("desc", banInfo.BanReason) - params.Add("notifytouser", banInfo.BanNotifyReason) - } else { - dura := (expireAt - time.Now().Unix()) / 60 // 神魔大陆封禁是分钟 - if dura <= 0 { - // 解封 - params.Add("forbidtime", "0") - } else { - params.Add("forbidtime", strconv.FormatInt(dura, 10)) - params.Add("desc", banInfo.BanReason) - params.Add("notifytouser", banInfo.BanNotifyReason) - } - } - - rsp := make(map[string]any) - err := httpclient.Request(alisrvAddr+"/"+banApi, "get", params, &rsp) - if err != nil { - return err - } + //et := (&entity.CommonResource{}).FromPo(&model.Notice{}).FromDto(dtoObj) + //banInfo := et.ToPo().(*model.Notice) + // + //banApi := "" + //switch banInfo.BanType { + //case consts.BanType_Role: + // banApi = "banrole" + //case consts.BanType_RoleChat: + // banApi = "banroletalk" + //default: + // xlog.Warnf("神魔大陆不支持此类型的封禁:%v", banInfo.BanType) + // return nil + //} + // + //roleId := banInfo.Value + // + //params := &url.Values{} + //params.Add("server", banInfo.ServerConfID) + //params.Add("roleid", roleId) + // + //expireAt := banInfo.ExpireAt.Unix() + // + //if expireAt <= 0 { + // // 解封 + // params.Add("forbidtime", "0") + // params.Add("desc", banInfo.BanReason) + // params.Add("notifytouser", banInfo.BanNotifyReason) + //} else { + // dura := (expireAt - time.Now().Unix()) / 60 // 神魔大陆封禁是分钟 + // if dura <= 0 { + // // 解封 + // params.Add("forbidtime", "0") + // } else { + // params.Add("forbidtime", strconv.FormatInt(dura, 10)) + // params.Add("desc", banInfo.BanReason) + // params.Add("notifytouser", banInfo.BanNotifyReason) + // } + //} + // + //rsp := make(map[string]any) + //err := httpclient.Request(alisrvAddr+"/"+banApi, "get", params, &rsp) + //if err != nil { + // return err + //} return nil } func (hook *NoticeHook) Delete(projectInfo *entity.Project, resource string, dtoObj dto.CommonDtoValues) error { + return nil + alisrvAddr := projectInfo.GetApiAddr() if alisrvAddr == "" { return errcode.New(errcode.ServerError, "项目%v没有配置api服务器地址", projectInfo.Po.Name) diff --git a/admin/apps/game/domain/projects/smdl/server.go b/admin/apps/game/domain/projects/smdl/server.go index eb52257..2853c41 100644 --- a/admin/apps/game/domain/projects/smdl/server.go +++ b/admin/apps/game/domain/projects/smdl/server.go @@ -58,6 +58,13 @@ func (hook *ServerHook) List(projectInfo *entity.Project, resource string, param return totalCount, fields, rows, nil } +func (hook *ServerHook) RowsSelection(projectInfo *entity.Project, resource string, btnKey string, dtoObjs []dto.CommonDtoValues) (*dto.CommonRowsSelectionRsp, error) { + return &dto.CommonRowsSelectionRsp{ + Msg: "执行行操作成功!", + NeedRefresh: true, + }, nil +} + type ServerInfo struct { ServerId string `json:"serverId"` ServerName string `json:"serverName"` @@ -135,7 +142,7 @@ func getAttachFields() []*dto.CommonDtoFieldDesc { Uneditable: true, }, { - Name: "是否只允许白名单登录", + Name: "停服维护中", Key: "IsWhitelistLogin", Type: "bool", HelpText: "打开就是相当于停服维护中了", diff --git a/admin/apps/game/domain/repo/cdkey.go b/admin/apps/game/domain/repo/cdkey.go index 00e6a00..62dd767 100644 --- a/admin/apps/game/domain/repo/cdkey.go +++ b/admin/apps/game/domain/repo/cdkey.go @@ -5,6 +5,7 @@ import ( "admin/apps/game/model" "admin/apps/game/model/dto" "admin/internal/errcode" + "admin/internal/global" "errors" "gorm.io/gorm" "time" @@ -23,6 +24,25 @@ func NewCDKeyRepo(db *gorm.DB) ICDKeyRepo { return &cdKeyRepoImpl{db: db} } +func cdKeyPreCreateHook(projectEt *entity.Project, dtoObj dto.CommonDtoValues) error { + et := (&entity.CommonResource{}).FromPo(&model.CDKey{}).FromDto(dtoObj) + do := entity.NewCDKey(et.Po.(*model.CDKey)) + if do.IsGlobalType() { + if do.Po.Code == "" { + return errcode.New(errcode.CDKeyInvalid, "cdkey empty:%v", dtoObj) + } + dbEt, find, err := NewCDKeyRepo(global.GLOB_DB).GetByKey(projectEt.GetProjectPo().ID, do.Po.Code) + if err != nil { + return errcode.New(errcode.DBError, "get cdkey by key:%v db error:%v", do.Po.Code, err) + } + if find { + return errcode.New(errcode.DBInsertDuplicate, "create cdkey:%v key duplicate with:%v", dtoObj, et, dbEt.Po) + } + } + + return nil +} + type cdKeyRepoImpl struct { db *gorm.DB } diff --git a/admin/apps/game/domain/repo/comm_resource.go b/admin/apps/game/domain/repo/comm_resource.go index 5d27d81..92a4553 100644 --- a/admin/apps/game/domain/repo/comm_resource.go +++ b/admin/apps/game/domain/repo/comm_resource.go @@ -4,6 +4,7 @@ import ( "admin/apps/game/domain/entity" "admin/apps/game/model" "admin/apps/game/model/dto" + "admin/internal/consts" "admin/internal/errcode" "admin/lib/xlog" "errors" @@ -15,10 +16,14 @@ import ( "time" ) +var createHooks = map[string]func(projectEt *entity.Project, et dto.CommonDtoValues) error{ + consts.ResourcesName_CDKey: cdKeyPreCreateHook, +} + type ICommonResourceRepo interface { List(project *entity.Project, params *dto.CommonListReq) (int, []*dto.CommonDtoFieldDesc, []*entity.CommonResource, error) GetById(projectEt *entity.Project, id int) ([]*dto.CommonDtoFieldDesc, *entity.CommonResource, bool, error) - Create(projectEt *entity.Project, et dto.CommonDtoValues) (*entity.CommonResource, error) + Create(projectEt *entity.Project, resource string, et dto.CommonDtoValues) (*entity.CommonResource, error) Edit(projectEt *entity.Project, et dto.CommonDtoValues) error Delete(projectEt *entity.Project, id int) (*entity.CommonResource, bool, error) } @@ -102,8 +107,14 @@ func (repo *commonResourceRepoImpl) GetById(projectEt *entity.Project, id int) ( return repo.fieldsDescInfoFun(projectEt), (&entity.CommonResource{}).FromPo(po), true, nil } -func (repo *commonResourceRepoImpl) Create(projectEt *entity.Project, dtoObj dto.CommonDtoValues) (*entity.CommonResource, error) { +func (repo *commonResourceRepoImpl) Create(projectEt *entity.Project, resource string, dtoObj dto.CommonDtoValues) (*entity.CommonResource, error) { et := (&entity.CommonResource{}).FromPo(repo.newEmptyPo()).FromDto(dtoObj) + if handler, find := createHooks[resource]; find { + if err := handler(projectEt, dtoObj); err != nil { + 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") { diff --git a/admin/apps/game/model/ban.go b/admin/apps/game/model/ban.go index 725d1b4..7d9fa55 100644 --- a/admin/apps/game/model/ban.go +++ b/admin/apps/game/model/ban.go @@ -4,6 +4,7 @@ import ( "admin/apps/game/model/dto" "admin/internal/consts" "admin/internal/db" + "database/sql" "time" ) @@ -12,14 +13,14 @@ func init() { } type Ban struct { - ID int `gorm:"primarykey" readonly:"true"` - ProjectId int `gorm:"uniqueIndex:idx_ban"` - ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_server" name:"区服id" required:"true" choices:"GetServerConfIDChoices" uneditable:"true"` - BanType string `name:"封禁类型" required:"true" choices:"GetBanTypeChoices" uneditable:"true"` - Value string `gorm:"type:varchar(128);uniqueIndex:idx_ban" name:"封禁值" required:"true" desc:"根据封禁类型填对应值,例如ip就填ip地址" uneditable:"true"` - BanReason string `name:"封禁描述" desc:"封禁描述,入库记录的描述信息" required:"true"` - BanNotifyReason string `name:"封禁弹窗" desc:"封禁弹窗内容,会推送给客户端弹窗" required:"true"` - ExpireAt time.Time `name:"封禁到期时间" desc:"封禁到期时间,0表示永久封禁"` + ID int `gorm:"primarykey" readonly:"true"` + ProjectId int `gorm:"index:project_id"` + ServerConfID string `gorm:"type:varchar(200);index:idx_server" name:"区服id" required:"true" choices:"GetServerConfIDChoices" uneditable:"true" where:"eq"` + BanType string `name:"封禁类型" required:"true" choices:"GetBanTypeChoices" uneditable:"true" where:"eq"` + Value string `gorm:"type:varchar(128);index:value" name:"封禁值" required:"true" desc:"根据封禁类型填对应值,例如ip就填ip地址" uneditable:"true" where:"eq"` + BanReason string `name:"封禁描述" desc:"封禁描述,入库记录的描述信息" required:"true"` + BanNotifyReason string `name:"封禁弹窗" desc:"封禁弹窗内容,会推送给客户端弹窗" required:"true"` + ExpireAt sql.NullTime `name:"封禁到期时间" desc:"封禁到期时间,0表示永久封禁"` CreatedAt time.Time `readonly:"true"` } diff --git a/admin/apps/game/model/cdkey.go b/admin/apps/game/model/cdkey.go index 190d280..fb0db54 100644 --- a/admin/apps/game/model/cdkey.go +++ b/admin/apps/game/model/cdkey.go @@ -18,7 +18,7 @@ type CDKey struct { 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""` CodeType int `name:"礼包类型" required:"true" choices:"GetCodeTypeChoices" uneditable:"true"` - Code string `gorm:"type:VARCHAR(50);index" name:"礼包码" desc:"一码通用才配置"` + Code string `gorm:"type:VARCHAR(50);index" name:"礼包码" desc:"一码通用才配置" uneditable:"true"` CodeNum int `name:"礼包数量" desc:"一码一用才配置"` ValidStartTime sql.NullTime `name:"生效起始时间"` ValidEndTime sql.NullTime `name:"生效结束时间"` diff --git a/admin/apps/game/model/dto/msg.go b/admin/apps/game/model/dto/msg.go index 6103555..bfb004a 100644 --- a/admin/apps/game/model/dto/msg.go +++ b/admin/apps/game/model/dto/msg.go @@ -43,6 +43,16 @@ type CommonDeleteRsp struct { Id int `json:"id"` } +type CommonRowsSelectionReq struct { + BtnKey string `json:"btn_key"` + Rows []CommonDtoValues `json:"rows"` +} + +type CommonRowsSelectionRsp struct { + Msg string `json:"msg"` + NeedRefresh bool `json:"need_refresh"` +} + type CommandListReq struct { Addr string `json:"addr"` } diff --git a/admin/apps/game/model/server.go b/admin/apps/game/model/server.go index 8b365a7..66fe1ba 100644 --- a/admin/apps/game/model/server.go +++ b/admin/apps/game/model/server.go @@ -16,6 +16,7 @@ type Server struct { ProjectId int `gorm:"uniqueIndex:idx_server"` ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_server" name:"区服id" required:"true" uneditable:"true"` Desc string `name:"描述"` + // command_list接口服务器地址,为空代表由由项目统一提供command_list. // 取决于每个项目改造难度: // 为空就代表项目要实现一个自己统一对外暴露的gm调用服务对内聚合、分发指令执行,本后台执行指令只调用一次; diff --git a/admin/apps/game/model/whitelist.go b/admin/apps/game/model/whitelist.go index 3706d2a..ace7379 100644 --- a/admin/apps/game/model/whitelist.go +++ b/admin/apps/game/model/whitelist.go @@ -13,9 +13,9 @@ 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" where:"eq"` + 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:"账户" required:"true"` + 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/ctl_common_rest.go b/admin/apps/game/server/ctl_common_rest.go index 3b32ba0..36040bf 100644 --- a/admin/apps/game/server/ctl_common_rest.go +++ b/admin/apps/game/server/ctl_common_rest.go @@ -61,6 +61,19 @@ func (ctl *controller) CommonDelete(ctx *context.WebContext, params *dto.CommonD return nil } +func (ctl *controller) CommonRowsSelection(ctx *context.WebContext, params *dto.CommonRowsSelectionReq, rsp *dto.CommonRowsSelectionRsp) error { + projectId, resource := getCtxURIProjectIdAndResource(ctx) + + ctx1 := stdContext.WithValue(ctx.Context, "user_id", ctx.Header.UserId) + ctx1 = stdContext.WithValue(ctx1, "user_name", ctx.Header.UserName) + + err := ctl.svc.CommonRowsSelection(ctx1, projectId, resource, params) + if err != nil { + return err + } + return nil +} + func (ctl *controller) OnClickCustomButton(ctx *context.WebContext, params *dto.CommonDeleteReq, rsp *dto.CommonDeleteRsp) error { return nil } diff --git a/admin/apps/game/server/route.go b/admin/apps/game/server/route.go index 7e19e9c..ec5d0c7 100644 --- a/admin/apps/game/server/route.go +++ b/admin/apps/game/server/route.go @@ -27,6 +27,7 @@ func (srv *Server) Route(engine *web.Engine, sdkEngine *web.Engine) { resourceUnderProjectGroup.Post("", "新增", consts.WebPathPermit_Read, srv.ctl.CommonPost) resourceUnderProjectGroup.Put("", "编辑", consts.WebPathPermit_Read, srv.ctl.CommonPut) resourceUnderProjectGroup.Delete("", "删除", consts.WebPathPermit_Read, srv.ctl.CommonDelete) + resourceUnderProjectGroup.Post("/selection", "多选", consts.WebPathPermit_Read, srv.ctl.CommonDelete) } projectGroup.Get("/:projectId/items", "获取项目所有道具列表", consts.WebPathPermit_Read, srv.ctl.GetProjectAllItems) diff --git a/admin/apps/game/service/service.go b/admin/apps/game/service/service.go index 5e93a92..de29aad 100644 --- a/admin/apps/game/service/service.go +++ b/admin/apps/game/service/service.go @@ -106,7 +106,7 @@ func (svc *Service) CommonDelete(ctx context.Context, projectId int, resourceNam if err != nil { return err } - + userId := ctx.Value("user_id").(int) userName := ctx.Value("user_name").(string) @@ -122,6 +122,27 @@ func (svc *Service) CommonDelete(ctx context.Context, projectId int, resourceNam return err } +func (svc *Service) CommonRowsSelection(ctx context.Context, projectId int, resourceName string, param *dto.CommonRowsSelectionReq) error { + rsp, err := svc.resourceSvc.RowsSelection(projectId, resourceName, param) + if err != nil { + return nil, err + } + + userId := ctx.Value("user_id").(int) + userName := ctx.Value("user_name").(string) + + event.GetMgrInstance().Publish(event.EventTopic_UserExecute, &event.EventPayload_UserExecute{ + UserId: userId, + UserName: userName, + ProjectId: projectId, + Resource: resourceName, + Method: "删除", + Any: param, + }) + + return rsp, err +} + func (svc *Service) GetSupportResourcesList(permissions []string) []*api.ResourceInitInfo { return svc.resourceSvc.GetSupportResourcesList(permissions) } diff --git a/admin/apps/game/service/service_project.go b/admin/apps/game/service/service_project.go index 02824d1..4a04e0f 100644 --- a/admin/apps/game/service/service_project.go +++ b/admin/apps/game/service/service_project.go @@ -31,6 +31,8 @@ func (svc *Service) GetRoutes(req *api.GetRoutesReq) (*api.GetRoutesRsp, error) Desc: v.Desc, ShowMethods: make([]string, 0), MethodsPermissionStr: make([]string, 0), + GlobalBtns: v.GlobalBtns, + RowBtns: v.RowBtns, } for _, resourceMethod := range v.ShowMethods { diff --git a/admin/cmd/all_in_one/all_in_one.exe b/admin/cmd/all_in_one/all_in_one.exe deleted file mode 100644 index 43b8d35..0000000 Binary files a/admin/cmd/all_in_one/all_in_one.exe and /dev/null differ diff --git a/admin/internal/consts/consts.go b/admin/internal/consts/consts.go index bcdb7eb..b0d2e17 100644 --- a/admin/internal/consts/consts.go +++ b/admin/internal/consts/consts.go @@ -55,3 +55,14 @@ const ( CDKeyType_Global = 0 // 一码通用 CDKeyType_Private = 1 // 一码一用 ) + +const ( + BtnKeyGlobal_Server_DownAll = "server:down:all" // 一键维护 + BtnKeyGlobal_Server_UpAll = "server:up:all" // 一键维护结束 + +) + +const ( + BtnKeyRow_Server_Down = "server:down" + BtnKeyRow_Server_Up = "server:up" +) diff --git a/admin/internal/event/topic.go b/admin/internal/event/topic.go index 9b7f16c..47db473 100644 --- a/admin/internal/event/topic.go +++ b/admin/internal/event/topic.go @@ -12,4 +12,5 @@ type EventPayload_UserExecute struct { Method string `json:"method"` OldData any `json:"old_data"` NewData any `json:"new_data"` + Any any `json:"any"` } diff --git a/admin/lib/dtimer/timer.go b/admin/lib/dtimer/timer.go new file mode 100644 index 0000000..c121b70 --- /dev/null +++ b/admin/lib/dtimer/timer.go @@ -0,0 +1,9 @@ +package dtimer + +/* + 分布式定时器,用于解决比如多个进程启动后,只有一个进程触发定时器事件执行, + 目标不影响架构复杂性,做个能用的出来。思路是用mysql做分布式锁,多个进程抢占单例执行 +*/ + +type DTimer struct { +} diff --git a/admin/lib/utils/time.go b/admin/lib/utils/time.go index 974d97c..c51da94 100644 --- a/admin/lib/utils/time.go +++ b/admin/lib/utils/time.go @@ -22,7 +22,7 @@ func ParseUnixTimestamp2LocalTime(ts int64) (local time.Time) { sec = ts nsec = 0 default: - panic(fmt.Errorf("ts:%v invalid parse to local time")) + panic(fmt.Errorf("ts:%v invalid parse to local time", ts)) } t := time.Unix(sec, nsec) diff --git a/ui/src/components/restful/table.vue b/ui/src/components/restful/table.vue index f59054a..ec55ac5 100644 --- a/ui/src/components/restful/table.vue +++ b/ui/src/components/restful/table.vue @@ -1,5 +1,5 @@