身份激活页面提供智能表单功能:
2025年11月3日
| 字段名 | 类型 | 必填 | 自动获取 | 说明 |
|---|---|---|---|---|
| 真实姓名 | 文本输入 | ✅ 是 | ✅ 是 | 从企微自动填充,用户可修改 |
| 所属部门 | 下拉选择 | ❌ 否 | ✅ 是 | 使用 getDepartment() 获取初始值 |
| 职位角色 | 下拉选择 | ❌ 否 | ✅ 是 | 使用 getUserRole() 获取初始值 |
| 手机号 | 电话输入 | ❌ 否 | ✅ 是 | 从企微自动填充,用户可修改 |
| 员工ID | 只读显示 | - | ✅ 是 | 企微 userid,不可编辑 |
┌─────────────────────────────────────┐
│ 用户身份确认 │
│ 请确认您的身份信息 │
├─────────────────────────────────────┤
│ [头像] │
│ 张设计师 │
│ 组员 │
├─────────────────────────────────────┤
│ 真实姓名 * │
│ [张设计师 ] ← 自动填充 │
│ │
│ 所属部门 │
│ [▼ 设计部 ] ← 自动选中 │
│ • 设计部 │
│ • 建模部 │
│ • 渲染部... │
│ │
│ 职位角色 │
│ [▼ 组员 ] ← 自动选中 │
│ • 组员 │
│ • 组长 │
│ • 主管... │
│ │
│ 手机号 │
│ [13800138000 ] ← 自动填充 │
│ │
│ 员工ID │
│ [test_user_001 ] ← 只读 │
├─────────────────────────────────────┤
│ [✓ 确认身份] │
└─────────────────────────────────────┘
表单数据(第52-58行):
formData = {
realname: '', // 真实姓名(必填)
department: '', // 所属部门(可选)
roleName: '', // 职位角色(可选)
mobile: '' // 手机号(可选)
};
部门列表(第60-69行):
departmentList = [
'设计部',
'建模部',
'渲染部',
'软装部',
'后期部',
'综合部',
'管理部'
];
角色列表(第71-77行):
roleList = [
'组员',
'组长',
'主管',
'经理'
];
使用原有方法获取初始值(第163-177行):
private populateFormData(): void {
// 姓名:从Profile或企微获取
this.formData.realname = this.profile?.get('realname') ||
this.profile?.get('name') ||
this.userInfo?.name || '';
// 手机号:从Profile或企微获取
this.formData.mobile = this.profile?.get('mobile') ||
this.userInfo?.mobile || '';
// 部门:使用原有方法获取(智能处理多种格式)
this.formData.department = this.getDepartment();
// 角色:使用原有方法获取
this.formData.roleName = this.getUserRole();
console.log('📝 自动填充表单数据:', this.formData);
}
只验证必填字段:姓名(第222-228行):
// 表单验证
if (!this.formData.realname?.trim()) {
alert('请填写您的真实姓名');
return;
}
// 部门和角色为可选,不做必填验证
保存用户选择的所有信息(第248-278行):
// 设置激活标记并保存表单数据
if (this.profile) {
this.profile.set('isActivated', true);
this.profile.set('activatedAt', new Date());
// 保存用户编辑的信息
this.profile.set('realname', this.formData.realname);
this.profile.set('name', this.formData.realname); // 同时更新name字段
// 保存部门和角色(可选)
if (this.formData.department) {
this.profile.set('department', this.formData.department);
this.profile.set('departmentName', this.formData.department);
}
if (this.formData.roleName) {
this.profile.set('roleName', this.formData.roleName);
}
// 保存手机号(可选)
if (this.formData.mobile) {
this.profile.set('mobile', this.formData.mobile);
}
await this.profile.save();
}
真实姓名(第47-58行):
<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>
所属部门(第60-72行):
<div class="form-group">
<label class="form-label">
<span class="label-text">所属部门</span>
</label>
<select
class="form-select"
[(ngModel)]="formData.department">
<option value="">请选择部门(可选)</option>
@for (dept of departmentList; track dept) {
<option [value]="dept">{{ dept }}</option>
}
</select>
</div>
职位角色(第74-86行):
<div class="form-group">
<label class="form-label">
<span class="label-text">职位角色</span>
</label>
<select
class="form-select"
[(ngModel)]="formData.roleName">
<option value="">请选择角色(可选)</option>
@for (role of roleList; track role) {
<option [value]="role">{{ role }}</option>
}
</select>
</div>
用户访问激活页面
↓
initAuth() - 初始化企微认证
↓
获取企微用户信息
├─ userid
├─ name
├─ mobile
├─ department (多种格式)
└─ avatar
↓
checkActivationStatus() - 查询Profile
↓
populateFormData() - 自动填充表单
├─ formData.realname ← name
├─ formData.mobile ← mobile
├─ formData.department ← getDepartment() 🔑
└─ formData.roleName ← getUserRole() 🔑
↓
显示表单(所有字段已填充)
表单已自动填充
↓
用户查看信息
↓
可选操作:
├─ 修改姓名 ✏️
├─ 重新选择部门 ✏️
├─ 重新选择角色 ✏️
├─ 修改手机号 ✏️
└─ 或保持默认值 ✅
↓
点击"确认身份"
↓
验证姓名不为空
↓
保存所有字段到Profile
↓
激活成功
位置:第368-393行
功能:智能处理企微部门信息的多种格式
getDepartment(): string {
const dept = this.userInfo?.department;
// 处理数组格式
if (Array.isArray(dept) && dept.length > 0) {
return `部门${dept[0]}`;
}
// 处理对象格式
if (dept && typeof dept === 'object' && !Array.isArray(dept)) {
return dept.name || dept.departmentName || '未知部门';
}
// 处理字符串格式
if (typeof dept === 'string') {
return dept;
}
// 从 Profile 获取部门信息
const profileDept = this.profile?.get('department') ||
this.profile?.get('departmentName');
if (profileDept) {
return typeof profileDept === 'string' ?
profileDept : (profileDept.name || '未知部门');
}
return '未分配部门';
}
优势:
位置:第361-363行
功能:获取用户角色
getUserRole(): string {
return this.profile?.get('roleName') || '员工';
}
优势:
企微返回:
name: "王刚"
department: "设计部"
roleName: "组员"
mobile: "13800138000"
↓
表单自动填充:
真实姓名: [王刚]
所属部门: [设计部] (已选中)
职位角色: [组员] (已选中)
手机号: [13800138000]
↓
用户点击"确认身份"
↓
✅ 激活成功(无需修改)
企微返回:
department: [1, 2]
↓
getDepartment() 处理:
return "部门1"
↓
表单显示:
所属部门: [部门1] (已选中)
↓
用户可以:
• 保持"部门1"
• 或选择"设计部"等其他部门
↓
✅ 保存用户选择
企微自动填充:
真实姓名: [测试员工]
所属部门: [部门1]
职位角色: [员工]
↓
用户修改:
真实姓名: [李设计师] ✏️
所属部门: [设计部] ✏️
职位角色: [组员] ✏️
↓
点击"确认身份"
↓
✅ 保存修改后的信息
用户操作:
真实姓名: [王刚] ✅ (必填)
所属部门: [请选择部门(可选)] (未选择)
职位角色: [请选择角色(可选)] (未选择)
手机号: [] (未填写)
↓
点击"确认身份"
↓
✅ 激活成功
↓
Profile保存:
realname: "王刚"
department: null (未设置)
roleName: null (未设置)
mobile: null (未设置)
{
// 必填字段
realname: "王刚",
name: "王刚",
// 可选字段(用户填写)
department: "设计部",
departmentName: "设计部",
roleName: "组员",
mobile: "13800138000",
// 企微字段(自动同步)
userid: "WangGang001",
avatar: "https://...",
// 系统字段
isActivated: true,
activatedAt: "2025-11-03T12:00:00.000Z"
}
{
// 必填字段
realname: "李设计师",
name: "李设计师",
// 可选字段(未填写,不保存)
// department: undefined
// departmentName: undefined
// roleName: undefined
// mobile: undefined
// 企微字段
userid: "test_user_001",
// 系统字段
isActivated: true,
activatedAt: "2025-11-03T12:00:00.000Z"
}
getDepartment() 和 getUserRole() 方法name/realname、department/departmentName表单样式已在 profile-activation.component.scss 中定义:
输入框样式:
.form-input {
width: 100%;
padding: 12px 16px;
border: 1px solid #e0e0e0;
border-radius: 8px;
&:focus {
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
}
下拉框样式:
.form-select {
appearance: none;
background-image: url("data:image/svg+xml,..."); // 自定义箭头
padding-right: 36px;
cursor: pointer;
}
只读字段样式:
.form-group.readonly {
.readonly-value {
padding: 12px 16px;
background: #f5f5f5;
border-radius: 8px;
color: #666;
}
}
* 标记async loadDepartments() {
const Parse = FmodeParse.with('nova');
const query = new Parse.Query('Department');
const departments = await query.find();
this.departmentList = departments.map(d => d.get('name'));
}
<input type="text"
placeholder="搜索部门"
(input)="filterDepartments($event)" />
// 根据选择的角色显示不同的权限说明
getRoleDescription(role: string): string {
const descriptions = {
'组员': '普通设计师,负责具体项目执行',
'组长': '小组负责人,管理团队成员',
'主管': '部门主管,负责部门整体运营',
'经理': '部门经理,负责战略决策'
};
return descriptions[role] || '';
}
validateMobile(): boolean {
if (!this.formData.mobile) return true; // 可选字段
return /^1[3-9]\d{9}$/.test(this.formData.mobile);
}
// 用户修改后自动保存草稿
private saveDraft = debounce(() => {
localStorage.setItem('activation_draft', JSON.stringify(this.formData));
}, 500);
最终方案实现了"智能自动 + 灵活可选"的完美平衡:
getDepartment() 和 getUserRole() 方法这种设计既保证了激活流程的便捷性,又给用户提供了充分的自主权,是企业内部系统的最佳实践。