add: multi-tenant
This commit is contained in:
@@ -208,7 +208,7 @@ func (r *RepoUdmSubUser) ClearAndInsert(neID string, subArr []model.UdmSubUser)
|
||||
batch := subArr[i:end]
|
||||
|
||||
// multi-tenancy
|
||||
r.SetTenantName(batch)
|
||||
r.SetTenantName(&batch)
|
||||
|
||||
// 调用 InsertMulti 函数将批量数据插入数据库
|
||||
results, err := datasource.DefaultDB().Table("u_sub_user").InsertMulti(batch)
|
||||
@@ -253,7 +253,7 @@ func (r *RepoUdmSubUser) Inserts(subUser []model.UdmSubUser) int64 {
|
||||
batch := subUser[i:end]
|
||||
|
||||
// multi-tenancy
|
||||
r.SetTenantName(batch)
|
||||
r.SetTenantName(&batch)
|
||||
|
||||
// 调用 InsertMulti 函数将批量数据插入数据库
|
||||
results, err := datasource.DefaultDB().Table("u_sub_user").InsertMulti(batch)
|
||||
@@ -285,7 +285,7 @@ func (r *RepoUdmSubUser) Insert4G(neID string, subUser model.UdmSubUser) int64 {
|
||||
|
||||
// multi-tenancy
|
||||
subUserSlice := []model.UdmSubUser{subUser}
|
||||
r.SetTenantName(subUserSlice)
|
||||
r.SetTenantName(&subUserSlice)
|
||||
|
||||
results, err := datasource.DefaultDB().Table("u_sub_user").Insert(subUser)
|
||||
if err == nil {
|
||||
@@ -475,15 +475,18 @@ func (r *RepoUdmSubUser) Deletes(neID, imsi, num string) int64 {
|
||||
}
|
||||
|
||||
// multi-tenancy solution, get tenant_name by imsi
|
||||
func (r *RepoUdmSubUser) SetTenantName(subArr []model.UdmSubUser) {
|
||||
for s := 0; s < len(subArr); s++ {
|
||||
func (r *RepoUdmSubUser) SetTenantName(subArr *[]model.UdmSubUser) {
|
||||
for s := 0; s < len(*subArr); s++ {
|
||||
var tenantName string
|
||||
err := datasource.DefaultDB().Table("sys_tenant_map").
|
||||
Where("mapping_type='udm_sub' and mapping_key='?'", subArr[s].Imsi).Cols("tenant_name").Find(tenantName)
|
||||
Where("mapping_type='udm_sub' and mapping_key='?'", (*subArr)[s].Imsi).Cols("tenant_name").Find(tenantName)
|
||||
if err != nil {
|
||||
log.Errorf("Find tenant_name err => %v", err)
|
||||
continue
|
||||
}
|
||||
subArr[s].TenantName = tenantName
|
||||
if tenantName != "" {
|
||||
log.Infof("tenantName=%s imsi=%s", tenantName, (*subArr)[s].Imsi)
|
||||
}
|
||||
(*subArr)[s].TenantName = tenantName
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,3 +49,21 @@ func SysDeptTreeSelect(sysDept systemModel.SysDept) TreeSelect {
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
// SysDeptTreeSelect 使用给定的 SysDept 对象解析为 TreeSelect 对象
|
||||
func SysTenantTreeSelect(sysTenant systemModel.SysTenant) TreeSelect {
|
||||
t := TreeSelect{}
|
||||
t.ID = sysTenant.TenantID
|
||||
t.Label = sysTenant.TenantName
|
||||
|
||||
if len(sysTenant.Children) > 0 {
|
||||
for _, tenant := range sysTenant.Children {
|
||||
child := SysTenantTreeSelect(tenant)
|
||||
t.Children = append(t.Children, child)
|
||||
}
|
||||
} else {
|
||||
t.Children = []TreeSelect{}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -40,7 +41,7 @@ var NewUDMSubImpl = &UDMSubImpl{
|
||||
"context_id": "ContextId",
|
||||
"apn_context": "ApnContext",
|
||||
"static_ip": "StaticIp",
|
||||
"tenant_name": "TenantName", // Tenant ID for multi-tenancy
|
||||
"tenant_name": "TenantName", // Tenant name for multi-tenancy
|
||||
},
|
||||
}
|
||||
|
||||
@@ -97,8 +98,9 @@ func (r *UDMSubImpl) SelectPage(query map[string]any) map[string]any {
|
||||
}
|
||||
// for multi-tenancy solution
|
||||
if v, ok := query["tenantName"]; ok && v != "" {
|
||||
conditions = append(conditions, "tenant_name = '?'")
|
||||
conditions = append(conditions, "tenant_name = ?")
|
||||
params = append(params, v)
|
||||
fmt.Printf("tenantName = %s", v)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
|
||||
381
src/modules/system/controller/sys_tenant.go
Normal file
381
src/modules/system/controller/sys_tenant.go
Normal file
@@ -0,0 +1,381 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/constants/common"
|
||||
"be.ems/src/framework/i18n"
|
||||
"be.ems/src/framework/utils/ctx"
|
||||
"be.ems/src/framework/vo"
|
||||
"be.ems/src/framework/vo/result"
|
||||
"be.ems/src/modules/system/model"
|
||||
"be.ems/src/modules/system/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gin-gonic/gin/binding"
|
||||
)
|
||||
|
||||
// 实例化控制层 SysTenantController 结构体
|
||||
var NewSysTenant = &SysTenantController{
|
||||
sysTenantService: service.NewSysTenantImpl,
|
||||
}
|
||||
|
||||
// 租户信息
|
||||
//
|
||||
// PATH /system/tenant
|
||||
type SysTenantController struct {
|
||||
// 租户服务
|
||||
sysTenantService service.ISysTenant
|
||||
}
|
||||
|
||||
// 租户列表
|
||||
//
|
||||
// GET /list
|
||||
func (s *SysTenantController) List(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
// 租户ID
|
||||
TenantID string `form:"tenantId"`
|
||||
// 父租户ID
|
||||
ParentID string `form:"parentId" `
|
||||
// 租户名称
|
||||
TenantName string `form:"tenantName" `
|
||||
// 租户状态(0正常 1停用)
|
||||
Status string `form:"status"`
|
||||
}
|
||||
err := c.ShouldBindQuery(&querys)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 多语言值转key查询
|
||||
if querys.TenantName != "" {
|
||||
querys.TenantName = i18n.TFindKeyPrefix(language, "tenant", querys.TenantName)
|
||||
}
|
||||
|
||||
SysTenantController := model.SysTenant{
|
||||
TenantID: querys.TenantID,
|
||||
ParentID: querys.ParentID,
|
||||
TenantName: querys.TenantName,
|
||||
Status: querys.Status,
|
||||
}
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysTenantService.SelectTenantList(SysTenantController, dataScopeSQL)
|
||||
|
||||
// 闭包函数处理多语言
|
||||
converI18n := func(language string, arr *[]model.SysTenant) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].TenantName = i18n.TKey(language, (*arr)[i].TenantName)
|
||||
}
|
||||
}
|
||||
converI18n(language, &data)
|
||||
|
||||
c.JSON(200, result.OkData(data))
|
||||
}
|
||||
|
||||
// 租户信息
|
||||
//
|
||||
// GET /:tenantId
|
||||
func (s *SysTenantController) Info(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
tenantId := c.Param("tenantId")
|
||||
if tenantId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
data := s.sysTenantService.SelectTenantById(tenantId)
|
||||
if data.TenantID == tenantId {
|
||||
// 处理多语言
|
||||
data.TenantName = i18n.TKey(language, data.TenantName)
|
||||
c.JSON(200, result.OkData(data))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 租户新增
|
||||
//
|
||||
// POST /
|
||||
func (s *SysTenantController) Add(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.SysTenant
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.TenantID != "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
tenantParent := s.sysTenantService.SelectTenantById(body.ParentID)
|
||||
if tenantParent.TenantID != body.ParentID {
|
||||
// 没有可访问租户数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "tenant.noData")))
|
||||
return
|
||||
}
|
||||
if tenantParent.Status == common.STATUS_NO {
|
||||
// 上级租户【%s】停用,不允许新增
|
||||
msg := i18n.TTemplate(language, "tenant.errParentStatus", map[string]any{"name": tenantParent.TenantName})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
if tenantParent.DelFlag == common.STATUS_YES {
|
||||
// 上级租户【%s】已删除,不允许新增
|
||||
msg := i18n.TTemplate(language, "tenant.errParentDelFlag", map[string]any{"name": tenantParent.TenantName})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
body.Ancestors = tenantParent.Ancestors + "," + body.ParentID
|
||||
} else {
|
||||
body.Ancestors = "0"
|
||||
}
|
||||
|
||||
// 检查同级下名称唯一
|
||||
uniqueTenantName := s.sysTenantService.CheckUniqueTenantName(body.TenantName, body.ParentID, "")
|
||||
if !uniqueTenantName {
|
||||
// 租户新增【%s】失败,租户名称已存在
|
||||
msg := i18n.TTemplate(language, "tenant.errNameExists", map[string]any{"name": body.TenantName})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
body.CreateBy = ctx.LoginUserToUserName(c)
|
||||
insertId := s.sysTenantService.InsertTenant(body)
|
||||
if insertId != "" {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 租户修改
|
||||
//
|
||||
// PUT /
|
||||
func (s *SysTenantController) Edit(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var body model.SysTenant
|
||||
err := c.ShouldBindBodyWith(&body, binding.JSON)
|
||||
if err != nil || body.TenantID == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级租户不能选自己
|
||||
if body.TenantID == body.ParentID {
|
||||
// 租户修改【%s】失败,上级租户不能是自己
|
||||
msg := i18n.TTemplate(language, "tenant.errParentID", map[string]any{"name": body.TenantName})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
tenantInfo := s.sysTenantService.SelectTenantById(body.TenantID)
|
||||
if tenantInfo.TenantID != body.TenantID {
|
||||
// 没有可访问租户数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "tenant.noData")))
|
||||
return
|
||||
}
|
||||
// 父级ID不为0是要检查
|
||||
if body.ParentID != "0" {
|
||||
tenantParent := s.sysTenantService.SelectTenantById(body.ParentID)
|
||||
if tenantParent.TenantID != body.ParentID {
|
||||
// 没有可访问租户数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "tenant.noData")))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 检查同级下名称唯一
|
||||
uniqueTenantName := s.sysTenantService.CheckUniqueTenantName(body.TenantName, body.ParentID, body.TenantID)
|
||||
if !uniqueTenantName {
|
||||
// 租户修改【%s】失败,租户名称已存在
|
||||
msg := i18n.TTemplate(language, "tenant.errNameExists", map[string]any{"name": body.TenantName})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 上级停用需要检查下级是否有在使用
|
||||
if body.Status == common.STATUS_NO {
|
||||
hasChild := s.sysTenantService.HasChildByTenantId(body.TenantID)
|
||||
if hasChild > 0 {
|
||||
// 该租户包含未停用的子租户数量:%d
|
||||
msg := i18n.TTemplate(language, "tenant.errHasChildUse", map[string]any{"num": hasChild})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// 多语言非原始值
|
||||
i18nValue := i18n.TKey(language, tenantInfo.TenantName)
|
||||
if i18nValue != tenantInfo.TenantName {
|
||||
i18n.UpdateKeyValue(language, tenantInfo.TenantName, body.TenantName)
|
||||
body.TenantName = tenantInfo.TenantName
|
||||
}
|
||||
|
||||
body.UpdateBy = ctx.LoginUserToUserName(c)
|
||||
rows := s.sysTenantService.UpdateTenant(body)
|
||||
if rows > 0 {
|
||||
c.JSON(200, result.Ok(nil))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 租户删除
|
||||
//
|
||||
// DELETE /:tenantId
|
||||
func (s *SysTenantController) Remove(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
tenantId := c.Param("tenantId")
|
||||
if tenantId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查数据是否存在
|
||||
tenant := s.sysTenantService.SelectTenantById(tenantId)
|
||||
if tenant.TenantID != tenantId {
|
||||
// 没有可访问租户数据!
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "tenant.noData")))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否存在子租户
|
||||
hasChild := s.sysTenantService.HasChildByTenantId(tenantId)
|
||||
if hasChild > 0 {
|
||||
// 不允许删除,存在子租户数:%d
|
||||
msg := i18n.TTemplate(language, "tenant.errHasChildUse", map[string]any{"num": hasChild})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
// 检查是否分配给用户
|
||||
existUser := s.sysTenantService.CheckTenantExistUser(tenantId)
|
||||
if existUser > 0 {
|
||||
// 不允许删除,租户已分配给用户数:%d
|
||||
msg := i18n.TTemplate(language, "tenant.errHasUserUse", map[string]any{"num": existUser})
|
||||
c.JSON(200, result.ErrMsg(msg))
|
||||
return
|
||||
}
|
||||
|
||||
rows := s.sysTenantService.DeleteTenantById(tenantId)
|
||||
if rows > 0 {
|
||||
// 删除成功:%d
|
||||
msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows})
|
||||
c.JSON(200, result.OkMsg(msg))
|
||||
return
|
||||
}
|
||||
c.JSON(200, result.Err(nil))
|
||||
}
|
||||
|
||||
// 租户列表(排除节点)
|
||||
//
|
||||
// GET /list/exclude/:tenantId
|
||||
func (s *SysTenantController) ExcludeChild(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
tenantId := c.Param("tenantId")
|
||||
if tenantId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
data := s.sysTenantService.SelectTenantList(model.SysTenant{}, dataScopeSQL)
|
||||
|
||||
// 过滤排除节点
|
||||
filtered := make([]model.SysTenant, 0)
|
||||
for _, tenant := range data {
|
||||
hasAncestor := false
|
||||
ancestorList := strings.Split(tenant.Ancestors, ",")
|
||||
for _, ancestor := range ancestorList {
|
||||
if ancestor == tenantId {
|
||||
hasAncestor = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !(tenant.TenantID == tenantId || hasAncestor) {
|
||||
tenant.TenantName = i18n.TKey(language, tenant.TenantName)
|
||||
filtered = append(filtered, tenant)
|
||||
}
|
||||
}
|
||||
c.JSON(200, result.OkData(filtered))
|
||||
}
|
||||
|
||||
// 租户树结构列表
|
||||
//
|
||||
// GET /treeSelect
|
||||
func (s *SysTenantController) TreeSelect(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
// 租户ID
|
||||
TenantID string `json:"tenantId"`
|
||||
// 父租户ID
|
||||
ParentID string `json:"parentId" `
|
||||
// 租户名称
|
||||
TenantName string `json:"tenantName" `
|
||||
// 租户状态(0正常 1停用)
|
||||
Status string `json:"status"`
|
||||
}
|
||||
err := c.ShouldBindQuery(&querys)
|
||||
if err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
SysTenantController := model.SysTenant{
|
||||
TenantID: querys.TenantID,
|
||||
ParentID: querys.ParentID,
|
||||
TenantName: querys.TenantName,
|
||||
Status: querys.Status,
|
||||
}
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
tenantTreeSelect := s.sysTenantService.SelectTenantTreeSelect(SysTenantController, dataScopeSQL)
|
||||
|
||||
// 闭包函数处理多语言
|
||||
var converI18n func(language string, arr *[]vo.TreeSelect)
|
||||
converI18n = func(language string, arr *[]vo.TreeSelect) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label)
|
||||
if len((*arr)[i].Children) > 0 {
|
||||
converI18n(language, &(*arr)[i].Children)
|
||||
}
|
||||
}
|
||||
}
|
||||
converI18n(language, &tenantTreeSelect)
|
||||
|
||||
c.JSON(200, result.OkData(tenantTreeSelect))
|
||||
}
|
||||
|
||||
// 租户树结构列表(指定角色)
|
||||
//
|
||||
// GET /roleTenantTreeSelect/:roleId
|
||||
func (s *SysTenantController) RoleTenantTreeSelect(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
roleId := c.Param("roleId")
|
||||
if roleId == "" {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
}
|
||||
|
||||
dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "")
|
||||
tenantTreeSelect := s.sysTenantService.SelectTenantTreeSelect(model.SysTenant{}, dataScopeSQL)
|
||||
checkedKeys := s.sysTenantService.SelectTenantListByRoleId(roleId)
|
||||
|
||||
// 闭包函数处理多语言
|
||||
var converI18n func(language string, arr *[]vo.TreeSelect)
|
||||
converI18n = func(language string, arr *[]vo.TreeSelect) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].Label = i18n.TKey(language, (*arr)[i].Label)
|
||||
if len((*arr)[i].Children) > 0 {
|
||||
converI18n(language, &(*arr)[i].Children)
|
||||
}
|
||||
}
|
||||
}
|
||||
converI18n(language, &tenantTreeSelect)
|
||||
|
||||
c.JSON(200, result.OkData(map[string]any{
|
||||
"tenants": tenantTreeSelect,
|
||||
"checkedKeys": checkedKeys,
|
||||
}))
|
||||
}
|
||||
@@ -16,6 +16,8 @@ type SysRole struct {
|
||||
MenuCheckStrictly string `json:"menuCheckStrictly"`
|
||||
// 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示)
|
||||
DeptCheckStrictly string `json:"deptCheckStrictly"`
|
||||
// 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示)
|
||||
TenantCheckStrictly string `json:"tenantCheckStrictly"`
|
||||
// 角色状态(0停用 1正常)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
@@ -37,4 +39,6 @@ type SysRole struct {
|
||||
MenuIds []string `json:"menuIds,omitempty"`
|
||||
// 部门组(数据权限)
|
||||
DeptIds []string `json:"deptIds,omitempty"`
|
||||
// 租户权限
|
||||
TenantIds []string `json:"tenantIds,omitempty"`
|
||||
}
|
||||
|
||||
15
src/modules/system/model/sys_role_tenant.go
Normal file
15
src/modules/system/model/sys_role_tenant.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package model
|
||||
|
||||
// SysRoleDept 角色和部门关联对象 sys_role_dept
|
||||
type SysRoleTenant struct {
|
||||
RoleID string `json:"roleId"` // 角色ID
|
||||
TenantID string `json:"TenantID"` // 部门ID
|
||||
}
|
||||
|
||||
// NewSysRoleDept 创建角色和部门关联对象的构造函数
|
||||
func NewSysRoleTenant(roleID string, tenantID string) SysRoleTenant {
|
||||
return SysRoleTenant{
|
||||
RoleID: roleID,
|
||||
TenantID: tenantID,
|
||||
}
|
||||
}
|
||||
39
src/modules/system/model/sys_tenant.go
Normal file
39
src/modules/system/model/sys_tenant.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
// SysTenant 部门对象 sys_Tenant
|
||||
type SysTenant struct {
|
||||
// 部门ID
|
||||
TenantID string `json:"TenantId"`
|
||||
// 父部门ID
|
||||
ParentID string `json:"parentId" binding:"required"`
|
||||
// 祖级列表
|
||||
Ancestors string `json:"ancestors"`
|
||||
// 部门名称
|
||||
TenantName string `json:"TenantName" binding:"required"`
|
||||
// 显示顺序
|
||||
OrderNum int `json:"orderNum"`
|
||||
// tenancy type: sd-sst, apn, imsi, msisdn
|
||||
Type string `json:"type"`
|
||||
// tenancy key: key of sd-sst, apn, imsi, msisdn
|
||||
Key string `json:"key"`
|
||||
// 部门状态(0正常 1停用)
|
||||
Status string `json:"status"`
|
||||
// 删除标志(0代表存在 1代表删除)
|
||||
DelFlag string `json:"delFlag"`
|
||||
// 创建者
|
||||
CreateBy string `json:"createBy"`
|
||||
// 创建时间
|
||||
CreateTime int64 `json:"createTime"`
|
||||
// 更新者
|
||||
UpdateBy string `json:"updateBy"`
|
||||
// 更新时间
|
||||
UpdateTime int64 `json:"updateTime"`
|
||||
|
||||
// ====== 非数据库字段属性 ======
|
||||
|
||||
// 子部门列表
|
||||
Children []SysTenant `json:"children,omitempty"`
|
||||
|
||||
// 父部门名称
|
||||
ParentName string `json:"parentName,omitempty"`
|
||||
}
|
||||
15
src/modules/system/repository/sys_role_tenant.go
Normal file
15
src/modules/system/repository/sys_role_tenant.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package repository
|
||||
|
||||
import "be.ems/src/modules/system/model"
|
||||
|
||||
// ISysRoleTenant 角色与部门关联表 数据层接口
|
||||
type ISysRoleTenant interface {
|
||||
// DeleteRoleTenant 批量删除角色部门关联信息
|
||||
DeleteRoleTenant(roleIds []string) int64
|
||||
|
||||
// DeleteTenantRole 批量删除部门角色关联信息
|
||||
DeleteTenantRole(tenantIds []string) int64
|
||||
|
||||
// BatchRoleTenant 批量新增角色部门信息
|
||||
BatchRoleTenant(sysRoleTenants []model.SysRoleTenant) int64
|
||||
}
|
||||
58
src/modules/system/repository/sys_role_tenant.impl.go
Normal file
58
src/modules/system/repository/sys_role_tenant.impl.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/datasource"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/repo"
|
||||
"be.ems/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysRoleTenantImpl 结构体
|
||||
var NewSysRoleTenantImpl = &SysRoleTenantImpl{}
|
||||
|
||||
// SysRoleTenantImpl 角色与部门关联表 数据层处理
|
||||
type SysRoleTenantImpl struct{}
|
||||
|
||||
// DeleteRoleTenant 批量删除角色部门关联信息
|
||||
func (r *SysRoleTenantImpl) DeleteRoleTenant(roleIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(roleIds))
|
||||
sql := "delete from sys_role_tenant where role_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(roleIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteTenantRole 批量删除部门角色关联信息
|
||||
func (r *SysRoleTenantImpl) DeleteTenantRole(tenantIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(tenantIds))
|
||||
sql := "delete from sys_role_tenant where tenant_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(tenantIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// BatchRoleTenant 批量新增角色部门信息
|
||||
func (r *SysRoleTenantImpl) BatchRoleTenant(sysRoleTenants []model.SysRoleTenant) int64 {
|
||||
keyValues := make([]string, 0)
|
||||
for _, item := range sysRoleTenants {
|
||||
keyValues = append(keyValues, fmt.Sprintf("(%s,%s)", item.RoleID, item.TenantID))
|
||||
}
|
||||
sql := "insert into sys_role_tenant(role_id, tenant_id) values " + strings.Join(keyValues, ",")
|
||||
results, err := datasource.ExecDB("", sql, nil)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
42
src/modules/system/repository/sys_tenant.go
Normal file
42
src/modules/system/repository/sys_tenant.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package repository
|
||||
|
||||
import "be.ems/src/modules/system/model"
|
||||
|
||||
// ISysTenant 租户表 数据层接口
|
||||
type ISysTenant interface {
|
||||
// SelectTenantList 查询租户管理数据
|
||||
SelectTenantList(sysTenant model.SysTenant, dataScopeSQL string) []model.SysTenant
|
||||
|
||||
// SelectTenantListByRoleId 根据角色ID查询租户树信息
|
||||
SelectTenantListByRoleId(roleId string, tenantCheckStrictly bool) []string
|
||||
|
||||
// SelectTenantById 根据租户ID查询信息
|
||||
SelectTenantById(tenantId string) model.SysTenant
|
||||
|
||||
// SelectChildrenTenantById 根据ID查询所有子租户
|
||||
SelectChildrenTenantById(tenantId string) []model.SysTenant
|
||||
|
||||
// HasChildByTenantId 是否存在子节点
|
||||
HasChildByTenantId(tenantId string) int64
|
||||
|
||||
// CheckTenantExistUser 查询租户是否存在用户
|
||||
CheckTenantExistUser(tenantId string) int64
|
||||
|
||||
// CheckUniqueTenant 校验租户是否唯一
|
||||
CheckUniqueTenant(sysTenant model.SysTenant) string
|
||||
|
||||
// InsertTenant 新增租户信息
|
||||
InsertTenant(sysTenant model.SysTenant) string
|
||||
|
||||
// UpdateTenant 修改租户信息
|
||||
UpdateTenant(sysTenant model.SysTenant) int64
|
||||
|
||||
// UpdateTenantStatusNormal 修改所在租户正常状态
|
||||
UpdateTenantStatusNormal(tenantIds []string) int64
|
||||
|
||||
// UpdateTenantChildren 修改子元素关系
|
||||
UpdateTenantChildren(sysTenants []model.SysTenant) int64
|
||||
|
||||
// DeleteTenantById 删除租户管理信息
|
||||
DeleteTenantById(tenantId string) int64
|
||||
}
|
||||
386
src/modules/system/repository/sys_tenant.impl.go
Normal file
386
src/modules/system/repository/sys_tenant.impl.go
Normal file
@@ -0,0 +1,386 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"be.ems/src/framework/datasource"
|
||||
"be.ems/src/framework/logger"
|
||||
"be.ems/src/framework/utils/parse"
|
||||
"be.ems/src/framework/utils/repo"
|
||||
"be.ems/src/modules/system/model"
|
||||
)
|
||||
|
||||
// 实例化数据层 SysTenantImpl 结构体
|
||||
var NewSysTenantImpl = &SysTenantImpl{
|
||||
selectSql: `select
|
||||
t.tenant_id, t.parent_id, t.ancestors, t.tenant_name, t.order_num, t.type, t.key, t.status, t.del_flag, t.create_by, t.create_time
|
||||
from sys_tenant t`,
|
||||
|
||||
resultMap: map[string]string{
|
||||
"tenant_id": "TenantID",
|
||||
"parent_id": "ParentID",
|
||||
"ancestors": "Ancestors",
|
||||
"tenant_name": "TenantName",
|
||||
"order_num": "OrderNum",
|
||||
"type": "Type",
|
||||
"key": "Key",
|
||||
"status": "Status",
|
||||
"del_flag": "DelFlag",
|
||||
"create_by": "CreateBy",
|
||||
"create_time": "CreateTime",
|
||||
"update_by": "UpdateBy",
|
||||
"update_time": "UpdateTime",
|
||||
"parent_name": "ParentName",
|
||||
},
|
||||
}
|
||||
|
||||
// SysTenantImpl 部门表 数据层处理
|
||||
type SysTenantImpl struct {
|
||||
// 查询视图对象SQL
|
||||
selectSql string
|
||||
// 结果字段与实体映射
|
||||
resultMap map[string]string
|
||||
}
|
||||
|
||||
// convertResultRows 将结果记录转实体结果组
|
||||
func (r *SysTenantImpl) convertResultRows(rows []map[string]any) []model.SysTenant {
|
||||
arr := make([]model.SysTenant, 0)
|
||||
for _, row := range rows {
|
||||
sysTenant := model.SysTenant{}
|
||||
for key, value := range row {
|
||||
if keyMapper, ok := r.resultMap[key]; ok {
|
||||
repo.SetFieldValue(&sysTenant, keyMapper, value)
|
||||
}
|
||||
}
|
||||
arr = append(arr, sysTenant)
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// SelectTenantList 查询部门管理数据
|
||||
func (r *SysTenantImpl) SelectTenantList(sysTenant model.SysTenant, dataScopeSQL string) []model.SysTenant {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysTenant.TenantID != "" {
|
||||
conditions = append(conditions, "tenant_id = ?")
|
||||
params = append(params, sysTenant.TenantID)
|
||||
}
|
||||
if sysTenant.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysTenant.ParentID)
|
||||
}
|
||||
if sysTenant.TenantName != "" {
|
||||
conditions = append(conditions, "tenant_name like concat(?, '%')")
|
||||
params = append(params, sysTenant.TenantName)
|
||||
}
|
||||
if sysTenant.Status != "" {
|
||||
conditions = append(conditions, "status = ?")
|
||||
params = append(params, sysTenant.Status)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := " where t.del_flag = '0' "
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " and " + strings.Join(conditions, " and ")
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
orderSql := " order by t.parent_id, t.order_num asc "
|
||||
querySql := r.selectSql + whereSql + dataScopeSQL + orderSql
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysTenant{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// SelectTenantListByRoleId 根据角色ID查询部门树信息
|
||||
func (r *SysTenantImpl) SelectTenantListByRoleId(roleId string, tenantCheckStrictly bool) []string {
|
||||
querySql := `select t.tenant_id as 'str' from sys_tenant d
|
||||
left join sys_role_tenant rd on t.tenant_id = rt.tenant_id
|
||||
where rt.role_id = ? `
|
||||
var params []any
|
||||
params = append(params, roleId)
|
||||
// 展开
|
||||
if tenantCheckStrictly {
|
||||
querySql += ` and t.tenant_id not in
|
||||
(select t.parent_id from sys_tenant d
|
||||
inner join sys_role_tenant rd on t.tenant_id = rt.tenant_id
|
||||
and rt.role_id = ?) `
|
||||
params = append(params, roleId)
|
||||
}
|
||||
querySql += "order by t.parent_id, t.order_num"
|
||||
|
||||
// 查询结果
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []string{}
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
ids := make([]string, 0)
|
||||
for _, v := range results {
|
||||
ids = append(ids, fmt.Sprintf("%v", v["str"]))
|
||||
}
|
||||
return ids
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectTenantById 根据部门ID查询信息
|
||||
func (r *SysTenantImpl) SelectTenantById(tenantId string) model.SysTenant {
|
||||
querySql := `select t.tenant_id, t.parent_id, t.ancestors,
|
||||
t.tenant_name, t.order_num, t.type, t.key, t.status,
|
||||
(select tenant_name from sys_tenant where tenant_id = t.parent_id) parent_name
|
||||
from sys_tenant t where t.tenant_id = ?`
|
||||
results, err := datasource.RawDB("", querySql, []any{tenantId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return model.SysTenant{}
|
||||
}
|
||||
// 转换实体
|
||||
rows := r.convertResultRows(results)
|
||||
if len(rows) > 0 {
|
||||
return rows[0]
|
||||
}
|
||||
return model.SysTenant{}
|
||||
}
|
||||
|
||||
// SelectChildrenTenantById 根据ID查询所有子部门
|
||||
func (r *SysTenantImpl) SelectChildrenTenantById(tenantId string) []model.SysTenant {
|
||||
querySql := r.selectSql + " where find_in_set(?, t.ancestors)"
|
||||
results, err := datasource.RawDB("", querySql, []any{tenantId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return []model.SysTenant{}
|
||||
}
|
||||
|
||||
// 转换实体
|
||||
return r.convertResultRows(results)
|
||||
}
|
||||
|
||||
// HasChildByTenantId 是否存在子节点
|
||||
func (r *SysTenantImpl) HasChildByTenantId(tenantId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_tenant where status = '1' and parent_id = ? limit 1"
|
||||
results, err := datasource.RawDB("", querySql, []any{tenantId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckTenantExistUser 查询部门是否存在用户
|
||||
func (r *SysTenantImpl) CheckTenantExistUser(tenantId string) int64 {
|
||||
querySql := "select count(1) as 'total' from sys_user where tenant_id = ? and del_flag = '0'"
|
||||
results, err := datasource.RawDB("", querySql, []any{tenantId})
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
return 0
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return parse.Number(results[0]["total"])
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// CheckUniqueTenant 校验部门是否唯一
|
||||
func (r *SysTenantImpl) CheckUniqueTenant(sysTenant model.SysTenant) string {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if sysTenant.TenantName != "" {
|
||||
conditions = append(conditions, "tenant_name = ?")
|
||||
params = append(params, sysTenant.TenantName)
|
||||
}
|
||||
if sysTenant.ParentID != "" {
|
||||
conditions = append(conditions, "parent_id = ?")
|
||||
params = append(params, sysTenant.ParentID)
|
||||
}
|
||||
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
if len(conditions) > 0 {
|
||||
whereSql += " where " + strings.Join(conditions, " and ")
|
||||
}
|
||||
if whereSql == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// 查询数据
|
||||
querySql := "select tenant_id as 'str' from sys_tenant " + whereSql + " and del_flag = '0' limit 1"
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err %v", err)
|
||||
return ""
|
||||
}
|
||||
if len(results) > 0 {
|
||||
return fmt.Sprint(results[0]["str"])
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// InsertTenant 新增部门信息
|
||||
func (r *SysTenantImpl) InsertTenant(sysTenant model.SysTenant) string {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysTenant.TenantID != "" {
|
||||
params["tenant_id"] = sysTenant.TenantID
|
||||
}
|
||||
if sysTenant.ParentID != "" {
|
||||
params["parent_id"] = sysTenant.ParentID
|
||||
}
|
||||
if sysTenant.TenantName != "" {
|
||||
params["tenant_name"] = sysTenant.TenantName
|
||||
}
|
||||
if sysTenant.Ancestors != "" {
|
||||
params["ancestors"] = sysTenant.Ancestors
|
||||
}
|
||||
if sysTenant.OrderNum > 0 {
|
||||
params["order_num"] = sysTenant.OrderNum
|
||||
}
|
||||
if sysTenant.Type != "" {
|
||||
params["type"] = sysTenant.Type
|
||||
}
|
||||
if sysTenant.Key != "" {
|
||||
params["key"] = sysTenant.Key
|
||||
}
|
||||
if sysTenant.Status != "" {
|
||||
params["status"] = sysTenant.Status
|
||||
}
|
||||
if sysTenant.CreateBy != "" {
|
||||
params["create_by"] = sysTenant.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
|
||||
sql := "insert into sys_tenant (" + strings.Join(keys, ",") + ")values(" + placeholder + ")"
|
||||
|
||||
db := datasource.DefaultDB()
|
||||
// 开启事务
|
||||
tx := db.Begin()
|
||||
// 执行插入
|
||||
err := tx.Exec(sql, values...).Error
|
||||
if err != nil {
|
||||
logger.Errorf("insert row : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 获取生成的自增 ID
|
||||
var insertedID string
|
||||
err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID)
|
||||
if err != nil {
|
||||
logger.Errorf("insert last id : %v", err.Error())
|
||||
tx.Rollback()
|
||||
return ""
|
||||
}
|
||||
// 提交事务
|
||||
tx.Commit()
|
||||
return insertedID
|
||||
}
|
||||
|
||||
// UpdateTenant 修改部门信息
|
||||
func (r *SysTenantImpl) UpdateTenant(sysTenant model.SysTenant) int64 {
|
||||
// 参数拼接
|
||||
params := make(map[string]any)
|
||||
if sysTenant.ParentID != "" {
|
||||
params["parent_id"] = sysTenant.ParentID
|
||||
}
|
||||
if sysTenant.TenantName != "" {
|
||||
params["tenant_name"] = sysTenant.TenantName
|
||||
}
|
||||
if sysTenant.Ancestors != "" {
|
||||
params["ancestors"] = sysTenant.Ancestors
|
||||
}
|
||||
if sysTenant.OrderNum > 0 {
|
||||
params["order_num"] = sysTenant.OrderNum
|
||||
}
|
||||
if sysTenant.Type != "" {
|
||||
params["type"] = sysTenant.Type
|
||||
}
|
||||
if sysTenant.Key != "" {
|
||||
params["key"] = sysTenant.Key
|
||||
}
|
||||
if sysTenant.Status != "" {
|
||||
params["status"] = sysTenant.Status
|
||||
}
|
||||
if sysTenant.UpdateBy != "" {
|
||||
params["update_by"] = sysTenant.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
}
|
||||
|
||||
// 构建执行语句
|
||||
keys, values := repo.KeyValueByUpdate(params)
|
||||
sql := "update sys_tenant set " + strings.Join(keys, ",") + " where tenant_id = ?"
|
||||
|
||||
// 执行更新
|
||||
values = append(values, sysTenant.TenantID)
|
||||
rows, err := datasource.ExecDB("", sql, values)
|
||||
if err != nil {
|
||||
logger.Errorf("update row : %v", err.Error())
|
||||
return 0
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
// UpdateTenantStatusNormal 修改所在部门正常状态
|
||||
func (r *SysTenantImpl) UpdateTenantStatusNormal(tenantIds []string) int64 {
|
||||
placeholder := repo.KeyPlaceholderByQuery(len(tenantIds))
|
||||
sql := "update sys_tenant set status = '1' where tenant_id in (" + placeholder + ")"
|
||||
parameters := repo.ConvertIdsSlice(tenantIds)
|
||||
results, err := datasource.ExecDB("", sql, parameters)
|
||||
if err != nil {
|
||||
logger.Errorf("update err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// UpdateTenantChildren 修改子元素关系
|
||||
func (r *SysTenantImpl) UpdateTenantChildren(sysTenants []model.SysTenant) int64 {
|
||||
// 无参数
|
||||
if len(sysTenants) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
// 更新条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
for _, tenant := range sysTenants {
|
||||
caseSql := fmt.Sprintf("WHEN tenant_id = '%s' THEN '%s'", tenant.TenantID, tenant.Ancestors)
|
||||
conditions = append(conditions, caseSql)
|
||||
params = append(params, tenant.TenantID)
|
||||
}
|
||||
|
||||
cases := strings.Join(conditions, " ")
|
||||
placeholders := repo.KeyPlaceholderByQuery(len(params))
|
||||
sql := "update sys_tenant set ancestors = CASE " + cases + " END where tenant_id in (" + placeholders + ")"
|
||||
results, err := datasource.ExecDB("", sql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// DeleteTenantById 删除部门管理信息
|
||||
func (r *SysTenantImpl) DeleteTenantById(tenantId string) int64 {
|
||||
sql := "update sys_tenant set status = '0', del_flag = '1' where tenant_id = ?"
|
||||
results, err := datasource.ExecDB("", sql, []any{tenantId})
|
||||
if err != nil {
|
||||
logger.Errorf("delete err => %v", err)
|
||||
return 0
|
||||
}
|
||||
return results
|
||||
}
|
||||
39
src/modules/system/service/sys_tenant.go
Normal file
39
src/modules/system/service/sys_tenant.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"be.ems/src/framework/vo"
|
||||
"be.ems/src/modules/system/model"
|
||||
)
|
||||
|
||||
// ISysTenant 租户管理 服务层接口
|
||||
type ISysTenant interface {
|
||||
// SelectTenantList 查询租户管理数据
|
||||
SelectTenantList(sysTenant model.SysTenant, dataScopeSQL string) []model.SysTenant
|
||||
|
||||
// SelectTenantListByRoleId 根据角色ID查询租户树信息
|
||||
SelectTenantListByRoleId(roleId string) []string
|
||||
|
||||
// SelectTenantById 根据租户ID查询信息
|
||||
SelectTenantById(tenantId string) model.SysTenant
|
||||
|
||||
// HasChildByTenantId 是否存在子节点
|
||||
HasChildByTenantId(tenantId string) int64
|
||||
|
||||
// CheckTenantExistUser 查询租户是否存在用户
|
||||
CheckTenantExistUser(tenantId string) int64
|
||||
|
||||
// CheckUniqueTenantName 校验同级租户名称是否唯一
|
||||
CheckUniqueTenantName(tenantName, parentId, tenantId string) bool
|
||||
|
||||
// InsertTenant 新增租户信息
|
||||
InsertTenant(sysTenant model.SysTenant) string
|
||||
|
||||
// UpdateTenant 修改租户信息
|
||||
UpdateTenant(sysTenant model.SysTenant) int64
|
||||
|
||||
// DeleteTenantById 删除租户管理信息
|
||||
DeleteTenantById(tenantId string) int64
|
||||
|
||||
// SelectTenantTreeSelect 查询租户树结构信息
|
||||
SelectTenantTreeSelect(sysTenant model.SysTenant, dataScopeSQL string) []vo.TreeSelect
|
||||
}
|
||||
202
src/modules/system/service/sys_tenant.impl.go
Normal file
202
src/modules/system/service/sys_tenant.impl.go
Normal file
@@ -0,0 +1,202 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"be.ems/src/framework/constants/common"
|
||||
"be.ems/src/framework/vo"
|
||||
"be.ems/src/modules/system/model"
|
||||
"be.ems/src/modules/system/repository"
|
||||
)
|
||||
|
||||
// 实例化服务层 SysTenantImpl 结构体
|
||||
var NewSysTenantImpl = &SysTenantImpl{
|
||||
sysTenantRepository: repository.NewSysTenantImpl,
|
||||
sysRoleRepository: repository.NewSysRoleImpl,
|
||||
sysRoleTenantRepository: repository.NewSysRoleTenantImpl,
|
||||
}
|
||||
|
||||
// SysTenantImpl 部门表 服务层处理
|
||||
type SysTenantImpl struct {
|
||||
// 部门服务
|
||||
sysTenantRepository repository.ISysTenant
|
||||
// 角色服务
|
||||
sysRoleRepository repository.ISysRole
|
||||
// 角色与部门关联服务
|
||||
sysRoleTenantRepository repository.ISysRoleTenant
|
||||
}
|
||||
|
||||
// SelectTenantList 查询部门管理数据
|
||||
func (r *SysTenantImpl) SelectTenantList(sysTenant model.SysTenant, dataScopeSQL string) []model.SysTenant {
|
||||
return r.sysTenantRepository.SelectTenantList(sysTenant, dataScopeSQL)
|
||||
}
|
||||
|
||||
// SelectTenantListByRoleId 根据角色ID查询部门树信息 TODO
|
||||
func (r *SysTenantImpl) SelectTenantListByRoleId(roleId string) []string {
|
||||
roles := r.sysRoleRepository.SelectRoleByIds([]string{roleId})
|
||||
if len(roles) > 0 {
|
||||
role := roles[0]
|
||||
if role.RoleID == roleId {
|
||||
return r.sysTenantRepository.SelectTenantListByRoleId(
|
||||
role.RoleID,
|
||||
role.TenantCheckStrictly == "1",
|
||||
)
|
||||
}
|
||||
}
|
||||
return []string{}
|
||||
}
|
||||
|
||||
// SelectTenantById 根据部门ID查询信息
|
||||
func (r *SysTenantImpl) SelectTenantById(tenantId string) model.SysTenant {
|
||||
return r.sysTenantRepository.SelectTenantById(tenantId)
|
||||
}
|
||||
|
||||
// HasChildByTenantId 是否存在子节点
|
||||
func (r *SysTenantImpl) HasChildByTenantId(tenantId string) int64 {
|
||||
return r.sysTenantRepository.HasChildByTenantId(tenantId)
|
||||
}
|
||||
|
||||
// CheckTenantExistUser 查询部门是否存在用户
|
||||
func (r *SysTenantImpl) CheckTenantExistUser(tenantId string) int64 {
|
||||
return r.sysTenantRepository.CheckTenantExistUser(tenantId)
|
||||
}
|
||||
|
||||
// CheckUniqueTenantName 校验同级部门名称是否唯一
|
||||
func (r *SysTenantImpl) CheckUniqueTenantName(tenantName, parentId, tenantId string) bool {
|
||||
uniqueId := r.sysTenantRepository.CheckUniqueTenant(model.SysTenant{
|
||||
TenantName: tenantName,
|
||||
ParentID: parentId,
|
||||
})
|
||||
if uniqueId == tenantId {
|
||||
return true
|
||||
}
|
||||
return uniqueId == ""
|
||||
}
|
||||
|
||||
// InsertTenant 新增部门信息
|
||||
func (r *SysTenantImpl) InsertTenant(sysTenant model.SysTenant) string {
|
||||
return r.sysTenantRepository.InsertTenant(sysTenant)
|
||||
}
|
||||
|
||||
// UpdateTenant 修改部门信息
|
||||
func (r *SysTenantImpl) UpdateTenant(sysTenant model.SysTenant) int64 {
|
||||
parentTenant := r.sysTenantRepository.SelectTenantById(sysTenant.ParentID)
|
||||
tenant := r.sysTenantRepository.SelectTenantById(sysTenant.TenantID)
|
||||
// 上级与当前部门祖级列表更新
|
||||
if parentTenant.TenantID == sysTenant.ParentID && tenant.TenantID == sysTenant.TenantID {
|
||||
newAncestors := parentTenant.Ancestors + "," + parentTenant.TenantID
|
||||
oldAncestors := tenant.Ancestors
|
||||
// 祖级列表不一致时更新
|
||||
if newAncestors != oldAncestors {
|
||||
sysTenant.Ancestors = newAncestors
|
||||
r.updateTenantChildren(sysTenant.TenantID, newAncestors, oldAncestors)
|
||||
}
|
||||
}
|
||||
// 如果该部门是启用状态,则启用该部门的所有上级部门
|
||||
if sysTenant.Status == common.STATUS_YES && parentTenant.Status == common.STATUS_NO {
|
||||
r.updateTenantStatusNormal(sysTenant.Ancestors)
|
||||
}
|
||||
return r.sysTenantRepository.UpdateTenant(sysTenant)
|
||||
}
|
||||
|
||||
// updateTenantStatusNormal 修改所在部门正常状态
|
||||
func (r *SysTenantImpl) updateTenantStatusNormal(ancestors string) int64 {
|
||||
if ancestors == "" || ancestors == "0" {
|
||||
return 0
|
||||
}
|
||||
tenantIds := strings.Split(ancestors, ",")
|
||||
return r.sysTenantRepository.UpdateTenantStatusNormal(tenantIds)
|
||||
}
|
||||
|
||||
// updateTenantChildren 修改子元素关系
|
||||
func (r *SysTenantImpl) updateTenantChildren(tenantId, newAncestors, oldAncestors string) int64 {
|
||||
childrens := r.sysTenantRepository.SelectChildrenTenantById(tenantId)
|
||||
if len(childrens) == 0 {
|
||||
return 0
|
||||
}
|
||||
// 替换父ID
|
||||
for i := range childrens {
|
||||
child := &childrens[i]
|
||||
ancestors := strings.Replace(child.Ancestors, oldAncestors, newAncestors, -1)
|
||||
child.Ancestors = ancestors
|
||||
}
|
||||
return r.sysTenantRepository.UpdateTenantChildren(childrens)
|
||||
}
|
||||
|
||||
// DeleteTenantById 删除部门管理信息
|
||||
func (r *SysTenantImpl) DeleteTenantById(tenantId string) int64 {
|
||||
// 删除角色与部门关联
|
||||
r.sysRoleTenantRepository.DeleteTenantRole([]string{tenantId})
|
||||
return r.sysTenantRepository.DeleteTenantById(tenantId)
|
||||
}
|
||||
|
||||
// SelectTenantTreeSelect 查询部门树结构信息
|
||||
func (r *SysTenantImpl) SelectTenantTreeSelect(sysTenant model.SysTenant, dataScopeSQL string) []vo.TreeSelect {
|
||||
sysTenants := r.sysTenantRepository.SelectTenantList(sysTenant, dataScopeSQL)
|
||||
tenants := r.parseDataToTree(sysTenants)
|
||||
tree := make([]vo.TreeSelect, 0)
|
||||
for _, tenant := range tenants {
|
||||
tree = append(tree, vo.SysTenantTreeSelect(tenant))
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
// parseDataToTree 将数据解析为树结构,构建前端所需要下拉树结构
|
||||
func (r *SysTenantImpl) parseDataToTree(sysTenants []model.SysTenant) []model.SysTenant {
|
||||
// 节点分组
|
||||
nodesMap := make(map[string][]model.SysTenant)
|
||||
// 节点id
|
||||
treeIds := []string{}
|
||||
// 树节点
|
||||
tree := []model.SysTenant{}
|
||||
|
||||
for _, item := range sysTenants {
|
||||
parentID := item.ParentID
|
||||
// 分组
|
||||
mapItem, ok := nodesMap[parentID]
|
||||
if !ok {
|
||||
mapItem = []model.SysTenant{}
|
||||
}
|
||||
mapItem = append(mapItem, item)
|
||||
nodesMap[parentID] = mapItem
|
||||
// 记录节点ID
|
||||
treeIds = append(treeIds, item.TenantID)
|
||||
}
|
||||
|
||||
for key, value := range nodesMap {
|
||||
// 选择不是节点ID的作为树节点
|
||||
found := false
|
||||
for _, id := range treeIds {
|
||||
if id == key {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
tree = append(tree, value...)
|
||||
}
|
||||
}
|
||||
|
||||
for i, node := range tree {
|
||||
iN := r.parseDataToTreeComponet(node, &nodesMap)
|
||||
tree[i] = iN
|
||||
}
|
||||
|
||||
return tree
|
||||
}
|
||||
|
||||
// parseDataToTreeComponet 递归函数处理子节点
|
||||
func (r *SysTenantImpl) parseDataToTreeComponet(node model.SysTenant, nodesMap *map[string][]model.SysTenant) model.SysTenant {
|
||||
id := node.TenantID
|
||||
children, ok := (*nodesMap)[id]
|
||||
if ok {
|
||||
node.Children = children
|
||||
}
|
||||
if len(node.Children) > 0 {
|
||||
for i, child := range node.Children {
|
||||
icN := r.parseDataToTreeComponet(child, nodesMap)
|
||||
node.Children[i] = icN
|
||||
}
|
||||
}
|
||||
return node
|
||||
}
|
||||
@@ -103,6 +103,46 @@ func Setup(router *gin.Engine) {
|
||||
)
|
||||
}
|
||||
|
||||
// 租户管理信息
|
||||
sysTenantGroup := router.Group("/system/tenant")
|
||||
{
|
||||
sysTenantGroup.GET("/list",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:list"}}),
|
||||
controller.NewSysTenant.List,
|
||||
)
|
||||
sysTenantGroup.GET("/:tenantId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:query"}}),
|
||||
controller.NewSysTenant.Info,
|
||||
)
|
||||
sysTenantGroup.POST("",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:add"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysTenant", collectlogs.BUSINESS_TYPE_INSERT)),
|
||||
controller.NewSysTenant.Add,
|
||||
)
|
||||
sysTenantGroup.PUT("",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:edit"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysTenant", collectlogs.BUSINESS_TYPE_UPDATE)),
|
||||
controller.NewSysTenant.Edit,
|
||||
)
|
||||
sysTenantGroup.DELETE("/:tenantId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:remove"}}),
|
||||
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.sysTenant", collectlogs.BUSINESS_TYPE_DELETE)),
|
||||
controller.NewSysTenant.Remove,
|
||||
)
|
||||
sysTenantGroup.GET("/list/exclude/:tenantId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:list"}}),
|
||||
controller.NewSysTenant.ExcludeChild,
|
||||
)
|
||||
sysTenantGroup.GET("/treeSelect",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:list", "system:user:list"}}),
|
||||
controller.NewSysTenant.TreeSelect,
|
||||
)
|
||||
sysTenantGroup.GET("/roleTenantTreeSelect/:roleId",
|
||||
middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:query", "system:user:edit"}}),
|
||||
controller.NewSysTenant.RoleTenantTreeSelect,
|
||||
)
|
||||
}
|
||||
|
||||
// 字典数据信息
|
||||
sysDictDataGroup := router.Group("/system/dict/data")
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user