/* * @desc:用户处理 * @company:云南奇讯科技有限公司 * @Author: yixiaohu * @Date: 2022/9/23 15:08 */ package tenant import ( "context" "database/sql" "errors" "fmt" "gitea.redpowerfuture.com/red-future/common/beans" "gitea.redpowerfuture.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, err = utils.GetFileAddressPrefix(ctx) liberr.ErrIsNil(ctx, err, "获取文件地址前缀失败") 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 }