根据提供的六张课目编号截图,将 CourseNames 补齐为 63 个项目,覆盖俯卧撑、仰卧起坐、跑步、球类、互动项目和体测项目。未知编号仍保留待确认课目的兜底显示,不修改实体数据类型、表结构或数据。 将项目名称筛选改为精确匹配,避免选择深蹲时混入深蹲跳等名称相近的记录。 验证:后端 Debug 构建成功(0 错误);与前端下拉选项核对均为 63 个项目。
249 lines
9.6 KiB
C#
249 lines
9.6 KiB
C#
using Microsoft.EntityFrameworkCore;
|
||
using VOL.Ai.IServices;
|
||
using VOL.Core.EFDbContext;
|
||
using VOL.Core.Extensions.AutofacManager;
|
||
using VOL.Core.ManageUser;
|
||
using VOL.Entity.DomainModels;
|
||
using VOL.Entity.DomainModels.YiLu;
|
||
using VOL.Entity.Enum;
|
||
using VOL.Model;
|
||
using VOL.Model.Ai.Request;
|
||
using VOL.Model.Ai.Response;
|
||
|
||
namespace VOL.Ai.Services
|
||
{
|
||
public class AiSportsStationService : IAiSportsStationService, IDependency
|
||
{
|
||
private readonly VOLContext _dbContext;
|
||
|
||
private static readonly Dictionary<int, string> CourseNames = new()
|
||
{
|
||
{ 1, "俯卧撑" },
|
||
{ 2, "仰卧起坐" },
|
||
{ 3, "引体向上" },
|
||
{ 7, "立定跳远" },
|
||
{ 8, "跳绳" },
|
||
{ 9, "开合跳" },
|
||
{ 10, "高抬腿" },
|
||
{ 11, "深蹲" },
|
||
{ 12, "50米跑" },
|
||
{ 13, "100米跑" },
|
||
{ 14, "800米跑" },
|
||
{ 15, "1000米跑" },
|
||
{ 16, "3000米跑" },
|
||
{ 20, "50米×8" },
|
||
{ 21, "篮球绕杆" },
|
||
{ 22, "足球绕杆" },
|
||
{ 23, "坐位体前屈" },
|
||
{ 24, "单脚跳" },
|
||
{ 25, "动态臀桥" },
|
||
{ 26, "左右跳" },
|
||
{ 27, "打地鼠" },
|
||
{ 28, "七上八下" },
|
||
{ 29, "消灭蚊子" },
|
||
{ 30, "石头剪刀布" },
|
||
{ 31, "变脸" },
|
||
{ 32, "打钉子" },
|
||
{ 33, "击鼓传花" },
|
||
{ 34, "踢足球" },
|
||
{ 35, "手脚并用" },
|
||
{ 36, "踢毽子" },
|
||
{ 37, "风火轮" },
|
||
{ 38, "顺序摸数字" },
|
||
{ 39, "俄罗斯方块" },
|
||
{ 40, "诗词满腹" },
|
||
{ 41, "单词大王" },
|
||
{ 42, "数学王者" },
|
||
{ 43, "音乐大师" },
|
||
{ 44, "历史小生" },
|
||
{ 45, "科学达人" },
|
||
{ 46, "纵跳摸高" },
|
||
{ 47, "半蹲跳" },
|
||
{ 48, "深蹲跳" },
|
||
{ 49, "侧向蹲起" },
|
||
{ 50, "篮球单手运球" },
|
||
{ 51, "篮球双手交替运球" },
|
||
{ 52, "身体绕球" },
|
||
{ 53, "足球踩球" },
|
||
{ 54, "足球颠球" },
|
||
{ 55, "足球踩单车" },
|
||
{ 56, "排球垫球" },
|
||
{ 57, "排球自传挑战" },
|
||
{ 60, "实心球" },
|
||
{ 61, "阳光跑" },
|
||
{ 62, "健身长拳" },
|
||
{ 63, "200米跑" },
|
||
{ 64, "400米×4" },
|
||
{ 65, "400米跑" },
|
||
{ 66, "6分钟跑" },
|
||
{ 67, "9分钟跑" },
|
||
{ 68, "1500米跑" },
|
||
{ 69, "60米跑" },
|
||
{ 1001, "体重系数(BMI)" },
|
||
{ 1002, "肺活量" }
|
||
};
|
||
|
||
public AiSportsStationService(VOLContext dbContext)
|
||
{
|
||
_dbContext = dbContext;
|
||
}
|
||
|
||
public async Task<PageDataDto<AiSportsStationDto>> GetAiSportsStationList(AiSportsStationListRequest paramDto)
|
||
{
|
||
paramDto.PageIndex = paramDto.PageIndex <= 0 ? 1 : paramDto.PageIndex;
|
||
paramDto.PageSize = paramDto.PageSize <= 0 ? 10 : paramDto.PageSize;
|
||
|
||
var currentUser = UserContext.Current;
|
||
var isAdmin = currentUser?.IsSuperAdmin == true
|
||
|| string.Equals(currentUser?.UserName, "admin", StringComparison.OrdinalIgnoreCase);
|
||
var schoolCode = currentUser?.TenantId;
|
||
int? schoolId = null;
|
||
|
||
if (!isAdmin)
|
||
{
|
||
schoolId = await _dbContext.Set<S_School>()
|
||
.Where(x => x.SchoolCode == schoolCode)
|
||
.Select(x => (int?)x.Id)
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (schoolId == null)
|
||
{
|
||
return new PageDataDto<AiSportsStationDto>
|
||
{
|
||
Total = 0,
|
||
TotalPages = 0,
|
||
PageIndex = paramDto.PageIndex,
|
||
PageSize = paramDto.PageSize,
|
||
Datas = new List<AiSportsStationDto>()
|
||
};
|
||
}
|
||
}
|
||
|
||
var studentName = paramDto.StudentName?.Trim();
|
||
var projectName = paramDto.ProjectName?.Trim();
|
||
var sex = GetSexType(paramDto.Sex);
|
||
|
||
var query =
|
||
from train in _dbContext.Set<YL_Train>().AsNoTracking()
|
||
join device in _dbContext.Set<YL_Device>().AsNoTracking()
|
||
on train.DeviceSerial equals device.SerialNumber
|
||
join school in _dbContext.Set<S_School>().AsNoTracking()
|
||
on device.OrgId equals (int?)school.Id into schoolGroup
|
||
from school in schoolGroup.DefaultIfEmpty()
|
||
join student in _dbContext.Set<S_Student>().AsNoTracking()
|
||
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<S_Class>().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,
|
||
DeviceSchoolCode = school.SchoolCode,
|
||
train.CourseId,
|
||
train.StartTime,
|
||
train.EndTime,
|
||
train.Score,
|
||
// Cast in SQL so int and float columns both materialize as the original int type.
|
||
StandardCounts = Convert.ToInt32(Convert.ToDouble(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 = 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.DeviceSchoolCode == schoolCode);
|
||
}
|
||
|
||
if (!string.IsNullOrWhiteSpace(studentName))
|
||
query = query.Where(x => x.StudentName.Contains(studentName));
|
||
|
||
if (sex.HasValue)
|
||
query = query.Where(x => x.Sex == sex.Value);
|
||
|
||
if (paramDto.ClassId > 0)
|
||
query = query.Where(x => x.ClassId == paramDto.ClassId);
|
||
|
||
if (paramDto.StartTime.HasValue)
|
||
query = query.Where(x => x.StartTime >= paramDto.StartTime.Value);
|
||
|
||
if (paramDto.EndTime.HasValue)
|
||
query = query.Where(x => x.StartTime <= paramDto.EndTime.Value);
|
||
|
||
var rows = await query
|
||
.OrderByDescending(x => x.StartTime)
|
||
.ThenByDescending(x => x.Id)
|
||
.ToListAsync();
|
||
|
||
if (!string.IsNullOrWhiteSpace(projectName))
|
||
rows = rows.Where(x => GetCourseName(x.CourseId) == projectName).ToList();
|
||
|
||
var total = rows.Count;
|
||
var datas = rows
|
||
.Skip((paramDto.PageIndex - 1) * paramDto.PageSize)
|
||
.Take(paramDto.PageSize)
|
||
.Select((x, index) => new AiSportsStationDto
|
||
{
|
||
Ind = (paramDto.PageIndex - 1) * paramDto.PageSize + index + 1,
|
||
StudentName = x.StudentName,
|
||
Sex = GetSexName(x.Sex),
|
||
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
|
||
})
|
||
.ToList();
|
||
|
||
return new PageDataDto<AiSportsStationDto>
|
||
{
|
||
Total = total,
|
||
TotalPages = (int)Math.Ceiling(total / (double)paramDto.PageSize),
|
||
PageIndex = paramDto.PageIndex,
|
||
PageSize = paramDto.PageSize,
|
||
Datas = datas
|
||
};
|
||
}
|
||
|
||
private static string GetCourseName(int courseId)
|
||
{
|
||
return CourseNames.TryGetValue(courseId, out var name) ? name : $"待确认课目(编号{courseId})";
|
||
}
|
||
|
||
private static SexType? GetSexType(string sex)
|
||
{
|
||
return sex switch
|
||
{
|
||
"男" => SexType.Male,
|
||
"女" => SexType.Female,
|
||
_ => null
|
||
};
|
||
}
|
||
|
||
private static string GetSexName(SexType? sex)
|
||
{
|
||
if (sex == null) return string.Empty;
|
||
return sex == SexType.Male ? "男" : "女";
|
||
}
|
||
}
|
||
}
|