profile-activation-auto-fix.md 12 KB

Profile激活状态自动修复 - 问题排查与解决

🔥 问题描述

症状:员工填写了基本信息(姓名、部门、角色、手机),但仍然无法访问项目管理页面,被重定向到"用户身份确认"页面

日志表现

✅ 用户信息获取成功: Object
📋 激活状态: false  ← 🔥 问题关键
📝 问卷状态: false
📝 自动填充表单数据: Object

影响范围

  • 员工ID:woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg
  • 可能还有其他已填写信息但未点击"确认激活"的员工

🔍 根本原因

激活流程不完整

正常激活流程

1. 用户访问激活页面
   ↓
2. 自动填充基本信息(从企微获取)
   ↓
3. 用户编辑/确认信息
   ↓
4. 点击"确认激活"按钮  ← 🔥 关键步骤
   ↓
5. 设置 isActivated = true
   ↓
6. 保存到数据库
   ↓
7. 可以访问其他页面 ✅

问题流程

1. 用户访问激活页面
   ↓
2. 自动填充基本信息
   ↓
3. 用户编辑/确认信息
   ↓
4. ❌ 直接关闭页面或刷新(未点击确认激活)
   ↓
5. isActivated 保持为 false
   ↓
6. 无法访问其他页面 ❌

Profile表字段状态

问题用户的Profile记录

{
  userid: 'woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg',
  realname: '请填与姓名',           // ✅ 已填写
  departmentName: '所属部门',        // ✅ 已填写
  roleName: '员工',                  // ✅ 已填写
  mobile: '13800138000',             // ✅ 已填写
  isActivated: false,                // ❌ 未激活
  surveyCompleted: false,            // ❌ 未完成问卷
  activatedAt: null                  // ❌ 无激活时间
}

✅ 解决方案

方案1:自动修复逻辑(推荐)✅

profile-activation.component.tscheckActivationStatus()方法中添加自动修复逻辑:

修复代码

// 🔥 关键修复2:如果Profile存在但未激活,判断是否需要自动激活
// 🔥 判断条件:已填写过基本信息的用户(老用户)才自动激活,新用户仍需填写
if (!this.isActivated && this.profile) {
  // 判断是否为"已填写过信息的老用户"
  const hasBasicInfo = !!(
    this.profile.get('realname') || 
    this.profile.get('name') ||
    this.profile.get('departmentName') ||
    this.profile.get('roleName') ||
    this.profile.get('mobile')
  );
  
  const hasActivatedBefore = !!this.profile.get('activatedAt');
  const hasSurveyData = !!this.profile.get('surveyCompleted');
  
  // 满足以下任一条件的老用户,自动激活:
  // 1. 填写过基本信息(realname/name/departmentName/roleName/mobile任一存在)
  // 2. 曾经激活过(有activatedAt字段)
  // 3. 完成过问卷(surveyCompleted=true)
  if (hasBasicInfo || hasActivatedBefore || hasSurveyData) {
    console.log('🔧 检测到老用户(已填写过信息),自动设置激活状态...');
    
    this.profile.set('isActivated', true);
    if (!this.profile.get('activatedAt')) {
      this.profile.set('activatedAt', new Date());
    }
    await this.profile.save();
    
    console.log('✅ 已自动设置激活状态');
    this.isActivated = true;
  } else {
    console.log('ℹ️ 检测到新用户(未填写过信息),需要完成激活流程');
  }
}

触发条件(满足任一即可自动激活)

  1. 填写过基本信息realname / name / departmentName / roleName / mobile 任一存在
  2. 曾经激活过activatedAt 字段存在
  3. 完成过问卷surveyCompleted = true

修复原理

  • 精准区分老用户和新用户:已填写过信息的老用户自动激活,新用户仍需填写
  • 保留激活流程:新员工首次访问时,仍然需要完成激活表单
  • 修复徐福静等老用户:已经填写过信息或完成过问卷的用户,不需要重复填写
  • 兼容历史数据:曾经激活过的用户(有activatedAt字段),也会自动激活

修复效果

  • ✅ 用户下次访问时自动激活
  • ✅ 无需重新填写信息
  • ✅ 自动设置activatedAt时间戳
  • ✅ 自动跳转回原始URL

方案2:用户手动重新激活

步骤

  1. 员工重新访问激活页面:/wxwork/{cid}/activation
  2. 确认信息正确
  3. 点击"确认激活"按钮
  4. 等待跳转

注意:这个方案需要员工操作,不如方案1自动


方案3:数据库手动修复

使用修复工具(如果有的话):

访问:/admin/employee-activation-fix
1. 点击"扫描所有员工"
2. 找到未激活但已填写信息的员工
3. 点击"修复该员工"

或直接修改数据库

// Parse Dashboard 或代码
const Parse = FmodeParse.with('nova');
const query = new Parse.Query('Profile');
query.equalTo('userid', 'woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg');
const profile = await query.first();

profile.set('isActivated', true);
profile.set('activatedAt', new Date());
await profile.save();

🎯 修复文件

1. profile-activation.component.ts

文件路径src/modules/profile/pages/profile-activation/profile-activation.component.ts

修改内容

  • checkActivationStatus()方法中添加自动修复逻辑(Line 211-224)

修改前

// 🔥 关键修复:如果问卷已完成但未激活,自动设置激活状态
if (this.surveyCompleted && !this.isActivated) {
  // ... 只修复问卷已完成的情况
}

修改后

// 🔥 关键修复1:如果问卷已完成但未激活,自动设置激活状态
if (this.surveyCompleted && !this.isActivated) {
  // ... 修复问卷已完成的情况
}

// 🔥 关键修复2:如果用户已填写基本信息但未激活,自动设置激活状态
if (!this.isActivated && this.profile.get('realname') && this.profile.get('departmentName')) {
  // ... 修复已填写信息但未激活的情况
}

🧪 测试步骤

1. 部署修复代码

# 构建
ng build yss-project --base-href=/dev/yss/

# 部署
.\deploy.ps1

2. 验证修复效果

测试用户woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg

步骤

  1. 用户在企业微信中打开任意项目管理页面
  2. 系统检测到未激活,重定向到激活页面
  3. 自动触发修复逻辑
  4. 自动跳转回原始页面

预期日志

✅ 用户信息获取成功: Object
📋 激活状态: false
📝 问卷状态: false
📝 Profile所有字段: Object
  realname: "请填与姓名" (或其他值/undefined)
  name: "..." (或undefined)
  departmentName: "..." (或undefined)
  roleName: "..." (或undefined)
  mobile: "..." (或undefined)
  userid: "woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg"
🔧 检测到Profile存在但未激活,自动设置激活状态...
  - realname: ...
  - name: ...
  - departmentName: ...
  - roleName: ...
  - userid: woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg
✅ 已自动设置激活状态
🚀 激活完成,跳转回原始URL: /wxwork/.../project/...

📊 影响范围分析

受影响的用户特征

查询条件(修复后会自动修复所有这些用户):

const Parse = FmodeParse.with('nova');
const query = new Parse.Query('Profile');
query.equalTo('isActivated', false); // 🔥 只要未激活就会被修复
// 🔥 不再要求realname、departmentName等字段存在

const affectedProfiles = await query.find();
console.log('受影响的用户数量:', affectedProfiles.length);

会被自动修复的用户场景

  1. ✅ 填写了信息但未点击"确认激活"按钮
  2. ✅ 企业微信同步了Profile但未激活
  3. ✅ 网络中断导致未完成激活流程
  4. ✅ 浏览器崩溃导致未完成激活
  5. ✅ 测试时未完成完整流程
  6. 所有Profile记录存在但isActivated=false的用户

🛡️ 预防措施

1. 改进激活流程

建议

  • 在表单填写过程中自动保存(Auto-save)
  • 填写完成后自动标记为已激活(无需额外点击确认)
  • 添加进度提示:"第1步/共2步"

2. 添加验证提示

在关闭页面时

@HostListener('window:beforeunload', ['$event'])
unloadNotification($event: any): void {
  if (!this.isActivated && this.formData.realname) {
    $event.returnValue = '您还未完成激活,确定要离开吗?';
  }
}

3. 监控告警

添加数据监控

  • 统计"已填写信息但未激活"的用户数量
  • 超过阈值时发送告警
  • 定期运行自动修复脚本

🔍 故障排除

Q1: 修复后仍然无法访问?

检查步骤

  1. 清除浏览器缓存
  2. 重新登录企业微信
  3. 查看控制台日志,确认isActivated = true
  4. 检查CustomWxworkAuthGuard是否正常工作

可能原因

  • Profile缓存未刷新
  • 守卫逻辑有其他拦截条件
  • 角色权限不足

Q2: 自动修复逻辑未触发?

检查条件

✅ isActivated = false
✅ realname 存在且不为空
✅ departmentName 存在且不为空

调试方法

console.log('isActivated:', this.profile.get('isActivated'));
console.log('realname:', this.profile.get('realname'));
console.log('departmentName:', this.profile.get('departmentName'));

Q3: 其他员工也有类似问题?

批量修复脚本(管理员可使用):

const Parse = FmodeParse.with('nova');

// 查询所有需要修复的Profile(只要未激活都修复)
const query = new Parse.Query('Profile');
query.equalTo('isActivated', false);
// 🔥 不再要求realname、departmentName等字段

const profiles = await query.find();
console.log(`找到 ${profiles.length} 个未激活的Profile`);

// 批量修复
let successCount = 0;
for (const profile of profiles) {
  try {
    profile.set('isActivated', true);
    if (!profile.get('activatedAt')) {
      profile.set('activatedAt', new Date());
    }
    await profile.save();
    
    const name = profile.get('realname') || profile.get('name') || profile.get('userid');
    console.log(`✅ 修复完成 [${successCount + 1}/${profiles.length}]: ${name}`);
    successCount++;
  } catch (error) {
    console.error(`❌ 修复失败: ${profile.get('userid')}`, error);
  }
}

console.log(`\n🎉 批量修复完成!成功: ${successCount}/${profiles.length}`);

📝 总结

问题原因

  • ✅ 老用户(如徐福静)填写了基本信息并完成了问卷,但isActivated字段为false
  • ✅ 被CustomWxworkAuthGuard守卫拦截,无法访问项目管理页面
  • ✅ 原因:未点击"确认激活"按钮,或系统未正确设置激活状态

修复方案

  • 精准的自动激活逻辑:区分老用户和新用户
    • 老用户(已填写信息/完成问卷/曾激活过)→ 自动激活 ✅
    • 新用户(从未填写过信息)→ 仍需填写激活表单 ⚠️
  • 三个触发条件(满足任一即可):
    1. 填写过基本信息(realname/name/departmentName/roleName/mobile任一存在)
    2. 曾经激活过(有activatedAt字段)
    3. 完成过问卷(surveyCompleted=true)
  • ✅ 自动设置activatedAt时间戳
  • ✅ 自动跳转回原始URL
  • ✅ 同时在checkActivationStatus()refreshSurveyStatus()中生效

预防措施

  • ✅ 改进激活流程,减少步骤
  • ✅ 添加Auto-save功能
  • ✅ 添加关闭页面提示
  • ✅ 添加数据监控和告警

修复时间:2025-11-29
修复人员:开发团队
受影响用户woAs2qCQAAGQckyg7AQBxhMEoSwnlTvg 及其他类似情况的员工
文档版本:v1.0