package service import ( "context" "fmt" "taotie-api/common" "taotie-api/core" "taotie-api/model/do/userdo" "taotie-api/model/po" "taotie-api/repo" "taotie-api/utils/sctx" "taotie-api/utils/sjwt" "time" "github.com/gookit/goutil/errorx" ) type UserService struct { cfg *core.Configuration userRepo *repo.UserRepo[*po.TUser] tenantRepo *repo.TenantRepo[*po.TTenant] } func NewUserService(mdb *repo.MongoDb, cfg *core.Configuration, userRepo *repo.UserRepo[*po.TUser], tenantRepo *repo.TenantRepo[*po.TTenant]) *UserService { return &UserService{ cfg, userRepo, tenantRepo, } } // Login 登录 func (s *UserService) Login(ctx context.Context, in *userdo.LoginIn) (*userdo.LoginOut, error) { // 验证租户 ttenant, err := s.tenantRepo.FindOneByTenantNo(ctx, in.TenantNo) if err != nil { return nil, err } if ttenant == nil { return nil, common.ErrUserTenantNotFound } // 验证用户 tuser, err := s.userRepo.FindOneByTenantIdAndUserName(ctx, ttenant.Id(), in.UserName) if err != nil { return nil, err } if tuser == nil { return nil, common.ErrUserNotFound } if tuser.Password != in.Password { return nil, common.ErrUserPasswordError } return &userdo.LoginOut{ TenantId: ttenant.Id(), UserId: tuser.Id(), UserName: tuser.UserName, }, nil } // GenToken 生成token func (s *UserService) GenToken(ctx context.Context, in *userdo.GenTokenIn) (*userdo.GenTokenOut, error) { token, err := sjwt.GenerateToken(in.TenantNo, in.UserId, in.UserName, s.cfg.JWT.TimeOut, s.cfg.JWT.SignString) if err != nil { return nil, err } return &userdo.GenTokenOut{ Token: token, }, nil } func (s *UserService) Create(ctx context.Context, in *userdo.CreateIn) (*userdo.CreateOut, error) { // 查重:租户名称 ttenant, err := s.tenantRepo.FindOneByTenantName(ctx, in.TenantName) if err != nil { return nil, err } if ttenant != nil { return nil, errorx.With(common.ErrSysDuplicate, "租户名称重复") } // 先设置临时用户到 context(避免 BaseRepo.Create 中 cuser 为 nil 导致 panic) sctx.SetCurrentUser(ctx, &sctx.CurrentUser{ UserId: "", UserName: in.UserName, TenantId: "", }) // 生成 tenantNo(基于时间戳) tenantNo := fmt.Sprintf("T%d", time.Now().UnixMilli()) // 创建租户 ttenant = &po.TTenant{ TenantNo: tenantNo, TenantName: in.TenantName, } tenantId, err := s.tenantRepo.Create(ctx, ttenant) if err != nil { return nil, err } // 更新 context 中的 TenantId sctx.SetCurrentUser(ctx, &sctx.CurrentUser{ UserId: "", UserName: in.UserName, TenantId: tenantId, }) // 创建用户 tuser := &po.TUser{ UserName: in.UserName, Password: in.Password, } userId, err := s.userRepo.Create(ctx, tuser) if err != nil { return nil, err } return &userdo.CreateOut{ TenantId: tenantId, UserId: userId, UserName: in.UserName, }, nil }