| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- <?php
- namespace App\Services;
- use App\Models\Student;
- use App\Models\Teacher;
- use App\Models\User;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Hash;
- use Illuminate\Support\Facades\Log;
- class ExternalIdService
- {
- /**
- * 处理学生外部ID
- * 如果ID不存在,自动创建用户和学生记录
- */
- public function handleStudentExternalId(int|string $studentId, array $studentData = []): Student
- {
- // student_id是int类型,直接使用
- // 检查学生是否已存在
- $student = Student::where('student_id', $studentId)->first();
- if ($student) {
- Log::info('外部学生ID已存在', ['student_id' => $studentId]);
- return $student;
- }
- // 创建用户记录
- $userData = [
- 'user_id' => (string) $studentId, // user表是varchar类型
- 'username' => $studentData['name'],
- 'password_hash' => Hash::make(env('STUDENT_HASH', 'UqB6KHYx84')),
- 'role' => 'student',
- 'full_name' => $studentData['name'] ?? '未知学生',
- 'email' => $studentId . '@student.edu',
- 'is_active' => 1,
- ];
- $user = User::create($userData);
- // 创建学生记录
- $student = Student::create([
- 'student_id' => $studentId,
- 'name' => $studentData['name'] ?? '未知学生',
- 'grade' => $studentData['grade'] ?? '未知年级',
- 'class_name' => $studentData['class_name'] ?? '',
- 'teacher_id' => $studentData['teacher_id'] ?? null,
- 'remark' => $studentData['remark'] ?? '自动创建',
- ]);
- Log::info('外部学生ID自动创建成功', [
- 'student_id' => $studentId,
- 'user_id' => $user->user_id
- ]);
- return $student;
- }
- /**
- * 处理教师外部ID
- * 如果ID存在,更新name;如果不存在,创建用户和教师记录
- * 【修复】避免邮箱重复导致的错误
- */
- public function handleTeacherExternalId(int|string $teacherId, array $teacherData = []): Teacher
- {
- // teacher_id是int类型,直接使用
- // 【修复】使用事务确保并发安全
- return DB::transaction(function () use ($teacherId, $teacherData) {
- // 检查教师是否已存在(使用forUpdate防止并发问题)
- $teacher = Teacher::where('teacher_id', $teacherId)
- ->lockForUpdate()
- ->first();
- if ($teacher) {
- // 教师已存在,检查是否需要更新name
- $needsUpdate = false;
- $updateData = [];
- if (!empty($teacherData['name']) && $teacher->name !== $teacherData['name']) {
- $updateData['name'] = $teacherData['name'];
- $needsUpdate = true;
- Log::info('外部教师ID存在,更新name', [
- 'teacher_id' => $teacherId,
- 'old_name' => $teacher->name,
- 'new_name' => $teacherData['name']
- ]);
- }
- if (!empty($teacherData['subject']) && $teacher->subject !== $teacherData['subject']) {
- $updateData['subject'] = $teacherData['subject'];
- $needsUpdate = true;
- }
- if ($needsUpdate) {
- $teacher->update($updateData);
- Log::info('外部教师信息更新成功', [
- 'teacher_id' => $teacherId,
- 'updated_fields' => array_keys($updateData)
- ]);
- } else {
- Log::info('外部教师ID已存在,无需更新', ['teacher_id' => $teacherId]);
- }
- return $teacher;
- }
- // 【修复】教师不存在,创建用户和教师记录
- // 先尝试创建用户,使用teacher_id作为邮箱
- $user = null;
- $email = $teacherId . '@teacher.edu';
- try {
- // 创建用户记录
- $userData = [
- 'user_id' => (string) $teacherId,
- 'username' => $teacherData['phone'] ?? (string) $teacherId,
- 'password_hash' => Hash::make(env('TEACHER_HASH', 'TeGiFkEim2')),
- 'role' => 'teacher',
- 'full_name' => $teacherData['name'] ?? '未知教师',
- 'email' => $email,
- 'is_active' => 1,
- ];
- $user = User::create($userData);
- Log::info('外部教师用户创建成功', [
- 'teacher_id' => $teacherId,
- 'user_id' => $user->user_id,
- 'email' => $email
- ]);
- } catch (\Exception $e) {
- // 如果邮箱重复,尝试使用teacher_id + 随机数
- if (str_contains($e->getMessage(), 'Duplicate entry') && str_contains($e->getMessage(), '@teacher.edu')) {
- Log::warning('邮箱已存在,尝试使用随机邮箱', [
- 'teacher_id' => $teacherId,
- 'original_email' => $email
- ]);
- // 生成唯一邮箱
- $uniqueEmail = $teacherId . '_' . uniqid() . '@teacher.edu';
- $userData['email'] = $uniqueEmail;
- $user = User::create($userData);
- Log::info('外部教师用户创建成功(使用唯一邮箱)', [
- 'teacher_id' => $teacherId,
- 'user_id' => $user->user_id,
- 'email' => $uniqueEmail
- ]);
- } else {
- // 其他错误,重新抛出
- throw $e;
- }
- }
- // 创建教师记录
- $teacher = Teacher::create([
- 'teacher_id' => $teacherId,
- 'teacher_string_id' => $teacherData['teacher_string_id'] ?? null,
- 'user_id' => $user->user_id,
- 'name' => $teacherData['name'] ?? '未知教师',
- 'subject' => $teacherData['subject'] ?? '数学',
- ]);
- Log::info('外部教师ID自动创建成功', [
- 'teacher_id' => $teacherId,
- 'user_id' => $user->user_id,
- 'name' => $teacherData['name'] ?? '未知教师'
- ]);
- return $teacher;
- });
- }
- /**
- * 批量处理学生外部ID
- */
- public function handleBatchStudentExternalIds(array $studentIds): array
- {
- $results = [];
- foreach ($studentIds as $studentId => $studentData) {
- try {
- $student = $this->handleStudentExternalId($studentId, $studentData);
- $results[$studentId] = ['success' => true, 'student' => $student];
- } catch (\Exception $e) {
- Log::error('批量处理学生ID失败', [
- 'student_id' => $studentId,
- 'error' => $e->getMessage()
- ]);
- $results[$studentId] = ['success' => false, 'error' => $e->getMessage()];
- }
- }
- return $results;
- }
- /**
- * 验证外部ID格式
- */
- public function validateExternalId(int|string $externalId, string $type = 'student'): bool
- {
- $externalId = (string) $externalId;
- // 基本格式验证
- if (empty($externalId)) {
- return false;
- }
- // 长度验证(1-64字符)
- if (strlen($externalId) > 64 || strlen($externalId) < 1) {
- return false;
- }
- // 字符验证(允许字母、数字、下划线、连字符)
- if (!preg_match('/^[a-zA-Z0-9_-]+$/', $externalId)) {
- return false;
- }
- return true;
- }
- /**
- * 通过外部ID获取学生信息(包含关联)
- */
- public function getStudentWithRelations(int|string $studentId): ?Student
- {
- return Student::with(['teacher.user', 'user'])
- ->where('student_id', $studentId)
- ->first();
- }
- /**
- * 通过外部ID获取教师信息(包含关联)
- */
- public function getTeacherWithRelations(int|string $teacherId): ?Teacher
- {
- return Teacher::with(['user', 'students'])
- ->where('teacher_id', $teacherId)
- ->first();
- }
- /**
- * 获取教师的学生列表
- */
- public function getTeacherStudents(int|string $teacherId): Collection
- {
- return Student::with(['user'])
- ->where('teacher_id', $teacherId)
- ->orderBy('name')
- ->get();
- }
- /**
- * 获取学生的试卷列表
- */
- public function getStudentPapers(int|string $studentId): Collection
- {
- return Student::find($studentId)
- ?->papers()
- ->with(['paperQuestions.question'])
- ->orderBy('created_at', 'desc')
- ->get() ?? collect();
- }
- /**
- * 检查外部ID是否存在
- */
- public function studentExists(int|string $studentId): bool
- {
- return Student::where('student_id', $studentId)->exists();
- }
- /**
- * 检查外部ID是否存在
- */
- public function teacherExists(int|string $teacherId): bool
- {
- return Teacher::where('teacher_id', $teacherId)->exists();
- }
- }
|