diff --git a/api/v1/system/sys_plugins.go b/api/v1/system/sys_plugins.go index f205721..fd8f8ed 100644 --- a/api/v1/system/sys_plugins.go +++ b/api/v1/system/sys_plugins.go @@ -3,9 +3,11 @@ package system import ( "github.com/gogf/gf/v2/frame/g" "github.com/sagoo-cloud/sagooiot/api/v1/common" + + "github.com/sagoo-cloud/sagooiot/internal/model" ) -//GetSysPluginsListReq 获取数据列表 +// GetSysPluginsListReq 获取数据列表 type GetSysPluginsListReq struct { g.Meta `path:"/plugins/list" method:"get" summary:"获取插件列表" tags:"插件管理"` common.PaginationReq @@ -15,7 +17,7 @@ type GetSysPluginsListRes struct { common.PaginationRes } -//GetSysPluginsByIdReq 获取指定ID的数据 +// GetSysPluginsByIdReq 获取指定ID的数据 type GetSysPluginsByIdReq struct { g.Meta `path:"/plugins/get" method:"get" summary:"获取插件" tags:"插件管理"` Id int `json:"id" description:"id" v:"required#id不能为空"` @@ -38,3 +40,11 @@ type EditSysPluginsStatusReq struct { Status int `json:"status" description:"状态,0停用,1启用"` } type EditSysPluginsStatusRes struct{} + +type GetSysPluginsTypesAllReq struct { + g.Meta `path:"/plugins/getTypesAll" method:"get" summary:"获取插件类型" tags:"插件管理"` + Types string `json:"types" description:"功能类型" v:"required#插件类型不能为空 协议(protocol)或者通知(notice)"` +} +type GetSysPluginsTypesAllRes struct { + Data []*model.SysPluginsInfoRes +} diff --git a/internal/consts/consts.go b/internal/consts/consts.go index b2f6383..ad3fdfd 100644 --- a/internal/consts/consts.go +++ b/internal/consts/consts.go @@ -79,3 +79,8 @@ const ( const ( DefaultProtocol = "SagooMqtt" ) + +const ( + TokenAuth = "token_auth" + AKSK = "aksk" +) diff --git a/internal/controller/system/sys_plugins.go b/internal/controller/system/sys_plugins.go index bf28239..547881e 100644 --- a/internal/controller/system/sys_plugins.go +++ b/internal/controller/system/sys_plugins.go @@ -39,3 +39,21 @@ func (a *cMenu) EditSysPluginsStatus(ctx context.Context, req *system.EditSysPlu err = service.SysPlugins().EditStatus(ctx, req.Id, req.Status) return } + +// GetSysPluginsTypesAll 获取插件通信方式类型 +func (u *cSystemSysPlugins) GetSysPluginsTypesAll(ctx context.Context, req *system.GetSysPluginsTypesAllReq) (res *system.GetSysPluginsTypesAllRes, err error) { + out, err := service.SysPlugins().GetSysPluginsTypesAll(ctx, req.Types) + if err != nil { + return + } + var data []*model.SysPluginsInfoRes + if len(out) > 0 { + if err = gconv.Scan(out, &data); err != nil { + return + } + } + res = &system.GetSysPluginsTypesAllRes{ + Data: data, + } + return +} diff --git a/internal/dao/internal/sys_plugins.go b/internal/dao/internal/sys_plugins.go index 7095778..24768d3 100644 --- a/internal/dao/internal/sys_plugins.go +++ b/internal/dao/internal/sys_plugins.go @@ -29,6 +29,7 @@ type SysPluginsColumns struct { Types string // 插件类型 Author string // StartTime string // + IsDeleted string // 是否删除 0未删除 1已删除 } // sysPluginsColumns holds the columns for table sys_plugins. diff --git a/internal/logic/context/context.go b/internal/logic/context/context.go index 7b7daf6..4de8eb3 100644 --- a/internal/logic/context/context.go +++ b/internal/logic/context/context.go @@ -67,3 +67,21 @@ func (s *sContext) GetUserDeptId(ctx context.Context) int { } return 0 } + +// GetChildrenDeptId 获取所有子部门ID +func (s *sContext) GetChildrenDeptId(ctx context.Context) []int { + user := s.GetLoginUser(ctx) + if user != nil { + return user.ChildrenDeptId + } + return nil +} + +// GetRequestWay 获取当前系统请求方式 +func (s *sContext) GetRequestWay(ctx context.Context) string { + user := s.GetLoginUser(ctx) + if user != nil { + return user.RequestWay + } + return "" +} diff --git a/internal/logic/system/sys_authorize.go b/internal/logic/system/sys_authorize.go index 7054ea2..c2e8b86 100644 --- a/internal/logic/system/sys_authorize.go +++ b/internal/logic/system/sys_authorize.go @@ -3,7 +3,9 @@ package system import ( "context" "encoding/json" + "github.com/gogf/gf/v2/container/gset" "github.com/gogf/gf/v2/container/gvar" + "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/os/gcache" @@ -604,3 +606,149 @@ func (s *sSysAuthorize) InitAuthorize(ctx context.Context) (err error) { } return } + +// FilterDataByPermissions 根据数据权限过滤数据 +func (s *sSysAuthorize) FilterDataByPermissions(ctx context.Context, model *gdb.Model) (*gdb.Model, error) { + where, err := service.SysAuthorize().GetDataWhere(ctx) + if err != nil { + return model, err + } + if where != nil && len(where) > 0 { + return model.Where(where), err + } + return model, err +} + +// GetDataWhere 获取数据权限条件查询 +func (s *sSysAuthorize) GetDataWhere(ctx context.Context) (where g.Map, err error) { + //判断请求方式 + requestWay := service.Context().GetRequestWay(ctx) + if strings.EqualFold(requestWay, consts.TokenAuth) { + loginUserId := service.Context().GetUserId(ctx) + loginUserDeptId := service.Context().GetUserDeptId(ctx) + //1、获取当前用户所属角色 + userRoleInfo, userRoleErr := service.SysUserRole().GetInfoByUserId(ctx, loginUserId) + if userRoleErr != nil { + err = gerror.New("获取用户角色失败") + return + } + if userRoleInfo == nil { + err = gerror.New("用户无权限访问") + return + } + //判断用户是否为超级管理员 + var isSuperAdmin = false + var roleIds []int + for _, userRole := range userRoleInfo { + if userRole.RoleId == 1 { + isSuperAdmin = true + } + roleIds = append(roleIds, userRole.RoleId) + } + if isSuperAdmin { + //超级管理员可以访问所有的数据 + return + } + //不是超级管理员则获取所有角色信息 + var roleInfo []*entity.SysRole + err = dao.SysRole.Ctx(ctx).WhereIn(dao.SysRole.Columns().Id, roleIds).Where(g.Map{ + dao.SysRole.Columns().Status: 1, + dao.SysRole.Columns().IsDeleted: 0, + }).Scan(&roleInfo) + if err != nil { + err = gerror.New("获取用户角色失败") + return + } + //2获取角色对应数据权限 + deptIdArr := gset.New() + for _, role := range roleInfo { + switch role.DataScope { + case 1: //全部数据权限 + return + case 2: //自定数据权限 + //获取角色所有的部门信息 + roleDeptInfo, _ := service.SysRoleDept().GetInfoByRoleId(ctx, int(role.Id)) + if roleDeptInfo == nil { + err = gerror.New(role.Name + "自定义数据范围,请先配置部门!") + return + } + var deptIds []int64 + for _, roleDept := range roleDeptInfo { + deptIds = append(deptIds, roleDept.DeptId) + } + deptIdArr.Add(gconv.Interfaces(deptIds)...) + case 3: //本部门数据权限 + deptIdArr.Add(gconv.Int64(loginUserDeptId)) + case 4: //本部门及以下数据权限 + deptIdArr.Add(gconv.Int64(loginUserDeptId)) + //获取所有部门 + var deptInfo []*entity.SysDept + m := dao.SysDept.Ctx(ctx) + _ = m.Where(g.Map{ + dao.SysDept.Columns().Status: 1, + dao.SysDept.Columns().IsDeleted: 0, + }).Scan(&deptInfo) + + if deptInfo != nil { + //获取当前部门所有的下级部门信息 + childrenDeptInfo := GetNextDeptInfoByNowDeptId(int64(loginUserDeptId), deptInfo) + if childrenDeptInfo != nil { + allChildrenDeptInfo := GetAllNextDeptInfoByChildrenDept(childrenDeptInfo, deptInfo, childrenDeptInfo) + if allChildrenDeptInfo != nil { + for _, allChildrenDept := range allChildrenDeptInfo { + deptIdArr.Add(gconv.Int64(allChildrenDept.DeptId)) + } + } + } + } + case 5: //仅限于自己的数据 + where = g.Map{"created_by": loginUserId} + return + } + } + //此添加是为了兼容以前的数据 + deptIdArr.Add(0) + if deptIdArr.Size() > 0 { + where = g.Map{"dept_id": deptIdArr.Slice()} + } + } else if strings.EqualFold(requestWay, consts.AKSK) { + //判断是父级部门还是子部门 + deptIdArr := gset.New() + parentDeptId := service.Context().GetUserDeptId(ctx) + if parentDeptId != 0 { + deptIdArr.Add(gconv.Int64(parentDeptId)) + //获取所有部门 + var deptInfo []*entity.SysDept + m := dao.SysDept.Ctx(ctx) + _ = m.Where(g.Map{ + dao.SysDept.Columns().Status: 1, + dao.SysDept.Columns().IsDeleted: 0, + }).Scan(&deptInfo) + if deptInfo != nil { + //获取当前部门所有的下级部门信息 + childrenDeptInfo := GetNextDeptInfoByNowDeptId(int64(parentDeptId), deptInfo) + if childrenDeptInfo != nil { + allChildrenDeptInfo := GetAllNextDeptInfoByChildrenDept(childrenDeptInfo, deptInfo, childrenDeptInfo) + if allChildrenDeptInfo != nil { + for _, allChildrenDept := range allChildrenDeptInfo { + deptIdArr.Add(gconv.Int64(allChildrenDept.DeptId)) + } + } + } + } + } else { + //获取传过来的子部门ID + childrenDeptIds := service.Context().GetChildrenDeptId(ctx) + for _, childrenDeptId := range childrenDeptIds { + deptIdArr.Add(gconv.Int64(childrenDeptId)) + } + } + //此添加是为了兼容以前的数据 + deptIdArr.Add(0) + if deptIdArr.Size() > 0 { + where = g.Map{"dept_id": deptIdArr.Slice()} + } + } + + return +} diff --git a/internal/logic/system/sys_plugins.go b/internal/logic/system/sys_plugins.go index 2c77fc7..59955fe 100644 --- a/internal/logic/system/sys_plugins.go +++ b/internal/logic/system/sys_plugins.go @@ -7,6 +7,7 @@ import ( "github.com/sagoo-cloud/sagooiot/internal/consts" "github.com/sagoo-cloud/sagooiot/internal/dao" "github.com/sagoo-cloud/sagooiot/internal/model" + "github.com/sagoo-cloud/sagooiot/internal/model/entity" "github.com/sagoo-cloud/sagooiot/internal/service" ) @@ -71,7 +72,7 @@ func (s *sSysPlugins) DeleteSysPlugins(ctx context.Context, Ids []int) (err erro return } -//SaveSysPlugins 存入插件数据,跟据插件类型与名称,数据中只保存一份 +// SaveSysPlugins 存入插件数据,跟据插件类型与名称,数据中只保存一份 func (s *sSysPlugins) SaveSysPlugins(ctx context.Context, in model.SysPluginsAddInput) (err error) { var req = g.Map{ dao.SysPlugins.Columns().Types: in.Types, @@ -97,3 +98,32 @@ func (s *sSysPlugins) EditStatus(ctx context.Context, id int, status int) (err e _, err = dao.SysPlugins.Ctx(ctx).Data("status", status).Where(dao.SysPlugins.Columns().Id, id).Update() return } + +// GetSysPluginsTypesAll 获取所有插件的通信方式类型 +func (s *sSysPlugins) GetSysPluginsTypesAll(ctx context.Context, types string) (out []*model.SysPluginsInfoOut, err error) { + m := dao.SysPlugins.Ctx(ctx) + + m = m.Where(g.Map{ + dao.SysPlugins.Columns().Status: 1, + dao.SysPlugins.Columns().IsDeleted: 0, + }).WhereIn(dao.SysPlugins.Columns().Types, types) + + //根据数据权限过滤数据 + m, _ = service.SysAuthorize().FilterDataByPermissions(ctx, m) + + //获取当前登录用户ID + var plugins []*entity.SysPlugins + err = m.Scan(&plugins) + if err != nil { + return + } + for _, plugin := range plugins { + var sysPlugins = new(model.SysPluginsInfoOut) + sysPlugins.Types = plugin.Types + sysPlugins.HandleType = plugin.HandleType + sysPlugins.Name = plugin.Name + sysPlugins.Title = plugin.Title + out = append(out, sysPlugins) + } + return +} diff --git a/internal/model/context.go b/internal/model/context.go index f06433d..2ebe96c 100644 --- a/internal/model/context.go +++ b/internal/model/context.go @@ -14,10 +14,12 @@ type Context struct { // ContextUser 请求上下文中的用户信息 type ContextUser struct { - Id int // 用户ID - Passport string // 用户账号 - Nickname string // 用户名称 - Avatar string // 用户 - IsAdmin bool // 是否是管理员 - DeptId int // 部门ID + Id int // 用户ID + Passport string // 用户账号 + Nickname string // 用户名称 + Avatar string // 用户 + IsAdmin bool // 是否是管理员 + DeptId int // 部门ID + RequestWay string // 请求方式 + ChildrenDeptId []int //子部门ID } diff --git a/internal/model/entity/sys_plugins.go b/internal/model/entity/sys_plugins.go index 82e904d..dc65205 100644 --- a/internal/model/entity/sys_plugins.go +++ b/internal/model/entity/sys_plugins.go @@ -12,6 +12,7 @@ import ( type SysPlugins struct { Id int `json:"id" description:"ID"` Name string `json:"name" description:"名称"` + HandleType string `json:"handleType" description:"功能类型"` Title string `json:"title" description:"标题"` Intro string `json:"intro" description:"介绍"` Version string `json:"version" description:"版本"` diff --git a/internal/model/sys_plugins.go b/internal/model/sys_plugins.go index 4a12165..a9facea 100644 --- a/internal/model/sys_plugins.go +++ b/internal/model/sys_plugins.go @@ -29,3 +29,17 @@ type SysPluginsEditInput struct { Id int `json:"id" description:"ID"` SysPluginsAddInput } + +type SysPluginsInfoRes struct { + Types string `json:"types" description:"插件与SagooIOT的通信方式"` + HandleType string `json:"handleType" description:"功能类型"` + Name string `json:"name" description:"名称"` + Title string `json:"title" description:"标题"` +} + +type SysPluginsInfoOut struct { + Types string `json:"types" description:"插件与SagooIOT的通信方式"` + HandleType string `json:"handleType" description:"功能类型"` + Name string `json:"name" description:"名称"` + Title string `json:"title" description:"标题"` +} diff --git a/internal/service/context.go b/internal/service/context.go index d369bc1..ecd9fd2 100644 --- a/internal/service/context.go +++ b/internal/service/context.go @@ -18,9 +18,13 @@ type IContext interface { GetLoginUser(ctx context.Context) *model.ContextUser GetUserId(ctx context.Context) int GetUserDeptId(ctx context.Context) int + GetChildrenDeptId(ctx context.Context) []int + GetRequestWay(ctx context.Context) string } -var localContext IContext +var ( + localContext IContext +) func Context() IContext { if localContext == nil { diff --git a/internal/service/system.go b/internal/service/system.go index 0a33660..1c71df4 100644 --- a/internal/service/system.go +++ b/internal/service/system.go @@ -7,6 +7,7 @@ package service import ( "context" + "github.com/gogf/gf/v2/database/gdb" "github.com/sagoo-cloud/sagooiot/api/v1/system" "github.com/sagoo-cloud/sagooiot/internal/model" "github.com/sagoo-cloud/sagooiot/internal/model/entity" @@ -88,6 +89,7 @@ type ( DeleteSysPlugins(ctx context.Context, Ids []int) (err error) SaveSysPlugins(ctx context.Context, in model.SysPluginsAddInput) (err error) EditStatus(ctx context.Context, id int, status int) (err error) + GetSysPluginsTypesAll(ctx context.Context, types string) (out []*model.SysPluginsInfoOut, err error) } ISysApi interface { GetInfoByIds(ctx context.Context, ids []int) (data []*entity.SysApi, err error) @@ -176,6 +178,8 @@ type ( AddAuthorize(ctx context.Context, roleId int, menuIds []string, buttonIds []string, columnIds []string, apiIds []string) (err error) IsAllowAuthorize(ctx context.Context, roleId int) (isAllow bool, err error) InitAuthorize(ctx context.Context) (err error) + FilterDataByPermissions(ctx context.Context, model *gdb.Model) (*gdb.Model, error) + GetDataWhere(ctx context.Context) (where g.Map, err error) } ISysUserPost interface { GetInfoByUserId(ctx context.Context, userId int) (data []*entity.SysUserPost, err error)