身份激活页面表单可编辑功能_最终版.md 12 KB

身份激活页面表单可编辑功能(最终版)

功能概述

为身份激活页面添加混合模式表单:

  • 可编辑字段:真实姓名、手机号(用户可修改)
  • 只读字段:部门、职位角色、员工ID(从企微自动获取)

实现"自动获取 + 选择性编辑"的最佳平衡。

实现日期

2025年11月3日

最终方案

📋 字段分类

字段名 类型 必填 可编辑 数据来源
真实姓名 文本输入 企微自动填充,可修改
手机号 电话输入 企微自动填充,可修改
所属部门 只读显示 - 企微自动获取
职位角色 只读显示 - 企微自动获取
员工ID 只读显示 - 企微自动获取

🎨 界面效果

┌─────────────────────────────────────┐
│  用户身份确认                       │
│  请确认您的身份信息                 │
├─────────────────────────────────────┤
│         [头像]                      │
│      张设计师                       │
│         组员                        │
├─────────────────────────────────────┤
│  真实姓名 *                         │
│  [张设计师        ] ← 可编辑 ✏️     │
│                                     │
│  所属部门                           │
│  [设计部          ] ← 只读 🔒       │
│                                     │
│  职位角色                           │
│  [组员            ] ← 只读 🔒       │
│                                     │
│  手机号                             │
│  [13800138000     ] ← 可编辑 ✏️     │
│                                     │
│  员工ID                             │
│  [test_user_001   ] ← 只读 🔒       │
├─────────────────────────────────────┤
│       [✓ 确认身份]                  │
└─────────────────────────────────────┘

修改的文件

1. profile-activation.component.ts

简化表单数据模型(第52-56行)

只保留可编辑字段:

// 可编辑的表单字段(只有姓名和手机号可编辑)
formData = {
  realname: '',
  mobile: ''
};

移除不需要的数据(已删除)

  • ❌ 删除 departmentList 数组(不需要下拉选择)
  • ❌ 删除 roleList 数组(不需要下拉选择)
  • ❌ 删除 formData.department(由企微自动同步)
  • ❌ 删除 formData.roleName(由企微自动同步)

简化 populateFormData() 方法(第139-153行)

只填充可编辑字段:

private populateFormData(): void {
  // 优先从Profile获取,其次从企微userInfo获取
  this.formData.realname = this.profile?.get('realname') || 
                           this.profile?.get('name') || 
                           this.userInfo?.name || '';
  
  this.formData.mobile = this.profile?.get('mobile') || 
                         this.userInfo?.mobile || '';
  
  console.log('📝 自动填充表单数据:', this.formData);
}

简化表单验证(第198-202行)

只验证姓名:

// 表单验证(只验证必填的姓名)
if (!this.formData.realname?.trim()) {
  alert('请填写您的真实姓名');
  return;
}

优化保存逻辑(第227-238行)

只保存用户可编辑的字段:

// 保存用户编辑的信息(只保存姓名和手机号,部门和角色由企微自动同步)
this.profile.set('realname', this.formData.realname);
this.profile.set('name', this.formData.realname); // 同时更新name字段
if (this.formData.mobile) {
  this.profile.set('mobile', this.formData.mobile);
}

await this.profile.save();
console.log('✅ 用户信息已保存:', {
  realname: this.formData.realname,
  mobile: this.formData.mobile
});

2. profile-activation.component.html

混合表单结构(第46-91行)

<div class="form-container">
  <!-- 真实姓名:可编辑 -->
  <div class="form-group">
    <label class="form-label">
      <span class="label-text">真实姓名</span>
      <span class="required">*</span>
    </label>
    <input 
      type="text" 
      class="form-input" 
      [(ngModel)]="formData.realname"
      placeholder="请输入您的真实姓名"
      required />
  </div>

  <!-- 所属部门:只读 -->
  <div class="form-group readonly">
    <label class="form-label">
      <span class="label-text">所属部门</span>
    </label>
    <div class="readonly-value">{{ getDepartment() }}</div>
  </div>

  <!-- 职位角色:只读 -->
  <div class="form-group readonly">
    <label class="form-label">
      <span class="label-text">职位角色</span>
    </label>
    <div class="readonly-value">{{ getUserRole() }}</div>
  </div>

  <!-- 手机号:可编辑 -->
  <div class="form-group">
    <label class="form-label">
      <span class="label-text">手机号</span>
    </label>
    <input 
      type="tel" 
      class="form-input" 
      [(ngModel)]="formData.mobile"
      placeholder="请输入手机号" />
  </div>

  <!-- 员工ID:只读 -->
  <div class="form-group readonly">
    <label class="form-label">
      <span class="label-text">员工ID</span>
    </label>
    <div class="readonly-value">{{ getUserId() }}</div>
  </div>
</div>

头像信息显示(第41-42行)

使用原有方法获取角色:

<h2 class="user-name">{{ formData.realname || '请填写姓名' }}</h2>
<p class="user-role">{{ getUserRole() }}</p>

3. profile-activation.component.scss

样式保持不变,已包含:

  • .form-input - 可编辑输入框样式
  • .form-group.readonly - 只读字段灰色背景样式
  • .readonly-value - 只读内容样式
  • ✅ 聚焦效果、响应式布局等

方法使用说明

原有方法继续使用

以下方法保持原有逻辑,用于获取企微数据:

  1. getDepartment()(第368-393行)

    • 智能处理企微部门信息的多种格式
    • 支持数组、对象、字符串格式
    • 用于只读显示
  2. getUserRole()(第361-363行)

    • 从Profile获取 roleName
    • 默认返回"员工"
    • 用于只读显示
  3. getUserId()(第398-400行)

    • 返回企微 userid
    • 用于只读显示
  4. getUserAvatar()(第341-346行)

    • 获取用户头像
    • 多级降级逻辑
  5. getUserName()(第351-356行)

    • 获取用户姓名
    • 优先使用 realname

数据流程

1. 初始化(自动填充)

页面加载
    ↓
initAuth() - 初始化企微认证
    ↓
获取企微用户信息
    ├─ userid
    ├─ name
    ├─ mobile
    ├─ department (数组/对象/字符串)
    └─ avatar
    ↓
checkActivationStatus() - 查询Profile
    ↓
populateFormData() - 自动填充
    ├─ formData.realname = userInfo.name ✅
    └─ formData.mobile = userInfo.mobile ✅
    ↓
显示表单
    ├─ 姓名输入框(已填充)✏️
    ├─ 部门只读框(getDepartment())🔒
    ├─ 角色只读框(getUserRole())🔒
    ├─ 手机输入框(已填充)✏️
    └─ ID只读框(getUserId())🔒

2. 提交保存

用户编辑姓名/手机号
    ↓
点击"确认身份"
    ↓
验证 realname 非空
    ↓
confirmActivation()
    ↓
wxAuth.syncUserInfo()
    ├─ 自动同步企微 department
    ├─ 自动同步企微 roleName
    └─ 自动同步企微 userid
    ↓
保存用户编辑的字段
    ├─ profile.set('realname', formData.realname) ✏️
    ├─ profile.set('name', formData.realname) ✏️
    └─ profile.set('mobile', formData.mobile) ✏️
    ↓
设置激活标记
    ├─ isActivated = true
    └─ activatedAt = new Date()
    ↓
激活成功

核心优势

✅ 保持企微数据一致性

  • 部门信息:由企微自动同步,不允许手动修改
  • 角色信息:由企微自动同步,保证权限准确
  • 员工ID:企微唯一标识,不可更改

✅ 允许个性化调整

  • 真实姓名:用户可以修正或完善企微姓名
  • 手机号:用户可以更新联系方式

✅ 简化用户操作

  • 无需选择部门(复杂的下拉列表)
  • 无需选择角色(由管理员在企微配置)
  • 只需要确认/修改基本个人信息

✅ 减少数据维护

  • 不需要维护 departmentList 列表
  • 不需要维护 roleList 列表
  • 部门和角色变更在企微统一管理

测试场景

场景1:新用户首次激活

  1. 访问 /wxwork/test/activation
  2. 看到姓名"测试员工"已自动填充 ✅
  3. 看到部门"部门1"为只读灰色显示 ✅
  4. 看到角色"组员"为只读灰色显示 ✅
  5. 修改姓名为"张设计师" ✏️
  6. 点击"确认身份"
  7. ✅ 激活成功,只保存了姓名

场景2:修改手机号

  1. 企微手机号"13800138000"已自动填充
  2. 修改为"13900139000" ✏️
  3. 点击"确认身份"
  4. ✅ 新手机号保存成功

场景3:企微部门复杂格式

  1. 企微返回部门为数组 [1, 2]
  2. getDepartment() 处理为"部门1" ✅
  3. 只读显示"部门1" 🔒
  4. 用户无法修改,保持企微数据一致性 ✅

场景4:表单验证

  1. 清空姓名字段
  2. 点击"确认身份"
  3. ✅ 弹出提示"请填写您的真实姓名"
  4. 填写姓名后成功激活 ✅

与企微同步机制

syncUserInfo() 的作用

confirmActivation() 中调用:

// 生产模式:同步用户信息
this.profile = await this.wxAuth!.syncUserInfo(this.userInfo);

自动同步以下企微字段

  • userid - 员工ID
  • department - 部门信息
  • roleName - 角色/职位
  • avatar - 头像
  • ✅ 其他企微标准字段

用户编辑的字段后续覆盖

  • realname - 用户填写的真实姓名
  • mobile - 用户填写的手机号

这样既保证了企微数据的准确性,又允许用户完善个人信息。

数据库最终保存

点击"确认身份"后,Profile表保存的数据:

{
  // 企微自动同步
  userid: "WangGang001",
  department: "设计部",
  roleName: "组员",
  avatar: "https://...",
  
  // 用户可编辑(覆盖企微数据)
  realname: "王刚",        // 用户修改
  name: "王刚",            // 同步更新
  mobile: "13900139000",   // 用户修改
  
  // 系统字段
  isActivated: true,
  activatedAt: "2025-11-03T12:00:00.000Z"
}

设计理念

🎯 简单即美

  • 只编辑必要的字段
  • 减少用户决策负担
  • 降低出错概率

🔒 数据源单一

  • 部门和角色由企微统一管理
  • 避免前端和企微数据不一致
  • 减少数据维护成本

✏️ 灵活补充

  • 允许用户修正姓名
  • 允许更新联系方式
  • 满足个性化需求

🎨 清晰区分

  • 可编辑:白色背景,有输入框
  • 只读:灰色背景,文本显示
  • 视觉上一目了然

总结

最终方案实现了"企微自动同步 + 用户选择性编辑"的完美平衡:

  • 🚀 高效:部门和角色自动获取,无需手动选择
  • 🎯 准确:企微数据保持权威,避免手动输入错误
  • ✏️ 灵活:允许用户完善姓名和联系方式
  • 🎨 直观:灰色背景清晰标识只读字段
  • 🔧 易维护:无需维护部门和角色列表

这种设计既保证了数据的规范性和一致性,又给用户提供了必要的灵活性,是企业内部系统的最佳实践。