将 YL_Train.StandardCounts 和 AiSportsStationDto.StandardCounts 从 double 恢复为 int,与原始实体定义及迁移快照保持一致。 列表查询保留显式数值转换,以适配测试库 float 和生产库 int 的列类型差异;不修改数据库表结构或数据。 验证:dotnet build VOL.WebApi/VOL.WebApi.csproj --no-restore -c Release 成功;git diff --cached --check 通过。
204 lines
8.1 KiB
C#
204 lines
8.1 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()
|
||
{
|
||
{ 3, "引体向上" },
|
||
{ 7, "立定跳远" },
|
||
{ 8, "跳绳" },
|
||
{ 9, "开合跳" },
|
||
{ 10, "高抬腿" },
|
||
{ 11, "深蹲" },
|
||
{ 23, "坐位体前屈" },
|
||
{ 24, "单脚跳" },
|
||
{ 25, "动态臀桥" },
|
||
{ 26, "左右跳" },
|
||
{ 27, "打地鼠" },
|
||
{ 28, "七上八下" },
|
||
{ 29, "消灭蚊子" },
|
||
{ 30, "石头剪刀布" },
|
||
{ 31, "变脸" },
|
||
{ 32, "打钉子" },
|
||
{ 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).Contains(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 ? "男" : "女";
|
||
}
|
||
}
|
||
}
|