optimize some
This commit is contained in:
parent
0e95de298e
commit
c51c430967
@ -27,20 +27,20 @@ type CommonResourceService struct {
|
||||
noticeRepo repo.INoticeRepo
|
||||
}
|
||||
|
||||
func initCommonResourcesRepo(db *gorm.DB) {
|
||||
func (svc *CommonResourceService) initCommonResourcesRepo(db *gorm.DB) {
|
||||
r(consts.ResourcesName_Project, "项目管理", repo.NewCommonResourceRepo(db, &model.Project{}), 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: "一键停服", BtnColorType: "info"},
|
||||
{Key: consts.BtnKeyGlobal_Server_UpAll, Name: "一键起服", BtnColorType: "warning"},
|
||||
{Key: consts.BtnKeyGlobal_Server_ExportCdn, Name: "一键导出cdn", BtnColorType: "danger"},
|
||||
{Key: consts.BtnKeyGlobal_Server_ExportCdn, Name: "预览导出cdn", BtnColorType: "default"},
|
||||
serverRepo.GlobalBtns = []*ResourceBtnInfo{
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Server_DownAll, Name: "一键停服", BtnColorType: "info"}, svc.handleServerUpOrDown},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Server_UpAll, Name: "一键起服", BtnColorType: "warning"}, svc.handleServerUpOrDown},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Server_ExportCdn, Name: "一键导出cdn", BtnColorType: "danger"}, svc.handleServerExportCdn},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Server_ExportCdn, Name: "预览导出cdn", BtnColorType: "default"}, svc.handleServerExportCdn},
|
||||
}
|
||||
serverRepo.RowBtns = []*api.ResourceBtnInfo{
|
||||
{Key: consts.BtnKeyRow_Server_Down, Name: "停服", BtnColorType: "info"},
|
||||
{Key: consts.BtnKeyRow_Server_Up, Name: "起服", BtnColorType: "warning"},
|
||||
serverRepo.RowBtns = []*ResourceBtnInfo{
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyRow_Server_Down, Name: "停服", BtnColorType: "info"}, svc.handleServerUpOrDown},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyRow_Server_Up, Name: "起服", BtnColorType: "warning"}, svc.handleServerUpOrDown},
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,24 +60,25 @@ func initCommonResourcesRepo(db *gorm.DB) {
|
||||
r(consts.ResourcesName_ItemBag, "道具礼包", repo.NewCommonResourceRepo(db, &model.ItemBag{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete)
|
||||
{
|
||||
noticeRepo := r(consts.ResourcesName_Notice, "公告", repo.NewCommonResourceRepo(db, &model.Notice{}), ShowMethod_Get|ShowMethod_Post|ShowMethod_Put|ShowMethod_Delete)
|
||||
noticeRepo.GlobalBtns = []*api.ResourceBtnInfo{
|
||||
{Key: consts.BtnKeyGlobal_Server_DownAll, Name: "一键禁用所有", BtnColorType: "info"},
|
||||
noticeRepo.GlobalBtns = []*ResourceBtnInfo{
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Notice_DisableAll, Name: "一键禁用", BtnColorType: "info"}, svc.handleNoticeDisable},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Notice_EnableAll, Name: "一键启用", BtnColorType: "warning"}, svc.handleNoticeEnable},
|
||||
}
|
||||
noticeRepo.RowBtns = []*api.ResourceBtnInfo{
|
||||
{Key: consts.BtnKeyRow_Server_Down, Name: "禁用", BtnColorType: "info"},
|
||||
{Key: consts.BtnKeyRow_Server_Up, Name: "启用", BtnColorType: "warning"},
|
||||
noticeRepo.RowBtns = []*ResourceBtnInfo{
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Notice_Disable, Name: "禁用", BtnColorType: "info"}, svc.handleNoticeDisable},
|
||||
{&api.ResourceBtnInfo{Key: consts.BtnKeyGlobal_Notice_Enable, Name: "启用", BtnColorType: "warning"}, svc.handleNoticeEnable},
|
||||
}
|
||||
}
|
||||
r(consts.ResourcesName_DevicePush, "设备推送(暂无)", repo.NewCommonResourceRepo(db, &model.DevicePush{}), ShowMethod_Get)
|
||||
}
|
||||
|
||||
func NewCommonResourceService(db *gorm.DB) *CommonResourceService {
|
||||
initCommonResourcesRepo(db)
|
||||
svc := &CommonResourceService{
|
||||
projectRepo: repo.NewProjectRepo(db),
|
||||
serverRepo: repo.NewServerRepo(db),
|
||||
noticeRepo: repo.NewNoticeRepo(db),
|
||||
}
|
||||
svc.initCommonResourcesRepo(db)
|
||||
svc.startEventSubscriber()
|
||||
svc.startLoadAllDelayInvokeDbData()
|
||||
return svc
|
||||
@ -305,33 +306,14 @@ func (svc *CommonResourceService) RowsSelection(projectId int, resourceName stri
|
||||
return projectEt, nil, errcode.New(errcode.ServerError, "not found project %v db data", projectId)
|
||||
}
|
||||
|
||||
if params.BtnKey == consts.BtnKeyGlobal_Server_ExportCdn {
|
||||
// 导出cdn,聚合公告信息一起导
|
||||
serverList, err := svc.serverRepo.List(projectId)
|
||||
if err != nil {
|
||||
return projectEt, nil, err
|
||||
}
|
||||
noticeList, err := svc.noticeRepo.List(projectId)
|
||||
if err != nil {
|
||||
return projectEt, nil, err
|
||||
}
|
||||
content, err := genCdnServerListContent(serverList, noticeList)
|
||||
if err != nil {
|
||||
return projectEt, nil, err
|
||||
}
|
||||
return projectEt, &dto2.CommonRowsSelectionRsp{
|
||||
Msg: content,
|
||||
NeedRefresh: false,
|
||||
FileName: projectEt.GetProjectPo().Name + "-区服公告信息.txt",
|
||||
}, nil
|
||||
} else {
|
||||
if hook, ok := projects.GetProjectResourceHook(projectEt, resourceName).(projects.IPostResourceOpRowsHook); ok {
|
||||
rsp, err := hook.RowsSelection(projectEt, resourceName, params.BtnKey, params.Rows)
|
||||
return projectEt, rsp, err
|
||||
}
|
||||
rRepo := findCommResourceRepo(resourceName)
|
||||
btnInfo, find := rRepo.findRowsSelectionBtn(params.BtnKey)
|
||||
if !find {
|
||||
return projectEt, nil, errcode.New(errcode.ServerError, "not found project %v resource %v rows section btn:%v",
|
||||
projectId, resourceName, params.BtnKey)
|
||||
}
|
||||
|
||||
return projectEt, nil, nil
|
||||
rsp, err := btnInfo.RowsSelectionHandler(projectEt, resourceName, params)
|
||||
return projectEt, rsp, err
|
||||
}
|
||||
|
||||
func (svc *CommonResourceService) GetResourceKeyByDto(resource string, dtoObj []dto2.CommonDtoValues) (string, string) {
|
||||
@ -358,7 +340,7 @@ func (svc *CommonResourceService) GetResourceKeyByDto(resource string, dtoObj []
|
||||
return desc, strings.Join(keyList, ",")
|
||||
}
|
||||
|
||||
func (svc *CommonResourceService) GetResourceSpecBtnKey(resource string, btnKey string) *api.ResourceBtnInfo {
|
||||
func (svc *CommonResourceService) GetResourceSpecBtnKey(resource string, btnKey string) *ResourceBtnInfo {
|
||||
resourceInfo := findCommResourceRepo(resource)
|
||||
for _, v := range resourceInfo.GlobalBtns {
|
||||
if v.Key == btnKey {
|
||||
@ -376,13 +358,18 @@ func (svc *CommonResourceService) GetResourceSpecBtnKey(resource string, btnKey
|
||||
func (svc *CommonResourceService) GetSupportResourcesList(permissions []string) []*api.ResourceInitInfo {
|
||||
list := make([]*api.ResourceInitInfo, 0, len(commResourcesRepo))
|
||||
for _, v := range commResourcesRepo {
|
||||
list = append(list, &api.ResourceInitInfo{
|
||||
initInfo := &api.ResourceInitInfo{
|
||||
Resource: v.Resource,
|
||||
Desc: v.Desc,
|
||||
ShowMethods: v.ShowMethods,
|
||||
GlobalBtns: v.GlobalBtns,
|
||||
RowBtns: v.RowBtns,
|
||||
})
|
||||
}
|
||||
for _, v := range v.GlobalBtns {
|
||||
initInfo.GlobalBtns = append(initInfo.GlobalBtns, v.ResourceBtnInfo)
|
||||
}
|
||||
for _, v := range v.RowBtns {
|
||||
initInfo.RowBtns = append(initInfo.RowBtns, v.ResourceBtnInfo)
|
||||
}
|
||||
list = append(list, initInfo)
|
||||
}
|
||||
return list
|
||||
}
|
||||
@ -394,17 +381,36 @@ const (
|
||||
ShowMethod_Delete = 1 << 3
|
||||
)
|
||||
|
||||
type ResourceBtnInfo struct {
|
||||
*api.ResourceBtnInfo
|
||||
RowsSelectionHandler func(projectEt *entity.Project, resourceName string, params *dto2.CommonRowsSelectionReq) (*dto2.CommonRowsSelectionRsp, error)
|
||||
}
|
||||
|
||||
type resourceRepoInfo struct {
|
||||
Resource string
|
||||
Desc string
|
||||
Repo repo.ICommonResourceRepo
|
||||
ShowMethods []string
|
||||
showMethods int
|
||||
GlobalBtns []*api.ResourceBtnInfo
|
||||
RowBtns []*api.ResourceBtnInfo
|
||||
GlobalBtns []*ResourceBtnInfo
|
||||
RowBtns []*ResourceBtnInfo
|
||||
HasDelayInvokeCreateHook bool
|
||||
}
|
||||
|
||||
func (repoInfo *resourceRepoInfo) findRowsSelectionBtn(clickedBtn string) (*ResourceBtnInfo, bool) {
|
||||
for _, btn := range repoInfo.GlobalBtns {
|
||||
if btn.Key == clickedBtn {
|
||||
return btn, true
|
||||
}
|
||||
}
|
||||
for _, btn := range repoInfo.RowBtns {
|
||||
if btn.Key == clickedBtn {
|
||||
return btn, true
|
||||
}
|
||||
}
|
||||
return nil, false
|
||||
}
|
||||
|
||||
var commResourcesRepo = make([]*resourceRepoInfo, 0)
|
||||
|
||||
func r(resource, desc string, repo repo.ICommonResourceRepo, showMethods int) *resourceRepoInfo {
|
||||
|
78
admin/apps/game/domain/comm_resource_selection.go
Normal file
78
admin/apps/game/domain/comm_resource_selection.go
Normal file
@ -0,0 +1,78 @@
|
||||
package domain
|
||||
|
||||
import (
|
||||
"admin/apps/game/domain/entity"
|
||||
"admin/apps/game/domain/projects"
|
||||
dto2 "admin/internal/model/dto"
|
||||
)
|
||||
|
||||
func (svc *CommonResourceService) handleServerUpOrDown(projectEt *entity.Project, resourceName string, params *dto2.CommonRowsSelectionReq) (*dto2.CommonRowsSelectionRsp, error) {
|
||||
if hook, ok := projects.GetProjectResourceHook(projectEt, resourceName).(projects.IPostResourceOpRowsHook); ok {
|
||||
rsp, err := hook.RowsSelection(projectEt, resourceName, params.BtnKey, params.Rows)
|
||||
return rsp, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (svc *CommonResourceService) handleServerExportCdn(projectEt *entity.Project, resourceName string, params *dto2.CommonRowsSelectionReq) (*dto2.CommonRowsSelectionRsp, error) {
|
||||
// 导出cdn,聚合公告信息一起导
|
||||
serverList, err := svc.serverRepo.List(projectEt.GetProjectPo().ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
noticeList, err := svc.noticeRepo.List(projectEt.GetProjectPo().ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := genCdnServerListContent(serverList, noticeList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto2.CommonRowsSelectionRsp{
|
||||
Msg: content,
|
||||
NeedRefresh: false,
|
||||
FileName: projectEt.GetProjectPo().Name + "-区服公告信息.txt",
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *CommonResourceService) handleNoticeDisable(projectEt *entity.Project, resourceName string, params *dto2.CommonRowsSelectionReq) (*dto2.CommonRowsSelectionRsp, error) {
|
||||
var err error
|
||||
if len(params.Rows) == 0 {
|
||||
// 禁用所有
|
||||
err = svc.noticeRepo.DisableAll(projectEt.GetProjectID())
|
||||
} else {
|
||||
ids := make([]int, 0, len(params.Rows))
|
||||
for _, v := range params.Rows {
|
||||
ids = append(ids, int(v["ID"].(float64)))
|
||||
}
|
||||
err = svc.noticeRepo.DisableSome(projectEt.GetProjectID(), ids)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto2.CommonRowsSelectionRsp{
|
||||
Msg: "禁用成功!",
|
||||
NeedRefresh: true,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *CommonResourceService) handleNoticeEnable(projectEt *entity.Project, resourceName string, params *dto2.CommonRowsSelectionReq) (*dto2.CommonRowsSelectionRsp, error) {
|
||||
var err error
|
||||
if len(params.Rows) == 0 {
|
||||
// 禁用所有
|
||||
err = svc.noticeRepo.EnableAll(projectEt.GetProjectID())
|
||||
} else {
|
||||
ids := make([]int, 0, len(params.Rows))
|
||||
for _, v := range params.Rows {
|
||||
ids = append(ids, int(v["ID"].(float64)))
|
||||
}
|
||||
err = svc.noticeRepo.EnableSome(projectEt.GetProjectID(), ids)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &dto2.CommonRowsSelectionRsp{
|
||||
Msg: "启用成功!",
|
||||
NeedRefresh: true,
|
||||
}, nil
|
||||
}
|
@ -25,6 +25,10 @@ func (project *Project) ToCommonResource() *CommonResource {
|
||||
return er.FromPo(project.Po)
|
||||
}
|
||||
|
||||
func (project *Project) GetProjectID() int {
|
||||
return project.Po.ID
|
||||
}
|
||||
|
||||
func (project *Project) GetProjectPo() *model.Project {
|
||||
return project.Po
|
||||
}
|
||||
|
@ -45,13 +45,13 @@ func (hook *ServerHook) List(projectInfo *entity.Project, resource string, param
|
||||
row["TotalRoleCount"] = findRemoteServerInfo.TotalRoleCount
|
||||
row["TotalAccountCount"] = findRemoteServerInfo.TotalAccountCount
|
||||
if findRemoteServerInfo.IsServerDown {
|
||||
row["IsServerDown"] = "是"
|
||||
row["IsServerDown"] = true
|
||||
} else {
|
||||
row["IsServerDown"] = "否"
|
||||
row["IsServerDown"] = false
|
||||
}
|
||||
} else {
|
||||
row["IsServerDown"] = "否"
|
||||
row["RunningStatus"] = "未知"
|
||||
row["IsServerDown"] = false
|
||||
row["RunningStatus"] = "失联"
|
||||
row["Ccu"] = 0
|
||||
row["TotalRoleCount"] = 0
|
||||
row["TotalAccountCount"] = 0
|
||||
|
@ -11,6 +11,10 @@ var NoticeRepoInstance INoticeRepo
|
||||
|
||||
type INoticeRepo interface {
|
||||
List(projectId int) ([]*entity.CommonResource, error)
|
||||
DisableAll(projectId int) error
|
||||
EnableAll(projectId int) error
|
||||
DisableSome(projectId int, ids []int) error
|
||||
EnableSome(projectId int, ids []int) error
|
||||
}
|
||||
|
||||
func NewNoticeRepo(db *gorm.DB) INoticeRepo {
|
||||
@ -23,7 +27,7 @@ type noticeRepoImpl struct {
|
||||
|
||||
func (impl *noticeRepoImpl) List(projectId int) ([]*entity.CommonResource, error) {
|
||||
list := make([]*model.Notice, 0)
|
||||
err := impl.db.Where("project_id = ?", projectId).Find(&list).Error
|
||||
err := impl.db.Where("project_id = ? and status = ?", projectId, true).Find(&list).Error
|
||||
if err != nil {
|
||||
return nil, errcode.New(errcode.DBError, "list server error:%v", err)
|
||||
}
|
||||
@ -34,3 +38,32 @@ func (impl *noticeRepoImpl) List(projectId int) ([]*entity.CommonResource, error
|
||||
}
|
||||
return list1, nil
|
||||
}
|
||||
|
||||
func (impl *noticeRepoImpl) DisableAll(projectId int) error {
|
||||
err := impl.db.Model(&model.Notice{}).Where("project_id = ?", projectId).Update("status", false).Error
|
||||
if err != nil {
|
||||
return errcode.New(errcode.DBError, "disable all error:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (impl *noticeRepoImpl) EnableAll(projectId int) error {
|
||||
err := impl.db.Model(&model.Notice{}).Where("project_id = ?", projectId).Update("status", true).Error
|
||||
if err != nil {
|
||||
return errcode.New(errcode.DBError, "enable all error:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (impl *noticeRepoImpl) DisableSome(projectId int, ids []int) error {
|
||||
err := impl.db.Model(&model.Notice{}).Where("project_id = ? and id in ?", projectId, ids).Update("status", false).Error
|
||||
if err != nil {
|
||||
return errcode.New(errcode.DBError, "disable all error:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (impl *noticeRepoImpl) EnableSome(projectId int, ids []int) error {
|
||||
err := impl.db.Model(&model.Notice{}).Where("project_id = ? and id in ?", projectId, ids).Update("status", true).Error
|
||||
if err != nil {
|
||||
return errcode.New(errcode.DBError, "disable all error:%v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import (
|
||||
"admin/apps/game/model"
|
||||
"admin/internal/errcode"
|
||||
"bytes"
|
||||
"sort"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
@ -68,6 +69,13 @@ func genCdnServerListContent(serverList, noticeList []*entity.CommonResource) (s
|
||||
}
|
||||
|
||||
info.NoticeVersion = time.Now().Format("200601021504")
|
||||
|
||||
sort.SliceStable(noticeList, func(i, j int) bool {
|
||||
infoI := noticeList[i].Po.(*model.Notice)
|
||||
infoJ := noticeList[j].Po.(*model.Notice)
|
||||
return infoI.SortWeight > infoJ.SortWeight
|
||||
})
|
||||
|
||||
for i, notice := range noticeList {
|
||||
noticeDbInfo := notice.Po.(*model.Notice)
|
||||
noticeInfo := &CdnNoticeInfo{}
|
||||
|
@ -19,7 +19,8 @@ type Notice struct {
|
||||
Content string `name:"公告内容" desc:"仅支持<color=#xxx></color>颜色标签和\\n换行标签" type:"text" required:"true"` // 公告内容
|
||||
//StartAt time.Time `name:"开始时间" required:"true"`
|
||||
//EndAt time.Time `name:"结束时间" required:"true"`
|
||||
Status bool `name:"是否启用" type:"tagStatus" choices:"GetStatusChoices" required:"true"`
|
||||
Status bool `name:"是否启用" desc:"启用的公告才会导出到cdn被客户端显示" type:"tagStatus" choices:"GetStatusChoices" required:"true"`
|
||||
SortWeight int `name:"排序" desc:"越大越靠前"`
|
||||
|
||||
CreatedAt time.Time `readonly:"true"`
|
||||
UpdatedAt time.Time `readonly:"true"`
|
||||
@ -39,7 +40,7 @@ func (m *Notice) GetChoiceServers(project *Project) []*dto.CommonDtoFieldChoice
|
||||
|
||||
func (m *Notice) GetStatusChoices(project *Project) []*dto.CommonDtoFieldChoice {
|
||||
return []*dto.CommonDtoFieldChoice{
|
||||
{Desc: "禁用", Value: false},
|
||||
{Desc: "启动", Value: true},
|
||||
{Desc: "禁用", Value: false, Type: 3}, // type: 0:plain 1:primary 2:success 3:info 4:warning 5:danger
|
||||
{Desc: "启用", Value: true, Type: 2},
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ type Role struct {
|
||||
Account string `name:"账号" json:"account" where:"eq"`
|
||||
RoleId string `name:"角色ID" json:"roleId" where:"eq"`
|
||||
Name string `name:"名称" json:"roleName" where:"eq"`
|
||||
Status string `name:"状态" desc:"离线|在线" type:"boolStatus" choices:"" json:"status"`
|
||||
Status string `name:"状态" desc:"离线|在线" type:"tagStatus" choices:"GetStatusChoices"`
|
||||
Level int `name:"等级" json:"roleLevel"`
|
||||
Profession string `name:"职业" json:"profession"`
|
||||
LatestLoginTime time.Time `name:"最近登录时间" json:"latestLoginAt"`
|
||||
@ -38,7 +38,7 @@ func (m *Role) GetServerConfIDChoices(project *Project) []*dto.CommonDtoFieldCho
|
||||
|
||||
func (m *Role) GetStatusChoices(project *Project) []*dto.CommonDtoFieldChoice {
|
||||
return []*dto.CommonDtoFieldChoice{
|
||||
{Desc: "离线", Value: "离线"},
|
||||
{Desc: "在线", Value: "在线"},
|
||||
{Desc: "离线", Value: "离线", Type: 3}, // type: 0:plain 1:primary 2:success 3:info 4:warning 5:danger
|
||||
{Desc: "在线", Value: "在线", Type: 2},
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package model
|
||||
import (
|
||||
"admin/internal/db"
|
||||
"admin/internal/global"
|
||||
"admin/internal/model/dto"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -17,11 +18,11 @@ type Server struct {
|
||||
ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_server" name:"区服id" required:"true" uneditable:"true"`
|
||||
Desc string `name:"描述"`
|
||||
ClientConnAddr string `name:"客户端连接地址" desc:"填 公网ip:公网端口" required:"true"`
|
||||
RunningStatus string `name:"进程运行状态" desc:"进程运行状态:未知、运行中、停止" readonly:"true" uneditable:"true"`
|
||||
RunningStatus string `name:"进程运行状态" desc:"进程运行状态:未知、运行中、停止" readonly:"true" uneditable:"true" type:"tagStatus" choices:"GetRunningStatusChoices"`
|
||||
Ccu int `name:"实时在线" desc:"ccu" readonly:"true" uneditable:"true"`
|
||||
TotalRoleCount int `name:"总角色数" desc:"" readonly:"true" uneditable:"true"`
|
||||
TotalAccountCount int `name:"总账号数" desc:"" readonly:"true" uneditable:"true"`
|
||||
IsServerDown bool `name:"停服维护中" desc:"" readonly:"true" uneditable:"true"`
|
||||
IsServerDown bool `name:"停服维护中" desc:"" readonly:"true" uneditable:"true" type:"tagStatus" choices:"GetServerDownStatusChoices"`
|
||||
// command_list接口服务器地址,为空代表由由项目统一提供command_list.
|
||||
// 取决于每个项目改造难度:
|
||||
// 为空就代表项目要实现一个自己统一对外暴露的gm调用服务对内聚合、分发指令执行,本后台执行指令只调用一次;
|
||||
@ -50,3 +51,17 @@ func (m *Server) ListByProjectId(projectId int) ([]*Server, error) {
|
||||
err := global.GLOB_DB.Where("project_id=?", projectId).Find(&list).Error
|
||||
return list, err
|
||||
}
|
||||
|
||||
func (m *Server) GetRunningStatusChoices(project *Project) []*dto.CommonDtoFieldChoice {
|
||||
return []*dto.CommonDtoFieldChoice{
|
||||
{Desc: "失联", Value: "失联", Type: 3}, // type: 0:plain 1:primary 2:success 3:info 4:warning 5:danger
|
||||
{Desc: "运行中", Value: "运行中", Type: 2},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Server) GetServerDownStatusChoices(project *Project) []*dto.CommonDtoFieldChoice {
|
||||
return []*dto.CommonDtoFieldChoice{
|
||||
{Desc: "否", Value: false, Type: 3}, // type: 0:plain 1:primary 2:success 3:info 4:warning 5:danger
|
||||
{Desc: "是", Value: true, Type: 2},
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,12 @@ import (
|
||||
"admin/internal/context"
|
||||
"admin/internal/errcode"
|
||||
"admin/internal/permission"
|
||||
"admin/lib/xlog"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (srv *Server) CheckToken(ctx *context.WebContext) {
|
||||
reqPath := ctx.GinCtx().Request.URL.Path
|
||||
xlog.Tracef("请求路径:%v, 头:%+v", reqPath, ctx.GinCtx().Request.Header)
|
||||
//xlog.Tracef("请求路径:%v, 头:%+v", reqPath, ctx.GinCtx().Request.Header)
|
||||
if strings.Contains(reqPath, "/login") {
|
||||
return
|
||||
}
|
||||
|
@ -3,13 +3,12 @@ package server
|
||||
import (
|
||||
"admin/internal/context"
|
||||
"admin/internal/errcode"
|
||||
"admin/lib/xlog"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (srv *Server) CheckToken(ctx *context.WebContext) {
|
||||
reqPath := ctx.GinCtx().Request.URL.Path
|
||||
xlog.Tracef("请求路径:%v, 头:%+v", reqPath, ctx.GinCtx().Request.Header)
|
||||
//xlog.Tracef("请求路径:%v, 头:%+v", reqPath, ctx.GinCtx().Request.Header)
|
||||
if strings.Contains(reqPath, "/login") {
|
||||
return
|
||||
}
|
||||
|
@ -58,9 +58,13 @@ const (
|
||||
)
|
||||
|
||||
const (
|
||||
BtnKeyGlobal_Server_DownAll = "server:down:all" // 一键维护
|
||||
BtnKeyGlobal_Server_UpAll = "server:up:all" // 一键维护结束
|
||||
BtnKeyGlobal_Server_ExportCdn = "server:export:cdn" // 一键导出cdn
|
||||
BtnKeyGlobal_Server_DownAll = "server:down:all" // 一键维护
|
||||
BtnKeyGlobal_Server_UpAll = "server:up:all" // 一键维护结束
|
||||
BtnKeyGlobal_Server_ExportCdn = "server:export:cdn" // 一键导出cdn
|
||||
BtnKeyGlobal_Notice_DisableAll = "notice:disable:all" // 一键禁用
|
||||
BtnKeyGlobal_Notice_EnableAll = "notice:enable:all" // 一键启用
|
||||
BtnKeyGlobal_Notice_Disable = "notice:disable" // 禁用
|
||||
BtnKeyGlobal_Notice_Enable = "notice:enable" // 启用
|
||||
|
||||
)
|
||||
|
||||
|
@ -37,7 +37,7 @@ func (ctx *WebContext) ExtractHeader() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
xlog.Debugf("提取请求头:%+v", ctx.GinCtx().Request.Header)
|
||||
//xlog.Debugf("提取请求头:%+v", ctx.GinCtx().Request.Header)
|
||||
ctx.Header = header
|
||||
return nil
|
||||
}
|
||||
|
79
ui/src/components/game/cdkeyDetail.vue
Normal file
79
ui/src/components/game/cdkeyDetail.vue
Normal file
@ -0,0 +1,79 @@
|
||||
<script setup>
|
||||
|
||||
import LocalCache from "@/stores/localCache.js";
|
||||
|
||||
const props = defineProps({
|
||||
rowInfo: {},
|
||||
fieldsDescInfo: {},
|
||||
})
|
||||
|
||||
const dialogObjectForm = props.rowInfo
|
||||
const fieldsDescInfo = props.fieldsDescInfo
|
||||
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-form ref="dialogLookFormRef" :model="dialogObjectForm" class="operation_form"
|
||||
label-width="130px">
|
||||
<template v-for="fieldDescInfo in fieldsDescInfo">
|
||||
|
||||
<!--如果是items类型,就是物品下拉框+道具组合-->
|
||||
<template v-if="(fieldDescInfo.type === 'items')">
|
||||
<el-form-item label="奖励列表" prop="Attach">
|
||||
<el-table :data="dialogObjectForm.Attach" border>
|
||||
<el-table-column label="道具id" prop="id"/>
|
||||
<el-table-column label="数量" prop="num"/>
|
||||
<el-table-column label="道具名" prop="desc"/>
|
||||
</el-table>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<!-- 有可选项的字段,走下拉框或者多选框 -->
|
||||
<template v-if="(fieldDescInfo.choices !== undefined && fieldDescInfo.choices.length > 0)">
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="bottom-start">
|
||||
<el-select :placeholder="(fieldDescInfo.multi_choice === true ? '--多选--' : '--单选--')"
|
||||
disabled
|
||||
v-model="dialogObjectForm[fieldDescInfo.key]" style="width: 150px"
|
||||
:multiple="(fieldDescInfo.multi_choice === true)">
|
||||
<el-option v-for="info in fieldDescInfo.choices" :key="info.desc" :label="info.desc"
|
||||
:value="info.value"></el-option>
|
||||
</el-select>
|
||||
</el-tooltip>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 时间戳字段,展示时间选择器 -->
|
||||
<template v-else-if="(fieldDescInfo.type === 'Time')">
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-date-picker v-model="dialogObjectForm[fieldDescInfo.key]" type="datetime"
|
||||
disabled
|
||||
placeholder="空时间" format="YYYY/MM/DD HH:mm:ss"
|
||||
value-format="YYYY/MM/DD HH:mm:ss"></el-date-picker>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<!-- 否则就是普通字段 -->
|
||||
<template v-else>
|
||||
<el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">
|
||||
<el-input v-model="dialogObjectForm[fieldDescInfo.key]"
|
||||
disabled></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<!-- <el-form-item :label="fieldDescInfo.name" :prop="fieldDescInfo.key">-->
|
||||
<!-- <el-input v-model="dialogEditForm[fieldDescInfo.key]"></el-input>-->
|
||||
<!-- </el-form-item>-->
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
75
ui/src/components/game/cdkeyUsedHistory.vue
Normal file
75
ui/src/components/game/cdkeyUsedHistory.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<script setup>
|
||||
|
||||
import LocalCache from "@/stores/localCache.js";
|
||||
import {cdkeyUsed} from "@/api/cdkey.js";
|
||||
|
||||
const props = defineProps({
|
||||
rowInfo: {},
|
||||
fieldsDescInfo: {},
|
||||
})
|
||||
|
||||
const dialogObjectForm = props.rowInfo
|
||||
const fieldsDescInfo = props.fieldsDescInfo
|
||||
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
|
||||
const cdkeyUsedHistoryList = ref([])
|
||||
|
||||
const cdkeyUsedHistoryTotal = ref([])
|
||||
cdkeyUsed(resource_url, {id: dialogObjectForm.ID}).then((res) => {
|
||||
cdkeyUsedHistoryList.value = res.data.list
|
||||
cdkeyUsedHistoryTotal.value = [
|
||||
{
|
||||
"filedKey1": "礼包名称",
|
||||
"filedValue1": dialogObjectForm.Name,
|
||||
"filedKey2": "礼包总数量",
|
||||
"filedValue2": dialogObjectForm.CodeNum,
|
||||
}, {
|
||||
"filedKey1": "礼包使用数量",
|
||||
"filedValue1": cdkeyUsedHistoryList.value.length,
|
||||
}]
|
||||
|
||||
}, (err) => {
|
||||
|
||||
})
|
||||
|
||||
const tableCellStyle = (row) => {
|
||||
if (row.columnIndex === 0 || row.columnIndex === 2) {
|
||||
// return 'background:#fde9d9 !import'
|
||||
return {"font-weight": "bold", "color": "black"}
|
||||
} else {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-row>
|
||||
<el-table :data="cdkeyUsedHistoryTotal" style="width: 100%" table-layout="auto" border :cell-style="tableCellStyle"
|
||||
:show-header="false">
|
||||
<el-table-column prop="filedKey1" label="" width="180"/>
|
||||
<el-table-column prop="filedValue1" label="" width="200"/>
|
||||
<el-table-column prop="filedKey2" label="" width="180"/>
|
||||
<el-table-column prop="filedValue2" label="" width="200"/>
|
||||
</el-table>
|
||||
</el-row>
|
||||
<el-divider content-position="left">使用详情</el-divider>
|
||||
<el-row>
|
||||
<el-table :data="cdkeyUsedHistoryList" style="width: 100%" height="300" max-height="300" table-layout="auto"
|
||||
stripe>
|
||||
<el-table-column prop="server_id" label="区服"></el-table-column>
|
||||
<el-table-column prop="account" label="账号名"></el-table-column>
|
||||
<el-table-column prop="role_id" label="角色id"></el-table-column>
|
||||
<el-table-column prop="role_name" label="角色名"></el-table-column>
|
||||
<el-table-column prop="key" label="码"></el-table-column>
|
||||
<el-table-column prop="ip" label="ip"></el-table-column>
|
||||
<el-table-column prop="device_id" label="设备号"></el-table-column>
|
||||
<el-table-column prop="created_at" label="使用时间"></el-table-column>
|
||||
</el-table>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -7,6 +7,7 @@ import LocalCache from "@/stores/localCache.js";
|
||||
|
||||
const props = defineProps({
|
||||
rowInfo: {},
|
||||
fieldsDescInfo: {},
|
||||
})
|
||||
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
|
@ -46,7 +46,6 @@ const rowClickBtnSelectRow = ref(null)
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
const fieldsDescInfo = ref([])
|
||||
const whereFieldsDescInfo = ref([])
|
||||
const calcElColSpan = ref(0)
|
||||
const rows = ref([])
|
||||
const itemBags = ref([])
|
||||
const rules = ref({})
|
||||
@ -63,6 +62,77 @@ const selectedItemBag = ref(null)
|
||||
|
||||
// console.log("enter table, resource:", cachedResource)
|
||||
|
||||
const handleServerRowData = (fieldsDescInfoData, rowData) => {
|
||||
for (let i = 0; i < fieldsDescInfoData.length; i++) {
|
||||
var field = fieldsDescInfoData[i]
|
||||
// dialogObjectForm.value[field.key] = ''
|
||||
|
||||
if (field.required === true) {
|
||||
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}]
|
||||
}
|
||||
|
||||
if (field.type === "items") {
|
||||
dialogObjectForm.value[field.key] = []
|
||||
rowData.jsonValue = JSON.stringify(rowData[field.key])
|
||||
if (field.required === true) {
|
||||
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", "change"],
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
const tagStatusColorArray = ["plain", "primary", "success", "info", "waring", "danger"]
|
||||
if (field.type === "tagStatus") {
|
||||
for (let k = 0; k < field.choices.length; k++) {
|
||||
if (rowData[field.key] === field.choices[k].value) {
|
||||
rowData.tagValue = field.choices[k].desc
|
||||
rowData.tagColor = tagStatusColorArray[field.choices[k].type]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (field.where !== "") {
|
||||
field.value1 = ""
|
||||
field.value2 = ""
|
||||
field.whereDesc = getWhereConditionDesc(field.where)
|
||||
let find = false
|
||||
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
|
||||
let whereField = whereFieldsDescInfo.value[i]
|
||||
if (whereField.key === field.key) {
|
||||
whereFieldsDescInfo.value[i].type = field.type
|
||||
whereFieldsDescInfo.value[i].where = field.where
|
||||
whereFieldsDescInfo.value[i].whereDesc = getWhereConditionDesc(field.where)
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
whereFieldsDescInfo.value.push(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rowData
|
||||
}
|
||||
|
||||
const handleServerRowsData = (fieldsDescInfoData, rowsData) => {
|
||||
let newRowsData = []
|
||||
rowsData.forEach((rowData) => {
|
||||
const newRowData = handleServerRowData(fieldsDescInfoData, rowData)
|
||||
// console.log("new data:", newRowData)
|
||||
newRowsData.push(newRowData)
|
||||
})
|
||||
return newRowsData
|
||||
}
|
||||
|
||||
const listData = async () => {
|
||||
try {
|
||||
let listParams = {
|
||||
@ -93,74 +163,9 @@ const listData = async () => {
|
||||
if (listRsp.value.code !== 200) throw new Error("请求失败,错误码:", listRsp.code);
|
||||
fieldsDescInfo.value = listRsp.value.data.fields_desc
|
||||
totalRowCount.value = listRsp.value.data.total_count
|
||||
rows.value = listRsp.value.data.rows
|
||||
rows.value = handleServerRowsData(fieldsDescInfo.value, listRsp.value.data.rows)
|
||||
itemBags.value = listRsp.value.data.item_bags
|
||||
|
||||
for (let i = 0; i < fieldsDescInfo.value.length; i++) {
|
||||
var field = fieldsDescInfo.value[i]
|
||||
// dialogObjectForm.value[field.key] = ''
|
||||
|
||||
if (field.required === true) {
|
||||
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}]
|
||||
}
|
||||
|
||||
if (field.type === "items") {
|
||||
dialogObjectForm.value[field.key] = []
|
||||
for (let j = 0; j < rows.value.length; j++) {
|
||||
rows.value[j].jsonValue = JSON.stringify(rows.value[j][field.key])
|
||||
}
|
||||
if (field.required === true) {
|
||||
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", "change"],
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
if (field.where !== "") {
|
||||
field.value1 = ""
|
||||
field.value2 = ""
|
||||
field.whereDesc = getWhereConditionDesc(field.where)
|
||||
let find = false
|
||||
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
|
||||
let whereField = whereFieldsDescInfo.value[i]
|
||||
if (whereField.key === field.key) {
|
||||
whereFieldsDescInfo.value[i].type = field.type
|
||||
whereFieldsDescInfo.value[i].where = field.where
|
||||
whereFieldsDescInfo.value[i].whereDesc = getWhereConditionDesc(field.where)
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
whereFieldsDescInfo.value.push(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calcElColSpan.value = 0
|
||||
// 计算el-col占用24格子的span数量
|
||||
let calcElColSpanTmp = 2
|
||||
whereFieldsDescInfo.value.forEach((field) => {
|
||||
if (field.where === "range") {
|
||||
calcElColSpanTmp += 2
|
||||
} else {
|
||||
calcElColSpanTmp += 1
|
||||
}
|
||||
})
|
||||
calcElColSpan.value = 24 / calcElColSpanTmp
|
||||
|
||||
// console.log("where fields:", whereFieldsDescInfo.value)
|
||||
// console.log('await list rsp:', listRsp.value, fieldsDescInfo.value, toRaw(rows.value), toRaw(rules.value))
|
||||
|
||||
listDataOK.value = true
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
@ -169,6 +174,29 @@ const listData = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
const calcFuncColumnBtnSize = () => {
|
||||
let btnCount = 0;
|
||||
if (resource_raw_node.meta.methods.put === true) {
|
||||
btnCount += 1
|
||||
}
|
||||
if (resource_raw_node.meta.methods.delete === true) {
|
||||
btnCount += 1
|
||||
}
|
||||
|
||||
btnCount += rowClickBtns.length
|
||||
|
||||
if (btnCount >= 4) {
|
||||
return "small"
|
||||
}
|
||||
if (btnCount >= 3) {
|
||||
return "default"
|
||||
}
|
||||
return "large"
|
||||
}
|
||||
|
||||
const funcBtnSize = ref("default")
|
||||
funcBtnSize.value = calcFuncColumnBtnSize()
|
||||
|
||||
onMounted(() => {
|
||||
listData();
|
||||
})
|
||||
@ -287,7 +315,9 @@ const submitAdd = async () => {
|
||||
duration: 4000,
|
||||
"show-close": true,
|
||||
})
|
||||
rows.value.push(res.data.dto)
|
||||
const newData = handleServerRowData(fieldsDescInfo.value, res.data.dto)
|
||||
rows.value.unshift(newData)
|
||||
// rows.value.push(res.data.dto)
|
||||
dialogAddVisible.value = false
|
||||
handleCloseDialog()
|
||||
}, (err) => {
|
||||
@ -320,7 +350,7 @@ const submitEdit = async () => {
|
||||
"show-close": true,
|
||||
})
|
||||
dialogEditVisible.value = false
|
||||
rows.value[oldIndex] = res.data.dto
|
||||
rows.value[oldIndex] = handleServerRowData(fieldsDescInfo.value, res.data.dto)
|
||||
handleCloseDialog()
|
||||
}, (err) => {
|
||||
console.log("添加报错:", err)
|
||||
@ -564,29 +594,39 @@ const handlePaginationCurChange = (val) => {
|
||||
<el-table-column prop="jsonValue" :label="fieldDescInfo.name" show-overflow-tooltip
|
||||
v-if="(fieldDescInfo.type === 'items')"></el-table-column>
|
||||
<!-- 角色状态 -->
|
||||
<el-table-column prop="jsonValue" :label="fieldDescInfo.name"
|
||||
v-else-if="(fieldDescInfo.type === 'boolStatus')">
|
||||
<el-table-column prop="tagValue" :label="fieldDescInfo.name"
|
||||
v-else-if="(fieldDescInfo.type === 'tagStatus')">
|
||||
<template #default="scope">
|
||||
<el-tag type="info" v-if="scope.row.Status === '离线'">{{ scope.row.Status }}</el-tag>
|
||||
<el-tag type="success" v-else-if="scope.row.Status === '在线'">{{ scope.row.Status }}</el-tag>
|
||||
<el-tag :type="scope.row.tagColor">{{ scope.row.tagValue }}</el-tag>
|
||||
<!-- <el-tag type="success" v-else-if="scope.row.Status === '在线'">{{ scope.row.Status }}</el-tag>-->
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 其它普通字段 -->
|
||||
<el-table-column :prop="fieldDescInfo.key" :label="fieldDescInfo.name"
|
||||
:show-overflow-tooltip="(fieldDescInfo.key === 'Title' || fieldDescInfo.key === 'Content')"
|
||||
v-else></el-table-column>
|
||||
v-else>
|
||||
<template #header>
|
||||
<el-tooltip effect="light" :content="fieldDescInfo.help_text" placement="top"
|
||||
v-if="fieldDescInfo.help_text !== ''">
|
||||
<span>{{ fieldDescInfo.name }}</span>
|
||||
</el-tooltip>
|
||||
<span v-else>{{ fieldDescInfo.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<el-table-column prop="func" label="功 能">
|
||||
<template #default="scope">
|
||||
|
||||
<el-button size="default" type="success" @click="handleEdit( scope.$index, scope.row)"
|
||||
<el-button :size="funcBtnSize" 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>-->
|
||||
<span>编辑</span>
|
||||
</el-button>
|
||||
<el-button size="default" type="danger" @click="handleDelete( scope.$index, scope.row)"
|
||||
<el-button :size="funcBtnSize" type="danger"
|
||||
@click="handleDelete( scope.$index, scope.row)"
|
||||
v-if="(resource_raw_node.meta.methods.delete === true)">
|
||||
<!-- <el-icon style="vertical-align: middle">-->
|
||||
<!-- <Delete/>-->
|
||||
@ -594,22 +634,22 @@ const handlePaginationCurChange = (val) => {
|
||||
<span>删除</span>
|
||||
</el-button>
|
||||
<template v-for="(btn, index) in rowClickBtns">
|
||||
<template v-if="btn.btn_type === 0">
|
||||
<el-button size="default" :type="btn.btn_color_type"
|
||||
<template v-if="btn.btn_type === 0"> <!--直接发送选择行数据到服务器的按钮类型-->
|
||||
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
|
||||
@click="tableSelectRows2(btn, scope.$index, scope.row)">
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template v-else-if="btn.btn_type === 1">
|
||||
<el-button size="default" :type="btn.btn_color_type"
|
||||
<template v-else-if="btn.btn_type === 1"> <!--带弹窗的按钮类型-->
|
||||
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
|
||||
@click="tableSelectRow3(index, scope.row)">
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template v-else-if="btn.btn_type === 2">
|
||||
<el-button size="default" :type="btn.btn_color_type"
|
||||
<template v-else-if="btn.btn_type === 2"> <!--带点击回调函数的按钮类型-->
|
||||
<el-button :size="funcBtnSize" :type="btn.btn_color_type"
|
||||
@click="tableSelectRow4(btn, scope.row)">
|
||||
{{ btn.name }}
|
||||
</el-button>
|
||||
@ -639,7 +679,8 @@ const handlePaginationCurChange = (val) => {
|
||||
<el-dialog v-model="rowClickBtnVisibleList[index]" :title="btn.name"
|
||||
@close="rowClickBtnVisibleList[index]=false"
|
||||
destroy-on-close>
|
||||
<component :is="btn.btn_callback_component" :rowInfo="rowClickBtnSelectRow"/>
|
||||
<component :is="btn.btn_callback_component" :rowInfo="rowClickBtnSelectRow"
|
||||
:fieldsDescInfo="fieldsDescInfo"/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
|
@ -35,6 +35,78 @@ const selectedItemBag = ref(null)
|
||||
|
||||
// console.log("enter table, resource:", cachedResource)
|
||||
|
||||
|
||||
const handleServerRowData = (fieldsDescInfoData, rowData) => {
|
||||
for (let i = 0; i < fieldsDescInfoData.length; i++) {
|
||||
var field = fieldsDescInfoData[i]
|
||||
// dialogObjectForm.value[field.key] = ''
|
||||
|
||||
if (field.required === true) {
|
||||
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: "blur"}]
|
||||
}
|
||||
|
||||
if (field.type === "items") {
|
||||
dialogObjectForm.value[field.key] = []
|
||||
rowData.jsonValue = JSON.stringify(rowData[field.key])
|
||||
if (field.required === true) {
|
||||
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", "change"],
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
const tagStatusColorArray = ["plain", "primary", "success", "info", "waring", "danger"]
|
||||
if (field.type === "tagStatus") {
|
||||
for (let k = 0; k < field.choices.length; k++) {
|
||||
if (rowData[field.key] === field.choices[k].value) {
|
||||
rowData.tagValue = field.choices[k].desc
|
||||
rowData.tagColor = tagStatusColorArray[field.choices[k].type]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (field.where !== "") {
|
||||
field.value1 = ""
|
||||
field.value2 = ""
|
||||
field.whereDesc = getWhereConditionDesc(field.where)
|
||||
let find = false
|
||||
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
|
||||
let whereField = whereFieldsDescInfo.value[i]
|
||||
if (whereField.key === field.key) {
|
||||
whereFieldsDescInfo.value[i].type = field.type
|
||||
whereFieldsDescInfo.value[i].where = field.where
|
||||
whereFieldsDescInfo.value[i].whereDesc = getWhereConditionDesc(field.where)
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
whereFieldsDescInfo.value.push(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
return rowData
|
||||
}
|
||||
|
||||
const handleServerRowsData = (fieldsDescInfoData, rowsData) => {
|
||||
let newRowsData = []
|
||||
rowsData.forEach((rowData) => {
|
||||
const newRowData = handleServerRowData(fieldsDescInfoData, rowData)
|
||||
// console.log("new data:", newRowData)
|
||||
newRowsData.push(newRowData)
|
||||
})
|
||||
return newRowsData
|
||||
}
|
||||
|
||||
const listData = async () => {
|
||||
try {
|
||||
let listParams = {
|
||||
@ -65,72 +137,9 @@ const listData = async () => {
|
||||
if (listRsp.value.code !== 200) throw new Error("请求失败,错误码:", listRsp.code);
|
||||
fieldsDescInfo.value = listRsp.value.data.fields_desc
|
||||
totalRowCount.value = listRsp.value.data.total_count
|
||||
rows.value = listRsp.value.data.rows
|
||||
rows.value = handleServerRowsData(fieldsDescInfo.value, listRsp.value.data.rows)
|
||||
itemBags.value = listRsp.value.data.item_bags
|
||||
|
||||
for (let i = 0; i < fieldsDescInfo.value.length; i++) {
|
||||
var field = fieldsDescInfo.value[i]
|
||||
dialogObjectForm.value[field.key] = ''
|
||||
|
||||
if (field.required == true) {
|
||||
rules.value[field.key] = [{required: true, message: field.name + "不能为空", trigger: ["blur", "change"]}]
|
||||
}
|
||||
|
||||
if (field.type == "items") {
|
||||
dialogObjectForm.value[field.key] = []
|
||||
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", "change"],
|
||||
}]
|
||||
}
|
||||
|
||||
if (field.where !== "") {
|
||||
field.value1 = ""
|
||||
field.value2 = ""
|
||||
field.whereDesc = getWhereConditionDesc(field.where)
|
||||
let find = false
|
||||
for (let i = 0; i < whereFieldsDescInfo.value.length; i++) {
|
||||
let whereField = whereFieldsDescInfo.value[i]
|
||||
if (whereField.key === field.key) {
|
||||
whereFieldsDescInfo.value[i].type = field.type
|
||||
whereFieldsDescInfo.value[i].where = field.where
|
||||
whereFieldsDescInfo.value[i].whereDesc = getWhereConditionDesc(field.where)
|
||||
find = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!find) {
|
||||
whereFieldsDescInfo.value.push(field)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
calcElColSpan.value = 0
|
||||
// 计算el-col占用24格子的span数量
|
||||
let calcElColSpanTmp = 2
|
||||
whereFieldsDescInfo.value.forEach((field) => {
|
||||
if (field.where === "range") {
|
||||
calcElColSpanTmp += 2
|
||||
} else {
|
||||
calcElColSpanTmp += 1
|
||||
}
|
||||
})
|
||||
calcElColSpan.value = 24 / calcElColSpanTmp
|
||||
|
||||
// console.log("where fields:", whereFieldsDescInfo.value)
|
||||
// console.log('await list rsp:', listRsp.value, fieldsDescInfo.value, toRaw(rows.value), toRaw(rules.value))
|
||||
|
||||
listDataOK.value = true
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
@ -169,7 +178,8 @@ const submitAdd = async () => {
|
||||
duration: 4000,
|
||||
"show-close": true,
|
||||
})
|
||||
rows.value.push(res.data.dto)
|
||||
const newData = handleServerRowData(fieldsDescInfo.value, res.data.dto)
|
||||
rows.value.unshift(newData)
|
||||
dialogAddVisible.value = false
|
||||
handleCloseDialog()
|
||||
}, (err) => {
|
||||
@ -202,7 +212,7 @@ const submitEdit = async () => {
|
||||
"show-close": true,
|
||||
})
|
||||
dialogEditVisible.value = false
|
||||
rows.value[oldIndex] = res.data.dto
|
||||
rows.value[oldIndex] = handleServerRowData(fieldsDescInfo.value, res.data.dto)
|
||||
handleCloseDialog()
|
||||
}, (err) => {
|
||||
console.log("添加报错:", err)
|
||||
|
@ -119,9 +119,9 @@ const userStore = defineStore(
|
||||
component: () => import('@/views/project/project_op.vue'),
|
||||
props: true
|
||||
}
|
||||
if (resource.resource === 'cdkey') {
|
||||
resourceRoute.component = () => import('@/views/project/project_cdkey.vue')
|
||||
}
|
||||
// if (resource.resource === 'cdkey') {
|
||||
// resourceRoute.component = () => import('@/views/project/project_cdkey.vue')
|
||||
// }
|
||||
resource.show_methods.forEach((method) => {
|
||||
if (method == "get") {
|
||||
projectHasAnyResourcePermission = true
|
||||
|
@ -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 cdkeyDetail from "@/components/game/cdkeyDetail.vue";
|
||||
import cdkeyUsedHistory from "@/components/game/cdkeyUsedHistory.vue";
|
||||
import router from '@/router/index.js'
|
||||
import userStore from "@/stores/user.js";
|
||||
import {cdkeyExport} from "@/api/cdkey.js";
|
||||
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
const homeRoutes = userStore().dynamicRouteChildren
|
||||
@ -83,6 +86,57 @@ switch (cachedResource.meta.resource) {
|
||||
}
|
||||
},)
|
||||
break
|
||||
case "cdkey":
|
||||
if (rowClickDialogBtns.length > 0) {
|
||||
break
|
||||
}
|
||||
rowClickDialogBtns.push({
|
||||
key: "cdkey:detail",
|
||||
name: "查看",
|
||||
btn_color_type: "primary",
|
||||
btn_type: 1,
|
||||
btn_callback_component: cdkeyDetail,
|
||||
}, {
|
||||
key: "cdkey:export",
|
||||
name: "导出",
|
||||
btn_color_type: "warning",
|
||||
btn_type: 2,
|
||||
click_handler: (row) => {
|
||||
const cachedResource = LocalCache.getCache("resource");
|
||||
const resource_url = cachedResource.meta.resource_url;
|
||||
cdkeyExport(resource_url, {id: row.ID}).then((res) => {
|
||||
console.log("导出cdkey返回:", res)
|
||||
|
||||
// 从响应头解析文件名
|
||||
const contentDisposition = res.headers['content-disposition'];
|
||||
let filename = 'default_filename.ext'; // 默认文件名
|
||||
|
||||
// 正则提取文件名(处理编码情况)
|
||||
const filenameRegex = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i;
|
||||
const matches = contentDisposition.match(filenameRegex);
|
||||
|
||||
if (matches && matches[1]) {
|
||||
filename = decodeURIComponent(matches[1]); // 解码特殊字符
|
||||
}
|
||||
|
||||
// 创建临时链接触发下载
|
||||
const blob = new Blob([res.data]);
|
||||
const link = document.createElement('a');
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = filename;
|
||||
link.click();
|
||||
|
||||
// 释放内存
|
||||
window.URL.revokeObjectURL(link.href);
|
||||
})
|
||||
},
|
||||
}, {
|
||||
key: "cdkey:used:history",
|
||||
name: "礼包使用",
|
||||
btn_color_type: "default",
|
||||
btn_type: 1,
|
||||
btn_callback_component: cdkeyUsedHistory,
|
||||
},)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user