更新
This commit is contained in:
+40
-68
@@ -55,7 +55,6 @@ import (
|
||||
"easygoadmin/internal/dao"
|
||||
"easygoadmin/internal/service"
|
||||
"easygoadmin/utility/cache"
|
||||
"easygoadmin/utility/crypto"
|
||||
)
|
||||
|
||||
// ============================== 租户业务实现 ==============================
|
||||
@@ -307,80 +306,53 @@ func (s *sTenant) Add(ctx context.Context, req *v1.TenantAddReq) (res *v1.IdRes,
|
||||
return &v1.IdRes{Id: idv}, nil
|
||||
}
|
||||
|
||||
// Account 创建租户账号
|
||||
// Account 添加租户账号
|
||||
//
|
||||
// 同时创建租户及其初始管理员账号;
|
||||
// bcrypt 属 CPU 密集操作,放在事务外预计算,保持短事务
|
||||
// 在指定租户(req.TenantId)下创建用户账号,返回目标租户ID、租户编码与新用户ID。
|
||||
// 平台级专属:拦截租户侧身份——本操作按请求显式指定的目标租户写入,
|
||||
// 且唯一性校验/用户数上限的查询链依赖平台视角(无租户收敛)。
|
||||
// 目标租户不存在返回 CodeTenantNotFound;账号唯一性、用户数上限、编码生成、
|
||||
// 密码加盐、头像转正、角色关联复用用户新增链路(sUser.addWithTenant)。
|
||||
func (s *sTenant) Account(ctx context.Context, req *v1.TenantAccountReq) (res *v1.TenantAccountRes, err error) {
|
||||
// 租户:自增回填(临时编码占位 → T%04d 修正)
|
||||
tempCode := fmt.Sprintf("T%010d", time.Now().UnixNano()%10000000000)
|
||||
tData := map[string]any{
|
||||
"name": req.Name,
|
||||
"code": tempCode,
|
||||
"contact": req.Contact,
|
||||
"mobile": req.Mobile,
|
||||
"email": req.Email,
|
||||
"address": req.Address,
|
||||
"status": 1,
|
||||
"max_user_num": req.MaxUserNum,
|
||||
"note": req.Note,
|
||||
if !consts.IsPlatform(ctx) {
|
||||
return nil, gerror.NewCode(consts.CodeForbidden)
|
||||
}
|
||||
if req.ExpireTime != "" {
|
||||
if t := gtime.New(req.ExpireTime); t != nil {
|
||||
tData["expire_time"] = t
|
||||
}
|
||||
// 目标租户存在性校验(同时取编码供响应回传)
|
||||
one, e := dao.Tenant.Ctx(ctx).Where("id", req.TenantId).Fields("code").One()
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
// bcrypt 属 CPU 密集操作,放在事务外预计算(短事务纪律)
|
||||
salt := crypto.GenerateSalt()
|
||||
hashed, err := crypto.HashPassword(req.Password, salt)
|
||||
if len(one) == 0 {
|
||||
return nil, gerror.NewCode(consts.CodeTenantNotFound)
|
||||
}
|
||||
// 用户表单字段转用户新增入参,按目标租户落库
|
||||
idRes, err := (&sUser{}).addWithTenant(ctx, req.TenantId, &v1.UserAddReq{
|
||||
Username: req.Username,
|
||||
Password: req.Password,
|
||||
Realname: req.Realname,
|
||||
Gender: req.Gender,
|
||||
Mobile: req.Mobile,
|
||||
Email: req.Email,
|
||||
Roles: req.Roles,
|
||||
DeptId: req.DeptId,
|
||||
LevelId: req.LevelId,
|
||||
PositionId: req.PositionId,
|
||||
City: req.City,
|
||||
Address: req.Address,
|
||||
Avatar: req.Avatar,
|
||||
Intro: req.Intro,
|
||||
Status: req.Status,
|
||||
Sort: req.Sort,
|
||||
Note: req.Note,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
realname := req.Realname
|
||||
if realname == "" {
|
||||
realname = req.Username
|
||||
}
|
||||
|
||||
// 租户 + 初始管理员三段写入保持原子性(全部经 txCtx)
|
||||
var tenantId, uid int64
|
||||
var code string
|
||||
if err = WithTrans(ctx, func(txCtx context.Context) error {
|
||||
tResult, e := dao.Tenant.Ctx(txCtx).Data(tData).Insert()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
tenantId, _ = tResult.LastInsertId()
|
||||
code = fmt.Sprintf("T%04d", tenantId)
|
||||
if _, e = dao.Tenant.Ctx(txCtx).Where("id", tenantId).Data(map[string]any{"code": code}).Update(); e != nil {
|
||||
return e
|
||||
}
|
||||
// 初始管理员(tenant_id 由 hooks 自动填充)
|
||||
tenantCtx := consts.WithTenantID(txCtx, int(tenantId))
|
||||
uResult, e := dao.User.Ctx(tenantCtx).Data(map[string]any{
|
||||
"username": req.Username,
|
||||
"code": fmt.Sprintf("%s-000001", code), // 首个用户序号 000001
|
||||
"password": hashed,
|
||||
"salt": salt,
|
||||
"realname": realname,
|
||||
"mobile": req.Mobile,
|
||||
"email": req.Email,
|
||||
"province_code": "",
|
||||
"city_code": "",
|
||||
"district_code": "",
|
||||
"street_code": "",
|
||||
"address": "",
|
||||
"status": 1,
|
||||
"tenant_id": int(tenantId),
|
||||
}).Insert()
|
||||
if e != nil {
|
||||
return e
|
||||
}
|
||||
uid, _ = uResult.LastInsertId()
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &v1.TenantAccountRes{TenantId: tenantId, Code: code, UserId: uid}, nil
|
||||
return &v1.TenantAccountRes{
|
||||
TenantId: int64(req.TenantId),
|
||||
Code: one["code"].String(),
|
||||
UserId: idRes.Id,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Users 查询租户用户列表
|
||||
|
||||
Reference in New Issue
Block a user