diff --git a/VOL.Ai/Services/AiAppService.cs b/VOL.Ai/Services/AiAppService.cs index bb79823..41715b6 100644 --- a/VOL.Ai/Services/AiAppService.cs +++ b/VOL.Ai/Services/AiAppService.cs @@ -142,181 +142,187 @@ 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; - - //// ========================= - //// 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 - // .Where(g => g.Classes != null && g.Classes.Any()) - // .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, Province = "", - City = "", - Grade = schoolClass.Grades - .Where(g => g.Classes != null && g.Classes.Any()) // ⭐ 只保留有班级的年级 - .Select((g, gradeIndex) => - { - var gradeId = gradeIndex + 1; // 年级 Id 从 1 开始 - - return new Grades - { - Id = gradeId, - Name = g.GradeName, - - Class = g.Classes - .Select((c, classIndex) => new Classes - { - Id = classIndex + 1, - Name = c.ClassName - }) - .ToList() - }; - }) - .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(); + + // 按 GradeNo 分组,只取每组第一个 + var distinctGrades = dbGrades + .GroupBy(g => g.GradeNo) + .Select(g => g.First()) + .ToList(); + + res.Grade = distinctGrades + .Where(g => g.Classes != null && g.Classes.Any()) + .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 + // .Where(g => g.Classes != null && g.Classes.Any()) // ⭐ 只保留有班级的年级 + // .Select((g, gradeIndex) => + // { + // var gradeId = gradeIndex + 1; // 年级 Id 从 1 开始 + + // return new Grades + // { + // Id = gradeId, + // Name = g.GradeName, + + // Class = g.Classes + // .Select((c, classIndex) => new Classes + // { + // Id = classIndex + 1, + // Name = c.ClassName + // }) + // .ToList() + // }; + // }) + // .ToList() + //}; + + //return res; } public Ai_OSSInfoDto OSSInfo(Ai_Request paramDto)