From 9a4b68310aa52f94a3c212fe7a6f0bc27aa8dd5d Mon Sep 17 00:00:00 2001 From: tanglong <842690096@qq.com> Date: Wed, 15 Jul 2026 14:46:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Dto/DeviceSync/DeviceSyncMyRecordDto.cs | 36 +++++ YD_YiLu/Controllers/DeviceSyncController.cs | 9 ++ YD_YiLu/Program.cs | 2 +- YD_YiLu/Services/Impl/DeviceSyncService.cs | 150 +++++++++++++++++- .../Services/Interface/IDeviceSyncService.cs | 2 + 5 files changed, 190 insertions(+), 9 deletions(-) diff --git a/YD_YiLu.Commons/Dto/DeviceSync/DeviceSyncMyRecordDto.cs b/YD_YiLu.Commons/Dto/DeviceSync/DeviceSyncMyRecordDto.cs index badae4c..cc86499 100644 --- a/YD_YiLu.Commons/Dto/DeviceSync/DeviceSyncMyRecordDto.cs +++ b/YD_YiLu.Commons/Dto/DeviceSync/DeviceSyncMyRecordDto.cs @@ -71,4 +71,40 @@ namespace YD_YiLu.Commons.Dto.DeviceSync public string AvgGrade { get; set; } public string WorstGrade { get; set; } } + + public class DeviceSyncYtpMyRecordRequestDto + { + public int DeviceType { get; set; } + public string DeviceSerial { get; set; } + public string UserSerial { get; set; } + public int DateType { get; set; } + public string QueryStartTime { get; set; } + public string QueryEndTime { get; set; } + } + + public class DeviceSyncYtpMyRecordResponseDto + { + public UserSyncDto UserSync { get; set; } + public int TrainCourseSum { get; set; } + public int TrainDays { get; set; } + public string TrainHours { get; set; } = "0.00"; + public int TrainCounts { get; set; } + public List GradeList { get; set; } = new List(); + public List GraphTrainList { get; set; } = new List(); + } + + public class YtpGradeListItem + { + public string Time { get; set; } + public string Duration { get; set; } + public string Count { get; set; } + } + + public class YtpGraphTrainListItem + { + public int CourseId { get; set; } + public string CourseName { get; set; } + public string Time { get; set; } + public int Count { get; set; } + } } diff --git a/YD_YiLu/Controllers/DeviceSyncController.cs b/YD_YiLu/Controllers/DeviceSyncController.cs index 2b1bddc..f2ef025 100644 --- a/YD_YiLu/Controllers/DeviceSyncController.cs +++ b/YD_YiLu/Controllers/DeviceSyncController.cs @@ -153,6 +153,7 @@ namespace YD_YiLu.Api.Controllers /// [HttpPost] [Route("/device/sync/grade/record")] + [Route("/applet/train/record_app")] public async Task RecordApp([FromBody] DeviceSyncRecordAppRequestDto dto) { var res = await _deviceSyncService.RecordAppAsync(dto); @@ -170,6 +171,14 @@ namespace YD_YiLu.Api.Controllers return res; } + [HttpPost] + [Route("/device/sync/train/my_record/ytp")] + public async Task YtpMyRecord([FromBody] DeviceSyncYtpMyRecordRequestDto dto) + { + var res = await _deviceSyncService.YtpMyRecordAsync(dto); + return res; + } + /// /// 视频回放上传。 /// diff --git a/YD_YiLu/Program.cs b/YD_YiLu/Program.cs index 2699c22..db274a4 100644 --- a/YD_YiLu/Program.cs +++ b/YD_YiLu/Program.cs @@ -19,7 +19,7 @@ namespace YD_YiLu.Api { serverOptions.Limits.MaxRequestBodySize = 10485760; }); - webBuilder.UseKestrel().UseUrls("http://*:9997"); + webBuilder.UseKestrel().UseUrls("http://*:9996"); webBuilder.UseIIS(); webBuilder.UseStartup(); }).UseServiceProviderFactory(new AutofacServiceProviderFactory()); diff --git a/YD_YiLu/Services/Impl/DeviceSyncService.cs b/YD_YiLu/Services/Impl/DeviceSyncService.cs index 0dca9c7..60246b0 100644 --- a/YD_YiLu/Services/Impl/DeviceSyncService.cs +++ b/YD_YiLu/Services/Impl/DeviceSyncService.cs @@ -891,6 +891,9 @@ namespace YD_YiLu.Api.Services.Impl // 👉 2. 时间范围 var (start, end) = GetDateRange(dto.DateType, dto.QueryStartTime, dto.QueryEndTime); + result.UserSync.Identity = "学生"; + result.UserSync.Gender = student.Sex == 1 ? "男" : "女"; + var query = _context.YL_Train .Where(x => x.UserSerial == dto.UserSerial && x.DeviceSerial == dto.DeviceSerial @@ -909,7 +912,15 @@ namespace YD_YiLu.Api.Services.Impl else if (dto.CourseType > 0) query = query.Where(x => x.CourseId == dto.CourseType); - var trains = await query.ToListAsync(); + var trains = await query + .Select(x => new + { + x.CourseId, + x.StartTime, + x.Duration, + x.Score + }) + .ToListAsync(); if (!trains.Any()) return result; @@ -990,6 +1001,117 @@ namespace YD_YiLu.Api.Services.Impl return result; } + public async Task YtpMyRecordAsync(DeviceSyncYtpMyRecordRequestDto dto) + { + var result = new DeviceSyncYtpMyRecordResponseDto(); + + var orgId = await GetOrgIdByDeviceAsync(dto.DeviceSerial); + if (!orgId.HasValue) return result; + + var schoolCode = await _context.School + .Where(x => x.Id == orgId) + .Select(x => x.SchoolCode) + .FirstAsync(); + + var student = await _context.Student + .FirstOrDefaultAsync(x => x.SchoolCode == schoolCode && x.StudentNo == dto.UserSerial); + + if (student == null) return result; + + var studentClass = await _context.Class.FindAsync(student.ClassId); + result.UserSync = new UserSyncDto + { + UserId = student.Id, + UserType = 2, + Nickname = student.StudentName, + OrganizationId = student.ClassId ?? 0, + OrganizationName = studentClass?.ClassName ?? student.ClassName ?? "", + FacePictureUrl = student.Photo ?? "", + Identity = "学生", + Gender = student.Sex == 1 ? "男" : "女", + Birthday = student.Birthday?.ToString("yyyy-MM-dd") ?? "", + UserSerial = student.StudentNo, + Height = "0", + Weight = "0" + }; + result.UserSync.Identity = "学生"; + result.UserSync.Gender = student.Sex == 1 ? "男" : "女"; + + var (start, end) = GetDateRange(dto.DateType, dto.QueryStartTime, dto.QueryEndTime); + + var query = _context.YL_Train + .AsNoTracking() + .Where(x => x.UserSerial == dto.UserSerial + && x.DeviceSerial == dto.DeviceSerial + && x.DeviceType == dto.DeviceType); + + if (start.HasValue) + query = query.Where(x => x.StartTime >= start.Value); + + if (end.HasValue) + query = query.Where(x => x.StartTime < end.Value.AddDays(1)); + + var trains = await query + .Select(x => new + { + x.CourseId, + x.StartTime, + x.Duration + }) + .ToListAsync(); + + if (!trains.Any()) + { + var today = DateTime.Now.Date; + result.GradeList = Enumerable.Range(0, 7) + .Select(i => today.AddDays(i - 6)) + .Select(day => new YtpGradeListItem + { + Time = day.ToString("yyyy-MM-dd"), + Duration = "0", + Count = "0" + }) + .ToList(); + return result; + } + + var totalSeconds = trains.Sum(x => x.Duration); + result.TrainCourseSum = trains.Select(x => x.CourseId).Distinct().Count(); + result.TrainDays = trains.Select(x => x.StartTime.Date).Distinct().Count(); + result.TrainHours = (totalSeconds / 3600.0).ToString("0.00"); + result.TrainCounts = trains.Count; + + var graphEnd = end?.Date ?? DateTime.Now.Date; + var graphStart = graphEnd.AddDays(-6); + result.GradeList = Enumerable.Range(0, 7) + .Select(i => graphStart.AddDays(i)) + .Select(day => + { + var dayTrains = trains.Where(x => x.StartTime.Date == day).ToList(); + return new YtpGradeListItem + { + Time = day.ToString("yyyy-MM-dd"), + Duration = dayTrains.Sum(x => x.Duration).ToString(), + Count = dayTrains.Count.ToString() + }; + }) + .ToList(); + + result.GraphTrainList = trains + .GroupBy(x => x.CourseId) + .Select(g => new YtpGraphTrainListItem + { + CourseId = g.Key, + CourseName = Util.GetEnumDescription(g.Key), + Time = g.Sum(x => x.Duration).ToString(), + Count = g.Count() + }) + .OrderByDescending(x => int.TryParse(x.Time, out var seconds) ? seconds : 0) + .ToList(); + + return result; + } + public async Task TeacherLoginAsync(TeacherLoginRequestDto dto) { var pwdHash = MD5Helper.MD5Encrypt32(dto.Password); @@ -1230,16 +1352,28 @@ namespace YD_YiLu.Api.Services.Impl private static (DateTime? start, DateTime? end) GetDateRange(int dateType, string queryStart, string queryEnd) { - var now = DateTime.Now; - return dateType switch + var today = DateTime.Now.Date; + var weekStart = today.AddDays(-(((int)today.DayOfWeek + 6) % 7)); + var monthStart = new DateTime(today.Year, today.Month, 1); + (DateTime? start, DateTime? end) result = dateType switch { - 1 => (now.Date, now.Date), - 2 => (now.AddDays(-(int)now.DayOfWeek + 1).Date, now.Date), - 3 => (new DateTime(now.Year, now.Month, 1), now.Date), - 4 => (now.Month >= 9 ? new DateTime(now.Year, 9, 1) : new DateTime(now.Year - 1, 9, 1), now.Date), + 0 => ((DateTime?)null, (DateTime?)null), + 1 => (today, today), + 2 => (weekStart, today), + 3 => (monthStart, today), + 4 => (today.Month >= 9 ? new DateTime(today.Year, 9, 1) : new DateTime(today.Year - 1, 9, 1), today), 5 => (DateTime.TryParse(queryStart, out var s) ? s : (DateTime?)null, DateTime.TryParse(queryEnd, out var e) ? e : (DateTime?)null), - _ => (null, null) + 6 => (weekStart.AddDays(-7), weekStart.AddDays(-1)), + 7 => (monthStart.AddMonths(-1), monthStart.AddDays(-1)), + 8 => (today.AddMonths(-3), today), + 9 => (new DateTime(today.Year, 1, 1), today), + _ => ((DateTime?)null, (DateTime?)null) }; + + if (result.start.HasValue && result.end.HasValue && result.start.Value > result.end.Value) + result = (result.end, result.start); + + return result; } private int CompareVersion(string v1, string v2) diff --git a/YD_YiLu/Services/Interface/IDeviceSyncService.cs b/YD_YiLu/Services/Interface/IDeviceSyncService.cs index 471a8ea..5b1093f 100644 --- a/YD_YiLu/Services/Interface/IDeviceSyncService.cs +++ b/YD_YiLu/Services/Interface/IDeviceSyncService.cs @@ -57,6 +57,8 @@ namespace YD_YiLu.Api.Services.Interface /// Task MyRecordAsync(DeviceSyncMyRecordRequestDto dto); + Task YtpMyRecordAsync(DeviceSyncYtpMyRecordRequestDto dto); + /// /// 老师登录 ///