Files
admin-go/internal/app/system/logic/tenant/tenant.go
2026-03-18 10:19:42 +08:00

304 lines
11 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* @desc:用户处理
* @company:云南奇讯科技有限公司
* @Author: yixiaohu<yxh669@qq.com>
* @Date: 2022/9/23 15:08
*/
package tenant
import (
"context"
"database/sql"
"errors"
"fmt"
"gitea.com/red-future/common/beans"
"gitea.com/red-future/common/minio"
"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) {
res.ImgAddressPrefix = minio.GetFileAddressPrefix(ctx)
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
}