diff --git a/admin/apps/game/domain/comm_resource.go b/admin/apps/game/domain/comm_resource.go
index 3a333e6..2c430a5 100644
--- a/admin/apps/game/domain/comm_resource.go
+++ b/admin/apps/game/domain/comm_resource.go
@@ -39,7 +39,7 @@ func NewCommonResourceService(db *gorm.DB) *CommonResourceService {
return svc
}
-func (svc *CommonResourceService) List(projectId int, resource string, pageNo, pageLen int, extraQuery string, args ...any) ([]*dto.CommonDtoFieldDesc, []dto.CommonDtoValues, error) {
+func (svc *CommonResourceService) List(projectId int, resource string, listParams *dto.CommonListReq) ([]*dto.CommonDtoFieldDesc, []dto.CommonDtoValues, error) {
_, projectEt, find, err := svc.projectRepo.GetById(projectId)
if err != nil {
return nil, nil, err
@@ -48,7 +48,8 @@ func (svc *CommonResourceService) List(projectId int, resource string, pageNo, p
return nil, nil, errcode.New(errcode.ServerError, "not found project %v db data", projectId)
}
- fieldsDescInfo, etList, err := findCommResourceRepo(resource).List(projectEt, pageNo, pageLen, extraQuery, args...)
+ fieldsDescInfo, etList, err := findCommResourceRepo(resource).List(projectEt,
+ listParams.PageNo, listParams.PageLen, listParams.ParsedWhereConditions.Conditions)
if err != nil {
return nil, nil, err
}
@@ -59,7 +60,7 @@ func (svc *CommonResourceService) List(projectId int, resource string, pageNo, p
// 执行各个项目特定的钩子方法
if hook, ok := projects.GetProjectResourceHook(projectEt, resource).(projects.IPostResourceOpListHook); ok {
- return hook.List(projectEt, resource, pageNo, pageLen, fieldsDescInfo, retList, extraQuery, args...)
+ return hook.List(projectEt, resource, listParams.PageNo, listParams.PageLen, fieldsDescInfo, retList, "")
}
return fieldsDescInfo, retList, nil
diff --git a/admin/apps/game/domain/entity/utils.go b/admin/apps/game/domain/entity/utils.go
index 004f5c0..ea3e3e0 100644
--- a/admin/apps/game/domain/entity/utils.go
+++ b/admin/apps/game/domain/entity/utils.go
@@ -52,6 +52,7 @@ func getFieldTypeDtoDescInfo(project *Project, poValue reflect.Value, fieldType
Choices: make([]*dto.CommonDtoFieldChoice, 0),
MultiChoice: fieldType.Tag.Get("multi_choice") == "true",
Uneditable: fieldType.Tag.Get("uneditable") == "true",
+ Where: fieldType.Tag.Get("where"),
}
if f1.Key == "CreatedAt" {
diff --git a/admin/apps/game/domain/project.go b/admin/apps/game/domain/project.go
index d5e2e8f..7132f07 100644
--- a/admin/apps/game/domain/project.go
+++ b/admin/apps/game/domain/project.go
@@ -2,8 +2,10 @@ package domain
import (
"admin/apps/game/domain/entity"
+ "admin/apps/game/domain/projects"
"admin/apps/game/domain/repo"
"admin/apps/game/model/dto"
+ "admin/internal/errcode"
"gorm.io/gorm"
)
@@ -68,3 +70,20 @@ func (svc *ProjectService) GetProjectInvokeApiAddr(projectId int, serverIds []in
}
return []string{et.Po.ApiAddr}, nil
}
+
+func (svc *ProjectService) GetAllItems(projectId int) ([]*dto.CommonDtoFieldChoice, error) {
+ _, projectEt, find, err := svc.repo.GetById(projectId)
+ if err != nil {
+ return nil, err
+ }
+ if !find {
+ return nil, errcode.New(errcode.ServerError, "not found project %v db data", projectId)
+ }
+
+ handler := projects.GetProjectValueChoicesGetHook(projectEt.Po.ProjectType)
+ if handler == nil {
+ return nil, errcode.New(errcode.ServerError, "not found project %v items handler", projectEt.Po.ProjectType)
+ }
+
+ return handler.GetItems(projectEt)
+}
diff --git a/admin/apps/game/domain/projects/projects.go b/admin/apps/game/domain/projects/projects.go
index 1749158..adc22c5 100644
--- a/admin/apps/game/domain/projects/projects.go
+++ b/admin/apps/game/domain/projects/projects.go
@@ -25,6 +25,7 @@ var projectsValueChoicesGetHook = map[string]IGetAllValueChoicesHook{
}
func GetProjectResourceHook(project *entity.Project, resource string) any {
+ return nil
projectResourceHooks, find := projectsResourceHookMgr[project.Po.ProjectType]
if !find {
return nil
diff --git a/admin/apps/game/domain/projects/smdl/items.go b/admin/apps/game/domain/projects/smdl/items.go
index 51b3b66..a8e4cdb 100644
--- a/admin/apps/game/domain/projects/smdl/items.go
+++ b/admin/apps/game/domain/projects/smdl/items.go
@@ -11,6 +11,12 @@ type Items struct {
}
func (items *Items) GetItems(projectInfo *entity.Project) ([]*dto.CommonDtoFieldChoice, error) {
+ return []*dto.CommonDtoFieldChoice{
+ {Desc: "黄金战甲", Value: 123, Type: 1},
+ {Desc: "黄金头盔", Value: 234, Type: 1},
+ {Desc: "黄金大刀", Value: 346, Type: 1},
+ {Desc: "白银大刀", Value: 346, Type: 1},
+ }, nil
alisrvAddr := projectInfo.GetApiAddr()
if alisrvAddr == "" {
return nil, errcode.New(errcode.ServerError, "项目%v没有配置api服务器地址", projectInfo.Po.Name)
diff --git a/admin/apps/game/domain/repo/comm_resource.go b/admin/apps/game/domain/repo/comm_resource.go
index 3ddb3b3..c0c80ac 100644
--- a/admin/apps/game/domain/repo/comm_resource.go
+++ b/admin/apps/game/domain/repo/comm_resource.go
@@ -5,13 +5,18 @@ import (
"admin/apps/game/model"
"admin/apps/game/model/dto"
"admin/internal/errcode"
+ "admin/lib/xlog"
"errors"
+ "fmt"
"gorm.io/gorm"
+ "gorm.io/gorm/schema"
"reflect"
+ "strings"
+ "time"
)
type ICommonResourceRepo interface {
- List(project *entity.Project, pageNo, pageLen int, extraQuery string, args ...any) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error)
+ List(project *entity.Project, pageNo, pageLen int, whereConditions []*dto.GetWhereCondition) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error)
GetById(projectEt *entity.Project, id int) ([]*dto.CommonDtoFieldDesc, *entity.CommonResource, bool, error)
Create(projectEt *entity.Project, et dto.CommonDtoValues) (*entity.CommonResource, error)
Edit(projectEt *entity.Project, et dto.CommonDtoValues) error
@@ -34,15 +39,28 @@ func newCommonResourceRepoImpl(db *gorm.DB, poTemplate model.IModel) *commonReso
}
func (repo *commonResourceRepoImpl) List(projectEt *entity.Project, pageNo, pageLen int,
- extraQuery string, args ...any) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error) {
+ whereConditions []*dto.GetWhereCondition) ([]*dto.CommonDtoFieldDesc, []*entity.CommonResource, error) {
+
+ if pageNo < 0 || pageLen <= 0 {
+ return nil, nil, errcode.New(errcode.ParamsInvalid, "page no or page len invalid:%v,%v", pageNo, pageLen)
+ }
+
+ limitStart := pageNo * pageLen
+ limitLen := pageLen
listType := reflect.New(reflect.SliceOf(reflect.TypeOf(repo.poTemplate)))
+
+ var tx *gorm.DB
var err error
- if extraQuery == "" {
- err = repo.db.Find(listType.Interface()).Error
+ if len(whereConditions) <= 0 {
+ tx = repo.db.Offset(limitStart).Limit(limitLen)
} else {
- err = repo.db.Where(extraQuery, args...).Find(listType.Interface()).Error
+ whereSql, whereArgs := repo.parseWhereConditions2Sql(whereConditions)
+ xlog.Debugf("list resource %v where sql:%v, args:%+v",
+ repo.poTemplate.TableName(), whereSql, whereArgs)
+ tx = repo.db.Where(whereSql, whereArgs...).Offset(limitStart).Limit(limitLen)
}
+ err = tx.Find(listType.Interface()).Error
if err != nil {
return nil, nil, errcode.New(errcode.DBError, "list resource %v error:%v", repo.poTemplate.TableName(), err)
}
@@ -110,3 +128,52 @@ func (repo *commonResourceRepoImpl) Delete(projectEt *entity.Project, id int) (*
func (repo *commonResourceRepoImpl) newEmptyPo() model.IModel {
return reflect.New(reflect.TypeOf(repo.poTemplate).Elem()).Interface().(model.IModel)
}
+
+func (repo *commonResourceRepoImpl) parseWhereConditions2Sql(conditions []*dto.GetWhereCondition) (whereSql string, args []any) {
+ namer := new(schema.NamingStrategy)
+ to := reflect.TypeOf(repo.poTemplate).Elem()
+ whereClause := make([]string, 0, len(conditions))
+ whereArgs := make([]interface{}, 0, len(conditions))
+ for _, cond := range conditions {
+ for i := 0; i < to.NumField(); i++ {
+ field := to.Field(i)
+ if field.Name != cond.Key {
+ continue
+ }
+ dbFieldName := namer.ColumnName("", field.Name)
+ if field.Type.Name() == "Time" {
+ cond.Value1, _ = time.ParseInLocation("2006/01/02 15:04:05", cond.Value1.(string), time.Local)
+ cond.Value2, _ = time.ParseInLocation("2006/01/02 15:04:05", cond.Value2.(string), time.Local)
+ }
+ switch field.Tag.Get("where") {
+ case "eq":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` = ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "gt":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` > ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "lt":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` < ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "le":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` <= ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "ge":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` >= ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "like":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` like ?", dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1)
+ case "range":
+ whereClause = append(whereClause, fmt.Sprintf("`%v` >= ? and `%v` <= ?", dbFieldName, dbFieldName))
+ whereArgs = append(whereArgs, cond.Value1, cond.Value2)
+ case "":
+ default:
+ panic(fmt.Errorf("unsupport where tag %v", field.Tag))
+ }
+
+ }
+ }
+ whereSql = strings.Join(whereClause, " AND ")
+ return whereSql, whereArgs
+}
diff --git a/admin/apps/game/model/account.go b/admin/apps/game/model/account.go
index 9aab85a..b34312e 100644
--- a/admin/apps/game/model/account.go
+++ b/admin/apps/game/model/account.go
@@ -12,8 +12,8 @@ func init() {
// Account 空表,就是用来兼容资源增删改查公共操作的,实际列举账号等都是走各个项目api拉取
type Account struct {
ProjectId int
- Account string `name:"账号" json:"account"`
- ServerConfId string `name:"区服id" json:"serveId"`
+ Account string `name:"账号" json:"account" where:"eq"`
+ ServerConfId string `name:"区服id" json:"serveId" where:"eq"`
RoleIds []string `gorm:"type:json;serializer:json" name:"角色id列表" json:"roleIds"`
LatestLoginTime time.Time `name:"最近登录时间" json:"latest_login_time"`
CreateTime time.Time `name:"创建时间" json:"create_time"`
diff --git a/admin/apps/game/model/dto/common.go b/admin/apps/game/model/dto/common.go
index 4b68a30..088f177 100644
--- a/admin/apps/game/model/dto/common.go
+++ b/admin/apps/game/model/dto/common.go
@@ -25,6 +25,7 @@ type CommonDtoFieldDesc struct {
Choices []*CommonDtoFieldChoice `json:"choices"` // 可选项,用于字段做下拉框
MultiChoice bool `json:"multi_choice"` // 是否多选
Uneditable bool `json:"uneditable"` // 不可编辑,某些数据一旦新增之后不能修改,例如封禁的值、服务器的id等
+ Where string `json:"where"` // sql list的where条件,用于表格页面查询条件编写,值:eq gt lt ge lt range like
}
//type CommonDtoValue struct {
@@ -43,3 +44,10 @@ type PathInfo struct {
Path string `json:"path"`
Method string `json:"method"`
}
+
+type GetWhereCondition struct {
+ Key string `json:"key"`
+ Op string `json:"op"` // eq,gt,lt,range
+ Value1 any `json:"value1"`
+ Value2 any `json:"value2"`
+}
diff --git a/admin/apps/game/model/dto/msg.go b/admin/apps/game/model/dto/msg.go
index 8868fdf..dd8bc54 100644
--- a/admin/apps/game/model/dto/msg.go
+++ b/admin/apps/game/model/dto/msg.go
@@ -5,12 +5,16 @@ type NilReq struct {
type NilRsp = NilReq
+type ListWhereConditionInfo struct {
+ Conditions []*GetWhereCondition `json:"conditions"`
+}
+
type CommonListReq struct {
- PageNo int `json:"page_no"`
- PageLen int `json:"page_len"`
- WhereValue1 string `json:"where_value1"`
- WhereValue2 string `json:"where_value2"`
- WhereValue3 string `json:"where_value3"`
+ PageNo int `json:"page_no"`
+ PageLen int `json:"page_len"`
+ //WhereConditions []*GetWhereCondition `json:"where_conditions"`
+ WhereConditions string `json:"where_conditions"` // json序列化数据,内容是{"conditions": []*GetWhereCondition}
+ ParsedWhereConditions *ListWhereConditionInfo `json:"-"`
}
type CommonPostReq struct {
@@ -46,3 +50,7 @@ type CommandListReq struct {
type CommandListRsp struct {
List []*PathInfo `json:"list"`
}
+
+type GetProjectAllItemsRsp struct {
+ Items []*CommonDtoFieldChoice `json:"items"`
+}
diff --git a/admin/apps/game/model/globalmail.go b/admin/apps/game/model/globalmail.go
index 50e92da..cdc05d2 100644
--- a/admin/apps/game/model/globalmail.go
+++ b/admin/apps/game/model/globalmail.go
@@ -10,17 +10,15 @@ func init() {
db.RegisterTableModels(GlobalMail{})
}
-var ProjectsAllItems = make(map[string][]*dto.CommonDtoFieldChoice)
-
type GlobalMail struct {
ID int `gorm:"primarykey" readonly:"true"`
ProjectId int
ServerIDs []string `gorm:"type:json;serializer:json" name:"区服" type:"[]string" choices:"GetChoiceServers" multi_choice:"true"`
Title string `name:"邮件标题" required:"true"`
Content string `name:"邮件内容" required:"true"`
- Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" choices:"GetChoiceItems"`
+ Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" desc:"搜索道具并点击添加"`
- CreatedAt time.Time `readonly:"true"`
+ CreatedAt time.Time `readonly:"true" where:"range"`
}
func (lm *GlobalMail) TableName() string {
@@ -34,7 +32,3 @@ func (m *GlobalMail) GetId() int {
func (m *GlobalMail) GetChoiceServers(project *Project) []*dto.CommonDtoFieldChoice {
return getChoiceServers(project)
}
-
-func (m *GlobalMail) GetChoiceItems(project *Project) []*dto.CommonDtoFieldChoice {
- return ProjectsAllItems[project.ProjectType]
-}
diff --git a/admin/apps/game/model/role.go b/admin/apps/game/model/role.go
index a303ea1..156c54c 100644
--- a/admin/apps/game/model/role.go
+++ b/admin/apps/game/model/role.go
@@ -12,10 +12,10 @@ func init() {
// Role 空表,就是用来兼容资源增删改查公共操作的,实际列举账号等都是走各个项目api拉取
type Role struct {
ProjectId int
- RoleId string `name:"角色ID" json:"roleId"`
- Account string `name:"账号" json:"account"`
- ServerConfId string `name:"区服id" json:"serverId"`
- Name string `name:"名称" json:"roleName"`
+ RoleId string `name:"角色ID" json:"roleId" where:"eq"`
+ Account string `name:"账号" json:"account" where:"eq"`
+ ServerConfId string `name:"区服id" json:"serverId" where:"eq"`
+ Name string `name:"名称" json:"roleName" where:"eq"`
Status string `name:"状态" desc:"离线|在线" json:"status"`
Level int `name:"等级" json:"roleLevel"`
Profession string `name:"职业" json:"profession"`
diff --git a/admin/apps/game/model/rolemail.go b/admin/apps/game/model/rolemail.go
index c890145..3a6ae88 100644
--- a/admin/apps/game/model/rolemail.go
+++ b/admin/apps/game/model/rolemail.go
@@ -20,12 +20,12 @@ type RoleMail struct {
ID int `gorm:"primarykey" readonly:"true"`
ProjectId int
RoleIDs []string `gorm:"type:json;serializer:json" name:"生效的角色id" desc:"生效的角色id,逗号分隔多个" required:"true"`
- ServerID string `name:"所属区服" choices:"GetChoiceServers" required:"true"`
+ ServerID string `name:"所属区服" choices:"GetChoiceServers" required:"true" where:"eq"`
Title string `name:"邮件标题" required:"true"`
Content string `name:"邮件内容" required:"true"`
- Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" choices:"GetChoiceItems"`
+ Attach []*MailAttachItem `gorm:"type:json;serializer:json" name:"邮件附件" type:"items" desc:"搜索道具并点击添加"`
- CreatedAt time.Time `readonly:"true"`
+ CreatedAt time.Time `readonly:"true" where:"range"`
}
func (lm *RoleMail) TableName() string {
@@ -39,7 +39,3 @@ func (m *RoleMail) GetId() int {
func (m *RoleMail) GetChoiceServers(project *Project) []*dto.CommonDtoFieldChoice {
return getChoiceServers(project)
}
-
-func (m *RoleMail) GetChoiceItems(project *Project) []*dto.CommonDtoFieldChoice {
- return ProjectsAllItems[project.ProjectType]
-}
diff --git a/admin/apps/game/model/whitelist.go b/admin/apps/game/model/whitelist.go
index d60c851..27d8fd9 100644
--- a/admin/apps/game/model/whitelist.go
+++ b/admin/apps/game/model/whitelist.go
@@ -13,11 +13,11 @@ func init() {
type WhiteList struct {
ID int `gorm:"primarykey" readonly:"true"`
ProjectId int `gorm:"uniqueIndex:idx_whitelist"`
- ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_server" name:"区服id" required:"true" choices:"GetChoiceServers"`
+ ServerConfID string `gorm:"type:varchar(200);uniqueIndex:idx_server" name:"区服id" required:"true" choices:"GetChoiceServers" where:"eq"`
Account string `gorm:"type:varchar(128);uniqueIndex:idx_whitelist" name:"账户" required:"true"`
Desc string `name:"描述"`
- CreatedAt time.Time `readonly:"true"`
+ CreatedAt time.Time `readonly:"true" where:"range"`
}
func (lm *WhiteList) TableName() string {
diff --git a/admin/apps/game/server/ctl_common_rest.go b/admin/apps/game/server/ctl_common_rest.go
index 3ba4b8e..f3185a4 100644
--- a/admin/apps/game/server/ctl_common_rest.go
+++ b/admin/apps/game/server/ctl_common_rest.go
@@ -3,6 +3,7 @@ package server
import (
"admin/apps/game/model/dto"
"admin/internal/context"
+ stdContext "context"
)
func (ctl *controller) CommonList(ctx *context.WebContext, params *dto.CommonListReq, rsp *dto.CommonListRsp) error {
@@ -17,7 +18,11 @@ func (ctl *controller) CommonList(ctx *context.WebContext, params *dto.CommonLis
func (ctl *controller) CommonPost(ctx *context.WebContext, params *dto.CommonPostReq, rsp *dto.CommonPostRsp) error {
projectId, resource := getCtxURIProjectIdAndResource(ctx)
- newObj, err := ctl.svc.CommonPost(ctx, projectId, resource, *params.Dto)
+
+ ctx1 := stdContext.WithValue(ctx.Context, "user_id", ctx.Header.UserId)
+ ctx1 = stdContext.WithValue(ctx1, "user_name", ctx.Header.UserId)
+
+ newObj, err := ctl.svc.CommonPost(ctx1, projectId, resource, *params.Dto)
if err != nil {
return err
}
@@ -47,3 +52,13 @@ func (ctl *controller) CommonDelete(ctx *context.WebContext, params *dto.CommonD
func (ctl *controller) OnClickCustomButton(ctx *context.WebContext, params *dto.CommonDeleteReq, rsp *dto.CommonDeleteRsp) error {
return nil
}
+
+func (ctl *controller) GetProjectAllItems(ctx *context.WebContext, params *dto.NilReq, rsp *dto.GetProjectAllItemsRsp) error {
+ projectId := getCtxURIProjectId(ctx)
+ items, err := ctl.svc.GetAllItems(projectId)
+ if err != nil {
+ return err
+ }
+ rsp.Items = items
+ return nil
+}
diff --git a/admin/apps/game/server/middleware.go b/admin/apps/game/server/middleware.go
index 1e06e27..7a14c6c 100644
--- a/admin/apps/game/server/middleware.go
+++ b/admin/apps/game/server/middleware.go
@@ -23,6 +23,8 @@ func (srv *Server) CheckToken(ctx *context.WebContext) {
return
}
+ ctx.Header.UserName = authRsp.User.NickName
+
ctx.GinCtx().Set("userInfo", authRsp)
return
}
diff --git a/admin/apps/game/server/route.go b/admin/apps/game/server/route.go
index b379aae..3096018 100644
--- a/admin/apps/game/server/route.go
+++ b/admin/apps/game/server/route.go
@@ -6,6 +6,8 @@ import (
)
func (srv *Server) Route(engine *web.Engine) {
+ engine.Use(srv.CheckToken)
+
apiGroup := engine.Group("/api", "")
{
@@ -24,5 +26,7 @@ func (srv *Server) Route(engine *web.Engine) {
resourceUnderProjectGroup.Put("", "编辑", consts.WebPathPermit_Read, srv.ctl.CommonPut)
resourceUnderProjectGroup.Delete("", "删除", consts.WebPathPermit_Read, srv.ctl.CommonDelete)
}
+
+ projectGroup.Get("/:projectId/items", "获取项目所有道具列表", consts.WebPathPermit_Read, srv.ctl.GetProjectAllItems)
}
}
diff --git a/admin/apps/game/service/service.go b/admin/apps/game/service/service.go
index 4a42237..39f60e4 100644
--- a/admin/apps/game/service/service.go
+++ b/admin/apps/game/service/service.go
@@ -5,7 +5,10 @@ import (
"admin/apps/game/domain"
"admin/apps/game/model/dto"
"admin/internal/consts"
+ "admin/internal/errcode"
+ "admin/internal/event"
"context"
+ "encoding/json"
"gorm.io/gorm"
)
@@ -30,17 +33,26 @@ func New(db *gorm.DB) (*Service, error) {
}
func (svc *Service) CommonList(ctx context.Context, projectId int, resourceName string, params *dto.CommonListReq) (*dto.CommonDtoList, error) {
- var (
- query string
- args []any
- )
+
+ params.ParsedWhereConditions = &dto.ListWhereConditionInfo{}
+ if params.WhereConditions != "" {
+ err := json.Unmarshal([]byte(params.WhereConditions), params.ParsedWhereConditions)
+ if err != nil {
+ return nil, errcode.New(errcode.ParamsInvalid, "unmarshal list condition:%v error:%v",
+ params.WhereConditions, err)
+ }
+ }
+
switch resourceName {
case consts.ResourcesName_Project:
default:
- query = "project_id = ?"
- args = append(args, projectId)
+ params.ParsedWhereConditions.Conditions = append([]*dto.GetWhereCondition{&dto.GetWhereCondition{
+ Key: "ProjectId",
+ Op: "eq",
+ Value1: projectId,
+ }}, params.ParsedWhereConditions.Conditions...)
}
- fieldsDescInfo, rows, err := svc.resourceSvc.List(projectId, resourceName, params.PageNo, params.PageLen, query, args)
+ fieldsDescInfo, rows, err := svc.resourceSvc.List(projectId, resourceName, params)
return &dto.CommonDtoList{FieldsDesc: fieldsDescInfo, Rows: rows}, err
}
@@ -48,18 +60,61 @@ func (svc *Service) CommonPost(ctx context.Context, projectId int, resourceName
if resourceName != consts.ResourcesName_Project {
params["ProjectId"] = projectId
}
- return svc.resourceSvc.Create(projectId, resourceName, params)
+
+ values, err := svc.resourceSvc.Create(projectId, resourceName, params)
+
+ userId := ctx.Value("user_id").(int)
+ userName := ctx.Value("user_name").(string)
+
+ event.GetMgrInstance().Publish(event.EventTopic_UserExecute, &event.EventPayload_UserExecute{
+ UserId: userId,
+ UserName: userName,
+ ProjectId: projectId,
+ Resource: resourceName,
+ Method: "新增",
+ NewData: params,
+ })
+
+ return values, err
}
func (svc *Service) CommonPut(ctx context.Context, projectId int, resourceName string, params dto.CommonDtoValues) error {
if resourceName != consts.ResourcesName_Project {
params["ProjectId"] = projectId
}
- return svc.resourceSvc.Edit(projectId, resourceName, params)
+ err := svc.resourceSvc.Edit(projectId, resourceName, params)
+
+ userId := ctx.Value("user_id").(int)
+ userName := ctx.Value("user_name").(string)
+
+ event.GetMgrInstance().Publish(event.EventTopic_UserExecute, &event.EventPayload_UserExecute{
+ UserId: userId,
+ UserName: userName,
+ ProjectId: projectId,
+ Resource: resourceName,
+ Method: "编辑",
+ NewData: params,
+ })
+
+ return err
}
func (svc *Service) CommonDelete(ctx context.Context, projectId int, resourceName string, id int) error {
- return svc.resourceSvc.Delete(projectId, resourceName, id)
+ err := svc.resourceSvc.Delete(projectId, resourceName, id)
+
+ userId := ctx.Value("user_id").(int)
+ userName := ctx.Value("user_name").(string)
+
+ event.GetMgrInstance().Publish(event.EventTopic_UserExecute, &event.EventPayload_UserExecute{
+ UserId: userId,
+ UserName: userName,
+ ProjectId: projectId,
+ Resource: resourceName,
+ Method: "删除",
+ NewData: id,
+ })
+
+ return err
}
func (svc *Service) GetSupportResourcesList(permissions []string) []*api.ResourceInitInfo {
diff --git a/admin/apps/game/service/service_project.go b/admin/apps/game/service/service_project.go
index a4cfa85..c1ff756 100644
--- a/admin/apps/game/service/service_project.go
+++ b/admin/apps/game/service/service_project.go
@@ -3,6 +3,7 @@ package service
import (
"admin/apps/game/api"
"admin/apps/game/domain/entity"
+ "admin/apps/game/model/dto"
"admin/internal/consts"
"admin/internal/permission"
)
@@ -66,3 +67,7 @@ func (svc *Service) GetProjectList() ([]*entity.Project, error) {
func (svc *Service) GetProjectInvokeApiAddr(projectId int, serverIds []int) ([]string, error) {
return svc.projectSvc.GetProjectInvokeApiAddr(projectId, serverIds)
}
+
+func (svc *Service) GetAllItems(projectId int) ([]*dto.CommonDtoFieldChoice, error) {
+ return svc.projectSvc.GetAllItems(projectId)
+}
diff --git a/admin/apps/user/api/api_user.go b/admin/apps/user/api/api_user.go
index fc16cf9..46b1556 100644
--- a/admin/apps/user/api/api_user.go
+++ b/admin/apps/user/api/api_user.go
@@ -24,6 +24,7 @@ type AuthReq struct {
type UserInfo struct {
UserId int `json:"user_id"`
+ UserName string `json:"user_name"`
NickName string `json:"nick_name"`
Icon string `json:"icon"`
Character string `json:"character"`
diff --git a/admin/apps/user/domain/repo/user.go b/admin/apps/user/domain/repo/user.go
index f3b0c8a..3f3bfa5 100644
--- a/admin/apps/user/domain/repo/user.go
+++ b/admin/apps/user/domain/repo/user.go
@@ -38,14 +38,22 @@ func (impl *userRepoImpl) CreateAdminUsers() error {
}
if err := impl.db.Create(adminCharacter).Error; err != nil {
- if !strings.Contains(err.Error(), "Duplicate entry") {
+ if strings.Contains(err.Error(), "Duplicate entry") {
+
+ } else if strings.Contains(err.Error(), "UNIQUE constraint") {
+
+ } else {
return errcode.New(errcode.DBError, "create admin character fail:%v", err)
}
}
if err := impl.db.Create(adminList).Error; err != nil {
- if !strings.Contains(err.Error(), "Duplicate entry") {
- return errcode.New(errcode.DBError, "create admin fail:%v", err)
+ if strings.Contains(err.Error(), "Duplicate entry") {
+
+ } else if strings.Contains(err.Error(), "UNIQUE constraint") {
+
+ } else {
+ return errcode.New(errcode.DBError, "create admin character fail:%v", err)
}
}
diff --git a/admin/apps/user/model/history.go b/admin/apps/user/model/history.go
new file mode 100644
index 0000000..6436e4a
--- /dev/null
+++ b/admin/apps/user/model/history.go
@@ -0,0 +1,35 @@
+package model
+
+import (
+ "admin/internal/db"
+ "admin/internal/global"
+ "time"
+)
+
+func init() {
+ db.RegisterTableModels(History{})
+}
+
+// History 用户执行历史
+type History struct {
+ ID int `gorm:"primarykey" readonly:"true"`
+ UserId int
+ UserName string
+ ProjectId int
+ Resource string
+ Method string
+ Data string `gorm:"type:longtext"`
+ CreateTime time.Time
+}
+
+func (m *History) TableName() string {
+ return "history"
+}
+
+func (m *History) GetId() int {
+ return m.ID
+}
+
+func (m *History) Create() error {
+ return global.GLOB_DB.Create(m).Error
+}
diff --git a/admin/apps/user/server/server.go b/admin/apps/user/server/server.go
index 5280a6f..2adad5c 100644
--- a/admin/apps/user/server/server.go
+++ b/admin/apps/user/server/server.go
@@ -1,6 +1,12 @@
package server
-import "admin/apps/user/service"
+import (
+ "admin/apps/user/model"
+ "admin/apps/user/service"
+ "admin/internal/event"
+ "admin/lib/xlog"
+ "encoding/json"
+)
type Server struct {
svc *service.Service
@@ -13,3 +19,28 @@ func New(svc *service.Service) *Server {
ctl: newController(svc),
}
}
+
+func (srv *Server) jobsSubscribe() {
+ event.GetMgrInstance().Subscribe("user", event.EventTopic_UserExecute, srv.subscriberHandlerUserExecute)
+}
+
+func (srv *Server) subscriberHandlerUserExecute(msg *event.Msg) {
+ po := new(model.History)
+ msgHistory := &event.EventPayload_UserExecute{}
+ err := json.Unmarshal(msg.Payload, msgHistory)
+ if err != nil {
+ xlog.Errorf("unmarshal msg(%+v) err:%v", string(msg.Payload), err)
+ }
+
+ po.UserId = msgHistory.UserId
+ po.UserName = msgHistory.UserName
+ po.ProjectId = msgHistory.ProjectId
+ po.Resource = msgHistory.Resource
+ po.Method = msgHistory.Method
+ po.Data = string(msg.Payload)
+
+ err = po.Create()
+ if err != nil {
+ xlog.Errorf("create user execute(%+v) err:%v", string(msg.Payload), err)
+ }
+}
diff --git a/admin/apps/user/service/service_user.go b/admin/apps/user/service/service_user.go
index 80bfd80..2b194b9 100644
--- a/admin/apps/user/service/service_user.go
+++ b/admin/apps/user/service/service_user.go
@@ -40,6 +40,7 @@ func (svc *Service) Auth(ctx context.Context, req *apiUser.AuthReq) (*apiUser.Au
}
rsp.User = &apiUser.UserInfo{
UserId: info.User.UserId,
+ UserName: info.User.NickName,
NickName: info.User.NickName,
Icon: info.User.Icon,
Character: info.User.Character,
diff --git a/admin/cmd/all_in_one/all_in_one.exe b/admin/cmd/all_in_one/all_in_one.exe
new file mode 100644
index 0000000..43b8d35
Binary files /dev/null and b/admin/cmd/all_in_one/all_in_one.exe differ
diff --git a/admin/go.mod b/admin/go.mod
index cd296ee..d37e64b 100644
--- a/admin/go.mod
+++ b/admin/go.mod
@@ -9,6 +9,7 @@ require (
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/prometheus/client_golang v1.22.0
github.com/rs/zerolog v1.34.0
+ golang.org/x/crypto v0.37.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.7
gorm.io/driver/sqlite v1.5.7
@@ -46,7 +47,6 @@ require (
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
golang.org/x/arch v0.16.0 // indirect
- golang.org/x/crypto v0.37.0 // indirect
golang.org/x/net v0.38.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/text v0.24.0 // indirect
diff --git a/admin/internal/config/flags.go b/admin/internal/config/flags.go
index a8b5796..387d39a 100644
--- a/admin/internal/config/flags.go
+++ b/admin/internal/config/flags.go
@@ -2,7 +2,7 @@ package config
type CommonBootFlags struct {
ApiPort string `env:"api_port" default:"8080" desc:"api端口,客户端请求的地址端口"`
- DBType string `env:"db_type" default:"sqlite3" desc:"数据库类型,默认sqlite,可选:sqlite|mysql|pg"`
+ DBType string `env:"db_type" default:"sqlite" desc:"数据库类型,默认sqlite,可选:sqlite|mysql|pg"`
DBAddr string `env:"db_addr" default:"localhost" desc:"数据库地址"`
DBName string `env:"db_name" default:"uniugm" desc:"数据库名字"`
DBUser string `env:"db_user" default:"root" desc:"数据库用户名"`
diff --git a/admin/internal/context/ctx_web.go b/admin/internal/context/ctx_web.go
index 6970e54..8bf413f 100644
--- a/admin/internal/context/ctx_web.go
+++ b/admin/internal/context/ctx_web.go
@@ -9,9 +9,10 @@ import (
)
type WebHeader struct {
- UserId int `json:"UserId"` // 用户id,会与下面token解析出用户id做匹配校验
- Token string `json:"Token"` // jwt token,内置一些信息
- Ip string `json:"IP"`
+ UserId int `json:"UserId"` // 用户id,会与下面token解析出用户id做匹配校验
+ Token string `json:"Token"` // jwt token,内置一些信息
+ Ip string `json:"IP"`
+ UserName string `json:"-"`
}
type WebContext struct {
diff --git a/admin/internal/db/db.go b/admin/internal/db/db.go
index 2c6e94f..0597be7 100644
--- a/admin/internal/db/db.go
+++ b/admin/internal/db/db.go
@@ -9,6 +9,7 @@ import (
"gorm.io/driver/mysql"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
+ "strings"
"sync"
"time"
)
@@ -25,39 +26,54 @@ func RegisterTableModels(models ...any) {
}
func NewDB(dbType, dbAddr, dbName, dbUser, dbPass string) (db *gorm.DB, err error) {
- switch dbType {
- case "sqlite":
- db, err = gorm.Open(sqlite.Open(dbName+".db"), &gorm.Config{})
- if err != nil {
- return nil, err
- }
- case "mysql":
- dsn := fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPass, dbAddr, dbName)
- dsnWithoutDB := fmt.Sprintf("%v:%v@tcp(%v)/?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPass, dbAddr)
- db, err = createDBAndGuaranteeMigrate(dsnWithoutDB, dsn, globalTables)
+ dsn := fmt.Sprintf("%v:%v@tcp(%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPass, dbAddr, dbName)
+ dsnWithoutDB := fmt.Sprintf("%v:%v@tcp(%v)/?charset=utf8mb4&parseTime=True&loc=Local", dbUser, dbPass, dbAddr)
+ db, err = createDBAndGuaranteeMigrate(dbType, dsnWithoutDB, dsn, globalTables)
+ if err != nil {
+ return nil, err
}
global.GLOB_DB = db
return db, nil
}
-func createDBAndGuaranteeMigrate(dsnWithoutDb, dsn string, tables []any) (*gorm.DB, error) {
+func createDBAndGuaranteeMigrate(dbType string, dsnWithoutDb, dsn string, tables []any) (*gorm.DB, error) {
mysqlDriverConf, err := mysqlDriver.ParseDSN(dsn)
if err != nil {
return nil, fmt.Errorf("parse dsn:%v error:%v", dsn, err)
}
dbName := mysqlDriverConf.DBName
- _, err = tryCreateDB(dbName, dsnWithoutDb)
+
+ var dialector gorm.Dialector
+ switch dbType {
+ case "sqlite":
+ dialector = sqlite.Open(dbName)
+ case "mysql":
+ dialector = mysql.Open(dsnWithoutDb)
+ default:
+ panic(fmt.Errorf("unsupported db type: %v", dbType))
+ }
+
+ _, err = tryCreateDB(dbType, dialector, dbName)
if err != nil {
xlog.Fatalf(err)
return nil, err
}
- driverConf := mysql.Config{
- DSN: dsn,
- DontSupportRenameColumn: true,
- //SkipInitializeWithVersion: false, // 根据数据库版本自动配置
+ switch dbType {
+ case "sqlite":
+ dialector = sqlite.Open(dbName)
+ case "mysql":
+ dialector = mysql.Open(dsn)
+ default:
+ panic(fmt.Errorf("unsupported db type: %v", dbType))
}
- dialector := mysql.New(driverConf)
+
+ //driverConf := mysql.Config{
+ // DSN: dsn,
+ // DontSupportRenameColumn: true,
+ // //SkipInitializeWithVersion: false, // 根据数据库版本自动配置
+ //}
+ //dialector = mysql.New(driverConf)
//slowLogger := logger.New(
// syslog.New(xlog.GetGlobalWriter(), "\n", syslog.LstdFlags),
@@ -97,13 +113,7 @@ func createDBAndGuaranteeMigrate(dsnWithoutDb, dsn string, tables []any) (*gorm.
return db, nil
}
-func tryCreateDB(dbName, dsn string) (string, error) {
- driverConf := mysql.Config{
- DSN: dsn,
- DontSupportRenameColumn: true,
- //SkipInitializeWithVersion: false, // 根据数据库版本自动配置
- }
- dialector := mysql.New(driverConf)
+func tryCreateDB(dbType string, dialector gorm.Dialector, dbName string) (string, error) {
db, err := gorm.Open(dialector, &gorm.Config{
PrepareStmt: false, // 关闭缓存sql语句功能,因为后续use db会报错,这个缓存会无限存储可能导致内存泄露
@@ -114,14 +124,16 @@ func tryCreateDB(dbName, dsn string) (string, error) {
}
// 检查数据库是否存在
- var count int
- db.Raw("SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?", dbName).Scan(&count)
- if count == 0 {
- // 数据库不存在,创建它
- sql := fmt.Sprintf("create database if not exists `%s` default charset utf8mb4 collate utf8mb4_unicode_ci",
- dbName)
- if e := db.Exec(sql).Error; e != nil {
- return "", fmt.Errorf("failed to create database:%v", e)
+ if dbType != "sqlite" {
+ var count int
+ db.Raw("SELECT COUNT(*) FROM information_schema.schemata WHERE schema_name = ?", dbName).Scan(&count)
+ if count == 0 {
+ // 数据库不存在,创建它
+ sql := fmt.Sprintf("create database if not exists `%s` default charset utf8mb4 collate utf8mb4_unicode_ci",
+ dbName)
+ if e := db.Exec(sql).Error; e != nil {
+ return "", fmt.Errorf("failed to create database:%v", e)
+ }
}
}
@@ -135,8 +147,17 @@ func autoMigrate(db *gorm.DB, tables ...interface{}) error {
// 这个函数是在InitConn之后调用的
// 初始化表
- if err := db.AutoMigrate(tables...); err != nil {
- return errcode.New(errcode.DBError, "failed to init tables:%v", err)
+ for _, table := range tables {
+ if err := db.AutoMigrate(table); err != nil {
+ if strings.Contains(err.Error(), "there is already a table named") {
+ continue
+ }
+ if strings.Contains(err.Error(), "already exists") {
+ continue
+ }
+ return errcode.New(errcode.DBError, "failed to init tables:%v", err)
+ }
}
+
return nil
}
diff --git a/admin/internal/errcode/code.go b/admin/internal/errcode/code.go
index 1101ac9..ad91540 100644
--- a/admin/internal/errcode/code.go
+++ b/admin/internal/errcode/code.go
@@ -9,4 +9,5 @@ const (
TokenInvalid = 5
UserOrPassInValid = 7 // 用户名或密码错误
NoPermission = 8 // 没有权限
+ ParamsInvalid = 9
)
diff --git a/admin/internal/event/event.go b/admin/internal/event/event.go
new file mode 100644
index 0000000..a51390d
--- /dev/null
+++ b/admin/internal/event/event.go
@@ -0,0 +1,15 @@
+package event
+
+import "admin/lib/eventmgr"
+
+type Msg = eventmgr.Msg
+
+var manager *eventmgr.Mgr
+
+func init() {
+ manager = eventmgr.NewMgr()
+}
+
+func GetMgrInstance() *eventmgr.Mgr {
+ return manager
+}
diff --git a/admin/internal/event/topic.go b/admin/internal/event/topic.go
new file mode 100644
index 0000000..9b7f16c
--- /dev/null
+++ b/admin/internal/event/topic.go
@@ -0,0 +1,15 @@
+package event
+
+const (
+ EventTopic_UserExecute = "user.execute"
+)
+
+type EventPayload_UserExecute struct {
+ UserId int `json:"user_id"`
+ UserName string `json:"user_name"`
+ ProjectId int `json:"project_id"`
+ Resource string `json:"resource"`
+ Method string `json:"method"`
+ OldData any `json:"old_data"`
+ NewData any `json:"new_data"`
+}
diff --git a/admin/lib/eventmgr/event.go b/admin/lib/eventmgr/event.go
new file mode 100644
index 0000000..938ae11
--- /dev/null
+++ b/admin/lib/eventmgr/event.go
@@ -0,0 +1,66 @@
+package eventmgr
+
+import (
+ "admin/lib/xlog"
+ "encoding/json"
+ "runtime"
+)
+
+type Msg struct {
+ Event string
+ Payload []byte
+}
+
+type subscriber struct {
+ name string
+ topic string
+ handler func(*Msg)
+}
+
+type Mgr struct {
+ subscribers []*subscriber
+ broker chan *Msg
+}
+
+func NewMgr() *Mgr {
+ mgr := &Mgr{
+ subscribers: make([]*subscriber, 0),
+ broker: make(chan *Msg, 1024),
+ }
+ mgr.start()
+ return mgr
+}
+
+func (m *Mgr) start() {
+ for i := 0; i < runtime.NumCPU(); i++ {
+ go func() {
+ for {
+ select {
+ case msg := <-m.broker:
+ for _, sub := range m.subscribers {
+ if sub.topic == msg.Event {
+ sub.handler(msg)
+ }
+ }
+ }
+ }
+ }()
+ }
+}
+
+func (m *Mgr) Subscribe(name string, topic string, handler func(*Msg)) {
+ m.subscribers = append(m.subscribers, &subscriber{name: name, topic: topic, handler: handler})
+}
+
+func (m *Mgr) Publish(event string, payload any) {
+ payloadBin, err := json.Marshal(payload)
+ if err != nil {
+ panic(err)
+ }
+ msg := &Msg{Event: event, Payload: payloadBin}
+ select {
+ case m.broker <- msg:
+ default:
+ xlog.Errorf("publish event:%v broker is full", event)
+ }
+}
diff --git a/admin/uniugm b/admin/uniugm
new file mode 100644
index 0000000..1ac481a
Binary files /dev/null and b/admin/uniugm differ
diff --git a/ui/.env.development b/ui/.env.development
index ff54252..1683d70 100644
--- a/ui/.env.development
+++ b/ui/.env.development
@@ -1,2 +1,2 @@
VITE_APP_BASE_API = '/api'
-VITE_APP_BASE_URL = 'http://192.168.78.128:8080/api'
\ No newline at end of file
+VITE_APP_BASE_URL = 'http://localhost:8080/api'
\ No newline at end of file
diff --git a/ui/README.md b/ui/README.md
index 82d7ccd..1a66c21 100644
--- a/ui/README.md
+++ b/ui/README.md
@@ -1,29 +1,5 @@
# ui
-This template should help get you started developing with Vue 3 in Vite.
-
-## Recommended IDE Setup
-
-[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur).
-
-## Customize configuration
-
-See [Vite Configuration Reference](https://vite.dev/config/).
-
-## Project Setup
-
-```sh
-npm install
-```
-
-### Compile and Hot-Reload for Development
-
-```sh
+npm install --registry=https://registry.npmmirror.com
npm run dev
-```
-
-### Compile and Minify for Production
-
-```sh
npm run build
-```
diff --git a/ui/src/api/resource.js b/ui/src/api/resource.js
index 295e85c..4df3332 100644
--- a/ui/src/api/resource.js
+++ b/ui/src/api/resource.js
@@ -38,4 +38,11 @@ export function resourceDelete(url, params) {
method: 'delete',
data: params
})
+}
+
+export function resourceGetAllItems(projectId) {
+ return request({
+ url: '/project/' + projectId.toString() + "/items",
+ method: 'get',
+ })
}
\ No newline at end of file
diff --git a/ui/src/components/restful/table.vue b/ui/src/components/restful/table.vue
index c96c6fe..7804e0d 100644
--- a/ui/src/components/restful/table.vue
+++ b/ui/src/components/restful/table.vue
@@ -1,20 +1,24 @@
@@ -217,10 +289,45 @@ const handleCloseDialog = () => {
-
- 添加
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 条件搜索
+
+
+
+
+
+ 添加
+
+
@@ -273,9 +380,11 @@ const handleCloseDialog = () => {
-
-
+
@@ -354,9 +463,9 @@ const handleCloseDialog = () => {
label-width="130px">
-
-
+
diff --git a/ui/src/router/index.js b/ui/src/router/index.js
index 21ff5b3..401078c 100644
--- a/ui/src/router/index.js
+++ b/ui/src/router/index.js
@@ -115,6 +115,7 @@ export function setProjectOperationRoutes(projectList) {
name: projectRoute.name + "_" + resource.resource,
meta: {
desc: resource.desc,
+ projectId: project.project_id,
resource: resource.resource,
resource_url: routePath,
methods: {},
diff --git a/ui/src/utils/string.js b/ui/src/utils/string.js
new file mode 100644
index 0000000..b634bed
--- /dev/null
+++ b/ui/src/utils/string.js
@@ -0,0 +1,19 @@
+
+export function getWhereConditionDesc(where) {
+ switch (where) {
+ case 'eq':
+ return "等于"
+ case 'gt':
+ return "大于"
+ case 'lt':
+ return "小于"
+ case 'ge':
+ return "大于等于"
+ case 'le':
+ return "小于等于"
+ case 'like':
+ return "包含"
+ case 'range':
+ return ""
+ }
+}
\ No newline at end of file
diff --git a/ui/src/views/Home.vue b/ui/src/views/Home.vue
index 8135126..ec66dcd 100644
--- a/ui/src/views/Home.vue
+++ b/ui/src/views/Home.vue
@@ -236,12 +236,12 @@ h1 {
:deep(.el-menu-vertical-demo .el-menu-item) {
color: #fff;
- background-color: cadetblue;
+ background-color: #4d4f52;
}
:deep(.el-menu-vertical-demo .el-sub-menu) {
color: #fff;
- background-color: cadetblue;
+ background-color: #4d4f52;
}
:deep(.el-menu-vertical-demo .el-sub-menu__title) {
@@ -255,7 +255,7 @@ h1 {
:deep(.el-menu-vertical-demo .el-menu-item.is-active),
:deep(.el-menu-vertical-demo .el-sub-menu__title.is-active) {
- background-color: #ffd04b;
+ background-color: #e91f63;
color: #545c64;
}
diff --git a/ui/todo.md b/ui/todo.md
new file mode 100644
index 0000000..ab21a52
--- /dev/null
+++ b/ui/todo.md
@@ -0,0 +1,7 @@
+# todo列表
+- [x] 道具列表选择支持远程搜索(避免道具列表太长卡顿)
+- [ ] 表格各种项目支持分页(难点是账户、角色、订单如何分)
+- [ ] 表格字段排序
+- [ ] 表格字段搜索
+- [ ] 表格定制化按钮,比如服务器列表支持单个服务器维护、一键维护(难点是带页面跳转的比如角色列表快速封禁)
+- [ ] 执行历史记录
\ No newline at end of file