package user import ( "context" "perms-system-server/internal/middleware" "perms-system-server/internal/response" "perms-system-server/internal/svc" "perms-system-server/internal/types" "github.com/zeromicro/go-zero/core/logx" ) type UserDetailLogic struct { logx.Logger ctx context.Context svcCtx *svc.ServiceContext } func NewUserDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserDetailLogic { return &UserDetailLogic{ Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx, } } // UserDetail 用户详情。查询指定用户的基本信息和当前产品下的角色绑定。产品成员只能查看同产品下用户,超管可查看任意用户。 func (l *UserDetailLogic) UserDetail(req *types.UserDetailReq) (resp *types.UserItem, err error) { caller := middleware.GetUserDetails(l.ctx) if caller == nil { return nil, response.ErrUnauthorized("未登录") } if !caller.IsSuperAdmin { if caller.ProductCode == "" { return nil, response.ErrForbidden("会话缺少产品上下文") } if _, err := l.svcCtx.SysProductMemberModel.FindOneByProductCodeUserId(l.ctx, caller.ProductCode, req.Id); err != nil { return nil, response.ErrForbidden("无权查看非本产品成员的用户信息") } } user, err := l.svcCtx.SysUserModel.FindOne(l.ctx, req.Id) if err != nil { return nil, response.ErrNotFound("用户不存在") } productCode := middleware.GetProductCode(l.ctx) var roleIds []int64 if productCode != "" { roleIds, err = l.svcCtx.SysUserRoleModel.FindRoleIdsByUserIdForProduct(l.ctx, user.Id, productCode) } else { roleIds, err = l.svcCtx.SysUserRoleModel.FindRoleIdsByUserId(l.ctx, user.Id) } if err != nil { return nil, err } avatar := "" if user.Avatar.Valid { avatar = user.Avatar.String } // 审计 M-R16-1:与 UserList 同口径——只在 SuperAdmin / 产品 ADMIN / 产品 DEVELOPER / caller 本人 // 才回填 email/phone/remark;普通 MEMBER 看他人时三个 PII 字段置空,避免全员通讯录外泄。 email, phone, remark := maskUserPII(caller, user) return &types.UserItem{ Id: user.Id, Username: user.Username, Nickname: user.Nickname, Avatar: avatar, Email: email, Phone: phone, Remark: remark, DeptId: user.DeptId, Status: user.Status, RoleIds: roleIds, CreateTime: user.CreateTime, }, nil }