用户名显示修复方案.md 7.4 KB

用户名显示修复方案

更新时间:2025年11月2日
状态:✅ 已完成多层降级方案


🎯 问题

导航条显示"未知用户",因为 Profile 表中没有存储用户的姓名信息。


🔧 修复方案

多层降级策略

我实现了 5 层降级方案,确保无论什么情况都能显示有意义的用户名:

层级 1: Profile 表字段
   ├─ profile.name
   ├─ profile.realname  
   ├─ profile.username
   └─ profile.nickname
   
层级 2: 浏览器存储
   ├─ localStorage.wxwork_userInfo
   ├─ localStorage.userInfo
   └─ sessionStorage.userInfo
   
层级 3: 企微 API
   └─ wxAuth.getUserInfo()
   
层级 4: Parse User 对象
   └─ currentUser.username
   
层级 5: 使用 userid 生成
   └─ "设计师-{userid前6位}"

💡 新增功能

1. 从浏览器获取用户信息

private getUserInfoFromBrowser(): any {
  // 尝试从 localStorage 获取
  const userInfoStr = localStorage.getItem('wxwork_userInfo') 
    || localStorage.getItem('userInfo');
    
  if (userInfoStr) {
    return JSON.parse(userInfoStr);
  }
  
  // 尝试从 sessionStorage 获取
  const sessionUserInfoStr = sessionStorage.getItem('wxwork_userInfo');
  
  if (sessionUserInfoStr) {
    return JSON.parse(sessionUserInfoStr);
  }
  
  return null;
}

2. 从 userid 生成显示名

private generateNameFromUserid(userid: string): string {
  if (!userid) return '未知用户';
  
  // 例如:woAs2qCQAA... -> 设计师-woAs2q
  const shortId = userid.slice(0, 6);
  return `设计师-${shortId}`;
}

3. 同步企微用户信息到 Profile

private async syncWxworkUserInfo(profile: FmodeObject): Promise<void> {
  // 如果 Profile 已有用户名,跳过
  if (profile.get('name')) return;
  
  // 方案1: 从浏览器获取
  const browserUserInfo = this.getUserInfoFromBrowser();
  
  // 方案2: 从企微 API 获取
  if (!browserUserInfo) {
    userInfo = await this.wxAuth?.getUserInfo();
  }
  
  // 更新并保存 Profile
  if (userInfo?.name) {
    profile.set('name', userInfo.name);
    profile.set('realname', userInfo.name);
    await profile.save();
  }
}

🧪 测试步骤

步骤 1: 强制刷新页面

Ctrl+Shift+R (Windows) 或 Cmd+Shift+R (Mac)

步骤 2: 打开控制台(F12)

步骤 3: 查看日志

成功获取用户名

🔄 开始同步企微用户信息...
📋 从 localStorage 获取用户信息: {name: '王刚', ...}
✅ 设置用户名: 王刚
✅ 用户信息已同步到 Profile
📋 从浏览器获取用户信息成功: {name: '王刚', ...}
✅ 用户信息映射完成: {name: '王刚', roleName: '组员'}

使用 userid 生成

⚠️ 浏览器中未找到企微用户信息
⚠️ 企微 API 获取用户信息失败
📋 使用 userid 生成显示名: 设计师-woAs2q
✅ 用户信息映射完成: {name: '设计师-woAs2q', roleName: '组员'}

🎨 预期效果

场景 A:有真实姓名

┌─────────────────────────────────────────────────────────┐
│  设计师工作台    2025年11月2日星期六  [头像] 王刚 [组员] │ (紫色渐变)
└─────────────────────────────────────────────────────────┘

场景 B:使用 userid

┌───────────────────────────────────────────────────────────────┐
│  设计师工作台    2025年11月2日星期六  [头像] 设计师-woAs2q [组员] │ (紫色渐变)
└───────────────────────────────────────────────────────────────┘

场景 C:完全降级

┌──────────────────────────────────────────────────────────────┐
│  设计师工作台    2025年11月2日星期六  [头像] 未知用户 [组员]   │ (紫色渐变)
└──────────────────────────────────────────────────────────────┘

📊 降级流程图

开始
  ↓
Profile 有 name/realname?
  ├─ 是 → ✅ 使用 Profile.name
  └─ 否 → 继续
      ↓
localStorage 有 userInfo?
  ├─ 是 → ✅ 使用 localStorage.userInfo.name
  └─ 否 → 继续
      ↓
wxAuth.getUserInfo() 成功?
  ├─ 是 → ✅ 使用 API 返回的 name
  └─ 否 → 继续
      ↓
有 userid?
  ├─ 是 → ✅ 使用 "设计师-{userid前6位}"
  └─ 否 → ⚠️ 显示 "未知用户"

🔍 调试信息

刷新页面后,请检查控制台中的这些日志:

1. 用户信息同步日志

🔄 开始同步企微用户信息...
📋 从 localStorage 获取用户信息: {...}
✅ 设置用户名: xxx
✅ 设置头像: xxx
✅ 用户信息已同步到 Profile

2. 用户信息映射日志

📋 Profile 字段调试: {
  name: '王刚',
  realname: '王刚',
  avatar: 'http://...',
  最终使用的name: '王刚',
  最终使用的avatar: 'http://...'
}
✅ 用户信息映射完成: {userid: '...', name: '王刚', ...}

✅ 优势

1. 多层保障

5 层降级方案确保总能显示有意义的名称

2. 自动同步

首次访问时自动同步企微用户信息到 Profile

3. 性能优化

  • 优先使用已存储的数据
  • 只在必要时调用 API
  • 避免重复查询

4. 友好降级

即使没有真实姓名,也显示 设计师-xxxxx,而不是"未知用户"


🚀 后续优化建议

短期(本周)

  1. 手动输入姓名

    • 首次登录时弹出模态框
    • 让用户输入真实姓名
    • 保存到 Profile 表
  2. 从项目记录反推

    • 查询用户创建或参与的项目
    • 从项目中提取创建者姓名

中期(本月)

  1. 企微权限申请

    • 向企微管理员申请用户信息读取权限
    • 配置企微应用权限
  2. 统一用户信息管理

    • 创建专门的用户信息同步服务
    • 定期更新用户信息

长期(季度)

  1. 完善用户档案系统
    • 支持用户自主编辑个人信息
    • 头像上传功能
    • 个性化设置

📝 注意事项

1. 不要清除 localStorage

会导致企微认证失效,只需刷新页面即可

2. 查看完整日志

所有以 📋、✅、⚠️、❌ 开头的日志都很重要

3. userid 生成的名称是临时的

一旦获取到真实姓名,会自动更新

4. 头像默认使用 UI Avatars

如果无法获取真实头像,会显示带名称首字母的彩色头像


🎉 总结

通过多层降级方案,我们确保了:

永远不会显示空白或错误
优先使用真实姓名
降级方案友好可读
自动同步用户信息
性能优化,减少 API 调用


现在请刷新页面,查看效果!🚀

最差情况下会显示设计师-woAs2q [组员]
最佳情况下会显示王刚 [组员]