diff --git a/VOL.Ai/Services/AiSportsStationService.cs b/VOL.Ai/Services/AiSportsStationService.cs index c1738bd..e71901d 100644 --- a/VOL.Ai/Services/AiSportsStationService.cs +++ b/VOL.Ai/Services/AiSportsStationService.cs @@ -82,28 +82,44 @@ namespace VOL.Ai.Services from train in _dbContext.Set().AsNoTracking() join device in _dbContext.Set().AsNoTracking() on train.DeviceSerial equals device.SerialNumber + join school in _dbContext.Set().AsNoTracking() + on device.OrgId equals (int?)school.Id into schoolGroup + from school in schoolGroup.DefaultIfEmpty() join student in _dbContext.Set().AsNoTracking() - on train.UserSerial equals student.StudentNo into studentGroup + on new { StudentNo = train.UserSerial, SchoolCode = school.SchoolCode } + equals new { student.StudentNo, student.SchoolCode } into studentGroup from student in studentGroup.DefaultIfEmpty() + join studentClass in _dbContext.Set().AsNoTracking() + on new { Id = student.ClassId, student.SchoolCode } + equals new { studentClass.Id, studentClass.SchoolCode } into classGroup + from studentClass in classGroup.DefaultIfEmpty() select new { train.Id, device.OrgId, - StudentSchoolCode = student == null ? schoolCode : student.SchoolCode, + DeviceSchoolCode = school.SchoolCode, train.CourseId, train.StartTime, train.EndTime, + train.Score, + train.StandardCounts, + train.UnStandardCounts, + train.TimeKeeping, + train.Duration, + train.Distance, train.UserSerial, StudentName = student == null ? train.UserSerial : student.StudentName, Sex = student == null ? (SexType?)null : student.Sex, ClassId = student == null ? 0 : student.ClassId, - ClassName = student == null ? string.Empty : student.ClassName + ClassName = studentClass == null || studentClass.ClassName == null || studentClass.ClassName == "" + ? (student == null ? string.Empty : student.ClassName) + : (studentClass.GradeName ?? string.Empty) + studentClass.ClassName }; if (!isAdmin) { var currentSchoolId = schoolId.GetValueOrDefault(); - query = query.Where(x => x.OrgId == currentSchoolId && x.StudentSchoolCode == schoolCode); + query = query.Where(x => x.OrgId == currentSchoolId && x.DeviceSchoolCode == schoolCode); } if (!string.IsNullOrWhiteSpace(studentName)) @@ -138,8 +154,15 @@ namespace VOL.Ai.Services Ind = (paramDto.PageIndex - 1) * paramDto.PageSize + index + 1, StudentName = x.StudentName, Sex = GetSexName(x.Sex), - ClassName = x.ClassName, + ClassName = string.IsNullOrWhiteSpace(x.ClassName) ? "未匹配班级" : x.ClassName, ProjectName = GetCourseName(x.CourseId), + CourseId = x.CourseId, + Score = x.Score, + StandardCounts = x.StandardCounts, + UnStandardCounts = x.UnStandardCounts, + TimeKeeping = x.TimeKeeping, + Duration = x.Duration, + Distance = x.Distance, StartTime = x.StartTime, EndTime = x.EndTime }) @@ -157,7 +180,7 @@ namespace VOL.Ai.Services private static string GetCourseName(int courseId) { - return CourseNames.TryGetValue(courseId, out var name) ? name : courseId.ToString(); + return CourseNames.TryGetValue(courseId, out var name) ? name : $"待确认课目(编号{courseId})"; } private static SexType? GetSexType(string sex) diff --git a/VOL.Business/Services/Norm/N_SportsTestResultService.cs b/VOL.Business/Services/Norm/N_SportsTestResultService.cs index 6029a71..d575563 100644 --- a/VOL.Business/Services/Norm/N_SportsTestResultService.cs +++ b/VOL.Business/Services/Norm/N_SportsTestResultService.cs @@ -1625,7 +1625,7 @@ namespace VOL.Business.Services select new StudentsTestDataModel() { Id = r.Id, - GradeId = r.Id, + GradeId = r.GradeId, GradeName = r.GradeName, StudentNo = r.StudentNo, StudentName = r.StudentName, @@ -1641,6 +1641,7 @@ namespace VOL.Business.Services Value = r.Value, Rank = r.Rank, CategoryId = c.Id, + CategoryValue = c.CategoryValue, Score = r.Score, Sex = r.Sex == SexType.Male ? "男" : "女", ScoreTime = r.ScoreTime @@ -1697,9 +1698,10 @@ namespace VOL.Business.Services select new StudentsTestDataModel() { Id = r.Id, - GradeId = r.Id, + GradeId = r.GradeId, GradeName = r.GradeName, StudentNo = r.StudentNo, + StudentName = r.StudentName, CategoryName = c.CategoryName, ClassId = r.ClassId, ClassName = r.ClassName, @@ -1712,8 +1714,10 @@ namespace VOL.Business.Services Value = r.Value, Rank = r.Rank, CategoryId = c.Id, + CategoryValue = c.CategoryValue, Score = r.Score, - Sex = r.Sex == SexType.Male ? "男" : "女" + Sex = r.Sex == SexType.Male ? "男" : "女", + ScoreTime = r.ScoreTime }; if (!string.IsNullOrWhiteSpace(paramDto.StudentNo)) @@ -1747,7 +1751,7 @@ namespace VOL.Business.Services } - var list = await query.ToListAsync(); + var list = await query.OrderByDescending(x => x.ScoreTime).ThenByDescending(x => x.Id).ToListAsync(); return list; } @@ -2090,4 +2094,4 @@ namespace VOL.Business.Services return scoreToAdditionalPoints[score]; } } -} \ No newline at end of file +} diff --git a/VOL.Business/Services/SunshineRun/SunshineRunService.cs b/VOL.Business/Services/SunshineRun/SunshineRunService.cs index 4f4187c..ed55b36 100644 --- a/VOL.Business/Services/SunshineRun/SunshineRunService.cs +++ b/VOL.Business/Services/SunshineRun/SunshineRunService.cs @@ -69,7 +69,11 @@ namespace VOL.Business.Services.SunshineRun private static string BuildWhere(SunshineRunFilterParam param, string schoolId) { - var conditions = new List { "1 = 1" }; + var conditions = new List + { + "ISNULL(r.EffectiveDistance, 0) > 0", + "ISNULL(r.Times, 0) - ISNULL(r.InvalidTimes, 0) > 0" + }; if (schoolId != null) conditions.Add("r.OrgId = @OrgId"); if (!string.IsNullOrWhiteSpace(param.StudentName)) diff --git a/VOL.Entity/DomainModels/YiLu/YL_Train.cs b/VOL.Entity/DomainModels/YiLu/YL_Train.cs index a4c5f1a..872bffe 100644 --- a/VOL.Entity/DomainModels/YiLu/YL_Train.cs +++ b/VOL.Entity/DomainModels/YiLu/YL_Train.cs @@ -72,7 +72,7 @@ namespace VOL.Entity.DomainModels.YiLu /// /// 有效个数 /// - public int StandardCounts { get; set; } + public double StandardCounts { get; set; } /// /// 不合格动作数 diff --git a/VOL.Model/Ai/Response/AiSportsStationDto.cs b/VOL.Model/Ai/Response/AiSportsStationDto.cs index ef97a07..bd37f8b 100644 --- a/VOL.Model/Ai/Response/AiSportsStationDto.cs +++ b/VOL.Model/Ai/Response/AiSportsStationDto.cs @@ -32,6 +32,35 @@ namespace VOL.Model.Ai.Response /// public string ProjectName { get; set; } + /// + /// 壹路课目编号 + /// + public int CourseId { get; set; } + + /// + /// 统一成绩值 + /// + public double? Score { get; set; } + + public double StandardCounts { get; set; } + + public int UnStandardCounts { get; set; } + + /// + /// 有效时长(秒) + /// + public double? TimeKeeping { get; set; } + + /// + /// 训练时长(秒) + /// + public int Duration { get; set; } + + /// + /// 距离(米) + /// + public double? Distance { get; set; } + /// /// 运动开始时间 /// diff --git a/VOL.Model/Norm/Response/StudentsTestDataModel.cs b/VOL.Model/Norm/Response/StudentsTestDataModel.cs index c2938e7..12065e2 100644 --- a/VOL.Model/Norm/Response/StudentsTestDataModel.cs +++ b/VOL.Model/Norm/Response/StudentsTestDataModel.cs @@ -39,6 +39,9 @@ namespace VOL.Model [Display(Name = "IgnoreColumnAttribute")] public int CategoryId { get; set; } + [Display(Name = "IgnoreColumnAttribute")] + public int CategoryValue { get; set; } + /// ///年级名称 /// diff --git a/VOL.Model/Norm/Response/SummaryOfGradesTestRecordExportModel.cs b/VOL.Model/Norm/Response/SummaryOfGradesTestRecordExportModel.cs new file mode 100644 index 0000000..63ef96d --- /dev/null +++ b/VOL.Model/Norm/Response/SummaryOfGradesTestRecordExportModel.cs @@ -0,0 +1,40 @@ +using System.ComponentModel.DataAnnotations; + +namespace VOL.Model +{ + public class SummaryOfGradesTestRecordExportModel + { + [Display(Name = "序号")] + public int Index { get; set; } + + [Display(Name = "年级-班级")] + public string GradeAndClass { get; set; } + + [Display(Name = "学生姓名")] + public string StudentName { get; set; } + + [Display(Name = "学生学号")] + public string StudentNo { get; set; } + + [Display(Name = "性别")] + public string Sex { get; set; } + + [Display(Name = "测试类别")] + public string CategoryName { get; set; } + + [Display(Name = "测试结果")] + public string TestResult { get; set; } + + [Display(Name = "得分")] + public float Score { get; set; } + + [Display(Name = "等级")] + public string Rank { get; set; } + + [Display(Name = "班级排名")] + public int ClassRank { get; set; } + + [Display(Name = "测试时间")] + public string ScoreTime { get; set; } + } +} diff --git a/VOL.WebApi/Controllers/Business/SportsTestResultController.cs b/VOL.WebApi/Controllers/Business/SportsTestResultController.cs index 9cbd0b3..fa2435e 100644 --- a/VOL.WebApi/Controllers/Business/SportsTestResultController.cs +++ b/VOL.WebApi/Controllers/Business/SportsTestResultController.cs @@ -3,6 +3,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; +using System.Globalization; +using System.Linq; using System.Threading.Tasks; using VOL.Business.IServices; using VOL.Business.Services; @@ -79,6 +81,57 @@ namespace VOL.WebApi.Controllers.Business return File(excelBytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", $"学生成绩{DateTime.Now.ToString("yyyyMMddHHmmss")}"); } + [HttpGet(nameof(ExportSummaryOfGrades))] + public async Task ExportSummaryOfGrades(StudentsTestDataListParam paramDto) + { + var records = await _sportsTestResultService.GetStudentsTestDataList(paramDto); + var rows = records.Select((row, index) => new SummaryOfGradesTestRecordExportModel + { + Index = index + 1, + GradeAndClass = string.Join("-", new[] { row.GradeName, row.ClassName } + .Where(x => !string.IsNullOrWhiteSpace(x))), + StudentName = row.StudentName, + StudentNo = row.StudentNo, + Sex = row.Sex, + CategoryName = row.CategoryName, + TestResult = FormatTestResult(row), + Score = row.Score, + Rank = row.Rank, + ClassRank = row.ClassRank, + ScoreTime = row.ScoreTime.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) + }).ToList(); + var columns = new List + { + nameof(SummaryOfGradesTestRecordExportModel.Index), + nameof(SummaryOfGradesTestRecordExportModel.GradeAndClass), + nameof(SummaryOfGradesTestRecordExportModel.StudentName), + nameof(SummaryOfGradesTestRecordExportModel.StudentNo), + nameof(SummaryOfGradesTestRecordExportModel.Sex), + nameof(SummaryOfGradesTestRecordExportModel.CategoryName), + nameof(SummaryOfGradesTestRecordExportModel.TestResult), + nameof(SummaryOfGradesTestRecordExportModel.Score), + nameof(SummaryOfGradesTestRecordExportModel.Rank), + nameof(SummaryOfGradesTestRecordExportModel.ClassRank), + nameof(SummaryOfGradesTestRecordExportModel.ScoreTime) + }; + var bytes = Tool.ExportToExcel( + new Dictionary> { ["体测数据记录"] = rows }, + columns, autoFitColumns: false); + return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", + $"体测数据记录{DateTime.Now:yyyyMMddHHmmss}.xlsx"); + } + + private static string FormatTestResult(StudentsTestDataModel row) + { + if (row.CategoryValue != 10 && row.CategoryValue != 11) + return row.Value.ToString("0.##", CultureInfo.InvariantCulture); + + // Some historical imports contain millisecond values despite the seconds-based category unit. + var seconds = row.Value >= 10000 ? row.Value / 1000d : row.Value; + var totalSeconds = (int)Math.Round(Math.Max(0, seconds), MidpointRounding.AwayFromZero); + return $"{totalSeconds / 60}分{totalSeconds % 60:D2}秒"; + } + /// /// 新增 /// @@ -115,4 +168,4 @@ namespace VOL.WebApi.Controllers.Business return Ok("更新成功"); } } -} \ No newline at end of file +}