2.8 KiB
2.8 KiB
修复学生导入:姓名与账号字段 — 设计文档
日期:2026-07-10
状态:已确认
关联:PRD 钉钉集成批次 2
1. 背景
batchImportStudents 创建 Student 时:
name填的是占位符dd_${dingUserId}phone未设置
正确行为:
name= 钉钉用户真实姓名phone= 钉钉用户手机号;无手机号时填dt_${dingUserId}
2. 方案:前端传用户信息
前端组织架构树已有 { userid, name, mobile } 数据(来自 getDeptUsers),导入时直接传给后端,零额外钉钉 API 调用。
3. 改动清单
3.1 后端 DTO
文件: apps/server/src/classes/dto/class.dto.ts
BatchImportStudentsDto:
// 旧
export class BatchImportStudentsDto {
dingUserIds: string[];
}
// 新
export class BatchImportStudentsDto {
@IsArray() @ArrayNotEmpty()
users: Array<{ dingUserId: string; name: string; mobile?: string }>;
}
CreateClassDto.dingUserIds 同改为 users 字段。
3.2 后端 Service
文件: apps/server/src/classes/classes.service.ts
batchImportStudents 签名改为:
async batchImportStudents(classId: number, users: Array<{
dingUserId: string; name: string; mobile?: string;
}>): Promise<{ imported: number; skipped: number }>
创建 Student 时:
this.studentRepo.create({
name: u.name,
phone: u.mobile || `dt_${u.dingUserId}`,
status: 'active',
})
create() 方法中 dingUserIds → users 透传。
3.3 后端 Controller
文件: apps/server/src/classes/classes.controller.ts
batchImportStudents 端点传参改为:
return this.service.batchImportStudents(+id, dto.users);
3.4 前端
文件: apps/admin/src/pages/IntegrationConfig/index.tsx
handleJoinClass 和 handleCreateClass:从 checkedKeys 反查 orgTree 提取完整用户信息,不再只传 ID。
// 旧
const userIds = checkedKeys.filter(...).map(k => k.replace('user-', ''));
api.post('/classes/.../import', { dingUserIds: userIds });
// 新
const checkedUsers = extractCheckedUsers(checkedKeys, orgTree);
api.post('/classes/.../import', { users: checkedUsers });
extractCheckedUsers 工具函数遍历 orgTree,匹配 checkedKeys 中的 user 节点,返回 { dingUserId, name, mobile }[]。
4. 不改的
DingTalkService.syncOneUser/syncAll— 不受影响Studententity — 字段不变- 数据库 schema — 不变
StudentDingMapping— 不受影响
5. 验收标准
- 导入新用户后,Student.name 为真实姓名,非
dd_xxx - 有手机号的用户,Student.phone = 手机号
- 无手机号的用户,Student.phone =
dt_<dingUserId> - 已存在 mapping 的用户跳过,不重复创建
- 班级创建时传入
users同样生效 tsc --noEmit编译通过