作者 yangfu

feat: 2.0 访问权限验证、角色修改

正在显示 28 个修改的文件 包含 398 行增加233 行删除
@@ -5,7 +5,6 @@ import ( @@ -5,7 +5,6 @@ import (
5 "github.com/samber/lo" 5 "github.com/samber/lo"
6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain" 6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/chat/internal/pkg/domain"
7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open" 7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/open"
8 - "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"  
9 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/tool" 8 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/tool"
10 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr" 9 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
11 10
@@ -34,7 +33,7 @@ func (l *ChatSessionGetLogic) ChatSessionGet(req *types.ChatSessionGetRequest) ( @@ -34,7 +33,7 @@ func (l *ChatSessionGetLogic) ChatSessionGet(req *types.ChatSessionGetRequest) (
34 conn = l.svcCtx.DefaultDBConn() 33 conn = l.svcCtx.DefaultDBConn()
35 session *domain.ChatSession 34 session *domain.ChatSession
36 records []*domain.ChatSessionRecord 35 records []*domain.ChatSessionRecord
37 - token = contextdata.GetUserTokenFromCtx(l.ctx) 36 + //token = contextdata.GetUserTokenFromCtx(l.ctx)
38 user open.User 37 user open.User
39 ) 38 )
40 // 货号唯一 39 // 货号唯一
@@ -44,14 +43,14 @@ func (l *ChatSessionGetLogic) ChatSessionGet(req *types.ChatSessionGetRequest) ( @@ -44,14 +43,14 @@ func (l *ChatSessionGetLogic) ChatSessionGet(req *types.ChatSessionGetRequest) (
44 if user, err = l.svcCtx.SystemOpen.User(l.ctx, conn, session.UserId); err != nil { 43 if user, err = l.svcCtx.SystemOpen.User(l.ctx, conn, session.UserId); err != nil {
45 return nil, xerr.NewErrMsgErr("用户不存在", err) 44 return nil, xerr.NewErrMsgErr("用户不存在", err)
46 } 45 }
47 - if _, records, err = l.svcCtx.ChatSessionRecordRepository.FindByCompanyUser(l.ctx, conn, token.CompanyId, token.UserId, domain.NewQueryOptions().MustWithKV("sessionId", session.Id)); err != nil { 46 + if _, records, err = l.svcCtx.ChatSessionRecordRepository.FindByCompanyUser(l.ctx, conn, session.CompanyId, session.UserId, domain.NewQueryOptions().MustWithKV("sessionId", session.Id)); err != nil {
48 return nil, xerr.NewErr(err) 47 return nil, xerr.NewErr(err)
49 } 48 }
50 var typesRecords []types.Record 49 var typesRecords []types.Record
51 lo.ForEach(records, func(item *domain.ChatSessionRecord, index int) { 50 lo.ForEach(records, func(item *domain.ChatSessionRecord, index int) {
52 typesRecords = append(typesRecords, NewTypesChatRecord(item, user)) 51 typesRecords = append(typesRecords, NewTypesChatRecord(item, user))
53 }) 52 })
54 - var documents []types.ChatDocumentItem 53 + var documents = make([]types.ChatDocumentItem, 0)
55 var dataset types.ChatDatasetItem 54 var dataset types.ChatDatasetItem
56 if session.Type == domain.TypeSparkDocumentsChat && len(session.Metadata.DocumentIds) > 0 { 55 if session.Type == domain.TypeSparkDocumentsChat && len(session.Metadata.DocumentIds) > 0 {
57 for _, id := range session.Metadata.DocumentIds { 56 for _, id := range session.Metadata.DocumentIds {
@@ -12,4 +12,6 @@ type Config struct { @@ -12,4 +12,6 @@ type Config struct {
12 Redis redis.RedisConf `json:",optional"` 12 Redis redis.RedisConf `json:",optional"`
13 SystemAuth config.Auth 13 SystemAuth config.Auth
14 DebugSmsCode string `json:",optional,default=999512"` 14 DebugSmsCode string `json:",optional,default=999512"`
  15 + CheckAuth bool `json:",optional,default=true"`
  16 + CheckAuthProba float64 `json:",optional,default=0.3"`
15 } 17 }
  1 +package app
  2 +
  3 +import (
  4 + "net/http"
  5 +
  6 + "github.com/zeromicro/go-zero/rest/httpx"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/logic/app"
  8 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  9 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  10 +)
  11 +
  12 +func SystemAppListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
  13 + return func(w http.ResponseWriter, r *http.Request) {
  14 + var req types.SystemAppSearchRequest
  15 + if err := httpx.Parse(r, &req); err != nil {
  16 + httpx.ErrorCtx(r.Context(), w, err)
  17 + return
  18 + }
  19 +
  20 + l := app.NewSystemAppListLogic(r.Context(), svcCtx)
  21 + resp, err := l.SystemAppList(&req)
  22 + if err != nil {
  23 + httpx.ErrorCtx(r.Context(), w, err)
  24 + } else {
  25 + httpx.OkJsonCtx(r.Context(), w, resp)
  26 + }
  27 + }
  28 +}
@@ -38,7 +38,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -38,7 +38,7 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
38 38
39 server.AddRoutes( 39 server.AddRoutes(
40 rest.WithMiddlewares( 40 rest.WithMiddlewares(
41 - []rest.Middleware{serverCtx.LogRequest}, 41 + []rest.Middleware{serverCtx.LogRequest, serverCtx.LoginStatusCheck},
42 []rest.Route{ 42 []rest.Route{
43 { 43 {
44 Method: http.MethodPost, 44 Method: http.MethodPost,
@@ -220,6 +220,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { @@ -220,6 +220,11 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
220 Path: "/system/app/set_config", 220 Path: "/system/app/set_config",
221 Handler: app.SystemAppSetConfigHandler(serverCtx), 221 Handler: app.SystemAppSetConfigHandler(serverCtx),
222 }, 222 },
  223 + {
  224 + Method: http.MethodPost,
  225 + Path: "/system/app/list",
  226 + Handler: app.SystemAppListHandler(serverCtx),
  227 + },
223 }..., 228 }...,
224 ), 229 ),
225 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret), 230 rest.WithJwt(serverCtx.Config.SystemAuth.AccessSecret),
  1 +package app
  2 +
  3 +import (
  4 + "context"
  5 +
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/svc"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/types"
  8 +
  9 + "github.com/zeromicro/go-zero/core/logx"
  10 +)
  11 +
  12 +type SystemAppListLogic struct {
  13 + logx.Logger
  14 + ctx context.Context
  15 + svcCtx *svc.ServiceContext
  16 +}
  17 +
  18 +func NewSystemAppListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SystemAppListLogic {
  19 + return &SystemAppListLogic{
  20 + Logger: logx.WithContext(ctx),
  21 + ctx: ctx,
  22 + svcCtx: svcCtx,
  23 + }
  24 +}
  25 +
  26 +func (l *SystemAppListLogic) SystemAppList(req *types.SystemAppSearchRequest) (resp interface{}, err error) {
  27 + logic := NewSystemAppSearchLogic(l.ctx, l.svcCtx)
  28 + var tmpResp *types.SystemAppSearchResponse
  29 + tmpResp, err = logic.SystemAppSearch(req)
  30 +
  31 + list := make([]types.App, 0)
  32 + for _, item := range tmpResp.List {
  33 + list = append(list, types.App{
  34 + Id: item.Id,
  35 + Name: item.Name,
  36 + Logo: item.Logo,
  37 + })
  38 + }
  39 + resp = map[string]interface{}{
  40 + "list": list,
  41 + }
  42 + return
  43 +}
@@ -106,5 +106,6 @@ func NewTypesSystemAppItem(item *domain.SysApp, cp *domain.SysCompanyApp) types. @@ -106,5 +106,6 @@ func NewTypesSystemAppItem(item *domain.SysApp, cp *domain.SysCompanyApp) types.
106 VisibleFlag: cp.VisibleFlag, 106 VisibleFlag: cp.VisibleFlag,
107 VisibleUsers: cp.VisibleUsers, 107 VisibleUsers: cp.VisibleUsers,
108 Sort: cp.Sort, 108 Sort: cp.Sort,
  109 + Url: item.Url,
109 } 110 }
110 } 111 }
@@ -85,6 +85,10 @@ func (l *SystemAuthLoginLogic) SystemAuthLogin(req *types.AuthLoginRequest) (res @@ -85,6 +85,10 @@ func (l *SystemAuthLoginLogic) SystemAuthLogin(req *types.AuthLoginRequest) (res
85 EmployeeId: currentEmployee.Id, 85 EmployeeId: currentEmployee.Id,
86 } 86 }
87 token, _ := userToken.GenerateToken(l.svcCtx.Config.SystemAuth.AccessSecret, l.svcCtx.Config.SystemAuth.AccessExpire) 87 token, _ := userToken.GenerateToken(l.svcCtx.Config.SystemAuth.AccessSecret, l.svcCtx.Config.SystemAuth.AccessExpire)
  88 + // 保存Token
  89 + if err = l.svcCtx.UserAuthService.Refresh(user.Id, token); err != nil {
  90 + return nil, xerr.NewErr(err)
  91 + }
88 resp = &types.AuthLoginResponse{ 92 resp = &types.AuthLoginResponse{
89 Token: token, 93 Token: token,
90 } 94 }
@@ -55,6 +55,12 @@ func (l *SystemAuthSwitchCompanyLogic) SystemAuthSwitchCompany(req *types.Switch @@ -55,6 +55,12 @@ func (l *SystemAuthSwitchCompanyLogic) SystemAuthSwitchCompany(req *types.Switch
55 EmployeeId: employee.Id, 55 EmployeeId: employee.Id,
56 } 56 }
57 tokenStr, _ := userToken.GenerateToken(l.svcCtx.Config.SystemAuth.AccessSecret, l.svcCtx.Config.SystemAuth.AccessExpire) 57 tokenStr, _ := userToken.GenerateToken(l.svcCtx.Config.SystemAuth.AccessSecret, l.svcCtx.Config.SystemAuth.AccessExpire)
  58 +
  59 + // 保存Token
  60 + if err = l.svcCtx.UserAuthService.Refresh(user.Id, tokenStr); err != nil {
  61 + return nil, xerr.NewErr(err)
  62 + }
  63 +
58 resp = &types.AuthLoginResponse{ 64 resp = &types.AuthLoginResponse{
59 Token: tokenStr, 65 Token: tokenStr,
60 } 66 }
@@ -75,7 +75,7 @@ func (l *SystemAuthUserInfoLogic) GetUserAuthMenus(userId int64, companyId int64 @@ -75,7 +75,7 @@ func (l *SystemAuthUserInfoLogic) GetUserAuthMenus(userId int64, companyId int64
75 if !lo.Contains(role.AuthUsers, userId) { 75 if !lo.Contains(role.AuthUsers, userId) {
76 continue 76 continue
77 } 77 }
78 - if role.AuthRange == domain.AuthRangeAll { 78 + if role.AuthRange == domain.AuthRangeAllMenu {
79 hasAllAuth = true 79 hasAllAuth = true
80 } 80 }
81 menusSet.Add(lo.ToAnySlice(role.Menus)...) 81 menusSet.Add(lo.ToAnySlice(role.Menus)...)
@@ -111,6 +111,15 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t @@ -111,6 +111,15 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t
111 err error 111 err error
112 ) 112 )
113 113
  114 + var appSets = collection.NewSet()
  115 + _, roles, _ := l.svcCtx.RoleRepository.FindByEmployee(l.ctx, conn, companyId, userId, domain.NewQueryOptions().WithFindOnly())
  116 + for _, role := range roles {
  117 + if !lo.Contains(role.Apps, userId) {
  118 + continue
  119 + }
  120 + appSets.Add(lo.ToAnySlice(role.Apps)...)
  121 + }
  122 +
114 if _, companyApps, err = l.svcCtx.CompanyAppRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithFindOnly().MustWithKV("companyId", companyId)); err != nil { 123 if _, companyApps, err = l.svcCtx.CompanyAppRepository.Find(l.ctx, conn, domain.NewQueryOptions().WithFindOnly().MustWithKV("companyId", companyId)); err != nil {
115 return typesApps 124 return typesApps
116 } 125 }
@@ -120,12 +129,19 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t @@ -120,12 +129,19 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t
120 if app == nil { 129 if app == nil {
121 continue 130 continue
122 } 131 }
  132 +
  133 + // 角色包含应用权限
123 typeApp := types.NewTypesSystemAppItem(app, companyApp) 134 typeApp := types.NewTypesSystemAppItem(app, companyApp)
124 - // 有指定用户权限  
125 - if len(companyApp.VisibleUsers) > 0 && lo.Contains(companyApp.VisibleUsers, userId) { 135 + if appSets.Contains(app.Id) {
126 typeApp.HasAuth = true 136 typeApp.HasAuth = true
127 } 137 }
128 - // 有部门权限 138 +
  139 + // 指定用户包含应用权限
  140 + if !(typeApp.HasAuth) && len(companyApp.VisibleUsers) > 0 && lo.Contains(companyApp.VisibleUsers, userId) {
  141 + typeApp.HasAuth = true
  142 + }
  143 +
  144 + // 部门包含应用权限
129 if !(typeApp.HasAuth) && len(companyApp.VisibleDepartments) > 0 { 145 if !(typeApp.HasAuth) && len(companyApp.VisibleDepartments) > 0 {
130 _, departments, _ := l.svcCtx.UserDepartmentRepository.FindByUser(l.ctx, conn, companyId, []int64{userId}) 146 _, departments, _ := l.svcCtx.UserDepartmentRepository.FindByUser(l.ctx, conn, companyId, []int64{userId})
131 if lo.ContainsBy(departments, func(item *domain.SysUserDepartment) bool { 147 if lo.ContainsBy(departments, func(item *domain.SysUserDepartment) bool {
@@ -139,6 +155,11 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t @@ -139,6 +155,11 @@ func (l *SystemAuthUserInfoLogic) GetUserApps(userId int64, companyId int64) []t
139 typeApp.HasAuth = true 155 typeApp.HasAuth = true
140 } 156 }
141 } 157 }
  158 +
  159 + //if !typeApp.HasAuth {
  160 + // continue
  161 + //}
  162 +
142 typesApps = append(typesApps, typeApp) 163 typesApps = append(typesApps, typeApp)
143 } 164 }
144 return typesApps 165 return typesApps
@@ -2,6 +2,7 @@ package role @@ -2,6 +2,7 @@ package role
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "github.com/samber/lo"
5 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain" 6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain"
6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr" 7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
7 8
@@ -36,17 +37,48 @@ func (l *SystemRoleGetLogic) SystemRoleGet(req *types.RoleGetRequest) (resp *typ @@ -36,17 +37,48 @@ func (l *SystemRoleGetLogic) SystemRoleGet(req *types.RoleGetRequest) (resp *typ
36 } 37 }
37 userLazyLoad := domain.NewLazyLoadService(l.svcCtx.UserRepository.FindOne) 38 userLazyLoad := domain.NewLazyLoadService(l.svcCtx.UserRepository.FindOne)
38 menuLazyLoad := domain.NewLazyLoadService(domain.FineOneMenu) 39 menuLazyLoad := domain.NewLazyLoadService(domain.FineOneMenu)
  40 + appLazyLoad := domain.NewLazyLoadService(l.svcCtx.AppRepository.FindOne)
  41 + departmentLazyLoad := domain.NewLazyLoadService(l.svcCtx.DepartmentRepository.FindOne)
39 role := NewTypesSysRole(dm) 42 role := NewTypesSysRole(dm)
40 for _, userId := range dm.AuthUsers { 43 for _, userId := range dm.AuthUsers {
41 if user, _ := userLazyLoad.Load(l.ctx, conn, userId); user != nil { 44 if user, _ := userLazyLoad.Load(l.ctx, conn, userId); user != nil {
42 role.AuthUsers = append(role.AuthUsers, types.NewTypesUser(user)) 45 role.AuthUsers = append(role.AuthUsers, types.NewTypesUser(user))
43 } 46 }
44 } 47 }
  48 +
  49 + // 查询用户部门
  50 + if len(dm.AuthUsers) > 0 {
  51 + _, userDeps, _ := l.svcCtx.UserDepartmentRepository.FindByUser(l.ctx, conn, dm.CompanyId, dm.AuthUsers)
  52 + userDepsGroup := lo.GroupBy(userDeps, func(item *domain.SysUserDepartment) int64 {
  53 + return item.UserId
  54 + })
  55 + for i := range role.AuthUsers {
  56 + uid := role.AuthUsers[i].Id
  57 + list, ok := userDepsGroup[uid]
  58 + if !ok {
  59 + continue
  60 + }
  61 + for _, item := range list {
  62 + if department, _ := departmentLazyLoad.Load(l.ctx, conn, item.DepartmentId); department != nil {
  63 + role.AuthUsers[i].Departments = append(role.AuthUsers[i].Departments, types.Department{
  64 + Id: department.Id,
  65 + Name: department.Name,
  66 + })
  67 + }
  68 + }
  69 + }
  70 + }
  71 +
45 for _, menuId := range dm.Menus { 72 for _, menuId := range dm.Menus {
46 if menu, _ := menuLazyLoad.Load(l.ctx, conn, menuId); menu != nil { 73 if menu, _ := menuLazyLoad.Load(l.ctx, conn, menuId); menu != nil {
47 role.Menus = append(role.Menus, types.NewTypesMenu(menu)) 74 role.Menus = append(role.Menus, types.NewTypesMenu(menu))
48 } 75 }
49 } 76 }
  77 + for _, appId := range dm.Apps {
  78 + if app, _ := appLazyLoad.Load(l.ctx, conn, appId); app != nil {
  79 + role.Apps = append(role.Apps, types.NewTypesApp(app))
  80 + }
  81 + }
50 resp = &types.RoleGetResponse{ 82 resp = &types.RoleGetResponse{
51 Role: role, 83 Role: role,
52 } 84 }
@@ -2,6 +2,7 @@ package role @@ -2,6 +2,7 @@ package role
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "github.com/samber/lo"
5 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain" 6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain"
6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata" 7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction" 8 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
@@ -53,20 +54,18 @@ func NewDomainSysRole(companyId int64, item types.Role) *domain.SysRole { @@ -53,20 +54,18 @@ func NewDomainSysRole(companyId int64, item types.Role) *domain.SysRole {
53 users := domain.Values(item.AuthUsers, func(item types.User) int64 { 54 users := domain.Values(item.AuthUsers, func(item types.User) int64 {
54 return item.Id 55 return item.Id
55 }) 56 })
56 - if item.AuthRange == 0 {  
57 - if len(menus) == len(domain.DefaultMenus) {  
58 - item.AuthRange = domain.AuthRangeAll  
59 - } else {  
60 - item.AuthRange = domain.AuthRangePart  
61 - }  
62 - }  
63 - return &domain.SysRole{ 57 + apps := domain.Values(item.Apps, func(item types.App) int64 { return item.Id })
  58 + role := &domain.SysRole{
64 CompanyId: companyId, 59 CompanyId: companyId,
65 Name: item.Name, 60 Name: item.Name,
66 Menus: menus, 61 Menus: menus,
67 AuthUsers: users, 62 AuthUsers: users,
68 - AuthRange: item.AuthRange, 63 + //AuthRange: item.AuthRange,
  64 + Remark: item.Remark,
69 } 65 }
  66 + role.AddAuthRange(lo.Ternary(len(menus) == len(domain.DefaultMenus), domain.AuthRangeAllMenu, 0))
  67 + role.AddAuthRange(lo.Ternary(len(apps) == len(domain.DefaultApps), domain.AuthRangeAllApp, 0))
  68 + return role
70 } 69 }
71 70
72 func NewTypesSysRole(item *domain.SysRole) types.Role { 71 func NewTypesSysRole(item *domain.SysRole) types.Role {
@@ -75,5 +74,6 @@ func NewTypesSysRole(item *domain.SysRole) types.Role { @@ -75,5 +74,6 @@ func NewTypesSysRole(item *domain.SysRole) types.Role {
75 Name: item.Name, 74 Name: item.Name,
76 AuthRange: item.AuthRange, 75 AuthRange: item.AuthRange,
77 UpdatedAt: item.UpdatedAt, 76 UpdatedAt: item.UpdatedAt,
  77 + Remark: item.Remark,
78 } 78 }
79 } 79 }
@@ -39,6 +39,7 @@ func (l *SystemRoleSearchLogic) SystemRoleSearch(req *types.RoleSearchRequest) ( @@ -39,6 +39,7 @@ func (l *SystemRoleSearchLogic) SystemRoleSearch(req *types.RoleSearchRequest) (
39 list := make([]types.Role, 0) 39 list := make([]types.Role, 0)
40 userLazyLoad := domain.NewLazyLoadService(l.svcCtx.UserRepository.FindOne) 40 userLazyLoad := domain.NewLazyLoadService(l.svcCtx.UserRepository.FindOne)
41 menuLazyLoad := domain.NewLazyLoadService(domain.FineOneMenu) 41 menuLazyLoad := domain.NewLazyLoadService(domain.FineOneMenu)
  42 + appLazyLoad := domain.NewLazyLoadService(l.svcCtx.AppRepository.FindOne)
42 for i := range dms { 43 for i := range dms {
43 role := NewTypesSysRole(dms[i]) 44 role := NewTypesSysRole(dms[i])
44 for j, userId := range dms[i].AuthUsers { 45 for j, userId := range dms[i].AuthUsers {
@@ -55,6 +56,11 @@ func (l *SystemRoleSearchLogic) SystemRoleSearch(req *types.RoleSearchRequest) ( @@ -55,6 +56,11 @@ func (l *SystemRoleSearchLogic) SystemRoleSearch(req *types.RoleSearchRequest) (
55 role.Menus = append(role.Menus, types.NewTypesMenu(menu)) 56 role.Menus = append(role.Menus, types.NewTypesMenu(menu))
56 } 57 }
57 } 58 }
  59 + for _, appId := range dms[i].Apps {
  60 + if app, _ := appLazyLoad.Load(l.ctx, conn, appId); app != nil {
  61 + role.Apps = append(role.Apps, types.NewTypesApp(app))
  62 + }
  63 + }
58 list = append(list, role) 64 list = append(list, role)
59 } 65 }
60 resp = &types.RoleSearchResponse{ 66 resp = &types.RoleSearchResponse{
@@ -2,6 +2,7 @@ package role @@ -2,6 +2,7 @@ package role
2 2
3 import ( 3 import (
4 "context" 4 "context"
  5 + "github.com/samber/lo"
5 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain" 6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/internal/pkg/domain"
6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction" 7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/transaction"
7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr" 8 "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
@@ -29,9 +30,9 @@ func NewSystemRoleUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) * @@ -29,9 +30,9 @@ func NewSystemRoleUpdateLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
29 func (l *SystemRoleUpdateLogic) SystemRoleUpdate(req *types.RoleUpdateRequest) (resp *types.RoleUpdateResponse, err error) { 30 func (l *SystemRoleUpdateLogic) SystemRoleUpdate(req *types.RoleUpdateRequest) (resp *types.RoleUpdateResponse, err error) {
30 var ( 31 var (
31 conn = l.svcCtx.DefaultDBConn() 32 conn = l.svcCtx.DefaultDBConn()
32 - dm *domain.SysRole 33 + role *domain.SysRole
33 ) 34 )
34 - if dm, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil { 35 + if role, err = l.svcCtx.RoleRepository.FindOne(l.ctx, conn, req.Id); err != nil {
35 return nil, xerr.NewErrMsgErr("不存在", err) 36 return nil, xerr.NewErrMsgErr("不存在", err)
36 } 37 }
37 // 不可编辑判断 38 // 不可编辑判断
@@ -43,22 +44,17 @@ func (l *SystemRoleUpdateLogic) SystemRoleUpdate(req *types.RoleUpdateRequest) ( @@ -43,22 +44,17 @@ func (l *SystemRoleUpdateLogic) SystemRoleUpdate(req *types.RoleUpdateRequest) (
43 users := domain.Values(req.Role.AuthUsers, func(item types.User) int64 { 44 users := domain.Values(req.Role.AuthUsers, func(item types.User) int64 {
44 return item.Id 45 return item.Id
45 }) 46 })
46 -  
47 - dm.Name = req.Role.Name  
48 - dm.Menus = menus  
49 - dm.AuthUsers = users  
50 - if req.Role.AuthRange == 0 {  
51 - if len(menus) == len(domain.DefaultMenus) {  
52 - dm.AuthRange = domain.AuthRangeAll  
53 - } else {  
54 - dm.AuthRange = domain.AuthRangePart  
55 - }  
56 - } else {  
57 - dm.AuthRange = req.Role.AuthRange  
58 - } 47 + apps := domain.Values(req.Role.Apps, func(item types.App) int64 { return item.Id })
  48 + role.Name = req.Role.Name
  49 + role.Menus = menus
  50 + role.AuthUsers = users
  51 + role.Apps = apps
  52 + role.Remark = req.Role.Remark
  53 + role.AddAuthRange(lo.Ternary(len(menus) == len(domain.DefaultMenus), domain.AuthRangeAllMenu, 0))
  54 + role.AddAuthRange(lo.Ternary(len(apps) == len(domain.DefaultApps), domain.AuthRangeAllApp, 0))
59 // 更新 55 // 更新
60 if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error { 56 if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {
61 - dm, err = l.svcCtx.RoleRepository.UpdateWithVersion(l.ctx, conn, dm) 57 + role, err = l.svcCtx.RoleRepository.UpdateWithVersion(l.ctx, conn, role)
62 return err 58 return err
63 }, true); err != nil { 59 }, true); err != nil {
64 return nil, xerr.NewErrMsg("更新失败") 60 return nil, xerr.NewErrMsg("更新失败")
1 package middleware 1 package middleware
2 2
3 -import "net/http" 3 +import (
  4 + "github.com/zeromicro/go-zero/rest/httpx"
  5 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  7 + "net/http"
  8 +)
4 9
5 type LoginStatusCheckMiddleware struct { 10 type LoginStatusCheckMiddleware struct {
  11 + compareFunc func(int64, string) error
  12 + secret string
6 } 13 }
7 14
8 -func NewLoginStatusCheckMiddleware() *LoginStatusCheckMiddleware {  
9 - return &LoginStatusCheckMiddleware{} 15 +func NewLoginStatusCheckMiddleware(fn func(int64, string) error, secret string) *LoginStatusCheckMiddleware {
  16 + return &LoginStatusCheckMiddleware{compareFunc: fn}
10 } 17 }
11 18
12 func (m *LoginStatusCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc { 19 func (m *LoginStatusCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
13 return func(w http.ResponseWriter, r *http.Request) { 20 return func(w http.ResponseWriter, r *http.Request) {
14 - // TODO generate middleware implement function, delete after code implementation  
15 -  
16 - // Passthrough to next handler if need 21 + token := r.Header.Get("Authorization")
  22 + if len(token) < 6 {
  23 + httpx.ErrorCtx(r.Context(), w, xerr.NewCodeErr(xerr.TokenExpireError, nil))
  24 + return
  25 + }
  26 + token = token[6:]
  27 + if tmpCtx, err := contextdata.ParseToken(r.Context(), m.secret, token); err != nil {
  28 + httpx.ErrorCtx(r.Context(), w, xerr.NewCodeErr(xerr.TokenExpireError, nil))
  29 + return
  30 + } else {
  31 + userToken := contextdata.GetUserTokenFromCtx(tmpCtx)
  32 + if err = m.compareFunc(userToken.UserId, token); err != nil {
  33 + httpx.ErrorCtx(r.Context(), w, xerr.NewCodeErr(xerr.TokenExpireError, err))
  34 + return
  35 + }
  36 + }
17 next(w, r) 37 next(w, r)
18 } 38 }
19 } 39 }
1 package svc 1 package svc
2 2
3 import ( 3 import (
  4 + "github.com/samber/lo"
4 "github.com/zeromicro/go-zero/core/stores/redis" 5 "github.com/zeromicro/go-zero/core/stores/redis"
5 "github.com/zeromicro/go-zero/rest" 6 "github.com/zeromicro/go-zero/rest"
6 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/config" 7 "gitlab.fjmaimaimai.com/allied-creation/su-micro/cmd/ep/system/api/internal/config"
@@ -26,6 +27,8 @@ type ServiceContext struct { @@ -26,6 +27,8 @@ type ServiceContext struct {
26 // 外部接口 27 // 外部接口
27 SmsService smslib.SMSService 28 SmsService smslib.SMSService
28 29
  30 + UserAuthService middleware.UserAuthService
  31 +
29 // 数据仓储 32 // 数据仓储
30 UserRepository domain.SysUserRepository 33 UserRepository domain.SysUserRepository
31 CompanyRepository domain.SysCompanyRepository 34 CompanyRepository domain.SysCompanyRepository
@@ -46,14 +49,15 @@ func NewServiceContext(c config.Config) *ServiceContext { @@ -46,14 +49,15 @@ func NewServiceContext(c config.Config) *ServiceContext {
46 //apiAuth := authlib.ApiAuthService{ 49 //apiAuth := authlib.ApiAuthService{
47 // Service: gateway.NewService(c.ApiAuth.Name, c.ApiAuth.Host, c.ApiAuth.Timeout), 50 // Service: gateway.NewService(c.ApiAuth.Name, c.ApiAuth.Host, c.ApiAuth.Timeout),
48 //} 51 //}
49 - 52 + userAuthService := middleware.NewUserAuthService(redis, c.Name)
50 return &ServiceContext{ 53 return &ServiceContext{
51 Config: c, 54 Config: c,
52 DB: db, 55 DB: db,
53 Redis: redis, 56 Redis: redis,
54 SmsService: smslib.SMSService{Service: gateway.NewService("短信服务", "https://sms.fjmaimaimai.com:9897", time.Second*5)}, 57 SmsService: smslib.SMSService{Service: gateway.NewService("短信服务", "https://sms.fjmaimaimai.com:9897", time.Second*5)},
55 58
56 - //LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware().Handle, 59 + UserAuthService: userAuthService,
  60 + LoginStatusCheck: middleware.NewLoginStatusCheckMiddleware(lo.Ternary(c.CheckAuth, userAuthService.Compare, nil), c.SystemAuth.AccessSecret, c.CheckAuthProba).Handle,
57 LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle, 61 LogRequest: middleware.NewLogRequestMiddleware(c.LogRequest).Handle,
58 UserRepository: repository.NewSysUserRepository(cache.NewCachedRepository(mlCache)), 62 UserRepository: repository.NewSysUserRepository(cache.NewCachedRepository(mlCache)),
59 CompanyRepository: repository.NewSysCompanyRepository(cache.NewCachedRepository(mlCache)), 63 CompanyRepository: repository.NewSysCompanyRepository(cache.NewCachedRepository(mlCache)),
@@ -17,3 +17,11 @@ func NewTypesSystemAppItem(item *domain.SysApp, cp *domain.SysCompanyApp) System @@ -17,3 +17,11 @@ func NewTypesSystemAppItem(item *domain.SysApp, cp *domain.SysCompanyApp) System
17 Sort: cp.Sort, 17 Sort: cp.Sort,
18 } 18 }
19 } 19 }
  20 +
  21 +func NewTypesApp(item *domain.SysApp) App {
  22 + return App{
  23 + Id: item.Id,
  24 + Name: item.Name,
  25 + Logo: item.Logo,
  26 + }
  27 +}
@@ -6,6 +6,7 @@ type User struct { @@ -6,6 +6,7 @@ type User struct {
6 Name string `json:"name,optional"` // 用户名称 6 Name string `json:"name,optional"` // 用户名称
7 Phone string `json:"phone,optional,omitempty"` // 用户手机号 7 Phone string `json:"phone,optional,omitempty"` // 用户手机号
8 Avatar string `json:"avatar,optional,omitempty"` // 头像 8 Avatar string `json:"avatar,optional,omitempty"` // 头像
  9 + Departments []Department `json:"departments,optional,omitempty"` // 部门列表
9 } 10 }
10 11
11 type CompanyRegisterRequest struct { 12 type CompanyRegisterRequest struct {
@@ -184,8 +185,10 @@ type Role struct { @@ -184,8 +185,10 @@ type Role struct {
184 Name string `json:"name,optional,omitempty"` // 角色名称 185 Name string `json:"name,optional,omitempty"` // 角色名称
185 Menus []Menu `json:"menus,optional,omitempty"` // 菜单列表 186 Menus []Menu `json:"menus,optional,omitempty"` // 菜单列表
186 AuthUsers []User `json:"users,optional,omitempty"` // 拥护该角色的用户列表 user_id 列表 187 AuthUsers []User `json:"users,optional,omitempty"` // 拥护该角色的用户列表 user_id 列表
187 - AuthRange int `json:"authRange,optional,omitempty,option=0|1|2"` // 权限范围(1:全部权限 2:部分权限) 188 + Apps []App `json:"apps,optional,omitempty"` // 应用列表
  189 + AuthRange int `json:"authRange,optional,omitempty,option=0|1|2"` // 权限范围(1:全部菜单 2:全部应用)
188 UpdatedAt int64 `json:"updatedAt,optional,omitempty"` // 更新时间 190 UpdatedAt int64 `json:"updatedAt,optional,omitempty"` // 更新时间
  191 + Remark string `json:"remark,optional,omitempty"` // 备注说明
189 } 192 }
190 193
191 type RoleGetRequest struct { 194 type RoleGetRequest struct {
@@ -247,6 +250,12 @@ type Menu struct { @@ -247,6 +250,12 @@ type Menu struct {
247 Sort int64 `json:"sort,optional,omitempty"` // 排序 250 Sort int64 `json:"sort,optional,omitempty"` // 排序
248 } 251 }
249 252
  253 +type App struct {
  254 + Id int64 `json:"id,optional,omitempty"` // 菜单ID
  255 + Name string `json:"name,optional,omitempty"` // 菜单名称
  256 + Logo string `json:"logo,optional,omitempty"` // 图标
  257 +}
  258 +
250 type Group struct { 259 type Group struct {
251 Id int64 `json:"id"` // 分组ID 260 Id int64 `json:"id"` // 分组ID
252 Name string `json:"name"` // 分组名称 261 Name string `json:"name"` // 分组名称
@@ -288,13 +297,14 @@ type SystemAppItem struct { @@ -288,13 +297,14 @@ type SystemAppItem struct {
288 VisibleUsers []int64 `json:"visibleUsers,omitempty"` // 可见的用户 所有用户:空 部分用户:用户ID列表 297 VisibleUsers []int64 `json:"visibleUsers,omitempty"` // 可见的用户 所有用户:空 部分用户:用户ID列表
289 Sort int `json:"sort,omitempty"` // 排序 298 Sort int `json:"sort,omitempty"` // 排序
290 HasAuth bool `json:"hasAuth"` // true:用户有权限 false:用户无权限 299 HasAuth bool `json:"hasAuth"` // true:用户有权限 false:用户无权限
  300 + Url string `json:"url,omitempty"` // 应用地址
291 } 301 }
292 302
293 type SystemAppSetConfigRequest struct { 303 type SystemAppSetConfigRequest struct {
294 AppId int64 `json:"id"` // 公司应用ID 304 AppId int64 `json:"id"` // 公司应用ID
295 VisibleFlag int `json:"visibleFlag"` // 1:全员可见 2:部分可见 305 VisibleFlag int `json:"visibleFlag"` // 1:全员可见 2:部分可见
296 VisibleUsers []int64 `json:"visibleUsers"` // 可见的用户 所有用户:空 部分用户:用户ID列表 306 VisibleUsers []int64 `json:"visibleUsers"` // 可见的用户 所有用户:空 部分用户:用户ID列表
297 - VisibleDepartments []int64 `json:"visibleDepartments"` // 可见的部门 部门ID列表 307 + VisibleDepartments []int64 `json:"visibleDepartments,optional"` // 可见的部门 部门ID列表
298 } 308 }
299 309
300 type SystemAppSetConfigResponse struct { 310 type SystemAppSetConfigResponse struct {
@@ -18,6 +18,9 @@ service Core { @@ -18,6 +18,9 @@ service Core {
18 @doc "应用-设置配置" 18 @doc "应用-设置配置"
19 @handler systemAppSetConfig 19 @handler systemAppSetConfig
20 post /system/app/set_config (SystemAppSetConfigRequest) returns (SystemAppSetConfigResponse) 20 post /system/app/set_config (SystemAppSetConfigRequest) returns (SystemAppSetConfigResponse)
  21 + @doc "应用-列表"
  22 + @handler systemAppList
  23 + post /system/app/list (SystemAppSearchRequest) returns (SystemAppSearchResponse)
21 } 24 }
22 25
23 type ( 26 type (
@@ -53,6 +56,7 @@ type ( @@ -53,6 +56,7 @@ type (
53 VisibleUsers []int64 `json:"visibleUsers,omitempty"` // 可见的用户 所有用户:空 部分用户:用户ID列表 56 VisibleUsers []int64 `json:"visibleUsers,omitempty"` // 可见的用户 所有用户:空 部分用户:用户ID列表
54 Sort int `json:"sort,omitempty"` // 排序 57 Sort int `json:"sort,omitempty"` // 排序
55 HasAuth bool `json:"hasAuth"` // true:用户有权限 false:用户无权限 58 HasAuth bool `json:"hasAuth"` // true:用户有权限 false:用户无权限
  59 + Url string `json:"url,omitempty"` // 应用地址
56 } 60 }
57 ) 61 )
58 62
@@ -62,7 +66,7 @@ type( @@ -62,7 +66,7 @@ type(
62 AppId int64 `json:"id"` // 公司应用ID 66 AppId int64 `json:"id"` // 公司应用ID
63 VisibleFlag int `json:"visibleFlag"` // 1:全员可见 2:部分可见 67 VisibleFlag int `json:"visibleFlag"` // 1:全员可见 2:部分可见
64 VisibleUsers []int64 `json:"visibleUsers"` // 可见的用户 所有用户:空 部分用户:用户ID列表 68 VisibleUsers []int64 `json:"visibleUsers"` // 可见的用户 所有用户:空 部分用户:用户ID列表
65 - VisibleDepartments []int64 `json:"visibleDepartments"` // 可见的部门 部门ID列表 69 + VisibleDepartments []int64 `json:"visibleDepartments,optional"` // 可见的部门 部门ID列表
66 } 70 }
67 SystemAppSetConfigResponse{ 71 SystemAppSetConfigResponse{
68 SystemApp SystemAppItem `json:"app"` 72 SystemApp SystemAppItem `json:"app"`
@@ -6,8 +6,10 @@ type( @@ -6,8 +6,10 @@ type(
6 Name string `json:"name,optional,omitempty"` // 角色名称 6 Name string `json:"name,optional,omitempty"` // 角色名称
7 Menus []Menu `json:"menus,optional,omitempty"` // 菜单列表 7 Menus []Menu `json:"menus,optional,omitempty"` // 菜单列表
8 AuthUsers []User `json:"users,optional,omitempty"` // 拥护该角色的用户列表 user_id 列表 8 AuthUsers []User `json:"users,optional,omitempty"` // 拥护该角色的用户列表 user_id 列表
9 - AuthRange int `json:"authRange,optional,omitempty,option=0|1|2"` // 权限范围(1:全部权限 2:部分权限) 9 + Apps []App `json:"apps,optional,omitempty"` // 应用列表
  10 + AuthRange int `json:"authRange,optional,omitempty,option=0|1|2"` // 权限范围(1:全部菜单 2:全部应用)
10 UpdatedAt int64 `json:"updatedAt,optional,omitempty"` // 更新时间 11 UpdatedAt int64 `json:"updatedAt,optional,omitempty"` // 更新时间
  12 + Remark string `json:"remark,optional,omitempty"` // 备注说明
11 } 13 }
12 ) 14 )
13 15
@@ -92,4 +94,9 @@ type( @@ -92,4 +94,9 @@ type(
92 Icon string `json:"icon,optional,omitempty"` // 图标 94 Icon string `json:"icon,optional,omitempty"` // 图标
93 Sort int64 `json:"sort,optional,omitempty"` // 排序 95 Sort int64 `json:"sort,optional,omitempty"` // 排序
94 } 96 }
  97 + App{
  98 + Id int64 `json:"id,optional,omitempty"` // 菜单ID
  99 + Name string `json:"name,optional,omitempty"` // 菜单名称
  100 + Logo string `json:"logo,optional,omitempty"` // 图标
  101 + }
95 ) 102 )
@@ -27,7 +27,7 @@ service Core { @@ -27,7 +27,7 @@ service Core {
27 @server( 27 @server(
28 prefix: v1 28 prefix: v1
29 group: auth 29 group: auth
30 - middleware: LogRequest 30 + middleware: LogRequest,LoginStatusCheck
31 jwt: SystemAuth 31 jwt: SystemAuth
32 ) 32 )
33 service Core { 33 service Core {
@@ -66,7 +66,8 @@ type( @@ -66,7 +66,8 @@ type(
66 Id int64 `json:"id,optional"` // 用户ID 66 Id int64 `json:"id,optional"` // 用户ID
67 Name string `json:"name,optional"` // 用户名称 67 Name string `json:"name,optional"` // 用户名称
68 Phone string `json:"phone,optional,omitempty"` // 用户手机号 68 Phone string `json:"phone,optional,omitempty"` // 用户手机号
69 - Avatar string `json:"avatar,optional,omitempty"`// 头像 69 + Avatar string `json:"avatar,optional,omitempty"` // 头像
  70 + Departments []Department `json:"departments,optional,omitempty"` // 部门列表
70 } 71 }
71 ) 72 )
72 73
1 -  
2 -syntax = "v1"  
3 -  
4 -info(  
5 - title: "xx实例"  
6 - desc: "xx实例"  
7 - author: "author"  
8 - email: "email"  
9 - version: "v1"  
10 -)  
11 -  
12 -@server(  
13 - prefix: v1  
14 - group: sys_employee  
15 - jwt: JwtAuth  
16 -)  
17 -service Core {  
18 - @doc "详情"  
19 - @handler sys_employeeGet  
20 - get /sys_employee/:id (SysEmployeeGetRequest) returns (SysEmployeeGetResponse)  
21 - @doc "保存"  
22 - @handler sys_employeeSave  
23 - post /sys_employee (SysEmployeeSaveRequest) returns (SysEmployeeSaveResponse)  
24 - @doc "删除"  
25 - @handler sys_employeeDelete  
26 - delete /sys_employee/:id (SysEmployeeDeleteRequest) returns (SysEmployeeDeleteResponse)  
27 - @doc "更新"  
28 - @handler sys_employeeUpdate  
29 - put /sys_employee/:id (SysEmployeeUpdateRequest) returns (SysEmployeeUpdateResponse)  
30 - @doc "搜索"  
31 - @handler sys_employeeSearch  
32 - post /sys_employee/search (SysEmployeeSearchRequest) returns (SysEmployeeSearchResponse)  
33 -}  
34 -  
35 -type (  
36 - SysEmployeeGetRequest {  
37 - Id int64 `path:"id"`  
38 - }  
39 - SysEmployeeGetResponse struct{  
40 - SysEmployee SysEmployeeItem `json:"sys_employee"`  
41 - }  
42 -  
43 - SysEmployeeSaveRequest struct{  
44 - SysEmployee SysEmployeeItem `json:"sys_employee"`  
45 - }  
46 - SysEmployeeSaveResponse struct{}  
47 -  
48 - SysEmployeeDeleteRequest struct{  
49 - Id int64 `path:"id"`  
50 - }  
51 - SysEmployeeDeleteResponse struct{}  
52 -  
53 - SysEmployeeUpdateRequest struct{  
54 - Id int64 `path:"id"`  
55 - SysEmployee SysEmployeeItem `json:"sys_employee"`  
56 - }  
57 - SysEmployeeUpdateResponse struct{}  
58 -  
59 - SysEmployeeSearchRequest struct{  
60 - Page int `json:"page"`  
61 - Size int `json:"size"`  
62 - }  
63 - SysEmployeeSearchResponse{  
64 - List []SysEmployeeItem `json:"list"`  
65 - Total int64 `json:"total"`  
66 - }  
67 - SysEmployeeItem struct{  
68 -  
69 - }  
70 -)  
71 -  
72 -// logic CRUD  
73 -// Save  
74 - //var (  
75 - // conn = l.svcCtx.DefaultDBConn()  
76 - // dm *domain.SysEmployee  
77 - //)  
78 - //// 唯一判断  
79 -  
80 - //dm = NewDomainSysEmployee(req.SysEmployee)  
81 - //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {  
82 - // dm, err = l.svcCtx.SysEmployeeRepository.Insert(l.ctx, conn, dm)  
83 - // return err  
84 - //}, true); err != nil {  
85 - // return nil, xerr.NewErrMsg("保存失败")  
86 - //}  
87 - ////resp = &types.SysEmployeeSaveResponse{}  
88 - //return  
89 -  
90 -//func NewDomainSysEmployee(item types.SysEmployeeItem) *domain.SysEmployee {  
91 -// return &domain.SysEmployee{  
92 -  
93 -// }  
94 -//}  
95 -//  
96 -//func NewTypesSysEmployee(item *domain.SysEmployee) types.SysEmployeeItem {  
97 -// return types.SysEmployeeItem{  
98 -// Id: item.Id,  
99 -// }  
100 -//}  
101 -  
102 -// Get  
103 - //var (  
104 - // conn = l.svcCtx.DefaultDBConn()  
105 - // dm *domain.SysEmployee  
106 - //)  
107 - //// 货号唯一  
108 - //if dm, err = l.svcCtx.SysEmployeeRepository.FindOne(l.ctx, conn, req.Id); err != nil {  
109 - // return nil, xerr.NewErrMsgErr("不存在", err)  
110 - //}  
111 - //resp = &types.SysEmployeeGetResponse{  
112 - // SysEmployee: NewTypesSysEmployee(dm),  
113 - //}  
114 - //return  
115 -  
116 -// Delete  
117 - //var (  
118 - // conn = l.svcCtx.DefaultDBConn()  
119 - // dm *domain.SysEmployee  
120 - //)  
121 - //if dm, err = l.svcCtx.SysEmployeeRepository.FindOne(l.ctx, conn, req.Id); err != nil {  
122 - // return nil, xerr.NewErrMsgErr("不存在", err)  
123 - //}  
124 - //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {  
125 - // if dm, err = l.svcCtx.SysEmployeeRepository.Delete(l.ctx, conn, dm); err != nil {  
126 - // return err  
127 - // }  
128 - // return nil  
129 - //}, true); err != nil {  
130 - // return nil, xerr.NewErrMsgErr("移除失败", err)  
131 - //}  
132 - //return  
133 -  
134 -// Search  
135 - //var (  
136 - // conn = l.svcCtx.DefaultDBConn()  
137 - // dms []*domain.SysEmployee  
138 - // total int64  
139 - //)  
140 - //  
141 - //queryOptions := domain.NewQueryOptions().WithOffsetLimit(req.Page, req.Size).  
142 - // WithKV("", "")  
143 -  
144 - //total, dms, err = l.svcCtx.SysEmployeeRepository.Find(l.ctx, conn, queryOptions)  
145 - //list := make([]types.SysEmployeeItem, 0)  
146 - //for i := range dms {  
147 - // list = append(list, NewTypesSysEmployee(dms[i]))  
148 - //}  
149 - //resp = &types.SysEmployeeSearchResponse{  
150 - // List: list,  
151 - // Total: total,  
152 - //}  
153 - //return  
154 -  
155 -// Update  
156 - //var (  
157 - // conn = l.svcCtx.DefaultDBConn()  
158 - // dm *domain.SysEmployee  
159 - //)  
160 - //if dm, err = l.svcCtx.SysEmployeeRepository.FindOne(l.ctx, conn, req.Id); err != nil {  
161 - // return nil, xerr.NewErrMsgErr("不存在", err)  
162 - //}  
163 - //// 不可编辑判断  
164 -  
165 - //// 赋值  
166 -  
167 - //// 更新  
168 - //if err = transaction.UseTrans(l.ctx, l.svcCtx.DB, func(ctx context.Context, conn transaction.Conn) error {  
169 - // dm, err = l.svcCtx.SysEmployeeRepository.UpdateWithVersion(l.ctx, conn, dm)  
170 - // return err  
171 - //}, true); err != nil {  
172 - // return nil, xerr.NewErrMsg("更新失败")  
173 - //}  
174 - //resp = &types.SysEmployeeUpdateResponse{}  
175 - //return  
@@ -17,6 +17,7 @@ type SysApp struct { @@ -17,6 +17,7 @@ type SysApp struct {
17 Type string // 分类 default 17 Type string // 分类 default
18 VersionNumber string // 应用版本号 18 VersionNumber string // 应用版本号
19 Status int // 1:启用、2:停用 19 Status int // 1:启用、2:停用
  20 + Url string
20 CreatedAt int64 21 CreatedAt int64
21 UpdatedAt int64 22 UpdatedAt int64
22 DeletedAt int64 23 DeletedAt int64
@@ -12,8 +12,10 @@ type SysRole struct { @@ -12,8 +12,10 @@ type SysRole struct {
12 CompanyId int64 // 公司ID 12 CompanyId int64 // 公司ID
13 Name string // 公司名称 13 Name string // 公司名称
14 Menus []int64 `gorm:"type:jsonb;serializer:json"` // 菜单列表 14 Menus []int64 `gorm:"type:jsonb;serializer:json"` // 菜单列表
  15 + Apps []int64 `gorm:"type:jsonb;serializer:json"` // 应用列表
15 AuthUsers []int64 `gorm:"type:jsonb;serializer:json"` // 拥护该角色的用户列表 16 AuthUsers []int64 `gorm:"type:jsonb;serializer:json"` // 拥护该角色的用户列表
16 AuthRange int 17 AuthRange int
  18 + Remark string
17 CreatedAt int64 19 CreatedAt int64
18 UpdatedAt int64 20 UpdatedAt int64
19 DeletedAt int64 21 DeletedAt int64
@@ -19,6 +19,7 @@ type SysApp struct { @@ -19,6 +19,7 @@ type SysApp struct {
19 //VisibleGroups []int64 `json:",omitempty"` // 可见的用户组 所有用户:空 部分用户:用户ID列表 19 //VisibleGroups []int64 `json:",omitempty"` // 可见的用户组 所有用户:空 部分用户:用户ID列表
20 //AppConfig AppConfig `json:",omitempty"` // 应用配置 20 //AppConfig AppConfig `json:",omitempty"` // 应用配置
21 //Sort int `json:",omitempty"` // 排序 21 //Sort int `json:",omitempty"` // 排序
  22 + Url string `json:",omitempty"` // 应用地址
22 CreatedAt int64 `json:",omitempty"` 23 CreatedAt int64 `json:",omitempty"`
23 UpdatedAt int64 `json:",omitempty"` 24 UpdatedAt int64 `json:",omitempty"`
24 DeletedAt int64 `json:",omitempty"` 25 DeletedAt int64 `json:",omitempty"`
@@ -11,8 +11,10 @@ type SysRole struct { @@ -11,8 +11,10 @@ type SysRole struct {
11 CompanyId int64 `json:"companyId"` // 公司ID 11 CompanyId int64 `json:"companyId"` // 公司ID
12 Name string `json:",omitempty"` // 角色名称 12 Name string `json:",omitempty"` // 角色名称
13 Menus []int64 `json:",omitempty"` // 菜单列表 13 Menus []int64 `json:",omitempty"` // 菜单列表
  14 + Apps []int64 `json:",omitempty"` // 应用列表
14 AuthUsers []int64 `json:",omitempty"` // 拥护该角色的用户列表 15 AuthUsers []int64 `json:",omitempty"` // 拥护该角色的用户列表
15 AuthRange int `json:",omitempty"` // 权限范围(1:全部权限 2:部分权限) 16 AuthRange int `json:",omitempty"` // 权限范围(1:全部权限 2:部分权限)
  17 + Remark string `json:",omitempty"` // 备注说明
16 CreatedAt int64 `json:",omitempty"` 18 CreatedAt int64 `json:",omitempty"`
17 UpdatedAt int64 `json:",omitempty"` 19 UpdatedAt int64 `json:",omitempty"`
18 DeletedAt int64 `json:",omitempty"` 20 DeletedAt int64 `json:",omitempty"`
@@ -46,6 +48,18 @@ func (role *SysRole) RemoveUser(userId int64) { @@ -46,6 +48,18 @@ func (role *SysRole) RemoveUser(userId int64) {
46 role.AuthUsers = lo.Without(role.AuthUsers, userId) 48 role.AuthUsers = lo.Without(role.AuthUsers, userId)
47 } 49 }
48 50
  51 +func (role *SysRole) AddAuthRange(auth int) {
  52 + if auth == 0 {
  53 + return
  54 + }
  55 + if !(auth == AuthRangeAllMenu || auth == AuthRangeAllApp) {
  56 + return
  57 + }
  58 + if role.AuthRange&auth == 0 {
  59 + role.AuthRange |= auth
  60 + }
  61 +}
  62 +
49 type SysMenu struct { 63 type SysMenu struct {
50 Id int64 `json:"id,omitempty"` // 菜单ID 64 Id int64 `json:"id,omitempty"` // 菜单ID
51 ParentId int64 `json:"parentId"` // 父级ID 65 ParentId int64 `json:"parentId"` // 父级ID
@@ -60,8 +74,8 @@ type SysMenu struct { @@ -60,8 +74,8 @@ type SysMenu struct {
60 } 74 }
61 75
62 const ( 76 const (
63 - AuthRangeAll = 1 // 全部权限  
64 - AuthRangePart = 2 // 部分权限 77 + AuthRangeAllMenu = 1 // 全部菜单权限
  78 + AuthRangeAllApp = 2 // 全部APP权限
65 ) 79 )
66 80
67 var DefaultMenus []*SysMenu = []*SysMenu{ 81 var DefaultMenus []*SysMenu = []*SysMenu{
  1 +package middleware
  2 +
  3 +import (
  4 + "fmt"
  5 + "github.com/pkg/errors"
  6 + "github.com/zeromicro/go-zero/core/stores/redis"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/tool"
  8 +)
  9 +
  10 +type UserAuthService struct {
  11 + redis *redis.Redis
  12 + appName string
  13 + checkAuth bool
  14 +}
  15 +
  16 +func NewUserAuthService(redis *redis.Redis, appName string) UserAuthService {
  17 + return UserAuthService{
  18 + redis: redis,
  19 + appName: appName,
  20 + }
  21 +}
  22 +
  23 +// Refresh 刷新缓存的User Token
  24 +func (l UserAuthService) Refresh(userId int64, token string) error {
  25 + err := l.redis.Set(l.CacheKey(userId), l.Hash(token))
  26 + if err != nil {
  27 + return err
  28 + }
  29 + return nil
  30 +}
  31 +
  32 +// Compare 比较当前的Token是否已经过期
  33 +func (l UserAuthService) Compare(userId int64, token string) error {
  34 + ok, err := l.redis.Exists(l.CacheKey(userId))
  35 + if err != nil {
  36 + return err
  37 + }
  38 + if !ok {
  39 + return errors.New("Token not exists.") //l.Refresh(userId, token)
  40 + }
  41 + cacheToken, err := l.redis.Get(l.CacheKey(userId))
  42 + if err != nil {
  43 + return err
  44 + }
  45 + if !l.compare(cacheToken, token) {
  46 + return errors.New("Token is expired.")
  47 + }
  48 + return nil
  49 +}
  50 +
  51 +func (l UserAuthService) compare(cacheToken, token string) bool {
  52 + if len(cacheToken) == len(token) && cacheToken == token {
  53 + return true
  54 + }
  55 + if cacheToken == l.Hash(token) {
  56 + return true
  57 + }
  58 + return false
  59 +}
  60 +
  61 +// Hash token哈希编码
  62 +func (l UserAuthService) Hash(token string) string {
  63 + return tool.Md5ByString(token)
  64 +}
  65 +
  66 +func (l UserAuthService) CacheKey(userId int64) string {
  67 + return fmt.Sprintf("%v:cache:%v:id:%v", l.appName, "user.auth", userId)
  68 +}
  1 +package middleware
  2 +
  3 +import (
  4 + "github.com/zeromicro/go-zero/core/mathx"
  5 + "github.com/zeromicro/go-zero/rest/httpx"
  6 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/contextdata"
  7 + "gitlab.fjmaimaimai.com/allied-creation/su-micro/pkg/xerr"
  8 + "net/http"
  9 +)
  10 +
  11 +type LoginStatusCheckMiddleware struct {
  12 + compareFunc func(int64, string) error
  13 + secret string
  14 + proba *mathx.Proba
  15 + kProba float64
  16 +}
  17 +
  18 +// NewLoginStatusCheckMiddleware 登录状态验证,kProba代表验证token的概率,需要小于1,越小校验的概率越低(不需要每次接口调用都验证)
  19 +func NewLoginStatusCheckMiddleware(fn func(int64, string) error, secret string, kProba float64) *LoginStatusCheckMiddleware {
  20 + return &LoginStatusCheckMiddleware{
  21 + compareFunc: fn,
  22 + secret: secret,
  23 + proba: mathx.NewProba(),
  24 + kProba: kProba,
  25 + }
  26 +}
  27 +
  28 +func (m *LoginStatusCheckMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
  29 + return func(w http.ResponseWriter, r *http.Request) {
  30 + if m.compareFunc == nil {
  31 + return
  32 + }
  33 + token := r.Header.Get("Authorization")
  34 + if len(token) < 7 {
  35 + //httpx.ErrorCtx(r.Context(), w, xerr.NewCodeErr(xerr.TokenExpireError, nil))
  36 + httpx.WriteJson(w, http.StatusUnauthorized, xerr.Error(xerr.TokenExpireError, ""))
  37 + return
  38 + }
  39 + token = token[7:]
  40 + if tmpCtx, err := contextdata.ParseToken(r.Context(), m.secret, token); err != nil {
  41 + httpx.WriteJson(w, http.StatusUnauthorized, xerr.Error(xerr.TokenExpireError, ""))
  42 + return
  43 + } else {
  44 + if m.proba.TrueOnProba(m.kProba) {
  45 + userToken := contextdata.GetUserTokenFromCtx(tmpCtx)
  46 + if err = m.compareFunc(userToken.UserId, token); err != nil {
  47 + httpx.WriteJson(w, http.StatusUnauthorized, xerr.Error(xerr.TokenExpireError, err.Error()))
  48 + return
  49 + }
  50 + }
  51 + }
  52 + next(w, r)
  53 + }
  54 +}
@@ -2,20 +2,23 @@ package tool @@ -2,20 +2,23 @@ package tool
2 2
3 import ( 3 import (
4 "crypto/md5" 4 "crypto/md5"
  5 + "encoding/hex"
5 "fmt" 6 "fmt"
6 - "io"  
7 ) 7 )
8 8
9 /** 加密方式 **/ 9 /** 加密方式 **/
10 10
11 func Md5ByString(str string) string { 11 func Md5ByString(str string) string {
12 - m := md5.New()  
13 - _, err := io.WriteString(m, str)  
14 - if err != nil {  
15 - panic(err)  
16 - }  
17 - arr := m.Sum(nil)  
18 - return fmt.Sprintf("%x", arr) 12 + //m := md5.New()
  13 + //_, err := io.WriteString(m, str)
  14 + //if err != nil {
  15 + // panic(err)
  16 + //}
  17 + //arr := m.Sum(nil)
  18 + //return fmt.Sprintf("%x", arr)
  19 +
  20 + sum := md5.Sum([]byte(str))
  21 + return hex.EncodeToString(sum[:])
19 } 22 }
20 23
21 func Md5ByBytes(b []byte) string { 24 func Md5ByBytes(b []byte) string {