From 986e118533b97343f3c17902ee07f4c7f3760657 Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Mon, 26 Jan 2026 17:35:18 +0800 Subject: [PATCH 1/4] =?UTF-8?q?=E8=A7=A3=E5=86=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VOL.Ai/Services/AiAppService.cs | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/VOL.Ai/Services/AiAppService.cs b/VOL.Ai/Services/AiAppService.cs index eec7259..b9ec719 100644 --- a/VOL.Ai/Services/AiAppService.cs +++ b/VOL.Ai/Services/AiAppService.cs @@ -139,14 +139,8 @@ namespace VOL.Ai.Services //if (res == null) // return new Ai_SchoolDto(); - - - - - //var schoolCode = paramDto.Code; - //// ========================= //// 2️⃣ 调用京师接口获取学校年级班级 //// ========================= @@ -291,11 +285,11 @@ namespace VOL.Ai.Services City = "", Grade = schoolClass.Grades.Select(g => new Grades { - Id = 0, // 京师接口没有数据库 Id,可用占位 + Id = 1, // 京师接口没有数据库 Id,可用占位 Name = g.GradeName, Class = g.Classes?.Select(c => new Classes { - Id = 0, // 同上 + Id = 1, // 同上 Name = c.ClassName }).ToList() ?? new List() }).ToList() @@ -304,8 +298,6 @@ namespace VOL.Ai.Services return res; } - - public Ai_OSSInfoDto OSSInfo(Ai_Request paramDto) { return new Ai_OSSInfoDto() From 379339627ec212a74149b5bebc31157a35845a4a Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Mon, 26 Jan 2026 17:45:37 +0800 Subject: [PATCH 2/4] ai --- VOL.Ai/Services/AiAppService.cs | 280 ++++++++++++++++---------------- 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/VOL.Ai/Services/AiAppService.cs b/VOL.Ai/Services/AiAppService.cs index b9ec719..aa76d7a 100644 --- a/VOL.Ai/Services/AiAppService.cs +++ b/VOL.Ai/Services/AiAppService.cs @@ -139,163 +139,163 @@ namespace VOL.Ai.Services //if (res == null) // return new Ai_SchoolDto(); - //var schoolCode = paramDto.Code; - - //// ========================= - //// 2️⃣ 调用京师接口获取学校年级班级 - //// ========================= - //var schoolClass = await _jingShiTiJiaoService.GetClassBySchoolAsync(schoolCode); - - //if (schoolClass?.Grades == null || !schoolClass.Grades.Any()) - // throw new Exception("获取京师年级班级失败!"); - - //var res = new Ai_SchoolDto() - //{ - // SchoolCode = schoolCode, - // Name = schoolClass.SchoolName, - // Type = 1, - // Province = "", - // City = "" - //}; - - //var gradeDtos = schoolClass.Grades; - - //// ========================= - //// 3️⃣ 提取所有 GradeNo / ClassNo - //// ========================= - //var allGradeNos = gradeDtos - // .Where(g => !string.IsNullOrWhiteSpace(g.GradeNo)) - // .Select(g => g.GradeNo) - // .ToList(); - - //var allClassNos = gradeDtos - // .SelectMany(g => g.Classes ?? new List()) - // .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo)) - // .Select(c => c.ClassNo) - // .ToList(); - - //// ========================= - //// 4️⃣ 查询数据库中已存在的数据(幂等) - //// ========================= - //var existGrades = await _studentRepository.DbContext.Set() - // .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) - // .ToListAsync(); - - //var existClasses = await _classRepository.DbContext.Set() - // .Where(x => x.SchoolCode == schoolCode && allClassNos.Contains(x.ClassNo)) - // .ToListAsync(); - - //var existGradeNoSet = existGrades.Select(x => x.GradeNo).ToHashSet(); - //var existClassNoSet = existClasses.Select(x => x.ClassNo).ToHashSet(); - - //// ========================= - //// 5️⃣ 构造待插入的年级 + 班级 - //// ========================= - //var newGrades = new List(); - - //foreach (var g in gradeDtos) - //{ - // if (string.IsNullOrWhiteSpace(g.GradeNo) || existGradeNoSet.Contains(g.GradeNo)) - // continue; - - // var grade = new JS_Grade - // { - // SchoolCode = schoolCode, - // Code = paramDto.Code, - // GradeNo = g.GradeNo, - // GradeName = g.GradeName, - // Classes = g.Classes? - // .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo) && !existClassNoSet.Contains(c.ClassNo)) - // .Select(c => new JS_Class - // { - // SchoolCode = schoolCode, - // Code = paramDto.Code, - // GradeNo = g.GradeNo, - // GradeName = g.GradeName, - // ClassNo = c.ClassNo, - // ClassName = c.ClassName - // }).ToList() ?? new List() - // }; - - // newGrades.Add(grade); - - // existGradeNoSet.Add(g.GradeNo); - // foreach (var c in grade.Classes) - // existClassNoSet.Add(c.ClassNo); - //} - - //if (newGrades.Any()) - // await _studentRepository.DbContext.Set().AddRangeAsync(newGrades); - - //// ========================= - //// 6️⃣ 保存(并发幂等兜底) - //// ========================= - //try - //{ - // await _studentRepository.DbContext.SaveChangesAsync(); - //} - //catch (DbUpdateException ex) when (ex.InnerException?.Message.Contains("UNIQUE") == true) - //{ - // // 并发下唯一索引冲突可忽略 - //} - - //// ========================= - //// 7️⃣ 回查数据库,组装返回 DTO - //// ========================= - //var dbGrades = await _studentRepository.DbContext.Set() - // .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) - // .Include(g => g.Classes) - // .ToListAsync(); - - //res.Grade = dbGrades.Select(g => new Grades - //{ - // Id = (int)g.Id, - // Name = g.GradeName, - // Class = g.Classes.Select(c => new Classes - // { - // Id = (int)c.Id, - // Name = c.ClassName - // }).ToList() - //}).ToList(); - - //return res; - - if (string.IsNullOrWhiteSpace(paramDto.Code)) - throw new ArgumentException("学校编码不能为空", nameof(paramDto.Code)); - var schoolCode = paramDto.Code; // ========================= - // 1️⃣ 调用京师接口获取学校信息及年级班级 + // 2️⃣ 调用京师接口获取学校年级班级 // ========================= var schoolClass = await _jingShiTiJiaoService.GetClassBySchoolAsync(schoolCode); if (schoolClass?.Grades == null || !schoolClass.Grades.Any()) throw new Exception("获取京师年级班级失败!"); - // ========================= - // 2️⃣ 组装返回 DTO - // ========================= var res = new Ai_SchoolDto() { SchoolCode = schoolCode, Name = schoolClass.SchoolName, - Type = 1, // 可根据业务修改 + Type = 1, Province = "", - City = "", - Grade = schoolClass.Grades.Select(g => new Grades - { - Id = 1, // 京师接口没有数据库 Id,可用占位 - Name = g.GradeName, - Class = g.Classes?.Select(c => new Classes - { - Id = 1, // 同上 - Name = c.ClassName - }).ToList() ?? new List() - }).ToList() + City = "" }; + var gradeDtos = schoolClass.Grades; + + // ========================= + // 3️⃣ 提取所有 GradeNo / ClassNo + // ========================= + var allGradeNos = gradeDtos + .Where(g => !string.IsNullOrWhiteSpace(g.GradeNo)) + .Select(g => g.GradeNo) + .ToList(); + + var allClassNos = gradeDtos + .SelectMany(g => g.Classes ?? new List()) + .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo)) + .Select(c => c.ClassNo) + .ToList(); + + // ========================= + // 4️⃣ 查询数据库中已存在的数据(幂等) + // ========================= + var existGrades = await _studentRepository.DbContext.Set() + .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) + .ToListAsync(); + + var existClasses = await _classRepository.DbContext.Set() + .Where(x => x.SchoolCode == schoolCode && allClassNos.Contains(x.ClassNo)) + .ToListAsync(); + + var existGradeNoSet = existGrades.Select(x => x.GradeNo).ToHashSet(); + var existClassNoSet = existClasses.Select(x => x.ClassNo).ToHashSet(); + + // ========================= + // 5️⃣ 构造待插入的年级 + 班级 + // ========================= + var newGrades = new List(); + + foreach (var g in gradeDtos) + { + if (string.IsNullOrWhiteSpace(g.GradeNo) || existGradeNoSet.Contains(g.GradeNo)) + continue; + + var grade = new JS_Grade + { + SchoolCode = schoolCode, + Code = paramDto.Code, + GradeNo = g.GradeNo, + GradeName = g.GradeName, + Classes = g.Classes? + .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo) && !existClassNoSet.Contains(c.ClassNo)) + .Select(c => new JS_Class + { + SchoolCode = schoolCode, + Code = paramDto.Code, + GradeNo = g.GradeNo, + GradeName = g.GradeName, + ClassNo = c.ClassNo, + ClassName = c.ClassName + }).ToList() ?? new List() + }; + + newGrades.Add(grade); + + existGradeNoSet.Add(g.GradeNo); + foreach (var c in grade.Classes) + existClassNoSet.Add(c.ClassNo); + } + + if (newGrades.Any()) + await _studentRepository.DbContext.Set().AddRangeAsync(newGrades); + + // ========================= + // 6️⃣ 保存(并发幂等兜底) + // ========================= + try + { + await _studentRepository.DbContext.SaveChangesAsync(); + } + catch (DbUpdateException ex) when (ex.InnerException?.Message.Contains("UNIQUE") == true) + { + // 并发下唯一索引冲突可忽略 + } + + // ========================= + // 7️⃣ 回查数据库,组装返回 DTO + // ========================= + var dbGrades = await _studentRepository.DbContext.Set() + .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) + .Include(g => g.Classes) + .ToListAsync(); + + res.Grade = dbGrades.Select(g => new Grades + { + Id = (int)g.Id, + Name = g.GradeName, + Class = g.Classes.Select(c => new Classes + { + Id = (int)c.Id, + Name = c.ClassName + }).ToList() + }).ToList(); + return res; + + //if (string.IsNullOrWhiteSpace(paramDto.Code)) + // throw new ArgumentException("学校编码不能为空", nameof(paramDto.Code)); + + //var schoolCode = paramDto.Code; + + //// ========================= + //// 1️⃣ 调用京师接口获取学校信息及年级班级 + //// ========================= + //var schoolClass = await _jingShiTiJiaoService.GetClassBySchoolAsync(schoolCode); + + //if (schoolClass?.Grades == null || !schoolClass.Grades.Any()) + // throw new Exception("获取京师年级班级失败!"); + + //// ========================= + //// 2️⃣ 组装返回 DTO + //// ========================= + //var res = new Ai_SchoolDto() + //{ + // SchoolCode = schoolCode, + // Name = schoolClass.SchoolName, + // Type = 1, // 可根据业务修改 + // Province = "", + // City = "", + // Grade = schoolClass.Grades.Select(g => new Grades + // { + // Id = 1, // 京师接口没有数据库 Id,可用占位 + // Name = g.GradeName, + // Class = g.Classes?.Select(c => new Classes + // { + // Id = 1, // 同上 + // Name = c.ClassName + // }).ToList() ?? new List() + // }).ToList() + //}; + + //return res; } public Ai_OSSInfoDto OSSInfo(Ai_Request paramDto) From 4223361919f5df100ad4fb87b9b640454584897a Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Mon, 26 Jan 2026 18:11:35 +0800 Subject: [PATCH 3/4] =?UTF-8?q?=E6=89=AB=E7=A0=81=E7=99=BB=E9=99=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VOL.Ai/Services/AiAppService.cs | 157 ++++++++++++++++---------------- 1 file changed, 76 insertions(+), 81 deletions(-) diff --git a/VOL.Ai/Services/AiAppService.cs b/VOL.Ai/Services/AiAppService.cs index aa76d7a..3211b28 100644 --- a/VOL.Ai/Services/AiAppService.cs +++ b/VOL.Ai/Services/AiAppService.cs @@ -1,5 +1,6 @@ using AutoMapper; using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -139,6 +140,9 @@ namespace VOL.Ai.Services //if (res == null) // return new Ai_SchoolDto(); + if (string.IsNullOrWhiteSpace(paramDto.Code)) + throw new ArgumentException("学校编码不能为空", nameof(paramDto.Code)); + var schoolCode = paramDto.Code; // ========================= @@ -1489,13 +1493,19 @@ namespace VOL.Ai.Services /// /// /// + [HttpPost(nameof(ScanCodeLogin))] public async Task ScanCodeLogin(Ai_Request paramDto) { + if (paramDto == null || string.IsNullOrWhiteSpace(paramDto.Code) || string.IsNullOrWhiteSpace(paramDto.SchoolCode)) + throw new ArgumentException("参数不能为空!"); + + var schoolCode = paramDto.SchoolCode; + // ========================= - // 1️⃣ 查询登录信息 + // 1️⃣ 查询扫码登录信息 // ========================= var loginInfo = await _scanCodeLoginRepository - .FindAsIQueryable(x => x.Code == paramDto.Code && x.SchoolCode == paramDto.SchoolCode) + .FindAsIQueryable(x => x.Code == paramDto.Code && x.SchoolCode == schoolCode) .FirstOrDefaultAsync(); if (loginInfo == null) @@ -1504,93 +1514,80 @@ namespace VOL.Ai.Services // ========================= // 2️⃣ 获取京师老师信息 // ========================= - var teacher = await _jingShiTiJiaoService - .GetClassListByTeacher(loginInfo.TeacherPhoneNo); - - if (teacher == null) + var teacher = await _jingShiTiJiaoService.GetClassListByTeacher(loginInfo.TeacherPhoneNo); + if (teacher == null || string.IsNullOrWhiteSpace(teacher.TeacherNo) || string.IsNullOrWhiteSpace(teacher.TeacherName)) throw new Exception("获取京师老师信息失败!"); - if (string.IsNullOrWhiteSpace(teacher.TeacherNo)) - throw new Exception("接口返回的教师编号为空!"); - if (string.IsNullOrWhiteSpace(teacher.TeacherName)) - throw new Exception("接口返回的教师姓名为空!"); - - var schoolCode = paramDto.SchoolCode; var gradeDtos = teacher.GradeList ?? new List(); // ========================= - // 3️⃣ 同步教师信息 + // 3️⃣ 提取所有 GradeNo / ClassNo // ========================= - var existingTeacher = await _teacherRepository.DbContext.Set() - .FirstOrDefaultAsync(t => t.TeacherNo == teacher.TeacherNo); - - long tId; - if (existingTeacher != null) - { - tId = existingTeacher.Id; - } - else - { - var jsTeacher = new JS_Teacher - { - Code = paramDto.Code, - SchoolCode = schoolCode, - SchoolName = teacher.School ?? "", - TeacherName = teacher.TeacherName, - TeacherNo = teacher.TeacherNo - }; - - try - { - await _teacherRepository.DbContext.Set().AddAsync(jsTeacher); - await _teacherRepository.SaveChangesAsync(); - tId = jsTeacher.Id; - } - catch (DbUpdateException ex) when ( - ex.InnerException?.Message.Contains("IX_JS_Teacher_TeacherNo") == true) - { - var conflictTeacher = await _teacherRepository.DbContext.Set() - .FirstAsync(t => t.TeacherNo == teacher.TeacherNo); - tId = conflictTeacher.Id; - } - } - - if (tId == 0) - throw new Exception("教师信息同步失败!"); - - // ===================================================== - // 4️⃣ 同步【年级 + 班级】(你提供的核心逻辑) - // ===================================================== - var allGradeNos = gradeDtos - .Where(g => !string.IsNullOrWhiteSpace(g.GradeNo)) - .Select(g => g.GradeNo) - .ToList(); - - var allClassNos = gradeDtos - .SelectMany(g => g.ClassList ?? new List()) - .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo)) - .Select(c => c.ClassNo) - .ToList(); + var allGradeNos = gradeDtos.Where(g => !string.IsNullOrWhiteSpace(g.GradeNo)) + .Select(g => g.GradeNo) + .ToList(); + // ========================= + // 4️⃣ 查询已有年级和班级 + // ========================= var existGrades = await _studentRepository.DbContext.Set() .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) - .ToListAsync(); - - var existClasses = await _classRepository.DbContext.Set() - .Where(x => x.SchoolCode == schoolCode && allClassNos.Contains(x.ClassNo)) + .Include(g => g.Classes) .ToListAsync(); var existGradeNoSet = existGrades.Select(x => x.GradeNo).ToHashSet(); - var existClassNoSet = existClasses.Select(x => x.ClassNo).ToHashSet(); + var existClassNoSet = existGrades.SelectMany(g => g.Classes).Select(c => c.ClassNo).ToHashSet(); var newGrades = new List(); foreach (var g in gradeDtos) { - if (string.IsNullOrWhiteSpace(g.GradeNo) || existGradeNoSet.Contains(g.GradeNo)) + if (string.IsNullOrWhiteSpace(g.GradeNo)) continue; - var grade = new JS_Grade + if (existGradeNoSet.Contains(g.GradeNo)) + { + // 已存在年级,更新老师信息 + var grade = existGrades.First(x => x.GradeNo == g.GradeNo); + grade.TeacherNo = teacher.TeacherNo; // ✅ 更新老师编号 + grade.TeacherName = teacher.TeacherName; // ✅ 更新老师姓名 + + foreach (var c in g.ClassList ?? new List()) + { + if (string.IsNullOrWhiteSpace(c.ClassNo)) + continue; + + var cls = grade.Classes.FirstOrDefault(x => x.ClassNo == c.ClassNo); + if (cls != null) + { + cls.TeacherNo = teacher.TeacherNo; // ✅ 更新班级老师编号 + cls.TeacherName = teacher.TeacherName; // ✅ 更新班级老师姓名 + } + else + { + // 新增班级 + var newClass = new JS_Class + { + TeacherNo = teacher.TeacherNo, + TeacherName = teacher.TeacherName, + SchoolCode = schoolCode, + Code = paramDto.Code, + GradeNo = g.GradeNo, + GradeName = g.GradeName, + ClassNo = c.ClassNo, + ClassName = c.ClassName, + GradeId = grade.Id + }; + grade.Classes.Add(newClass); + existClassNoSet.Add(c.ClassNo); + } + } + + continue; + } + + // 新增年级 + 班级 + var gradeNew = new JS_Grade { TeacherNo = teacher.TeacherNo, TeacherName = teacher.TeacherName, @@ -1599,8 +1596,7 @@ namespace VOL.Ai.Services GradeNo = g.GradeNo, GradeName = g.GradeName, Classes = g.ClassList? - .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo) - && !existClassNoSet.Contains(c.ClassNo)) + .Where(c => !string.IsNullOrWhiteSpace(c.ClassNo)) .Select(c => new JS_Class { TeacherNo = teacher.TeacherNo, @@ -1614,16 +1610,18 @@ namespace VOL.Ai.Services }).ToList() ?? new List() }; - newGrades.Add(grade); - + newGrades.Add(gradeNew); existGradeNoSet.Add(g.GradeNo); - foreach (var c in grade.Classes) + foreach (var c in gradeNew.Classes) existClassNoSet.Add(c.ClassNo); } if (newGrades.Any()) await _studentRepository.DbContext.Set().AddRangeAsync(newGrades); + // ========================= + // 5️⃣ 保存(EF Core 自动生成 UPDATE) + // ========================= try { await _studentRepository.DbContext.SaveChangesAsync(); @@ -1634,22 +1632,18 @@ namespace VOL.Ai.Services } // ========================= - // 5️⃣ 重新读取数据库,获取 Id + // 6️⃣ 组装返回 DTO // ========================= var dbGrades = await _studentRepository.DbContext.Set() .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) .Include(g => g.Classes) .ToListAsync(); - // ========================= - // 6️⃣ 组装返回 DTO - // ========================= var res = new Ai_TeacherFaceInfo { - Id = (int)tId, + Id = 0, // 老师表不操作 TeacherName = teacher.TeacherName, Phone = teacher.TeacherNo, - //Photo = teacher.TeacherNo, GradeAndClassList = dbGrades .SelectMany(g => g.Classes) .Select(c => new Classes @@ -1669,6 +1663,7 @@ namespace VOL.Ai.Services return res; } + /// /// 登录 /// From 17d110a8780b0467859ef0d3ca08723922f7ac75 Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Mon, 26 Jan 2026 18:52:09 +0800 Subject: [PATCH 4/4] =?UTF-8?q?ai=20=20=E8=BF=90=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- VOL.Ai/Services/AiAppService.cs | 135 +++++++++++--------------------- 1 file changed, 47 insertions(+), 88 deletions(-) diff --git a/VOL.Ai/Services/AiAppService.cs b/VOL.Ai/Services/AiAppService.cs index 3211b28..710c8d5 100644 --- a/VOL.Ai/Services/AiAppService.cs +++ b/VOL.Ai/Services/AiAppService.cs @@ -21,6 +21,7 @@ using VOL.Model.JingShiTiJiao; using VOL.Model.Norm.Response; using VOL.Model.Training.Response; using VOL.System.IRepositories; +using VOL.System.Repositories; namespace VOL.Ai.Services { @@ -251,16 +252,20 @@ namespace VOL.Ai.Services .Include(g => g.Classes) .ToListAsync(); - res.Grade = dbGrades.Select(g => new Grades - { - Id = (int)g.Id, - Name = g.GradeName, - Class = g.Classes.Select(c => new Classes + res.Grade = dbGrades + .Where(g => g.Classes != null && g.Classes.Any()) + .Select(g => new Grades { - Id = (int)c.Id, - Name = c.ClassName - }).ToList() - }).ToList(); + Id = (int)g.Id, + Name = g.GradeName, + Class = g.Classes.Select(c => new Classes + { + Id = (int)c.Id, + Name = c.ClassName + }).ToList() + }) + .ToList(); + return res; @@ -1494,6 +1499,7 @@ namespace VOL.Ai.Services /// /// [HttpPost(nameof(ScanCodeLogin))] + [HttpPost(nameof(ScanCodeLogin))] public async Task ScanCodeLogin(Ai_Request paramDto) { if (paramDto == null || string.IsNullOrWhiteSpace(paramDto.Code) || string.IsNullOrWhiteSpace(paramDto.SchoolCode)) @@ -1501,9 +1507,7 @@ namespace VOL.Ai.Services var schoolCode = paramDto.SchoolCode; - // ========================= // 1️⃣ 查询扫码登录信息 - // ========================= var loginInfo = await _scanCodeLoginRepository .FindAsIQueryable(x => x.Code == paramDto.Code && x.SchoolCode == schoolCode) .FirstOrDefaultAsync(); @@ -1511,82 +1515,45 @@ namespace VOL.Ai.Services if (loginInfo == null) throw new Exception("未查询到登录信息!"); - // ========================= // 2️⃣ 获取京师老师信息 - // ========================= var teacher = await _jingShiTiJiaoService.GetClassListByTeacher(loginInfo.TeacherPhoneNo); if (teacher == null || string.IsNullOrWhiteSpace(teacher.TeacherNo) || string.IsNullOrWhiteSpace(teacher.TeacherName)) throw new Exception("获取京师老师信息失败!"); var gradeDtos = teacher.GradeList ?? new List(); - - // ========================= - // 3️⃣ 提取所有 GradeNo / ClassNo - // ========================= var allGradeNos = gradeDtos.Where(g => !string.IsNullOrWhiteSpace(g.GradeNo)) .Select(g => g.GradeNo) .ToList(); - // ========================= - // 4️⃣ 查询已有年级和班级 - // ========================= + // 3️⃣ 查询数据库已有年级和班级 var existGrades = await _studentRepository.DbContext.Set() .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) .Include(g => g.Classes) .ToListAsync(); - var existGradeNoSet = existGrades.Select(x => x.GradeNo).ToHashSet(); - var existClassNoSet = existGrades.SelectMany(g => g.Classes).Select(c => c.ClassNo).ToHashSet(); + // 4️⃣ 更新已存在的年级老师信息(直接 UPDATE) + foreach (var grade in existGrades) + { + grade.TeacherNo = teacher.TeacherNo; + grade.TeacherName = teacher.TeacherName; + foreach (var cls in grade.Classes) + { + cls.TeacherNo = teacher.TeacherNo; + cls.TeacherName = teacher.TeacherName; + } + } + + // 5️⃣ 构造新增年级和班级 var newGrades = new List(); + var existGradeNoSet = existGrades.Select(g => g.GradeNo).ToHashSet(); + var existClassNoSet = existGrades.SelectMany(g => g.Classes).Select(c => c.ClassNo).ToHashSet(); foreach (var g in gradeDtos) { - if (string.IsNullOrWhiteSpace(g.GradeNo)) + if (string.IsNullOrWhiteSpace(g.GradeNo) || existGradeNoSet.Contains(g.GradeNo)) continue; - if (existGradeNoSet.Contains(g.GradeNo)) - { - // 已存在年级,更新老师信息 - var grade = existGrades.First(x => x.GradeNo == g.GradeNo); - grade.TeacherNo = teacher.TeacherNo; // ✅ 更新老师编号 - grade.TeacherName = teacher.TeacherName; // ✅ 更新老师姓名 - - foreach (var c in g.ClassList ?? new List()) - { - if (string.IsNullOrWhiteSpace(c.ClassNo)) - continue; - - var cls = grade.Classes.FirstOrDefault(x => x.ClassNo == c.ClassNo); - if (cls != null) - { - cls.TeacherNo = teacher.TeacherNo; // ✅ 更新班级老师编号 - cls.TeacherName = teacher.TeacherName; // ✅ 更新班级老师姓名 - } - else - { - // 新增班级 - var newClass = new JS_Class - { - TeacherNo = teacher.TeacherNo, - TeacherName = teacher.TeacherName, - SchoolCode = schoolCode, - Code = paramDto.Code, - GradeNo = g.GradeNo, - GradeName = g.GradeName, - ClassNo = c.ClassNo, - ClassName = c.ClassName, - GradeId = grade.Id - }; - grade.Classes.Add(newClass); - existClassNoSet.Add(c.ClassNo); - } - } - - continue; - } - - // 新增年级 + 班级 var gradeNew = new JS_Grade { TeacherNo = teacher.TeacherNo, @@ -1609,39 +1576,32 @@ namespace VOL.Ai.Services ClassName = c.ClassName }).ToList() ?? new List() }; - newGrades.Add(gradeNew); - existGradeNoSet.Add(g.GradeNo); - foreach (var c in gradeNew.Classes) - existClassNoSet.Add(c.ClassNo); } if (newGrades.Any()) await _studentRepository.DbContext.Set().AddRangeAsync(newGrades); - // ========================= - // 5️⃣ 保存(EF Core 自动生成 UPDATE) - // ========================= - try - { - await _studentRepository.DbContext.SaveChangesAsync(); - } - catch (DbUpdateException ex) when (ex.InnerException?.Message.Contains("UNIQUE") == true) - { - // 并发唯一索引冲突可忽略 - } + // 6️⃣ 保存所有修改和新增 - // ========================= - // 6️⃣ 组装返回 DTO - // ========================= + // EF Core 显式标记更新 + _studentRepository.UpdateRange(existGrades); + + // 同时更新所有班级(必须显式) + var allClasses = existGrades.SelectMany(g => g.Classes).ToList(); + _classRepository.UpdateRange(allClasses); + + await _studentRepository.DbContext.SaveChangesAsync(); + + // 7️⃣ 返回结果 var dbGrades = await _studentRepository.DbContext.Set() - .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo)) + .Where(x => x.SchoolCode == schoolCode && allGradeNos.Contains(x.GradeNo) && x.TeacherNo == teacher.TeacherNo) .Include(g => g.Classes) .ToListAsync(); var res = new Ai_TeacherFaceInfo { - Id = 0, // 老师表不操作 + Id = 0, TeacherName = teacher.TeacherName, Phone = teacher.TeacherNo, GradeAndClassList = dbGrades @@ -1654,9 +1614,7 @@ namespace VOL.Ai.Services .ToList() }; - // ========================= - // 7️⃣ 删除扫码记录 - // ========================= + // 8️⃣ 删除扫码记录 _scanCodeLoginRepository.Delete(loginInfo); await _scanCodeLoginRepository.SaveChangesAsync(); @@ -1664,6 +1622,7 @@ namespace VOL.Ai.Services } + /// /// 登录 ///