package applogic import ( "context" "fmt" "strings" "time" "aijianzhan/platform/internal/authx" "aijianzhan/platform/internal/invitestore" "aijianzhan/platform/internal/svc" "aijianzhan/platform/internal/types" "aijianzhan/platform/internal/userstore" ) func (l *AuthLogic) issueUser(u *userstore.User) (*types.TokenResp, error) { resp, err := l.issue(u.TenantID, u.UserID, u.Role, u.Username, u.DisplayName, u.OrgUnitID) if err != nil { return nil, err } resp.Phone = u.Phone resp.UsernameLoginDisabled = u.UsernameLoginDisabled resp.Status = u.Status if resp.Status == "" { if u.HasTenant() || u.IsPlatformAdmin() { resp.Status = userstore.StatusActive } else { resp.Status = userstore.StatusPending } } fillUserSyncOnToken(l.svcCtx, resp, u) if u.IsPlatformAdmin() { resp.Message = "平台超级管理员工作台:管理全部公司;打开某公司可查看其内部功能" return resp, nil } if !u.HasTenant() { resp.Message = "账号待加入租户:请使用邀请码加入公司,或创建自己的公司" } return resp, nil } func (l *AuthLogic) AcceptInvite(req *types.InviteAcceptReq) (*types.TokenResp, error) { if l.svcCtx.Users == nil || l.svcCtx.Invites == nil { return nil, fmt.Errorf("invite store unavailable") } code := strings.TrimSpace(req.Code) if code == "" { return nil, fmt.Errorf("invite code required") } userID := authx.UserID(l.ctx) cur, err := l.svcCtx.Users.GetByID(l.ctx, userID) if err != nil { return nil, err } if cur.HasTenant() { return nil, fmt.Errorf("already joined a tenant") } inv, err := l.svcCtx.Invites.GetByCode(l.ctx, code) if err != nil { return nil, fmt.Errorf("invalid invite code") } if err := invitestore.ValidateUsable(inv); err != nil { return nil, err } if inv.OrgUnitID > 0 && l.svcCtx.OrgUnits != nil { if _, err := l.svcCtx.OrgUnits.Get(l.ctx, inv.TenantID, inv.OrgUnitID); err != nil { return nil, fmt.Errorf("invite org unit invalid") } } if err := l.svcCtx.Invites.Consume(l.ctx, inv.InviteID); err != nil { return nil, err } u, err := l.svcCtx.Users.JoinTenant(l.ctx, userID, inv.TenantID, inv.Role, inv.OrgUnitID) if err != nil { return nil, err } if l.svcCtx.Roles != nil { _ = l.svcCtx.Roles.EnsureDefaults(l.ctx, u.TenantID) } resp, err := l.issueUser(u) if err != nil { return nil, err } resp.Message = "已加入租户" return resp, nil } func (l *AuthLogic) CreateTenant(req *types.TenantCreateReq) (*types.TokenResp, error) { if l.svcCtx.Users == nil { return nil, fmt.Errorf("user store unavailable") } userID := authx.UserID(l.ctx) u, err := l.svcCtx.Users.CreateTenantAsOwner(l.ctx, userID, req.Name) if err != nil { return nil, err } if l.svcCtx.Roles != nil { _ = l.svcCtx.Roles.EnsureDefaults(l.ctx, u.TenantID) } if l.svcCtx.TenantPerm != nil { _ = l.svcCtx.TenantPerm.EnsureDefault(l.ctx, u.TenantID) } resp, err := l.issueUser(u) if err != nil { return nil, err } resp.Message = "已创建公司并成为管理员" return resp, nil } type InviteAdminLogic struct { AuthLogic } func NewInviteAdminLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InviteAdminLogic { return &InviteAdminLogic{AuthLogic: AuthLogic{ctx: ctx, svcCtx: svcCtx}} } func (l *InviteAdminLogic) List() ([]invitestore.Invite, error) { if l.svcCtx.Invites == nil { return nil, fmt.Errorf("invite store unavailable") } return l.svcCtx.Invites.List(l.ctx, authx.TenantID(l.ctx)) } func (l *InviteAdminLogic) Create(req *types.InviteCreateReq) (*invitestore.Invite, error) { if l.svcCtx.Invites == nil { return nil, fmt.Errorf("invite store unavailable") } tid := authx.TenantID(l.ctx) if req.OrgUnitID > 0 { if l.svcCtx.OrgUnits == nil { return nil, fmt.Errorf("org unit store unavailable") } if _, err := l.svcCtx.OrgUnits.Get(l.ctx, tid, req.OrgUnitID); err != nil { return nil, fmt.Errorf("invalid org_unit_id") } } in := invitestore.CreateInput{ Role: req.Role, OrgUnitID: req.OrgUnitID, MaxUses: req.MaxUses, } if req.ExpiresInHours > 0 { in.ExpiresIn = time.Duration(req.ExpiresInHours) * time.Hour } return l.svcCtx.Invites.Create(l.ctx, tid, authx.UserID(l.ctx), in) } func (l *InviteAdminLogic) Revoke(inviteID int64) error { if l.svcCtx.Invites == nil { return fmt.Errorf("invite store unavailable") } return l.svcCtx.Invites.Revoke(l.ctx, authx.TenantID(l.ctx), inviteID) }