作者 yangfu

菜单批量 启用、禁用/删除

  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type BatchDeleteMenuCommand struct {
  12 + // 菜单ID列表
  13 + MenuIds []int64 `cname:"菜单ID列表" json:"menuIds,omitempty"`
  14 +}
  15 +
  16 +func (batchDeleteMenuCommand *BatchDeleteMenuCommand) Valid(validation *validation.Validation) {
  17 + //validation.SetError("CustomValid", "未实现的自定义认证")
  18 +}
  19 +
  20 +func (batchDeleteMenuCommand *BatchDeleteMenuCommand) ValidateCommand() error {
  21 + valid := validation.Validation{}
  22 + b, err := valid.Valid(batchDeleteMenuCommand)
  23 + if err != nil {
  24 + return err
  25 + }
  26 + if !b {
  27 + elem := reflect.TypeOf(batchDeleteMenuCommand).Elem()
  28 + for _, validErr := range valid.Errors {
  29 + field, isExist := elem.FieldByName(validErr.Field)
  30 + if isExist {
  31 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  32 + } else {
  33 + return fmt.Errorf(validErr.Message)
  34 + }
  35 + }
  36 + }
  37 + return nil
  38 +}
  1 +package command
  2 +
  3 +import (
  4 + "fmt"
  5 + "reflect"
  6 + "strings"
  7 +
  8 + "github.com/beego/beego/v2/core/validation"
  9 +)
  10 +
  11 +type BatchEnableMenuCommand struct {
  12 + // 菜单ID列表
  13 + MenuIds []int64 `cname:"菜单ID列表" json:"menuIds,omitempty"`
  14 + // 菜单状态
  15 + Status int `cname:"菜单状态" json:"status,omitempty"`
  16 +}
  17 +
  18 +func (batchEnableMenuCommand *BatchEnableMenuCommand) Valid(validation *validation.Validation) {
  19 + //validation.SetError("CustomValid", "未实现的自定义认证")
  20 +}
  21 +
  22 +func (batchEnableMenuCommand *BatchEnableMenuCommand) ValidateCommand() error {
  23 + valid := validation.Validation{}
  24 + b, err := valid.Valid(batchEnableMenuCommand)
  25 + if err != nil {
  26 + return err
  27 + }
  28 + if !b {
  29 + elem := reflect.TypeOf(batchEnableMenuCommand).Elem()
  30 + for _, validErr := range valid.Errors {
  31 + field, isExist := elem.FieldByName(validErr.Field)
  32 + if isExist {
  33 + return fmt.Errorf(strings.Replace(validErr.Message, validErr.Field, field.Tag.Get("cname"), -1))
  34 + } else {
  35 + return fmt.Errorf(validErr.Message)
  36 + }
  37 + }
  38 + }
  39 + return nil
  40 +}
@@ -26,7 +26,7 @@ type CreateMenuCommand struct { @@ -26,7 +26,7 @@ type CreateMenuCommand struct {
26 // 菜单是否公开状态,[0:隐藏],[1:显示],默认显示 26 // 菜单是否公开状态,[0:隐藏],[1:显示],默认显示
27 IsPublish int `json:"isPublish" valid:"Required"` 27 IsPublish int `json:"isPublish" valid:"Required"`
28 // 启用状态(启用:1 禁用:2),默认启用 28 // 启用状态(启用:1 禁用:2),默认启用
29 - EnableStatus int `json:"enableStatus" valid:"Required"` 29 + EnableStatus int `json:"enableStatus" `
30 } 30 }
31 31
32 func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) { 32 func (createMenuCommand *CreateMenuCommand) Valid(validation *validation.Validation) {
@@ -41,7 +41,7 @@ func (menuService *MenuService) CreateMenu(createMenuCommand *command.CreateMenu @@ -41,7 +41,7 @@ func (menuService *MenuService) CreateMenu(createMenuCommand *command.CreateMenu
41 Sort: createMenuCommand.Sort, 41 Sort: createMenuCommand.Sort,
42 Remark: createMenuCommand.Desc, 42 Remark: createMenuCommand.Desc,
43 IsPublish: createMenuCommand.IsPublish, 43 IsPublish: createMenuCommand.IsPublish,
44 - EnableStatus: createMenuCommand.EnableStatus, 44 + EnableStatus: domain.MenuStatusDisable,
45 } 45 }
46 var menuRepository domain.MenuRepository 46 var menuRepository domain.MenuRepository
47 if value, err := factory.CreateMenuRepository(map[string]interface{}{ 47 if value, err := factory.CreateMenuRepository(map[string]interface{}{
@@ -292,6 +292,81 @@ func (menuService *MenuService) UpdateMenu(updateMenuCommand *command.UpdateMenu @@ -292,6 +292,81 @@ func (menuService *MenuService) UpdateMenu(updateMenuCommand *command.UpdateMenu
292 } 292 }
293 } 293 }
294 294
  295 +// 批量删除菜单
  296 +func (menuService *MenuService) BatchDeleteMenu(batchDeleteMenu *command.BatchDeleteMenuCommand) (interface{}, error) {
  297 + if err := batchDeleteMenu.ValidateCommand(); err != nil {
  298 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  299 + }
  300 + transactionContext, err := factory.CreateTransactionContext(nil)
  301 + if err != nil {
  302 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  303 + }
  304 + if err := transactionContext.StartTransaction(); err != nil {
  305 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  306 + }
  307 + defer func() {
  308 + transactionContext.RollbackTransaction()
  309 + }()
  310 + menuRepository, _, err := factory.FastPgMenu(transactionContext, 0)
  311 + if err != nil {
  312 + return nil, err
  313 + }
  314 +
  315 + for i := 0; i < len(batchDeleteMenu.MenuIds); i++ {
  316 + if menu, err := menuRepository.FindOne(map[string]interface{}{"menuId": batchDeleteMenu.MenuIds[i]}); err != nil {
  317 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  318 + } else {
  319 + if _, err := menuRepository.Remove(menu); err != nil {
  320 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  321 + }
  322 + }
  323 + }
  324 +
  325 + if err := transactionContext.CommitTransaction(); err != nil {
  326 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  327 + }
  328 + return struct{}{}, nil
  329 +}
  330 +
  331 +// 批量删除菜单
  332 +func (menuService *MenuService) BatchEnableMenu(batchEnableMenu *command.BatchEnableMenuCommand) (interface{}, error) {
  333 + if err := batchEnableMenu.ValidateCommand(); err != nil {
  334 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  335 + }
  336 + transactionContext, err := factory.CreateTransactionContext(nil)
  337 + if err != nil {
  338 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  339 + }
  340 + if err := transactionContext.StartTransaction(); err != nil {
  341 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  342 + }
  343 + defer func() {
  344 + transactionContext.RollbackTransaction()
  345 + }()
  346 +
  347 + menuRepository, _, err := factory.FastPgMenu(transactionContext, 0)
  348 + if err != nil {
  349 + return nil, err
  350 + }
  351 + for i := 0; i < len(batchEnableMenu.MenuIds); i++ {
  352 + if menu, err := menuRepository.FindOne(map[string]interface{}{"menuId": batchEnableMenu.MenuIds[i]}); err != nil {
  353 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  354 + } else {
  355 + if err := menu.SetPublic(batchEnableMenu.Status); err != nil {
  356 + return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
  357 + }
  358 + if _, err := menuRepository.Save(menu); err != nil {
  359 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
  360 + }
  361 + }
  362 + }
  363 +
  364 + if err := transactionContext.CommitTransaction(); err != nil {
  365 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
  366 + }
  367 + return struct{}{}, nil
  368 +}
  369 +
295 func NewMenuService(options map[string]interface{}) *MenuService { 370 func NewMenuService(options map[string]interface{}) *MenuService {
296 newMenuService := &MenuService{} 371 newMenuService := &MenuService{}
297 return newMenuService 372 return newMenuService
@@ -27,6 +27,8 @@ type ListUserQuery struct { @@ -27,6 +27,8 @@ type ListUserQuery struct {
27 DepName string `cname:"部门名称" json:"depName,omitempty"` 27 DepName string `cname:"部门名称" json:"depName,omitempty"`
28 // 手机号码 28 // 手机号码
29 Phone string `cname:"手机号码" json:"phone,omitempty"` 29 Phone string `cname:"手机号码" json:"phone,omitempty"`
  30 + // 用户类型
  31 + UserType int `cname:"用户类型 1:普通用户 2:共创用户 1024:企业注册用户" json:"userType,omitempty"`
30 // 实时拉取数据 (获取最新的) 32 // 实时拉取数据 (获取最新的)
31 PullRealTime bool `cname:"拉取最新数据" json:"pullRealTime,omitempty"` 33 PullRealTime bool `cname:"拉取最新数据" json:"pullRealTime,omitempty"`
32 } 34 }
@@ -151,6 +151,14 @@ func (menu *Menu) ValidMenuType() bool { @@ -151,6 +151,14 @@ func (menu *Menu) ValidMenuType() bool {
151 return false 151 return false
152 } 152 }
153 153
  154 +func (menu *Menu) SetPublic(status int) error {
  155 + if !(status == MenuPublic || status == MenuPrivate) {
  156 + return fmt.Errorf("非法的公开状态: %v", status)
  157 + }
  158 + menu.IsPublish = status
  159 + return nil
  160 +}
  161 +
154 /***** 1.实现树 *****/ 162 /***** 1.实现树 *****/
155 /*1.1 实现树的方法*/ 163 /*1.1 实现树的方法*/
156 // GetParentPath 获取菜单路径 164 // GetParentPath 获取菜单路径
@@ -28,4 +28,6 @@ type Menu struct { @@ -28,4 +28,6 @@ type Menu struct {
28 IsPublish int `comment:"菜单是否公开状态,[2:隐藏],[1:显示],默认显示"` 28 IsPublish int `comment:"菜单是否公开状态,[2:隐藏],[1:显示],默认显示"`
29 // 启用状态(启用:1 禁用:2),默认启用 29 // 启用状态(启用:1 禁用:2),默认启用
30 EnableStatus int `comment:"启用状态(启用:1 禁用:2),默认启用"` 30 EnableStatus int `comment:"启用状态(启用:1 禁用:2),默认启用"`
  31 + // 删除时间
  32 + //DeletedAt time.Time `comment:"删除时间"`
31 } 33 }
@@ -196,6 +196,7 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int @@ -196,6 +196,7 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int
196 query.SetWhereByQueryOption("company_id=?", "companyId") 196 query.SetWhereByQueryOption("company_id=?", "companyId")
197 query.SetWhereByQueryOption("organization_id=?", "organizationId") 197 query.SetWhereByQueryOption("organization_id=?", "organizationId")
198 query.SetWhereByQueryOption("user_base_id=?", "userBaseId") 198 query.SetWhereByQueryOption("user_base_id=?", "userBaseId")
  199 + query.SetWhereByQueryOption("(user_type & ?)>0", "userType")
199 if v, ok := queryOptions["depName"]; ok && len(v.(string)) > 0 { 200 if v, ok := queryOptions["depName"]; ok && len(v.(string)) > 0 {
200 query.Where(fmt.Sprintf(`ext->>'depName' like '%%%v%%'`, v)) 201 query.Where(fmt.Sprintf(`ext->>'depName' like '%%%v%%'`, v))
201 } 202 }
@@ -203,7 +204,7 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int @@ -203,7 +204,7 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int
203 query.Where(fmt.Sprintf(`ext->>'userName' like '%%%v%%'`, v)) 204 query.Where(fmt.Sprintf(`ext->>'userName' like '%%%v%%'`, v))
204 } 205 }
205 if v, ok := queryOptions["cooperationCompany"]; ok && len(v.(string)) > 0 { 206 if v, ok := queryOptions["cooperationCompany"]; ok && len(v.(string)) > 0 {
206 - query.Where(fmt.Sprintf(`cooperation_info->>'cooperationCompany'' like '%%%v%%'`, v)) 207 + query.Where(fmt.Sprintf(`cooperation_info->>'cooperationCompany' like '%%%v%%'`, v))
207 } 208 }
208 query.SetOffsetAndLimit(999) 209 query.SetOffsetAndLimit(999)
209 query.SetOrderDirect("user_id", "DESC") 210 query.SetOrderDirect("user_id", "DESC")
@@ -72,3 +72,19 @@ func (controller *MenuController) SearchMenu() { @@ -72,3 +72,19 @@ func (controller *MenuController) SearchMenu() {
72 data, err := menuService.ListMenu(listMenuQuery) 72 data, err := menuService.ListMenu(listMenuQuery)
73 controller.Response(data, err) 73 controller.Response(data, err)
74 } 74 }
  75 +
  76 +func (controller *MenuController) BatchDeleteMenu() {
  77 + menuService := service.NewMenuService(nil)
  78 + batchDeleteMenuCommand := &command.BatchDeleteMenuCommand{}
  79 + controller.Unmarshal(batchDeleteMenuCommand)
  80 + data, err := menuService.BatchDeleteMenu(batchDeleteMenuCommand)
  81 + controller.Response(data, err)
  82 +}
  83 +
  84 +func (controller *MenuController) BatchEnableMenu() {
  85 + menuService := service.NewMenuService(nil)
  86 + batchEnableMenu := &command.BatchEnableMenuCommand{}
  87 + controller.Unmarshal(batchEnableMenu)
  88 + data, err := menuService.BatchEnableMenu(batchEnableMenu)
  89 + controller.Response(data, err)
  90 +}
@@ -12,6 +12,8 @@ func init() { @@ -12,6 +12,8 @@ func init() {
12 web.Router("/menus/:menuId", &controllers.MenuController{}, "Delete:RemoveMenu") 12 web.Router("/menus/:menuId", &controllers.MenuController{}, "Delete:RemoveMenu")
13 web.Router("/menus/", &controllers.MenuController{}, "Get:ListMenu") 13 web.Router("/menus/", &controllers.MenuController{}, "Get:ListMenu")
14 web.Router("/menus/search", &controllers.MenuController{}, "Post:SearchMenu") 14 web.Router("/menus/search", &controllers.MenuController{}, "Post:SearchMenu")
  15 + web.Router("/menus/batch-delete", &controllers.MenuController{}, "Post:BatchDeleteMenu")
  16 + web.Router("/menus/batch-enable", &controllers.MenuController{}, "Post:BatchEnableMenu")
15 17
16 web.Router("/v1/web/menus/", &controllers.MenuController{}, "Post:CreateMenu") 18 web.Router("/v1/web/menus/", &controllers.MenuController{}, "Post:CreateMenu")
17 web.Router("/v1/web/menus/:menuId", &controllers.MenuController{}, "Put:UpdateMenu") 19 web.Router("/v1/web/menus/:menuId", &controllers.MenuController{}, "Put:UpdateMenu")
@@ -19,6 +21,8 @@ func init() { @@ -19,6 +21,8 @@ func init() {
19 web.Router("/v1/web/menus/:menuId", &controllers.MenuController{}, "Delete:RemoveMenu") 21 web.Router("/v1/web/menus/:menuId", &controllers.MenuController{}, "Delete:RemoveMenu")
20 web.Router("/v1/web/menus/search", &controllers.MenuController{}, "Get:ListMenu") 22 web.Router("/v1/web/menus/search", &controllers.MenuController{}, "Get:ListMenu")
21 web.Router("/v1/web/menus/search", &controllers.MenuController{}, "Post:SearchMenu") 23 web.Router("/v1/web/menus/search", &controllers.MenuController{}, "Post:SearchMenu")
  24 + web.Router("/v1/web/menus/batch-delete", &controllers.MenuController{}, "Post:BatchDeleteMenu")
  25 + web.Router("/v1/web/menus/batch-enable", &controllers.MenuController{}, "Post:BatchEnableMenu")
22 26
23 web.Router("/v1/web/common/dictionary/search", &controllers.CommonController{}, "Post:DictionarySearch") 27 web.Router("/v1/web/common/dictionary/search", &controllers.CommonController{}, "Post:DictionarySearch")
24 } 28 }
  1 +package menu
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/gavv/httpexpect"
  7 + . "github.com/onsi/ginkgo"
  8 + . "github.com/onsi/gomega"
  9 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  10 +)
  11 +
  12 +var _ = Describe("批量删除菜单", func() {
  13 + var menuId int64
  14 + BeforeEach(func() {
  15 + _, err := pG.DB.QueryOne(
  16 + pg.Scan(&menuId),
  17 + "INSERT INTO menus (menu_id, parent_id, menu_name, code, access_code, menu_type, icon, sort, remark, category, parent_path, enable_status, is_publish) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING menu_id",
  18 + "testMenuId", "testParentId", "testMenuName", "testCode", "testAccessCode", "testMenuType", "testIcon", "testSort", "testRemark", "testCategory", "testParentPath", "testEnableStatus", "testIsPublish")
  19 + Expect(err).NotTo(HaveOccurred())
  20 + })
  21 + Describe("批量删除菜单", func() {
  22 + Context("", func() {
  23 + It("", func() {
  24 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  25 + body := map[string]interface{}{
  26 + "menuIds": "array",
  27 + }
  28 + httpExpect.POST("/menu/batch-delete").
  29 + WithJSON(body).
  30 + Expect().
  31 + Status(http.StatusOK).
  32 + JSON().
  33 + Object().
  34 + ContainsKey("code").ValueEqual("code", 0).
  35 + ContainsKey("msg").ValueEqual("msg", "ok").
  36 + ContainsKey("data").Value("data").Object()
  37 + })
  38 + })
  39 + })
  40 + AfterEach(func() {
  41 + _, err := pG.DB.Exec("DELETE FROM menus WHERE true")
  42 + Expect(err).NotTo(HaveOccurred())
  43 + })
  44 +})
  1 +package menu
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/gavv/httpexpect"
  7 + . "github.com/onsi/ginkgo"
  8 + . "github.com/onsi/gomega"
  9 + pG "gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/pg"
  10 +)
  11 +
  12 +var _ = Describe("批量启用菜单", func() {
  13 + var menuId int64
  14 + BeforeEach(func() {
  15 + _, err := pG.DB.QueryOne(
  16 + pg.Scan(&menuId),
  17 + "INSERT INTO menus (menu_id, parent_id, menu_name, code, access_code, menu_type, icon, sort, remark, category, parent_path, enable_status, is_publish) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) RETURNING menu_id",
  18 + "testMenuId", "testParentId", "testMenuName", "testCode", "testAccessCode", "testMenuType", "testIcon", "testSort", "testRemark", "testCategory", "testParentPath", "testEnableStatus", "testIsPublish")
  19 + Expect(err).NotTo(HaveOccurred())
  20 + })
  21 + Describe("批量启用菜单", func() {
  22 + Context("", func() {
  23 + It("", func() {
  24 + httpExpect := httpexpect.New(GinkgoT(), server.URL)
  25 + body := map[string]interface{}{
  26 + "menuIds": "array",
  27 + "status": "int",
  28 + }
  29 + httpExpect.POST("/menu/batch-enable").
  30 + WithJSON(body).
  31 + Expect().
  32 + Status(http.StatusOK).
  33 + JSON().
  34 + Object().
  35 + ContainsKey("code").ValueEqual("code", 0).
  36 + ContainsKey("msg").ValueEqual("msg", "ok").
  37 + ContainsKey("data").Value("data").Object()
  38 + })
  39 + })
  40 + })
  41 + AfterEach(func() {
  42 + _, err := pG.DB.Exec("DELETE FROM menus WHERE true")
  43 + Expect(err).NotTo(HaveOccurred())
  44 + })
  45 +})