From e1fac41f8c35ab89c7eb4274494aef497fc89908 Mon Sep 17 00:00:00 2001
From: ltx <1006158920@qq.com>
Date: Sat, 10 Oct 2026 09:44:15 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E8=AF=BE=E5=A0=82?=
=?UTF-8?q?=E8=B7=B3=E7=BB=B3=E6=8A=A5=E5=91=8A=E6=9F=A5=E8=AF=A2=E4=B8=8E?=
=?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
按课堂记录和学校权限范围查询 Ai_FastJumpRopeData,提供分页报告与 Excel 导出。
导出完整课堂数据并关闭 Excel 自动列宽,避免 GDI 依赖。
---
.../Training/II_TrainingDataService.cs | 4 ++
.../Training/I_TrainingDataService.cs | 54 +++++++++++++++++++
.../Response/FastJumpRopeReportModel.cs | 38 +++++++++++++
.../Business/TrainingDataController.cs | 41 ++++++++++++++
4 files changed, 137 insertions(+)
create mode 100644 VOL.Model/Training/Response/FastJumpRopeReportModel.cs
diff --git a/VOL.Business/IServices/Training/II_TrainingDataService.cs b/VOL.Business/IServices/Training/II_TrainingDataService.cs
index ca03a8b..7c94ebd 100644
--- a/VOL.Business/IServices/Training/II_TrainingDataService.cs
+++ b/VOL.Business/IServices/Training/II_TrainingDataService.cs
@@ -169,6 +169,10 @@ namespace VOL.Business.IServices.Training
///
Task GetClassReportDetails(int id);
+ Task> GetFastJumpRopeReport(int classRoomRecordId, int pageIndex, int pageSize);
+
+ Task> GetFastJumpRopeReportExport(int classRoomRecordId);
+
///
/// 学生课堂报告详情
///
diff --git a/VOL.Business/Services/Training/I_TrainingDataService.cs b/VOL.Business/Services/Training/I_TrainingDataService.cs
index b0cd315..a86fc12 100644
--- a/VOL.Business/Services/Training/I_TrainingDataService.cs
+++ b/VOL.Business/Services/Training/I_TrainingDataService.cs
@@ -1987,6 +1987,60 @@ namespace VOL.Business.Services.Training
#region 课堂报告
+ private IQueryable FastJumpRopeReportQuery(int classRoomRecordId)
+ {
+ var schoolCode = UserContext.Current.TenantId;
+ var isSuperAdmin = UserContext.Current.IsSuperAdmin;
+ var classrooms = _teacherRepository.DbContext.Set().AsNoTracking();
+ return _teacherRepository.DbContext.Set().AsNoTracking()
+ .Where(row => row.ClassRoomRecordId == classRoomRecordId &&
+ classrooms.Any(room => room.Id == classRoomRecordId &&
+ room.SchoolCode == row.SchoolCode &&
+ (isSuperAdmin || room.SchoolCode == schoolCode)));
+ }
+
+ private static List ToFastJumpRopeReportRows(List rows, int offset)
+ {
+ return rows.Select((row, index) => new FastJumpRopeReportModel
+ {
+ Index = offset + index + 1,
+ StudentNo = row.StudentNo,
+ StudentName = row.StudentName,
+ GradeAndClass = $"{row.GradeName}-{row.ClassName}",
+ ModeName = string.IsNullOrWhiteSpace(row.ModelName) ? row.ModeType.GetDescription() : row.ModelName,
+ JumpValue = row.JumpValue,
+ ErrorNumber = row.ErrorNumber,
+ MotionDuration = row.MotionDuration,
+ RankName = row.Rank.HasValue && global::System.Enum.IsDefined(typeof(AchievementRank), row.Rank.Value)
+ ? ((AchievementRank)row.Rank.Value).GetDescription() : "-",
+ ScoreTime = row.ScoreTime
+ }).ToList();
+ }
+
+ public async Task> GetFastJumpRopeReport(int classRoomRecordId, int pageIndex, int pageSize)
+ {
+ var query = FastJumpRopeReportQuery(classRoomRecordId);
+ var total = await query.CountAsync();
+ var offset = (pageIndex - 1) * pageSize;
+ var rows = await query.OrderByDescending(row => row.ScoreTime).ThenByDescending(row => row.Id)
+ .Skip(offset).Take(pageSize).ToListAsync();
+ return new PageDataDto
+ {
+ Total = total,
+ PageIndex = pageIndex,
+ PageSize = pageSize,
+ TotalPages = (int)Math.Ceiling(total / (double)pageSize),
+ Datas = ToFastJumpRopeReportRows(rows, offset)
+ };
+ }
+
+ public async Task> GetFastJumpRopeReportExport(int classRoomRecordId)
+ {
+ var rows = await FastJumpRopeReportQuery(classRoomRecordId)
+ .OrderByDescending(row => row.ScoreTime).ThenByDescending(row => row.Id).ToListAsync();
+ return ToFastJumpRopeReportRows(rows, 0);
+ }
+
///
/// 课堂记录列表
///
diff --git a/VOL.Model/Training/Response/FastJumpRopeReportModel.cs b/VOL.Model/Training/Response/FastJumpRopeReportModel.cs
new file mode 100644
index 0000000..29c627d
--- /dev/null
+++ b/VOL.Model/Training/Response/FastJumpRopeReportModel.cs
@@ -0,0 +1,38 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+
+namespace VOL.Model
+{
+ public class FastJumpRopeReportModel
+ {
+ [Display(Name = "序号")]
+ public int Index { get; set; }
+
+ [Display(Name = "学号")]
+ public string StudentNo { get; set; } = string.Empty;
+
+ [Display(Name = "姓名")]
+ public string StudentName { get; set; } = string.Empty;
+
+ [Display(Name = "年级班级")]
+ public string GradeAndClass { get; set; } = string.Empty;
+
+ [Display(Name = "跳绳模式")]
+ public string ModeName { get; set; } = string.Empty;
+
+ [Display(Name = "跳绳次数")]
+ public int? JumpValue { get; set; }
+
+ [Display(Name = "错误次数")]
+ public int? ErrorNumber { get; set; }
+
+ [Display(Name = "运动时长(秒)")]
+ public int? MotionDuration { get; set; }
+
+ [Display(Name = "成绩等级")]
+ public string RankName { get; set; } = string.Empty;
+
+ [Display(Name = "测试时间")]
+ public DateTime ScoreTime { get; set; }
+ }
+}
diff --git a/VOL.WebApi/Controllers/Business/TrainingDataController.cs b/VOL.WebApi/Controllers/Business/TrainingDataController.cs
index e49c2b8..a868a0a 100644
--- a/VOL.WebApi/Controllers/Business/TrainingDataController.cs
+++ b/VOL.WebApi/Controllers/Business/TrainingDataController.cs
@@ -365,6 +365,47 @@ namespace VOL.WebApi.Controllers.Business
return await _trainingDataService.GetClassReportDetails(id);
}
+ ///
+ /// 当前课堂的跳绳报告。
+ ///
+ [HttpGet(nameof(GetFastJumpRopeReport))]
+ public Task> GetFastJumpRopeReport(
+ [FromQuery] int classRoomRecordId, [FromQuery] int pageIndex = 1, [FromQuery] int pageSize = 10)
+ {
+ if (classRoomRecordId <= 0 || pageIndex <= 0 || pageSize <= 0 || pageSize > 200)
+ throw new ArgumentException("课堂记录、页码或每页行数不正确");
+ return _trainingDataService.GetFastJumpRopeReport(classRoomRecordId, pageIndex, pageSize);
+ }
+
+ ///
+ /// 导出当前课堂的全部跳绳成绩。
+ ///
+ [HttpGet(nameof(ExportFastJumpRopeReport))]
+ public async Task ExportFastJumpRopeReport([FromQuery] int classRoomRecordId)
+ {
+ if (classRoomRecordId <= 0)
+ throw new ArgumentException("课堂记录不正确");
+ var rows = await _trainingDataService.GetFastJumpRopeReportExport(classRoomRecordId);
+ var columns = new List
+ {
+ nameof(FastJumpRopeReportModel.Index),
+ nameof(FastJumpRopeReportModel.StudentNo),
+ nameof(FastJumpRopeReportModel.StudentName),
+ nameof(FastJumpRopeReportModel.GradeAndClass),
+ nameof(FastJumpRopeReportModel.ModeName),
+ nameof(FastJumpRopeReportModel.JumpValue),
+ nameof(FastJumpRopeReportModel.ErrorNumber),
+ nameof(FastJumpRopeReportModel.MotionDuration),
+ nameof(FastJumpRopeReportModel.RankName),
+ nameof(FastJumpRopeReportModel.ScoreTime)
+ };
+ var bytes = Tool.ExportToExcel(
+ new Dictionary> { ["跳绳报告"] = rows },
+ columns, autoFitColumns: false);
+ return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ $"跳绳报告{DateTime.Now:yyyyMMddHHmmss}.xlsx");
+ }
+
///
/// 学生课堂报告详情
///