diff --git a/VOL.Ai/IServices/IAiSportsStationService.cs b/VOL.Ai/IServices/IAiSportsStationService.cs new file mode 100644 index 0000000..93a5f87 --- /dev/null +++ b/VOL.Ai/IServices/IAiSportsStationService.cs @@ -0,0 +1,15 @@ +using VOL.Core.Extensions.AutofacManager; +using VOL.Model; +using VOL.Model.Ai.Request; +using VOL.Model.Ai.Response; + +namespace VOL.Ai.IServices +{ + public interface IAiSportsStationService : IDependency + { + /// + /// 获取壹路AI运动站列表 + /// + Task> GetAiSportsStationList(AiSportsStationListRequest paramDto); + } +} diff --git a/VOL.Ai/Services/AiSportsStationService.cs b/VOL.Ai/Services/AiSportsStationService.cs new file mode 100644 index 0000000..c1738bd --- /dev/null +++ b/VOL.Ai/Services/AiSportsStationService.cs @@ -0,0 +1,179 @@ +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 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> 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() + .Where(x => x.SchoolCode == schoolCode) + .Select(x => (int?)x.Id) + .FirstOrDefaultAsync(); + + if (schoolId == null) + { + return new PageDataDto + { + Total = 0, + TotalPages = 0, + PageIndex = paramDto.PageIndex, + PageSize = paramDto.PageSize, + Datas = new List() + }; + } + } + + var studentName = paramDto.StudentName?.Trim(); + var projectName = paramDto.ProjectName?.Trim(); + var sex = GetSexType(paramDto.Sex); + + var query = + from train in _dbContext.Set().AsNoTracking() + join device in _dbContext.Set().AsNoTracking() + on train.DeviceSerial equals device.SerialNumber + join student in _dbContext.Set().AsNoTracking() + on train.UserSerial equals student.StudentNo into studentGroup + from student in studentGroup.DefaultIfEmpty() + select new + { + train.Id, + device.OrgId, + StudentSchoolCode = student == null ? schoolCode : student.SchoolCode, + train.CourseId, + train.StartTime, + train.EndTime, + 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 + }; + + if (!isAdmin) + { + var currentSchoolId = schoolId.GetValueOrDefault(); + query = query.Where(x => x.OrgId == currentSchoolId && x.StudentSchoolCode == 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 = x.ClassName, + ProjectName = GetCourseName(x.CourseId), + StartTime = x.StartTime, + EndTime = x.EndTime + }) + .ToList(); + + return new PageDataDto + { + 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.ToString(); + } + + 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 ? "男" : "女"; + } + } +} diff --git a/VOL.Model/Ai/Request/AiSportsStationRequest.cs b/VOL.Model/Ai/Request/AiSportsStationRequest.cs new file mode 100644 index 0000000..2d198ea --- /dev/null +++ b/VOL.Model/Ai/Request/AiSportsStationRequest.cs @@ -0,0 +1,41 @@ +using System; +using VOL.Model; + +namespace VOL.Model.Ai.Request +{ + /// + /// 壹路AI运动站列表查询 + /// + public class AiSportsStationListRequest : PageDto + { + /// + /// 学生姓名 + /// + public string StudentName { get; set; } + + /// + /// 性别 + /// + public string Sex { get; set; } + + /// + /// 班级Id + /// + public int ClassId { get; set; } + + /// + /// 课目名称 + /// + public string ProjectName { get; set; } + + /// + /// 运动开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 运动结束时间 + /// + public DateTime? EndTime { get; set; } + } +} diff --git a/VOL.Model/Ai/Response/AiSportsStationDto.cs b/VOL.Model/Ai/Response/AiSportsStationDto.cs new file mode 100644 index 0000000..ef97a07 --- /dev/null +++ b/VOL.Model/Ai/Response/AiSportsStationDto.cs @@ -0,0 +1,45 @@ +using System; + +namespace VOL.Model.Ai.Response +{ + /// + /// 壹路AI运动站列表数据 + /// + public class AiSportsStationDto + { + /// + /// 序号 + /// + public int Ind { get; set; } + + /// + /// 学生姓名 + /// + public string StudentName { get; set; } + + /// + /// 性别 + /// + public string Sex { get; set; } + + /// + /// 班级名称 + /// + public string ClassName { get; set; } + + /// + /// 课目名称 + /// + public string ProjectName { get; set; } + + /// + /// 运动开始时间 + /// + public DateTime? StartTime { get; set; } + + /// + /// 运动结束时间 + /// + public DateTime? EndTime { get; set; } + } +} diff --git a/VOL.WebApi/Controllers/AI/AiSportsStationController.cs b/VOL.WebApi/Controllers/AI/AiSportsStationController.cs new file mode 100644 index 0000000..d766bf0 --- /dev/null +++ b/VOL.WebApi/Controllers/AI/AiSportsStationController.cs @@ -0,0 +1,36 @@ +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using VOL.Ai.IServices; +using VOL.Core.Filters; +using VOL.Model; +using VOL.Model.Ai.Request; +using VOL.Model.Ai.Response; + +namespace VOL.WebApi.Controllers.AI +{ + /// + /// 壹路AI运动站 + /// + [Route("api/[controller]")] + [ApiController] + [ApiExplorerSettings(GroupName = "v6")] + [TypeFilter(typeof(CustomApiResponseFilter))] + public class AiSportsStationController : ControllerBase + { + private readonly IAiSportsStationService _aiSportsStationService; + + public AiSportsStationController(IAiSportsStationService aiSportsStationService) + { + _aiSportsStationService = aiSportsStationService; + } + + /// + /// 获取壹路AI运动站列表 + /// + [HttpGet(nameof(GetAiSportsStationList))] + public async Task> GetAiSportsStationList([FromQuery] AiSportsStationListRequest paramDto) + { + return await _aiSportsStationService.GetAiSportsStationList(paramDto); + } + } +}