package logic import ( "admin/admin" "admin/internal/dao" "admin/internal/model" "admin/internal/svc" "admin/validator" "context" "strconv" "strings" "github.com/zeromicro/go-zero/core/logx" "pkg.local/modelbase" "pkg.local/utils" ) type LoginRoutesLogic struct { ctx context.Context svcCtx *svc.ServiceContext logx.Logger BaseLogic } func NewLoginRoutesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginRoutesLogic { return &LoginRoutesLogic{ ctx: ctx, svcCtx: svcCtx, Logger: logx.WithContext(ctx), } } func (l *LoginRoutesLogic) LoginRoutes(in *admin.RoutesRequest) (*admin.Response, error) { var v validator.LoginRoutesValidator l.Logger.Errorf("LoginRoutes in: %v", in.ServiceId) if fail := l.checkParams(in, &v); fail != nil { return fail, nil } adminInfo := utils.GetUserFromCtx(l.ctx) if adminInfo.ID < utils.NumberOne { return l.fail(utils.ErrorNoLoginInfo), nil } var items = dao.Routes{} var rules []string var rErr utils.Status rules, rErr = l.getIds(adminInfo.ID, in.ServiceId) if rErr != utils.Ok { return l.fail(rErr), nil } if len(rules) == utils.NumberZero { return l.ok(items), nil } items, rErr = l.userAuthority(rules, in.ServiceId) if rErr != utils.Ok { return l.fail(rErr), nil } return l.ok(items), nil } func (l *LoginRoutesLogic) getIds(adminId, serviceId int64) ([]string, utils.Status) { ids, uErr := l.userRoles(adminId) if uErr != utils.Ok { return nil, uErr } if len(ids) < utils.NumberOne { return nil, uErr } rules, rErr := l.userRules(ids, serviceId) if rErr != utils.Ok { return nil, rErr } if len(rules) < utils.NumberOne { return nil, rErr } return rules, utils.Ok } func (l *LoginRoutesLogic) userRules(idsString string, serviceId int64) ([]string, utils.Status) { idsArray := strings.Split(idsString, utils.DecollatorComma) var rules []string w := modelbase.Params{ Eq: map[string]string{"status": utils.StringStatusOk, "service_id": strconv.FormatInt(serviceId, utils.NumberTen)}, In: map[string][]string{"id in ?": idsArray}, } var info []dao.RoleRulesItems err := model.RoleModel{}.Init().Items(w, &info) if err != nil { return nil, utils.Fail } if len(info) < utils.NumberOne { return rules, utils.Ok } for _, role := range info { if len(role.Rules) > utils.NumberZero { tmp := strings.Split(role.Rules, utils.DecollatorComma) rules = append(rules, tmp...) } } var ruleArray []string keys := make(map[string]bool) for _, rule := range rules { if _, value := keys[rule]; !value { keys[rule] = true ruleArray = append(ruleArray, rule) } } return ruleArray, utils.Ok } func (l *LoginRoutesLogic) userAuthority(idsArray []string, serviceId int64) (dao.Routes, utils.Status) { var items = dao.Routes{} w := modelbase.Params{ Eq: map[string]string{"status": utils.StringStatusOk, "service_id": strconv.FormatInt(serviceId, utils.NumberTen)}, In: map[string][]string{"id in ?": idsArray}, } w.Order = "level ASC, parent_id ASC, sort ASC" var info []dao.Authority err := model.AuthorityModel{}.Init().Items(w, &info) if err != nil { return items, utils.Fail } items.Menu = l.getList(info, utils.NumberZero) for _, item := range info { items.Auth = append(items.Auth, dao.RoutesAuth{ Id: item.Id, Type: item.Type, Identification: item.Identification, }) } return items, utils.Ok } func (l *LoginRoutesLogic) getList(data []dao.Authority, pid int64) []dao.RoutesMenu { var dataArr []dao.RoutesMenu for _, v := range data { if v.ParentId == pid { if v.Type == dao.TypeDir || v.Type == dao.TypeWeb || v.Type == dao.TypeUrl { // 这里可以理解为每次都从最原始的数据里面找出相对就的ID进行匹配,直到找不到就返回 children := l.getList(data, v.Id) node := dao.RoutesMenu{ Id: v.Id, Name: v.Name, Sort: v.Sort, ParentId: v.ParentId, Description: v.Description, Level: v.Level, Children: children, Api: v.Api, Path: v.Path, ViewPath: v.ViewPath, Identification: v.Identification, Type: v.Type, IsShow: v.IsShow, Icon: v.Icon, } dataArr = append(dataArr, node) } } } return dataArr } func (l *LoginRoutesLogic) userRoles(adminId int64) (string, utils.Status) { w := modelbase.Params{Or: []map[string]string{{"id": strconv.FormatInt(adminId, utils.NumberTen)}}} var info dao.AdminInfo err := model.AdminModel{}.Init().GetOne(w, &info) if err != nil { l.Logger.Error(err) return utils.StringEmpty, utils.Fail } if info.Id < utils.NumberOne { return utils.StringEmpty, utils.ErrorNotFund } return info.Roles, utils.Ok }