修复个人中心问题

This commit is contained in:
2026-09-29 18:25:09 +08:00
parent 0dc5c2f075
commit ca4220f92c
44 changed files with 1793 additions and 310 deletions
+75 -24
View File
@@ -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()