做统一认证登录
This commit is contained in:
@@ -0,0 +1,148 @@
|
||||
// Package auth 统一认证中心(UAC)业务层。
|
||||
//
|
||||
// 认证中心只负责「你是谁、你能进哪些企业、你能用哪些应用」,
|
||||
// 菜单/按钮/数据权限仍由各业务端自治。
|
||||
package auth
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
|
||||
"server/models"
|
||||
)
|
||||
|
||||
// TenantOption 登录后可选择进入的企业(一人可在多家企业任职)
|
||||
type TenantOption struct {
|
||||
Tid uint64 `json:"tid"`
|
||||
TenantName string `json:"tenant_name"`
|
||||
Name string `json:"name"`
|
||||
GroupID uint64 `json:"group_id"`
|
||||
OrgID uint64 `json:"org_id"`
|
||||
IsDefault bool `json:"is_default"`
|
||||
}
|
||||
|
||||
// IdentityProfile 认证中心视角的身份概要
|
||||
type IdentityProfile struct {
|
||||
ID uint64 `json:"id"`
|
||||
UnionID string `json:"union_id"`
|
||||
Mobile string `json:"mobile"`
|
||||
Email string `json:"email"`
|
||||
Nickname string `json:"nickname"`
|
||||
Avatar string `json:"avatar"`
|
||||
Status int8 `json:"status"`
|
||||
MfaOn bool `json:"mfa_enabled"`
|
||||
Tenants []TenantOption `json:"tenants"`
|
||||
}
|
||||
|
||||
// FindIdentityByAccount 按登录账号查找身份。
|
||||
// 匹配顺序:手机号 → 邮箱 → 企业内账号(先查绑定再回查身份)。
|
||||
func FindIdentityByAccount(account string) (*models.AuthIdentity, error) {
|
||||
account = strings.TrimSpace(account)
|
||||
if account == "" {
|
||||
return nil, orm.ErrNoRows
|
||||
}
|
||||
base := models.Orm.QueryTable(new(models.AuthIdentity)).Filter("delete_time__isnull", true)
|
||||
|
||||
for _, field := range []string{"mobile", "email"} {
|
||||
m := &models.AuthIdentity{}
|
||||
if err := base.Filter(field, account).One(m); err == nil {
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 企业内账号:yz_auth_tenant_user.account → identity_id
|
||||
var bind models.AuthTenantUser
|
||||
if err := models.Orm.QueryTable(new(models.AuthTenantUser)).
|
||||
Filter("account", account).
|
||||
Filter("delete_time__isnull", true).
|
||||
OrderBy("-is_default", "id").
|
||||
One(&bind); err == nil {
|
||||
m := &models.AuthIdentity{}
|
||||
if err := models.Orm.QueryTable(new(models.AuthIdentity)).Filter("id", bind.IdentityID).One(m); err == nil {
|
||||
return m, nil
|
||||
}
|
||||
}
|
||||
return nil, orm.ErrNoRows
|
||||
}
|
||||
|
||||
// ListTenantOptions 列出该身份可登录的企业(过滤企业停用与绑定停用)。
|
||||
func ListTenantOptions(identityID uint64) ([]TenantOption, error) {
|
||||
var binds []models.AuthTenantUser
|
||||
if _, err := models.Orm.QueryTable(new(models.AuthTenantUser)).
|
||||
Filter("identity_id", identityID).
|
||||
Filter("status", 1).
|
||||
Filter("delete_time__isnull", true).
|
||||
OrderBy("-is_default", "id").
|
||||
All(&binds); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := make([]TenantOption, 0, len(binds))
|
||||
for _, b := range binds {
|
||||
var tenant models.SystemTenant
|
||||
if err := models.Orm.QueryTable(new(models.SystemTenant)).
|
||||
Filter("id", b.Tid).
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&tenant); err != nil {
|
||||
continue // 租户不存在或已删除
|
||||
}
|
||||
if tenant.Status != 1 {
|
||||
continue // 租户停用
|
||||
}
|
||||
opt := TenantOption{
|
||||
Tid: b.Tid,
|
||||
TenantName: strings.TrimSpace(tenant.TenantName),
|
||||
GroupID: b.GroupID,
|
||||
OrgID: b.OrgID,
|
||||
IsDefault: b.IsDefault == 1,
|
||||
}
|
||||
if b.Name != nil {
|
||||
opt.Name = strings.TrimSpace(*b.Name)
|
||||
}
|
||||
out = append(out, opt)
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// GetTenantUser 获取身份在指定企业的绑定关系
|
||||
func GetTenantUser(identityID, tid uint64) (*models.AuthTenantUser, error) {
|
||||
var bind models.AuthTenantUser
|
||||
err := models.Orm.QueryTable(new(models.AuthTenantUser)).
|
||||
Filter("identity_id", identityID).
|
||||
Filter("tid", tid).
|
||||
Filter("delete_time__isnull", true).
|
||||
One(&bind)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &bind, nil
|
||||
}
|
||||
|
||||
// BuildProfile 组装身份概要(含可选企业列表)
|
||||
func BuildProfile(m *models.AuthIdentity) (*IdentityProfile, error) {
|
||||
tenants, err := ListTenantOptions(m.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p := &IdentityProfile{
|
||||
ID: m.ID,
|
||||
UnionID: m.UnionID,
|
||||
Status: m.Status,
|
||||
MfaOn: m.MfaEnabled == 1,
|
||||
Tenants: tenants,
|
||||
}
|
||||
if m.Mobile != nil {
|
||||
p.Mobile = *m.Mobile
|
||||
}
|
||||
if m.Email != nil {
|
||||
p.Email = *m.Email
|
||||
}
|
||||
if m.Nickname != nil {
|
||||
p.Nickname = *m.Nickname
|
||||
}
|
||||
if m.Avatar != nil {
|
||||
p.Avatar = *m.Avatar
|
||||
}
|
||||
return p, nil
|
||||
}
|
||||
Reference in New Issue
Block a user