c
This commit is contained in:
parent
d562c644dd
commit
23c83b745c
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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 == "" {
|
||||
|
@ -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)
|
||||
|
@ -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: "打开就是相当于停服维护中了",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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") {
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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:"生效结束时间"`
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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调用服务对内聚合、分发指令执行,本后台执行指令只调用一次;
|
||||
|
@ -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"`
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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 {
|
||||
|
Binary file not shown.
@ -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"
|
||||
)
|
||||
|
@ -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"`
|
||||
}
|
||||
|
9
admin/lib/dtimer/timer.go
Normal file
9
admin/lib/dtimer/timer.go
Normal file
@ -0,0 +1,9 @@
|
||||
package dtimer
|
||||
|
||||
/*
|
||||
分布式定时器,用于解决比如多个进程启动后,只有一个进程触发定时器事件执行,
|
||||
目标不影响架构复杂性,做个能用的出来。思路是用mysql做分布式锁,多个进程抢占单例执行
|
||||
*/
|
||||
|
||||
type DTimer struct {
|
||||
}
|
@ -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)
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import {ElNotification} from "element-plus";
|
||||
import {ElNotification, selectGroupKey} from "element-plus";
|
||||
import {resourceDelete, resourceList, resourcePost, resourcePut, resourceGetAllItems} from "@/api/resource.js";
|
||||
import {ref, toRaw} from "vue";
|
||||
import {useRoute} from 'vue-router';
|
||||
@ -14,6 +14,10 @@ const listDataOK = ref(false)
|
||||
const projectId = cachedResource.meta.projectId
|
||||
const resource_raw_node = cachedResource;
|
||||
const hasListPermit = resource_raw_node.meta.methods.get !== undefined && resource_raw_node.meta.methods.get === true;
|
||||
const globalClickBtns = resource_raw_node.meta.global_click_btns ? resource_raw_node.meta.global_click_btns : [];
|
||||
const rowClickBtns = resource_raw_node.meta.row_click_btns ? resource_raw_node.meta.row_click_btns : [];
|
||||
|
||||
console.log("global btns:", resource_raw_node)
|
||||
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
const fieldsDescInfo = ref([])
|
||||
@ -139,6 +143,20 @@ const dialogObjectForm = ref({
|
||||
Attach: [],
|
||||
})
|
||||
|
||||
const tableSelectRows = ref([])
|
||||
|
||||
const handleTableSelectRowsSendToServer = (keyType, rows) => {
|
||||
console.log(`选择表格行,类型:${keyType},:`, rows)
|
||||
}
|
||||
const handleTableSelectChange = (rows) => {
|
||||
tableSelectRows.value = rows
|
||||
}
|
||||
const tableSelectRows1 = (keyType) => {
|
||||
handleTableSelectRowsSendToServer(keyType, tableSelectRows.value)
|
||||
}
|
||||
const tableSelectRows2 = (keyType, index, row) => {
|
||||
handleTableSelectRowsSendToServer(keyType, [row])
|
||||
}
|
||||
|
||||
const submitAdd = async () => {
|
||||
try {
|
||||
@ -363,14 +381,25 @@ const handlePaginationCurChange = (val) => {
|
||||
</el-row>
|
||||
|
||||
<el-row style="margin-top: 10px">
|
||||
<el-button @click="dialogAddVisible = true" size="large" type="primary"
|
||||
<el-button @click="dialogAddVisible = true" size="default" type="primary"
|
||||
v-if="(resource_raw_node.meta.methods.post === true)">
|
||||
添加
|
||||
</el-button>
|
||||
|
||||
<el-button v-for="btn in globalClickBtns" size="default" :type="btn.btn_type"
|
||||
@click="tableSelectRows1(btn.key)">
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
</el-row>
|
||||
|
||||
|
||||
</el-header>
|
||||
<el-main>
|
||||
<el-table :data="rows" style="width: 100%" table-layout="auto" stripe>
|
||||
<el-table :data="rows" style="width: 100%" table-layout="auto" stripe
|
||||
@selection-change="handleTableSelectChange">
|
||||
<el-table-column type="selection" v-if="globalClickBtns.length > 0 || rowClickBtns.length > 0">
|
||||
|
||||
</el-table-column>
|
||||
<template v-for="fieldDescInfo in fieldsDescInfo">
|
||||
<el-table-column prop="jsonValue" :label="fieldDescInfo.name" show-overflow-tooltip
|
||||
v-if="(fieldDescInfo.type === 'items')"></el-table-column>
|
||||
@ -382,18 +411,22 @@ const handlePaginationCurChange = (val) => {
|
||||
|
||||
<el-button size="default" type="success" @click="handleEdit( scope.$index, scope.row)"
|
||||
v-if="(resource_raw_node.meta.methods.put === true)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<Edit/>
|
||||
</el-icon>
|
||||
<!-- <el-icon style="vertical-align: middle">-->
|
||||
<!-- <Edit/>-->
|
||||
<!-- </el-icon>-->
|
||||
<span>编辑</span>
|
||||
</el-button>
|
||||
<el-button size="default" type="danger" @click="handleDelete( scope.$index, scope.row)"
|
||||
v-if="(resource_raw_node.meta.methods.delete === true)">
|
||||
<el-icon style="vertical-align: middle">
|
||||
<Delete/>
|
||||
</el-icon>
|
||||
<!-- <el-icon style="vertical-align: middle">-->
|
||||
<!-- <Delete/>-->
|
||||
<!-- </el-icon>-->
|
||||
<span>删除</span>
|
||||
</el-button>
|
||||
<el-button v-for="btn in rowClickBtns" size="default" :type="btn.btn_type"
|
||||
@click="tableSelectRows2(btn.key, scope.$index, scope.row)">
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -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 = []
|
||||
@ -119,6 +119,8 @@ export function setProjectOperationRoutes(projectList) {
|
||||
resource: resource.resource,
|
||||
resource_url: routePath,
|
||||
methods: {},
|
||||
global_click_btns: resource.global_btns,
|
||||
row_click_btns: resource.row_btns,
|
||||
},
|
||||
component: () => import('@/views/project/project_op.vue'),
|
||||
props: true
|
||||
|
@ -25,6 +25,7 @@
|
||||
- [ ] 公告发送游戏
|
||||
- [ ] 订单列表从游戏服拉取可以查看
|
||||
- [ ] 优化header右上角昵称部分显示
|
||||
- [ ] 角色在线状态
|
||||
|
||||
* bug记录
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user