修复个人中心问题
This commit is contained in:
@@ -2,12 +2,14 @@ package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"server/models"
|
||||
"server/pkg/jwtutil"
|
||||
"server/pkg/passwordutil"
|
||||
"server/services"
|
||||
|
||||
@@ -28,6 +30,7 @@ type backendUserInfoDTO struct {
|
||||
Name *string `json:"name"`
|
||||
Phone *string `json:"phone"`
|
||||
Email *string `json:"email"`
|
||||
Avatar *string `json:"avatar"`
|
||||
Sex uint8 `json:"sex"`
|
||||
Birth *string `json:"birth"`
|
||||
IsDefault int8 `json:"is_default"`
|
||||
@@ -94,6 +97,12 @@ func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO {
|
||||
tenantCode = tenant.TenantCode
|
||||
}
|
||||
|
||||
// 头像取自认证中心身份(业务用户表 yz_system_tenant_user 不存头像)
|
||||
var avatar *string
|
||||
if a := services.GetIdentityAvatar(u.Uid); a != "" {
|
||||
avatar = &a
|
||||
}
|
||||
|
||||
return backendUserInfoDTO{
|
||||
ID: u.ID,
|
||||
Tid: u.Tid,
|
||||
@@ -103,6 +112,7 @@ func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO {
|
||||
Name: u.Name,
|
||||
Phone: u.Phone,
|
||||
Email: u.Email,
|
||||
Avatar: avatar,
|
||||
Sex: u.Sex,
|
||||
Birth: formatBackendBirth(u.Birth),
|
||||
IsDefault: u.IsDefault,
|
||||
@@ -115,21 +125,43 @@ func toBackendUserInfoDTO(u models.SystemTenantUser) backendUserInfoDTO {
|
||||
}
|
||||
}
|
||||
|
||||
// getJWTUidTid 取当前登录者标识:
|
||||
// - uid:令牌里的 user_id,即认证中心 identity_id
|
||||
// - tid:令牌里的 tenant_id
|
||||
//
|
||||
// 键名历史上有两套写法(uid/tid 与 userId/tenantId),这里都兼容;
|
||||
// 中间件在 warn/off 模式下可能没有注入,故再兜底自行解析 Authorization 头,
|
||||
// 否则会静默拿到 0(曾导致按 identity_id 直查老表、显示到别人的资料)。
|
||||
func (c *BackendAdminUserController) getJWTUidTid() (uint64, uint64) {
|
||||
var uid uint64
|
||||
var tid uint64
|
||||
|
||||
data := c.Ctx.Input.Data()
|
||||
|
||||
if jwtUid := data["uid"]; jwtUid != nil {
|
||||
if v, ok := jwtUid.(uint64); ok {
|
||||
for _, key := range []string{"uid", "userId"} {
|
||||
if v, ok := data[key].(uint64); ok && v > 0 {
|
||||
uid = v
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"tid", "tenantId"} {
|
||||
if v, ok := data[key].(uint64); ok && v > 0 {
|
||||
tid = v
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if jwtTid := data["tid"]; jwtTid != nil {
|
||||
if v, ok := jwtTid.(uint64); ok {
|
||||
tid = v
|
||||
if uid == 0 || tid == 0 {
|
||||
auth := c.Ctx.Request.Header.Get("Authorization")
|
||||
if parts := strings.SplitN(auth, " ", 2); len(parts) == 2 && parts[0] == "Bearer" {
|
||||
if claims, err := jwtutil.ParseToken(parts[1]); err == nil {
|
||||
if uid == 0 {
|
||||
uid = uint64(claims.UserID)
|
||||
}
|
||||
if tid == 0 {
|
||||
tid = uint64(claims.TenantId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,33 +181,44 @@ func (c *BackendAdminUserController) parseTenantUserPayload() (backendTenantUser
|
||||
return p, true
|
||||
}
|
||||
|
||||
// findBackendTenantUser 按「用户在认证中心的 identity_id」或「记录主键 id」查租户用户。
|
||||
//
|
||||
// 注意查询顺序:令牌/前端传来的用户标识是认证中心 identity_id,而
|
||||
// yz_system_tenant_user.uid 仍是老 uid(老表不在 uid 全量迁移范围内),
|
||||
// 因此必须先换算再按 uid 查;先按主键 id 查会把 identity_id 命中的是
|
||||
// 主键恰好相同的**别人**的记录(个人中心显示他人资料就是这么来的)。
|
||||
func findBackendTenantUser(idOrUid uint64, jwtTid uint64) (*models.SystemTenantUser, error) {
|
||||
var row models.SystemTenantUser
|
||||
|
||||
qs := models.Orm.QueryTable(new(models.SystemTenantUser)).
|
||||
Filter("delete_time__isnull", true)
|
||||
|
||||
if jwtTid > 0 {
|
||||
qs = qs.Filter("tid", jwtTid)
|
||||
if idOrUid == 0 {
|
||||
return nil, errors.New("用户ID不能为空")
|
||||
}
|
||||
|
||||
err := qs.Filter("id", idOrUid).One(&row)
|
||||
if err == nil {
|
||||
base := func() orm.QuerySeter {
|
||||
qs := models.Orm.QueryTable(new(models.SystemTenantUser)).
|
||||
Filter("delete_time__isnull", true)
|
||||
if jwtTid > 0 {
|
||||
qs = qs.Filter("tid", jwtTid)
|
||||
}
|
||||
return qs
|
||||
}
|
||||
|
||||
// 1) 当作 identity_id:换算成本租户老 uid 后匹配
|
||||
var row models.SystemTenantUser
|
||||
if uid := services.ResolveTenantUID(jwtTid, idOrUid); uid > 0 {
|
||||
if err := base().Filter("uid", uid).One(&row); err == nil {
|
||||
return &row, nil
|
||||
}
|
||||
}
|
||||
|
||||
// 2) 当作记录主键 id(用户管理页传的就是 row.id)
|
||||
if err := base().Filter("id", idOrUid).One(&row); err == nil {
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
qs = models.Orm.QueryTable(new(models.SystemTenantUser)).
|
||||
Filter("delete_time__isnull", true)
|
||||
|
||||
if jwtTid > 0 {
|
||||
qs = qs.Filter("tid", jwtTid)
|
||||
}
|
||||
|
||||
err = qs.Filter("uid", idOrUid).One(&row)
|
||||
// 3) 兜底:本来就是老 uid 的场景
|
||||
err := base().Filter("uid", idOrUid).One(&row)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
@@ -355,7 +398,15 @@ func (c *BackendAdminUserController) AddUser() {
|
||||
p.Password = &hashed
|
||||
|
||||
if p.Uid == 0 {
|
||||
uid, err := generateTenantUID(p.Tid)
|
||||
// 统一走 uid:优先用认证中心 identity_id,与已全量迁移的业务表口径一致
|
||||
uid, err := ensureTenantUIDForNewUser(
|
||||
p.Tid,
|
||||
strOrEmpty(p.Account),
|
||||
strOrEmpty(p.Name),
|
||||
strOrEmpty(p.Phone),
|
||||
strOrEmpty(p.Email),
|
||||
strOrEmpty(p.Password),
|
||||
)
|
||||
if err != nil {
|
||||
c.Data["json"] = map[string]interface{}{"code": 500, "msg": "生成用户ID失败"}
|
||||
_ = c.ServeJSON()
|
||||
|
||||
Reference in New Issue
Block a user