正在显示
9 个修改的文件
包含
174 行增加
和
9 行删除
| @@ -14,7 +14,7 @@ type CreateMenuCommand struct { | @@ -14,7 +14,7 @@ type CreateMenuCommand struct { | ||
| 14 | // 菜单编码 SYSTEM_USER_EDIT / 100101 (字符编码) | 14 | // 菜单编码 SYSTEM_USER_EDIT / 100101 (字符编码) |
| 15 | Code string `json:"code" valid:"Required"` | 15 | Code string `json:"code" valid:"Required"` |
| 16 | // 权限编码 users:edit | 16 | // 权限编码 users:edit |
| 17 | - AccessCode string `json:"accessCode" valid:"Required"` | 17 | + AccessCode string `json:"accessCode"` |
| 18 | // 菜单类型 (目录catalog、菜单menu、按钮button) | 18 | // 菜单类型 (目录catalog、菜单menu、按钮button) |
| 19 | MenuType string `json:"menuType" valid:"Required"` | 19 | MenuType string `json:"menuType" valid:"Required"` |
| 20 | // 菜单图标 | 20 | // 菜单图标 |
| @@ -24,7 +24,7 @@ type CreateMenuCommand struct { | @@ -24,7 +24,7 @@ type CreateMenuCommand struct { | ||
| 24 | // 菜单说明 | 24 | // 菜单说明 |
| 25 | Desc string `json:"desc,omitempty"` | 25 | Desc string `json:"desc,omitempty"` |
| 26 | // 菜单是否公开状态,[0:隐藏],[1:显示],默认显示 | 26 | // 菜单是否公开状态,[0:隐藏],[1:显示],默认显示 |
| 27 | - IsPublish int `json:"isPublish" valid:"Required"` | 27 | + IsPublish int `json:"isPublish"` |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) { | 30 | func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) { |
| @@ -9,10 +9,12 @@ import ( | @@ -9,10 +9,12 @@ import ( | ||
| 9 | type ListMenuQuery struct { | 9 | type ListMenuQuery struct { |
| 10 | // 菜单类别 web app | 10 | // 菜单类别 web app |
| 11 | MenuCategory string `json:"menuCategory,omitempty"` | 11 | MenuCategory string `json:"menuCategory,omitempty"` |
| 12 | - // 菜单父级id 0:查询所有 n:父级id为n的菜单列表 | ||
| 13 | - MenuParentId int64 `json:"parentId,omitempty"` | 12 | + // 菜单父级id 0:查询所有 n:parent_id为n的菜单列表 |
| 13 | + ParentId int64 `json:"parentId,omitempty"` | ||
| 14 | // 菜单名称过滤 | 14 | // 菜单名称过滤 |
| 15 | MenuName string `json:"menuName,omitempty"` | 15 | MenuName string `json:"menuName,omitempty"` |
| 16 | + // 结构类型 树型:tree 列表型:list | ||
| 17 | + StructType string `json:"structType,omitempty"` | ||
| 16 | // 查询偏离量 | 18 | // 查询偏离量 |
| 17 | Offset int `json:"offset"` | 19 | Offset int `json:"offset"` |
| 18 | // 查询限制 | 20 | // 查询限制 |
| @@ -8,6 +8,7 @@ import ( | @@ -8,6 +8,7 @@ import ( | ||
| 8 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/application/menu/command" | 8 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/application/menu/command" |
| 9 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/application/menu/query" | 9 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/application/menu/query" |
| 10 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/domain" | 10 | "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/domain" |
| 11 | + "gitlab.fjmaimaimai.com/mmm-go-pp/terms/pkg/infrastructure/common" | ||
| 11 | "strconv" | 12 | "strconv" |
| 12 | ) | 13 | ) |
| 13 | 14 | ||
| @@ -49,14 +50,24 @@ func (menuService *MenuService) CreateMenu(createMenuCommand *command.CreateMenu | @@ -49,14 +50,24 @@ func (menuService *MenuService) CreateMenu(createMenuCommand *command.CreateMenu | ||
| 49 | } else { | 50 | } else { |
| 50 | menuRepository = value | 51 | menuRepository = value |
| 51 | } | 52 | } |
| 53 | + // 1.菜单类型验证 | ||
| 54 | + if newMenu.ValidMenuType() { | ||
| 55 | + return nil, application.ThrowError(application.ARG_ERROR, domain.ErrorMenuType.Error()) | ||
| 56 | + } | ||
| 57 | + // 2.菜单编码验证 | ||
| 58 | + if menu, err := menuRepository.FindOne(map[string]interface{}{"code": createMenuCommand.Code}); err == nil && menu != nil { | ||
| 59 | + return nil, application.ThrowError(application.ARG_ERROR, fmt.Sprintf("菜单编码:%v已重复,请重新输入", createMenuCommand.Code)) | ||
| 60 | + } | ||
| 61 | + // 3.更新菜单路径 | ||
| 52 | if newMenu.ParentId > 0 { | 62 | if newMenu.ParentId > 0 { |
| 53 | if pMenu, err := menuRepository.FindOne(map[string]interface{}{"menuId": newMenu.ParentId}); err != nil { | 63 | if pMenu, err := menuRepository.FindOne(map[string]interface{}{"menuId": newMenu.ParentId}); err != nil { |
| 54 | - return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 64 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "父级菜单不存在") |
| 55 | } else { | 65 | } else { |
| 56 | newMenu.ParentPath = pMenu.GetParentPath() | 66 | newMenu.ParentPath = pMenu.GetParentPath() |
| 57 | newMenu.Category = pMenu.GetCategory() | 67 | newMenu.Category = pMenu.GetCategory() |
| 58 | } | 68 | } |
| 59 | } | 69 | } |
| 70 | + // 4.保存菜单项 | ||
| 60 | if menu, err := menuRepository.Save(newMenu); err != nil { | 71 | if menu, err := menuRepository.Save(newMenu); err != nil { |
| 61 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 72 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 62 | } else { | 73 | } else { |
| @@ -127,7 +138,7 @@ func (menuService *MenuService) ListMenu(listMenuQuery *query.ListMenuQuery) (in | @@ -127,7 +138,7 @@ func (menuService *MenuService) ListMenu(listMenuQuery *query.ListMenuQuery) (in | ||
| 127 | } else { | 138 | } else { |
| 128 | menuRepository = value | 139 | menuRepository = value |
| 129 | } | 140 | } |
| 130 | - queryOptions := tool_funs.SimpleStructToMap(listMenuQuery) | 141 | + queryOptions := common.SimpleStructToMap(listMenuQuery) |
| 131 | if len(listMenuQuery.MenuCategory) > 0 { | 142 | if len(listMenuQuery.MenuCategory) > 0 { |
| 132 | queryOptions["code"] = "" | 143 | queryOptions["code"] = "" |
| 133 | if m, e := menuRepository.FindOne(map[string]interface{}{"code": listMenuQuery.MenuCategory}); e == nil && m != nil { | 144 | if m, e := menuRepository.FindOne(map[string]interface{}{"code": listMenuQuery.MenuCategory}); e == nil && m != nil { |
| @@ -140,6 +151,18 @@ func (menuService *MenuService) ListMenu(listMenuQuery *query.ListMenuQuery) (in | @@ -140,6 +151,18 @@ func (menuService *MenuService) ListMenu(listMenuQuery *query.ListMenuQuery) (in | ||
| 140 | if err := transactionContext.CommitTransaction(); err != nil { | 151 | if err := transactionContext.CommitTransaction(); err != nil { |
| 141 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) | 152 | return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) |
| 142 | } | 153 | } |
| 154 | + // 树形返回 | ||
| 155 | + if listMenuQuery.StructType == domain.StructTree { | ||
| 156 | + var treeNodes = make([]domain.TreeNode, len(menus)) | ||
| 157 | + for i := 0; i < len(menus); i++ { | ||
| 158 | + treeNodes[i] = menus[i] | ||
| 159 | + } | ||
| 160 | + return map[string]interface{}{ | ||
| 161 | + "count": count, | ||
| 162 | + "menus": domain.NewTrees(treeNodes).Nodes, | ||
| 163 | + }, nil | ||
| 164 | + } | ||
| 165 | + // 列表返回 | ||
| 143 | return map[string]interface{}{ | 166 | return map[string]interface{}{ |
| 144 | "count": count, | 167 | "count": count, |
| 145 | "menus": menus, | 168 | "menus": menus, |
| @@ -170,6 +193,7 @@ func (menuService *MenuService) RemoveMenu(removeMenuCommand *command.RemoveMenu | @@ -170,6 +193,7 @@ func (menuService *MenuService) RemoveMenu(removeMenuCommand *command.RemoveMenu | ||
| 170 | } else { | 193 | } else { |
| 171 | menuRepository = value | 194 | menuRepository = value |
| 172 | } | 195 | } |
| 196 | + // 1.节点是否存在 | ||
| 173 | menu, err := menuRepository.FindOne(map[string]interface{}{"menuId": removeMenuCommand.MenuId}) | 197 | menu, err := menuRepository.FindOne(map[string]interface{}{"menuId": removeMenuCommand.MenuId}) |
| 174 | if err != nil { | 198 | if err != nil { |
| 175 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 199 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| @@ -177,6 +201,10 @@ func (menuService *MenuService) RemoveMenu(removeMenuCommand *command.RemoveMenu | @@ -177,6 +201,10 @@ func (menuService *MenuService) RemoveMenu(removeMenuCommand *command.RemoveMenu | ||
| 177 | if menu == nil { | 201 | if menu == nil { |
| 178 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeMenuCommand.MenuId))) | 202 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(removeMenuCommand.MenuId))) |
| 179 | } | 203 | } |
| 204 | + // 2. 是否存在子节点 | ||
| 205 | + if m, err := menuRepository.FindOne(map[string]interface{}{"parentId": menu.MenuId}); err == nil && m != nil { | ||
| 206 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "下级菜单不为空") | ||
| 207 | + } | ||
| 180 | if menu, err := menuRepository.Remove(menu); err != nil { | 208 | if menu, err := menuRepository.Remove(menu); err != nil { |
| 181 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | 209 | return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) |
| 182 | } else { | 210 | } else { |
| @@ -217,7 +245,13 @@ func (menuService *MenuService) UpdateMenu(updateMenuCommand *command.UpdateMenu | @@ -217,7 +245,13 @@ func (menuService *MenuService) UpdateMenu(updateMenuCommand *command.UpdateMenu | ||
| 217 | if menu == nil { | 245 | if menu == nil { |
| 218 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateMenuCommand.MenuId))) | 246 | return nil, application.ThrowError(application.RES_NO_FIND_ERROR, fmt.Sprintf("%s", string(updateMenuCommand.MenuId))) |
| 219 | } | 247 | } |
| 220 | - // 父级节点有发生更新 | 248 | + // 1.验证code是否有重复的情况 |
| 249 | + if menu.Code != updateMenuCommand.Code { | ||
| 250 | + if m, e := menuRepository.FindOne(map[string]interface{}{"code": updateMenuCommand.Code}); e == nil && m.MenuId != menu.MenuId { | ||
| 251 | + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error()) | ||
| 252 | + } | ||
| 253 | + } | ||
| 254 | + // 2.验证父级节点是否有发生更新 | ||
| 221 | if updateMenuCommand.ParentId != menu.ParentId && (updateMenuCommand.ParentId != 0 && menu.ParentId != 0) { | 255 | if updateMenuCommand.ParentId != menu.ParentId && (updateMenuCommand.ParentId != 0 && menu.ParentId != 0) { |
| 222 | var oldParentFullPath, newParentFullPath = menu.GetFullPath(), menu.GetFullPath() | 256 | var oldParentFullPath, newParentFullPath = menu.GetFullPath(), menu.GetFullPath() |
| 223 | var oldParentPath = menu.ParentPath | 257 | var oldParentPath = menu.ParentPath |
| @@ -5,6 +5,7 @@ import "os" | @@ -5,6 +5,7 @@ import "os" | ||
| 5 | const SERVICE_NAME = "terms.base" | 5 | const SERVICE_NAME = "terms.base" |
| 6 | 6 | ||
| 7 | var LOG_LEVEL = "debug" | 7 | var LOG_LEVEL = "debug" |
| 8 | +var EnableCaching = false | ||
| 8 | 9 | ||
| 9 | func init() { | 10 | func init() { |
| 10 | if os.Getenv("LOG_LEVEL") != "" { | 11 | if os.Getenv("LOG_LEVEL") != "" { |
| 1 | package domain | 1 | package domain |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | + "errors" | ||
| 4 | "fmt" | 5 | "fmt" |
| 5 | "strconv" | 6 | "strconv" |
| 6 | "strings" | 7 | "strings" |
| 7 | ) | 8 | ) |
| 8 | 9 | ||
| 9 | -var PathSegment = "," | 10 | +const PathSegment = "," |
| 11 | + | ||
| 12 | +var ( | ||
| 13 | + Catalog MenuType = "catalog" // 目录 | ||
| 14 | + Menu_ MenuType = "menu" // 菜单 | ||
| 15 | + Button MenuType = "button" // 按钮 | ||
| 16 | +) | ||
| 17 | + | ||
| 18 | +var ( | ||
| 19 | + ErrorMenuType = errors.New(fmt.Sprintf("菜单类型有误 可选值 %v、%v、%v", Catalog, Menu_, Button)) | ||
| 20 | +) | ||
| 21 | + | ||
| 22 | +// 菜单类型 | ||
| 23 | +type MenuType string | ||
| 10 | 24 | ||
| 11 | // 系统菜单 | 25 | // 系统菜单 |
| 12 | type Menu struct { | 26 | type Menu struct { |
| @@ -128,3 +142,19 @@ func (menu *Menu) UpdateParentPath(old, new string) { | @@ -128,3 +142,19 @@ func (menu *Menu) UpdateParentPath(old, new string) { | ||
| 128 | } | 142 | } |
| 129 | menu.ParentPath = strings.Replace(menu.ParentPath, old, new, 1) | 143 | menu.ParentPath = strings.Replace(menu.ParentPath, old, new, 1) |
| 130 | } | 144 | } |
| 145 | + | ||
| 146 | +func (menu *Menu) ValidMenuType() bool { | ||
| 147 | + mt := MenuType(menu.MenuType) | ||
| 148 | + if mt == Catalog || mt == Menu_ || mt == Button { | ||
| 149 | + return true | ||
| 150 | + } | ||
| 151 | + return false | ||
| 152 | +} | ||
| 153 | + | ||
| 154 | +// 实现 TreeNode | ||
| 155 | +func (menu *Menu) PID() string { | ||
| 156 | + return menu.ParentPath | ||
| 157 | +} | ||
| 158 | +func (menu *Menu) ID() string { | ||
| 159 | + return menu.GetFullPath() | ||
| 160 | +} |
pkg/domain/tree.go
0 → 100644
| 1 | +package domain | ||
| 2 | + | ||
| 3 | +const ( | ||
| 4 | + StructTree = "tree" | ||
| 5 | + StructList = "list" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +type TreeNode interface { | ||
| 9 | + PID() string | ||
| 10 | + ID() string | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +type Tree struct { | ||
| 14 | + Node TreeNode `json:"node"` | ||
| 15 | + Nodes []*Tree `json:"nodes"` | ||
| 16 | +} | ||
| 17 | + | ||
| 18 | +func traverse(tree *Tree, node TreeNode) bool { | ||
| 19 | + list := tree.Nodes | ||
| 20 | + var match bool = false | ||
| 21 | + for i := range list { | ||
| 22 | + id, pid := list[i].Node.ID(), node.PID() //list[i].Node.PID() == node.ID() | ||
| 23 | + if pid == id { | ||
| 24 | + list[i].Nodes = append(list[i].Nodes, NewTree(node)) | ||
| 25 | + return true | ||
| 26 | + } | ||
| 27 | + if match || traverse(list[i], node) { | ||
| 28 | + match = true | ||
| 29 | + break | ||
| 30 | + } | ||
| 31 | + } | ||
| 32 | + return match | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +func NewTrees(nodes []TreeNode) *Tree { | ||
| 36 | + var tree = &Tree{ | ||
| 37 | + Node: nil, | ||
| 38 | + Nodes: make([]*Tree, 0), | ||
| 39 | + } | ||
| 40 | + for i := range nodes { | ||
| 41 | + match := traverse(tree, nodes[i]) | ||
| 42 | + if !match { | ||
| 43 | + tree.Nodes = append(tree.Nodes, NewTree(nodes[i])) | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + return tree | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +func NewTree(node TreeNode) *Tree { | ||
| 50 | + return &Tree{ | ||
| 51 | + Node: node, | ||
| 52 | + Nodes: make([]*Tree, 0), | ||
| 53 | + } | ||
| 54 | +} |
pkg/infrastructure/common/common.go
0 → 100644
| 1 | +package common | ||
| 2 | + | ||
| 3 | +import ( | ||
| 4 | + "github.com/linmadan/egglib-go/utils/string_convert" | ||
| 5 | + "reflect" | ||
| 6 | +) | ||
| 7 | + | ||
| 8 | +func SimpleStructToMap(toMapStruct interface{}) map[string]interface{} { | ||
| 9 | + m := ObjectToMap(toMapStruct) | ||
| 10 | + if pageNumber, ok := m["pageNumber"]; ok { | ||
| 11 | + var pageSize int64 | ||
| 12 | + if _, ok := m["pageSize"]; ok { | ||
| 13 | + pageSize = m["pageSize"].(int64) | ||
| 14 | + } else { | ||
| 15 | + pageSize = 20 | ||
| 16 | + } | ||
| 17 | + m["offset"] = (pageNumber.(int64) - 1) * pageSize | ||
| 18 | + m["limit"] = pageSize | ||
| 19 | + } | ||
| 20 | + return m | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +func ObjectToMap(o interface{}) map[string]interface{} { | ||
| 24 | + if o == nil { | ||
| 25 | + return nil | ||
| 26 | + } | ||
| 27 | + value := reflect.ValueOf(o) | ||
| 28 | + if value.Kind() != reflect.Ptr { | ||
| 29 | + return nil | ||
| 30 | + } | ||
| 31 | + elem := value.Elem() | ||
| 32 | + relType := elem.Type() | ||
| 33 | + m := make(map[string]interface{}) | ||
| 34 | + for i := 0; i < relType.NumField(); i++ { | ||
| 35 | + field := relType.Field(i) | ||
| 36 | + if elem.Field(i).IsZero() { | ||
| 37 | + continue | ||
| 38 | + } | ||
| 39 | + m[string_convert.CamelCase(field.Name, false, false)] = elem.Field(i).Interface() | ||
| 40 | + } | ||
| 41 | + return m | ||
| 42 | +} |
| @@ -163,6 +163,7 @@ func (repository *MenuRepository) Find(queryOptions map[string]interface{}) (int | @@ -163,6 +163,7 @@ func (repository *MenuRepository) Find(queryOptions map[string]interface{}) (int | ||
| 163 | if v, ok := queryOptions["menuName"]; ok { | 163 | if v, ok := queryOptions["menuName"]; ok { |
| 164 | query.Where(fmt.Sprintf("menu_name like '%%%v%%'", v)) | 164 | query.Where(fmt.Sprintf("menu_name like '%%%v%%'", v)) |
| 165 | } | 165 | } |
| 166 | + query.SetWhereByQueryOption("parent_id = ?", "parentId") | ||
| 166 | query.SetOffsetAndLimit(20) | 167 | query.SetOffsetAndLimit(20) |
| 167 | query.SetOrderDirect("menu_id", "asc") | 168 | query.SetOrderDirect("menu_id", "asc") |
| 168 | if count, err := query.SelectAndCount(); err != nil { | 169 | if count, err := query.SelectAndCount(); err != nil { |
| @@ -56,8 +56,9 @@ func (controller *MenuController) ListMenu() { | @@ -56,8 +56,9 @@ func (controller *MenuController) ListMenu() { | ||
| 56 | limit, _ := controller.GetInt("limit") | 56 | limit, _ := controller.GetInt("limit") |
| 57 | listMenuQuery.Limit = limit | 57 | listMenuQuery.Limit = limit |
| 58 | listMenuQuery.MenuCategory = controller.GetString("menuCategory") | 58 | listMenuQuery.MenuCategory = controller.GetString("menuCategory") |
| 59 | - listMenuQuery.MenuParentId, _ = controller.GetInt64("parentId", 0) | 59 | + listMenuQuery.ParentId, _ = controller.GetInt64("parentId", 0) |
| 60 | listMenuQuery.MenuName = controller.GetString("menuName") | 60 | listMenuQuery.MenuName = controller.GetString("menuName") |
| 61 | + listMenuQuery.StructType = controller.GetString("structType") | ||
| 61 | data, err := menuService.ListMenu(listMenuQuery) | 62 | data, err := menuService.ListMenu(listMenuQuery) |
| 62 | controller.Response(data, err) | 63 | controller.Response(data, err) |
| 63 | } | 64 | } |
-
请 注册 或 登录 后发表评论