2026-03-18 10:19:42 +08:00
/ *
* @ desc : 用户处理
* @ company : 云南奇讯科技有限公司
* @ Author : yixiaohu < yxh669 @ qq . com >
* @ Date : 2022 / 9 / 23 15 : 0 8
* /
package tenant
import (
"context"
"database/sql"
"errors"
"fmt"
2026-03-24 16:13:42 +08:00
2026-03-18 10:19:42 +08:00
"gitea.com/red-future/common/beans"
"gitea.com/red-future/common/utils"
"github.com/gogf/gf/v2/container/gset"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
"github.com/gogf/gf/v2/util/grand"
"github.com/tiger1103/gfast/v3/api/v1/system"
commonService "github.com/tiger1103/gfast/v3/internal/app/common/service"
"github.com/tiger1103/gfast/v3/internal/app/system/consts"
"github.com/tiger1103/gfast/v3/internal/app/system/dao"
"github.com/tiger1103/gfast/v3/internal/app/system/model/do"
"github.com/tiger1103/gfast/v3/internal/app/system/model/entity"
"github.com/tiger1103/gfast/v3/internal/app/system/service"
"github.com/tiger1103/gfast/v3/library/libUtils"
"github.com/tiger1103/gfast/v3/library/liberr"
)
func init ( ) {
service . RegisterTenant ( New ( ) )
}
type sTenant struct {
}
func New ( ) * sTenant {
return & sTenant { }
}
func ( s * sTenant ) GetTenantListSearch ( ctx context . Context , req * system . TenantListReq ) ( res * system . TenantListRes , err error ) {
res = new ( system . TenantListRes )
err = g . Try ( ctx , func ( ctx context . Context ) {
2026-03-24 16:13:42 +08:00
res . ImgAddressPrefix , err = utils . GetFileAddressPrefix ( ctx )
liberr . ErrIsNil ( ctx , err , "获取文件地址前缀失败" )
2026-03-18 10:19:42 +08:00
model := dao . TenantDao . Ctx ( ctx )
// 根据toke获取用户id
userId := service . Context ( ) . GetUserId ( ctx )
getUserById , err := service . SysUser ( ) . GetUserById ( ctx , userId )
liberr . ErrIsNil ( ctx , err , "获取用户信息失败" )
roleIds , err := service . SysUser ( ) . GetAdminRoleIds ( ctx , userId )
// 根据用户角色查询对应数据( 9代理, 10普通)
for _ , v := range roleIds {
if v == consts . SalesAgentId || v == consts . SiteAdminId {
model = model . Where ( dao . TenantDao . Columns ( ) . TenantSource , gconv . Int64 ( getUserById . TenantId ) )
}
}
if ! g . IsEmpty ( req . TenantName ) {
model = model . Where ( dao . TenantDao . Columns ( ) . TenantName + " like ? " , "%" + req . TenantName + "%" )
}
if ! g . IsEmpty ( req . TenantType ) {
model = model . Where ( dao . TenantDao . Columns ( ) . TenantType , gconv . Int ( req . TenantType ) )
}
if ! g . IsEmpty ( req . CityCode ) {
model = model . Where ( dao . TenantDao . Columns ( ) . CityCode , gconv . String ( req . CityCode ) )
}
res . Total , err = model . Count ( )
liberr . ErrIsNil ( ctx , err , "获取租户数据失败" )
if req . PageNum == 0 {
req . PageNum = 1
}
res . CurrentPage = req . PageNum
if req . PageSize == 0 {
req . PageSize = consts . PageSize
}
err = model . Page ( res . CurrentPage , req . PageSize ) . Order ( dao . TenantDao . Columns ( ) . CreatedAt + " desc" ) . Scan ( & res . List )
liberr . ErrIsNil ( ctx , err , "获取数据失败" )
var list [ ] map [ string ] interface { }
err = utils . Struct ( res . List , & list )
liberr . ErrIsNil ( ctx , err , "转换数据失败" )
// 2. 提取id
userIds := make ( [ ] int , 0 , len ( list ) )
cityIds := make ( [ ] string , 0 , len ( list ) )
for _ , obj := range list {
// 提取id并转换( JSON数字是float64)
idFloat , ok := obj [ "adminBy" ] . ( float64 )
if ! ok {
fmt . Println ( "警告: adminBy字段非数字" )
continue
}
cityFloat , ok := obj [ "cityCode" ] . ( string )
if ! ok {
fmt . Println ( "警告: cityCode字段非字符串" )
continue
}
userIds = append ( userIds , int ( idFloat ) )
cityIds = append ( cityIds , cityFloat )
}
userList , err := service . SysUser ( ) . GetUsers ( ctx , userIds )
liberr . ErrIsNil ( ctx , err , "获取租户信息失败" )
areaDicList , err := service . AreaDict ( ) . GetAreaDict ( ctx )
liberr . ErrIsNil ( ctx , err , "获取地区字典失败" )
for _ , list := range res . List {
for _ , areas := range areaDicList {
if fmt . Sprintf ( "%d" , areas . Id ) == list . CityCode {
list . CityName = areas . CityName
list . CityMergerName = areas . MergerName
}
}
for _ , users := range userList {
if users . Id == list . AdminBy {
list . UserName = users . UserName
list . Mobile = users . Mobile
list . UserNickname = users . UserNickname
}
}
}
} )
return
}
func ( s * sTenant ) Add ( ctx context . Context , req * system . TenantAddReq ) ( err error ) {
err = g . DB ( ) . Transaction ( ctx , func ( ctx context . Context , tx gdb . TX ) error {
err = g . Try ( ctx , func ( ctx context . Context ) {
// 根据token获取用户id
userId := service . Context ( ) . GetUserId ( ctx )
var getUserInfo * beans . User
getUserInfo , err = utils . GetUserInfo ( ctx )
var userTenantId uint64
if err == nil && ! g . IsEmpty ( getUserInfo . TenantId ) {
userTenantId = gconv . Uint64 ( getUserInfo . TenantId )
}
if ! g . IsEmpty ( userId ) {
var roleIds [ ] uint
roleIds , err = service . SysUser ( ) . GetAdminRoleIds ( ctx , userId )
liberr . ErrIsNil ( ctx , err , "获取用户角色失败" )
// 如果是代理和普通用户只能添加普通类型( 1普通类型, 2代理类型)
for _ , v := range roleIds {
if v == consts . SalesAgentId || v == consts . SiteAdminId {
req . TenantType = consts . TenantTypeSite
if v == consts . SalesAgentId {
// 验证代理区域是否在当前代理的管辖范围内
tenantEntity := new ( entity . Tenant )
err = dao . TenantDao . Ctx ( ctx ) . TX ( tx ) . Where ( dao . TenantDao . Columns ( ) . Id , userTenantId ) . Scan ( tenantEntity )
liberr . ErrIsNil ( ctx , err , "获取租户数据失败" )
var count int
count , err = dao . AreaDictDao . Ctx ( ctx ) . TX ( tx ) . Where ( "(" + dao . AreaDictDao . Columns ( ) . Id + "=? OR " + dao . AreaDictDao . Columns ( ) . ParentId + "=?) AND " + dao . AreaDictDao . Columns ( ) . Id + "=?" , tenantEntity . CityCode , tenantEntity . CityCode , req . CityCode ) . Count ( )
liberr . ErrIsNil ( ctx , err , "验证代理区域失败" )
if count == 0 {
liberr . ErrIsNil ( ctx , errors . New ( "所选城市不在当前代理的管辖范围内" ) )
}
} else {
if req . TenantType == consts . TenantTypeAgent {
liberr . ErrIsNil ( ctx , errors . New ( "代理商不能添加代理商" ) )
}
}
break
}
}
} else {
// 如果是普通用户只能添加普通类型( 1普通类型, 2代理类型)
req . TenantType = consts . TenantTypeSite
}
if req . TenantType == consts . TenantTypeAgent {
// 验证代理区域是否已有代理商
var count int
count , err = dao . TenantDao . Ctx ( ctx ) . TX ( tx ) . Where ( dao . TenantDao . Columns ( ) . CityCode , req . CityCode ) . Count ( )
liberr . ErrIsNil ( ctx , err , "获取租户数据失败" )
if count > 0 {
liberr . ErrIsNil ( ctx , errors . New ( "该城市已有代理商" ) )
}
}
var tenantId int64
tenantId , err = dao . TenantDao . Ctx ( ctx ) . TX ( tx ) . InsertAndGetId ( do . Tenant {
CreateBy : userId ,
UpdateBy : userId ,
TenantName : req . TenantName ,
TenantType : req . TenantType ,
CityCode : req . CityCode ,
BusinessLicense : req . BusinessLicense ,
TenantSource : userTenantId ,
} )
liberr . ErrIsNil ( ctx , err , "添加租户失败" )
var RoleIds = [ ] int64 { consts . SiteAdminId }
if ! g . IsNil ( req . TenantType ) && req . TenantType == consts . TenantTypeAgent {
RoleIds = [ ] int64 { consts . SalesAgentId }
}
// 在同一事务中添加部门
var deptId int64
var deptInsertId sql . Result
deptInsertId , err = dao . SysDept . Ctx ( ctx ) . TX ( tx ) . Insert ( do . SysDept {
ParentId : 0 ,
DeptName : req . TenantName ,
OrderNum : 0 ,
Leader : req . UserNickname ,
Phone : req . Mobile ,
Email : req . Mobile + "@qq.com" ,
Status : 1 ,
CreatedBy : userId ,
TenantId : uint64 ( tenantId ) ,
} )
liberr . ErrIsNil ( ctx , err , "添加部门失败" )
deptId , err = deptInsertId . LastInsertId ( )
liberr . ErrIsNil ( ctx , err , "获取部门ID失败" )
// 在同一事务中添加用户
err = service . SysUser ( ) . UserNameOrMobileExists ( ctx , req . UserName , req . Mobile )
liberr . ErrIsNil ( ctx , err )
userSalt := grand . S ( 10 )
userPassword := libUtils . EncryptPassword ( req . UserPassword , userSalt )
var adminUserId int64
adminUserId , err = dao . SysUser . Ctx ( ctx ) . TX ( tx ) . InsertAndGetId ( do . SysUser {
UserName : req . UserName ,
Mobile : req . Mobile ,
UserNickname : req . UserNickname ,
UserPassword : userPassword ,
UserSalt : userSalt ,
UserStatus : 1 ,
DeptId : uint64 ( deptId ) ,
IsAdmin : 1 ,
TenantId : uint64 ( tenantId ) ,
} )
liberr . ErrIsNil ( ctx , err , "添加用户失败" )
// 添加用户角色信息( 使用Casbin)
enforcer , e := commonService . CasbinEnforcer ( ctx )
liberr . ErrIsNil ( ctx , e , "获取权限引擎失败" )
for _ , v := range RoleIds {
_ , e = enforcer . AddGroupingPolicy ( fmt . Sprintf ( "u_%d" , adminUserId ) , gconv . String ( v ) )
liberr . ErrIsNil ( ctx , e , "设置用户权限失败" )
}
// 更新租户的AdminBy字段
_ , err = dao . TenantDao . Ctx ( ctx ) . TX ( tx ) . WherePri ( tenantId ) . Update ( do . Tenant {
AdminBy : adminUserId ,
} )
liberr . ErrIsNil ( ctx , err , "修改租户信息失败" )
} )
return err
} )
return
}
func ( s * sTenant ) Edit ( ctx context . Context , req * system . TenantEditReq ) ( err error ) {
err = g . DB ( ) . Transaction ( ctx , func ( ctx context . Context , tx gdb . TX ) error {
err = g . Try ( ctx , func ( ctx context . Context ) {
userId := service . Context ( ) . GetUserId ( ctx )
tenant := do . Tenant {
UpdateBy : userId ,
TenantName : req . TenantName ,
CityCode : req . CityCode ,
BusinessLicense : req . BusinessLicense ,
}
if ! g . IsEmpty ( req . TenantType ) {
tenant . TenantType = req . TenantType
}
_ , err = dao . TenantDao . Ctx ( ctx ) . TX ( tx ) . WherePri ( req . Id ) . Update ( tenant )
liberr . ErrIsNil ( ctx , err , "修改租户信息失败" )
} )
return err
} )
return
}
func ( s * sTenant ) GetTenantDetailsByIds ( ctx context . Context , req * system . GetTenantDetailsByIdsReq ) ( res * system . GetTenantDetailsByIdsRes , err error ) {
res = new ( system . GetTenantDetailsByIdsRes )
if len ( req . TenantIds ) == 0 {
return
}
idsSet := gset . NewIntSetFrom ( gconv . Ints ( req . TenantIds ) ) . Slice ( )
err = g . Try ( ctx , func ( ctx context . Context ) {
err = dao . TenantDao . Ctx ( ctx ) . Where ( dao . TenantDao . Columns ( ) . Id + " in(?)" , idsSet ) . Order ( dao . TenantDao . Columns ( ) . Id + " ASC" ) . Scan ( & res . List )
} )
return
}
func ( s * sTenant ) GetTenantDetails ( ctx context . Context , id uint64 ) ( res * entity . Tenant , err error ) {
err = g . Try ( ctx , func ( ctx context . Context ) {
err = dao . TenantDao . Ctx ( ctx ) . WherePri ( id ) . Scan ( & res )
} )
return
}
func ( s * sTenant ) GetTenantAdminById ( ctx context . Context , id uint64 ) ( res [ ] entity . Tenant , err error ) {
err = g . Try ( ctx , func ( ctx context . Context ) {
err = dao . TenantDao . Ctx ( ctx ) . Where ( dao . TenantDao . Columns ( ) . Id + " =(?) or " + dao . TenantDao . Columns ( ) . TenantSource + " =(?)" , id , id ) . Order ( dao . TenantDao . Columns ( ) . Id + " ASC" ) . Scan ( & res )
} )
return
}
func ( s * sTenant ) GetTenantIdList ( ctx context . Context , req * system . GetTenantListReq ) ( res [ ] entity . Tenant , err error ) {
err = g . Try ( ctx , func ( ctx context . Context ) {
model := dao . TenantDao . Ctx ( ctx )
if ! g . IsEmpty ( req . TenantId ) {
model . Where ( dao . TenantDao . Columns ( ) . Id , req . TenantId )
}
err = model . Scan ( & res )
} )
return
}