From 409e1afc9f01ccd53ee2bf81ddc95ec9bc0d2076 Mon Sep 17 00:00:00 2001 From: simonzhangsz Date: Fri, 7 Jun 2024 10:09:25 +0800 Subject: [PATCH] add: multi-tenant --- src/modules/system/model/sys_role_tenant.go | 2 +- src/modules/system/model/sys_tenant.go | 8 ++-- src/modules/system/model/sys_user.go | 4 ++ .../system/repository/sys_tenant.impl.go | 48 +++++++++---------- .../system/repository/sys_user.impl.go | 39 +++++++++++++-- src/modules/system/system.go | 16 +++---- 6 files changed, 77 insertions(+), 40 deletions(-) diff --git a/src/modules/system/model/sys_role_tenant.go b/src/modules/system/model/sys_role_tenant.go index 4c522567..21a9cf13 100644 --- a/src/modules/system/model/sys_role_tenant.go +++ b/src/modules/system/model/sys_role_tenant.go @@ -3,7 +3,7 @@ package model // SysRoleDept 角色和部门关联对象 sys_role_dept type SysRoleTenant struct { RoleID string `json:"roleId"` // 角色ID - TenantID string `json:"TenantID"` // 部门ID + TenantID string `json:"tenantID"` // 部门ID } // NewSysRoleDept 创建角色和部门关联对象的构造函数 diff --git a/src/modules/system/model/sys_tenant.go b/src/modules/system/model/sys_tenant.go index 4023e0bf..9a628885 100644 --- a/src/modules/system/model/sys_tenant.go +++ b/src/modules/system/model/sys_tenant.go @@ -3,19 +3,19 @@ package model // SysTenant 部门对象 sys_Tenant type SysTenant struct { // 部门ID - TenantID string `json:"TenantId"` + TenantID string `json:"tenantId"` // 父部门ID ParentID string `json:"parentId" binding:"required"` // 祖级列表 Ancestors string `json:"ancestors"` // 部门名称 - TenantName string `json:"TenantName" binding:"required"` + TenantName string `json:"tenantName" binding:"required"` // 显示顺序 OrderNum int `json:"orderNum"` // tenancy type: sd-sst, apn, imsi, msisdn - Type string `json:"type"` + TenancyType string `json:"tenancyType"` // tenancy key: key of sd-sst, apn, imsi, msisdn - Key string `json:"key"` + TenancyKey string `json:"tenancyKey"` // 部门状态(0正常 1停用) Status string `json:"status"` // 删除标志(0代表存在 1代表删除) diff --git a/src/modules/system/model/sys_user.go b/src/modules/system/model/sys_user.go index c580784f..4f1464a8 100644 --- a/src/modules/system/model/sys_user.go +++ b/src/modules/system/model/sys_user.go @@ -6,6 +6,8 @@ type SysUser struct { UserID string `json:"userId"` // 部门ID DeptID string `json:"deptId"` + // 租户ID + TenantID string `json:"tenantId"` // 用户账号 UserName string `json:"userName" binding:"required"` // 用户昵称 @@ -45,6 +47,8 @@ type SysUser struct { // 部门对象 Dept SysDept `json:"dept,omitempty" binding:"structonly"` + // 租户对象 + Tenant SysTenant `json:"tenant,omitempty" binding:"structonly"` // 角色对象组 Roles []SysRole `json:"roles"` // 角色ID diff --git a/src/modules/system/repository/sys_tenant.impl.go b/src/modules/system/repository/sys_tenant.impl.go index 4d28c42b..fc0e6436 100644 --- a/src/modules/system/repository/sys_tenant.impl.go +++ b/src/modules/system/repository/sys_tenant.impl.go @@ -15,24 +15,24 @@ import ( // 实例化数据层 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 + t.tenant_id, t.parent_id, t.ancestors, t.tenant_name, t.order_num, t.tenancy_type, t.tenancy_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", + "tenant_id": "TenantID", + "parent_id": "ParentID", + "ancestors": "Ancestors", + "tenant_name": "TenantName", + "order_num": "OrderNum", + "tenancy_type": "TenancyType", + "tenancy_key": "TenancyKey", + "status": "Status", + "del_flag": "DelFlag", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + "parent_name": "ParentName", }, } @@ -137,7 +137,7 @@ func (r *SysTenantImpl) SelectTenantListByRoleId(roleId string, tenantCheckStric // 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, + t.tenant_name, t.order_num, t.tenancy_type, t.tenancy_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}) @@ -249,11 +249,11 @@ func (r *SysTenantImpl) InsertTenant(sysTenant model.SysTenant) string { if sysTenant.OrderNum > 0 { params["order_num"] = sysTenant.OrderNum } - if sysTenant.Type != "" { - params["type"] = sysTenant.Type + if sysTenant.TenancyType != "" { + params["tenancy_type"] = sysTenant.TenancyType } - if sysTenant.Key != "" { - params["key"] = sysTenant.Key + if sysTenant.TenancyKey != "" { + params["tenancy_key"] = sysTenant.TenancyKey } if sysTenant.Status != "" { params["status"] = sysTenant.Status @@ -306,11 +306,11 @@ func (r *SysTenantImpl) UpdateTenant(sysTenant model.SysTenant) int64 { if sysTenant.OrderNum > 0 { params["order_num"] = sysTenant.OrderNum } - if sysTenant.Type != "" { - params["type"] = sysTenant.Type + if sysTenant.TenancyType != "" { + params["tenancy_type"] = sysTenant.TenancyType } - if sysTenant.Key != "" { - params["key"] = sysTenant.Key + if sysTenant.TenancyKey != "" { + params["tenancy_key"] = sysTenant.TenancyKey } if sysTenant.Status != "" { params["status"] = sysTenant.Status diff --git a/src/modules/system/repository/sys_user.impl.go b/src/modules/system/repository/sys_user.impl.go index bbcbe849..708f010f 100644 --- a/src/modules/system/repository/sys_user.impl.go +++ b/src/modules/system/repository/sys_user.impl.go @@ -16,7 +16,7 @@ import ( // 实例化数据层 SysUserImpl 结构体 var NewSysUserImpl = &SysUserImpl{ selectSql: `select - u.user_id, u.dept_id, u.user_name, u.nick_name, u.user_type, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, + u.user_id, u.dept_id, u.tenant_id, u.user_name, u.nick_name, u.user_type, u.email, u.avatar, u.phonenumber, u.password, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_id, d.parent_id, d.ancestors, d.dept_name, d.order_num, d.leader, d.status as dept_status, r.role_id, r.role_name, r.role_key, r.role_sort, r.data_scope, r.status as role_status from sys_user u @@ -27,6 +27,7 @@ var NewSysUserImpl = &SysUserImpl{ sysUserMap: map[string]string{ "user_id": "UserID", "dept_id": "DeptID", + "tenant_id": "TenantID", "user_name": "UserName", "nick_name": "NickName", "user_type": "UserType", @@ -56,6 +57,17 @@ var NewSysUserImpl = &SysUserImpl{ "dept_status": "Status", }, + sysTenantMap: map[string]string{ + "tenant_id": "TenantID", + "parent_id": "ParentID", + "Tenant_name": "TenantName", + "ancestors": "Ancestors", + "order_num": "OrderNum", + "tenancy_type": "TenancyType", + "tenancy_key": "TenancyKey", + "tenant_status": "Status", + }, + sysRoleMap: map[string]string{ "role_id": "RoleID", "role_name": "RoleName", @@ -74,6 +86,8 @@ type SysUserImpl struct { sysUserMap map[string]string // 用户部门实体映射 一对一 sysDeptMap map[string]string + // 用户租户实体映射 一对一 + sysTenantMap map[string]string // 用户角色实体映射 一对多 sysRoleMap map[string]string } @@ -85,6 +99,7 @@ func (r *SysUserImpl) convertResultRows(rows []map[string]any) []model.SysUser { for _, row := range rows { sysUser := model.SysUser{} sysDept := model.SysDept{} + sysTenant := model.SysTenant{} sysRole := model.SysRole{} sysUser.Roles = []model.SysRole{} @@ -95,12 +110,16 @@ func (r *SysUserImpl) convertResultRows(rows []map[string]any) []model.SysUser { if keyMapper, ok := r.sysDeptMap[key]; ok { repo.SetFieldValue(&sysDept, keyMapper, value) } + if keyMapper, ok := r.sysTenantMap[key]; ok { + repo.SetFieldValue(&sysTenant, keyMapper, value) + } if keyMapper, ok := r.sysRoleMap[key]; ok { repo.SetFieldValue(&sysRole, keyMapper, value) } } sysUser.Dept = sysDept + sysUser.Tenant = sysTenant if sysRole.RoleKey != "" { sysUser.Roles = append(sysUser.Roles, sysRole) } @@ -127,6 +146,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) selectUserTotalSql := `select count(distinct u.user_id) as 'total' from sys_user u left join sys_dept d on u.dept_id = d.dept_id + left join sys_tenant t on u.tenant_id = t.tenant_id left join sys_user_role ur on u.user_id = ur.user_id left join sys_role r on r.role_id = ur.role_id` @@ -171,6 +191,12 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) params = append(params, v) } + if v, ok := query["tenantId"]; ok && v != "" { + conditions = append(conditions, "(u.tenant_id = ? or u.tenant_id in ( select n.tenant_id from sys_tenant n where find_in_set(?, ancestors) ))") + params = append(params, v) + params = append(params, v) + } + // 构建查询条件语句 whereSql := " where u.del_flag = '0' and u.user_id != '1' " if len(conditions) > 0 { @@ -310,9 +336,10 @@ func (r *SysUserImpl) SelectAllocatedPage(query map[string]any, dataScopeSQL str // SelectUserList 根据条件查询用户列表 func (r *SysUserImpl) SelectUserList(sysUser model.SysUser, dataScopeSQL string) []model.SysUser { selectUserSql := `select - u.user_id, u.dept_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader + u.user_id, u.dept_id, u.tenant_id, u.nick_name, u.user_name, u.email, u.avatar, u.phonenumber, u.sex, u.status, u.del_flag, u.login_ip, u.login_date, u.create_by, u.create_time, u.remark, d.dept_name, d.leader from sys_user u - left join sys_dept d on u.dept_id = d.dept_id` + left join sys_dept d on u.dept_id = d.dept_id + left join sys_tenant d on u.tenant_id = t.tenant_id` // 查询条件拼接 var conditions []string @@ -390,6 +417,9 @@ func (r *SysUserImpl) InsertUser(sysUser model.SysUser) string { if sysUser.DeptID != "" { params["dept_id"] = sysUser.DeptID } + if sysUser.TenantID != "" { + params["tenant_id"] = sysUser.TenantID + } if sysUser.UserName != "" { params["user_name"] = sysUser.UserName } @@ -460,6 +490,9 @@ func (r *SysUserImpl) UpdateUser(sysUser model.SysUser) int64 { if sysUser.DeptID != "" { params["dept_id"] = sysUser.DeptID } + if sysUser.TenantID != "" { + params["tenant_id"] = sysUser.TenantID + } if sysUser.UserName != "" { params["user_name"] = sysUser.UserName } diff --git a/src/modules/system/system.go b/src/modules/system/system.go index 7db0237a..18f18ad1 100644 --- a/src/modules/system/system.go +++ b/src/modules/system/system.go @@ -107,38 +107,38 @@ func Setup(router *gin.Engine) { sysTenantGroup := router.Group("/system/tenant") { sysTenantGroup.GET("/list", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:list"}}), + middleware.PreAuthorize(nil), controller.NewSysTenant.List, ) sysTenantGroup.GET("/:tenantId", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:query"}}), + middleware.PreAuthorize(nil), controller.NewSysTenant.Info, ) sysTenantGroup.POST("", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:add"}}), + middleware.PreAuthorize(nil), 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"}}), + middleware.PreAuthorize(nil), 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"}}), + middleware.PreAuthorize(nil), 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"}}), + middleware.PreAuthorize(nil), controller.NewSysTenant.ExcludeChild, ) sysTenantGroup.GET("/treeSelect", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:list", "system:user:list"}}), + middleware.PreAuthorize(nil), controller.NewSysTenant.TreeSelect, ) sysTenantGroup.GET("/roleTenantTreeSelect/:roleId", - middleware.PreAuthorize(map[string][]string{"hasPerms": {"system:tenant:query", "system:user:edit"}}), + middleware.PreAuthorize(nil), controller.NewSysTenant.RoleTenantTreeSelect, ) }