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