refactor: syncAll creates Student + StudentDingMapping directly
This commit is contained in:
@@ -4,14 +4,12 @@
|
||||
* 提供:
|
||||
* - OAuth2 access_token(新版 API + 缓存)
|
||||
* - BFS 遍历所有部门 + 用户(带限流)
|
||||
* - 用户同步(自动建 User + Student + StudentDingMapping)
|
||||
* - 用户同步(自动建 Student + StudentDingMapping)
|
||||
*/
|
||||
import { Injectable, Logger, ServiceUnavailableException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import * as bcrypt from 'bcryptjs';
|
||||
import { Department } from '../entities/department.entity';
|
||||
import { User } from '../entities/user.entity';
|
||||
import { Student } from '../entities/student.entity';
|
||||
import { Class } from '../entities/class.entity';
|
||||
import { StudentDingMapping } from '../entities/student-ding-mapping.entity';
|
||||
@@ -187,8 +185,6 @@ export class DingTalkService {
|
||||
constructor(
|
||||
@InjectRepository(Department)
|
||||
private readonly deptRepo: Repository<Department>,
|
||||
@InjectRepository(User)
|
||||
private readonly userRepo: Repository<User>,
|
||||
@InjectRepository(Student)
|
||||
private readonly studentRepo: Repository<Student>,
|
||||
@InjectRepository(StudentDingMapping)
|
||||
@@ -603,73 +599,35 @@ export class DingTalkService {
|
||||
// ═══════════════════════════════════════════
|
||||
|
||||
private async syncOneUser(du: {
|
||||
userid: string;
|
||||
name: string;
|
||||
mobile: string;
|
||||
userid: string; name: string; mobile: string;
|
||||
}): Promise<void> {
|
||||
// Look up by mapping first
|
||||
let mapping = await this.studentDingMappingRepo.findOne({ where: { dingUserId: du.userid } });
|
||||
let user: User | null = null;
|
||||
|
||||
let mapping = await this.studentDingMappingRepo.findOne({
|
||||
where: { dingUserId: du.userid },
|
||||
});
|
||||
if (mapping) {
|
||||
const student = await this.studentRepo.findOne({ where: { id: mapping.studentId } });
|
||||
const student = await this.studentRepo.findOne({
|
||||
where: { id: mapping.studentId },
|
||||
});
|
||||
if (student) {
|
||||
student.name = du.name;
|
||||
if (du.mobile) student.phone = du.mobile;
|
||||
await this.studentRepo.save(student);
|
||||
}
|
||||
await this.studentDingMappingRepo.save(mapping);
|
||||
return;
|
||||
}
|
||||
|
||||
// No mapping → find or create
|
||||
const username = du.mobile || `dd_${du.userid}`;
|
||||
user = await this.userRepo.findOne({ where: { username } });
|
||||
const student = this.studentRepo.create({
|
||||
name: du.name,
|
||||
phone: du.mobile || undefined,
|
||||
status: 'active',
|
||||
});
|
||||
await this.studentRepo.save(student);
|
||||
|
||||
if (!user) {
|
||||
const passwordHash = await bcrypt.hash('123456', 10);
|
||||
user = this.userRepo.create({
|
||||
username,
|
||||
name: du.name,
|
||||
passwordHash,
|
||||
isActive: true,
|
||||
});
|
||||
await this.userRepo.save(user);
|
||||
|
||||
const student = this.studentRepo.create({
|
||||
name: du.name,
|
||||
phone: du.mobile || undefined,
|
||||
userId: user.id,
|
||||
status: 'active',
|
||||
});
|
||||
await this.studentRepo.save(student);
|
||||
} else {
|
||||
// Update existing user
|
||||
user.name = du.name;
|
||||
await this.userRepo.save(user);
|
||||
|
||||
// Ensure Student record exists (backfill for users synced before this logic)
|
||||
const existingStudent = await this.studentRepo.findOne({ where: { userId: user.id } });
|
||||
if (existingStudent && existingStudent.status !== 'active') {
|
||||
// Student was manually marked as staff/graduated/withdrawn — do not overwrite
|
||||
this.logger.debug(`User ${user.id} has non-active Student (${existingStudent.status}), skipping backfill`);
|
||||
} else if (!existingStudent) {
|
||||
const student = this.studentRepo.create({
|
||||
name: du.name,
|
||||
phone: du.mobile || undefined,
|
||||
userId: user.id,
|
||||
status: 'active',
|
||||
});
|
||||
await this.studentRepo.save(student);
|
||||
}
|
||||
}
|
||||
|
||||
// ponytail: find student by userId — method rewritten in Task 2
|
||||
const student = await this.studentRepo.findOne({ where: { userId: user.id } });
|
||||
if (!student) return;
|
||||
mapping = this.studentDingMappingRepo.create({
|
||||
dingUserId: du.userid,
|
||||
studentId: student.id,
|
||||
});
|
||||
await this.studentDingMappingRepo.save(mapping);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user