From e87e5e209681fdc5bcdde56c0fa6ee368e7ee5b9 Mon Sep 17 00:00:00 2001 From: wangziqi Date: Thu, 9 Jul 2026 17:05:54 +0800 Subject: [PATCH] refactor: syncAll creates Student + StudentDingMapping directly --- .../src/integration/dingtalk.service.ts | 74 ++++--------------- 1 file changed, 16 insertions(+), 58 deletions(-) diff --git a/apps/server/src/integration/dingtalk.service.ts b/apps/server/src/integration/dingtalk.service.ts index 7fe1822..ea6226c 100644 --- a/apps/server/src/integration/dingtalk.service.ts +++ b/apps/server/src/integration/dingtalk.service.ts @@ -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, - @InjectRepository(User) - private readonly userRepo: Repository, @InjectRepository(Student) private readonly studentRepo: Repository, @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 { - // 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); } // ═══════════════════════════════════════════