366 lines
13 KiB
C#
Raw Normal View History

2025-06-06 14:57:20 +08:00
using AutoMapper;
using Microsoft.EntityFrameworkCore;
using YD_WeChatApplet.Api.Entitys;
using YD_WeChatApplet.Api.SmartSportsEntitys;
using YD_WeChatApplet.Api.Utilities;
using YD_WeChatApplet.Commons.Dto;
using YD_WeChatApplet.Commons.Dto.HomeWork;
using YD_WeChatApplet.Commons.Dto.Patriarch;
using YD_WeChatApplet.Commons.Dto.Resource;
using YD_WeChatApplet.Commons.Dto.School;
using YD_WeChatApplet.Commons.Dto.SportsTest;
using YD_WeChatApplet.Commons.Dto.Teacher;
using YD_WeChatApplet.Commons.Enum;
using YD_WeChatApplet.Context;
using YD_WeChatApplet.Services;
namespace YD_WeChatApplet.Api.Services.Impl
{
/// <summary>
/// 家长端
/// </summary>
public class PatriarchService : IPatriarchService
{
public UserContext _userContext;
public SmartSportsContext _sportsContext;
private readonly IMapper _mapper;
public PatriarchService(UserContext userContext, SmartSportsContext sportsContext, IMapper mapper)
{
_userContext = userContext;
_sportsContext = sportsContext;
_mapper = mapper;
}
/// <summary>
/// 新建训练数据
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public async Task AddExerciseData(AddExerciseDataDto dto)
{
var entity = _mapper.Map<WCA_ExerciseData>(dto);
entity.RoleId = UserLoginContext.Current.RoleId;
entity.UserId = UserLoginContext.Current.UserId;
entity.UserName = UserLoginContext.Current.UserName;
entity.CreateTime = DateTime.Now;
if (dto.HomeWorkId == 0)
{
await _userContext.AddAsync(entity);
await _userContext.SaveChangesAsync();
return;
}
var work = await _sportsContext.HomeWork.Where(x => x.Id == dto.HomeWorkId).Select(x => new
{
x.Id,
x.Amount,
x.GroupNumber
}).FirstAsync();
entity.Status = dto.GroupNumber >= work.GroupNumber ? 2 : 1;
var student = await _sportsContext.HomeWorkStudents.FirstAsync(x => x.HomeWorkId == dto.HomeWorkId && x.StudentNo == UserLoginContext.Current.UserNo);
student.WorkStatus = entity.Status;
if (entity.RoleId == 3)
{
entity.StudentNo = UserLoginContext.Current.UserNo;
entity.StudentName = UserLoginContext.Current.UserName;
}
student.Value = dto.WorkModeType == 1 ? dto.Amount : dto.Duration;
_sportsContext.HomeWorkStudents.Update(student);
await _sportsContext.SaveChangesAsync();
await _userContext.AddAsync(entity);
await _userContext.SaveChangesAsync();
}
/// <summary>
/// 作业记录
/// </summary>
/// <param name="dto"></param>
/// <returns></returns>
public async Task<PageDataDto<HomeWorkRecordByPatriarchDto>> HomeWorkRecordByPatriarch(PatriarchHomeWorkHistoryDto dto)
{
var userNo = UserLoginContext.Current.UserNo;
var currentTime = DateTime.Now;
var query = _sportsContext.HomeWorkStudents
.Join(_sportsContext.HomeWork, a => a.HomeWorkId, s => s.Id, (a, s) => new
{
s.Id,
a.StudentNo,
a.WorkStatus,
s.WorkName,
s.WorkTypeName,
s.GroupNumber,
s.StartTime,
s.EndTime
})
.Where(a => a.StudentNo == userNo);
2025-08-12 10:28:07 +08:00
switch (dto.WorkStatus)
{
case 1: // 未开始
query = query.Where(x => x.StartTime > currentTime);
break;
case 2: // 进行中
query = query.Where(x => x.StartTime <= currentTime && x.EndTime >= currentTime);
break;
case 3: // 已结束
query = query.Where(x => x.EndTime < currentTime);
break;
default:
break;
}
//query = dto.IsHistory
// ? query.Where(x => x.EndTime < currentTime)
// : query.Where(x => x.EndTime >= currentTime);
2025-06-06 14:57:20 +08:00
var totalCount = await query.CountAsync();
var list = await query
.Select(x => new HomeWorkRecordByPatriarchDto
{
Id = x.Id,
WorkName = x.WorkName,
WorkTypeName = x.WorkTypeName,
2025-08-12 10:28:07 +08:00
//WorkStatus = x.EndTime < currentTime ? 3 : (x.StartTime > currentTime ? 1 : 2),
WorkStatus = dto.WorkStatus,
2025-06-06 14:57:20 +08:00
GroupNumber = x.GroupNumber,
IsComplete = x.WorkStatus == 2,
StartTime = x.StartTime,
EndTime = x.EndTime
})
2025-08-12 10:28:07 +08:00
.OrderByDescending(x => x.EndTime)
2025-06-06 14:57:20 +08:00
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
return new PageDataDto<HomeWorkRecordByPatriarchDto>
{
Total = totalCount,
Datas = list
};
}
/// <summary>
/// 作业详情
/// </summary>
/// <param name="homeWorkId"></param>
/// <returns></returns>
public async Task<PatriarchHomeWorkDetailsDto> HomeWorkDetailsByPatriarch(int homeWorkId)
{
var res = await _sportsContext.HomeWork.Where(x => x.Id == homeWorkId).Select(x => new PatriarchHomeWorkDetailsDto()
{
Id = x.Id,
WorkName = x.WorkName,
StartTime = x.StartTime,
EndTime = x.EndTime,
WorkText = x.WorkText,
WorkType = (int)x.WorkType,
WorkTypeName = x.WorkTypeName,
WorkModeType = x.WorkModeType,
WorkModeTypeName = x.WorkModeTypeName,
Amount = x.Amount,
Duration = x.Duration,
GroupNumber = x.GroupNumber,
IsRepeat = x.IsRepeat,
RepetitionPeriod = x.RepetitionPeriod,
WorkStatus = x.WorkStatus
}).FirstOrDefaultAsync();
return res;
}
/// <summary>
/// 学生报告
/// </summary>
/// <returns></returns>
2026-04-21 16:01:53 +08:00
public async Task<StudentReportDto> StudentReport(string studentNo)
2025-06-06 14:57:20 +08:00
{
var res = new StudentReportDto();
2026-04-21 16:01:53 +08:00
if (string.IsNullOrWhiteSpace(studentNo))
return res;
//var studentNo = UserLoginContext.Current.UserNo;
2025-06-06 14:57:20 +08:00
var student = await _sportsContext.Student.Where(x => x.StudentNo == studentNo).FirstOrDefaultAsync();
if (student == null)
return res;
var classInfo = await _sportsContext.Class.FirstOrDefaultAsync(x => x.Id == student.ClassId);
if (classInfo == null)
return res;
2026-04-24 15:58:55 +08:00
var categorys = new List<dynamic>
2025-06-06 14:57:20 +08:00
{
2026-04-24 15:58:55 +08:00
new
{
Id = 1,
CategoryValue = 1,
CategoryName = "BMI",
CategoryEnum = "BMI",
Weight = 0.15f
},
new
{
Id = 2,
CategoryValue = 2,
CategoryName = "肺活量",
CategoryEnum = "VitalCapacity",
Weight = 0.2f
},
new
{
Id = 4,
CategoryValue = 4,
CategoryName = "坐位体前屈",
CategoryEnum = "Sit_And_Reach",
Weight = 0.15f
},
new
{
Id = 5,
CategoryValue = 5,
CategoryName = "一分钟跳绳",
CategoryEnum = "OneMinuteJumpRope",
Weight = 0.2f
},
new
{
Id = 6,
CategoryValue = 6,
CategoryName = "一分钟仰卧起坐",
CategoryEnum = "One_Minute_Sit_Up",
Weight = 0.15f
},
new
{
Id = 8,
CategoryValue = 6,
CategoryName = "立定跳远",
CategoryEnum = "StandingLongJump",
Weight = 0.15f
}
};
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var sportsTestResults = await _sportsContext.SportsTestValue.Where(x => x.IsDisplay && x.SchoolCode == student.SchoolCode).Select(x => new SportsTestValueModel()
2025-06-06 14:57:20 +08:00
{
StudentNo = x.StudentNo,
Value = x.Value,
Score = x.Score,
AdditionalScore = x.AdditionalScore,
2026-04-21 16:01:53 +08:00
CategoryValue = x.CategoryValue,
ScoreTime = x.ScoreTime
2025-06-06 14:57:20 +08:00
}).ToListAsync();
2026-04-21 16:01:53 +08:00
res.CategoryScoreList = new List<CategoryScoreDto>();
foreach (var item in categorys)
2025-06-06 14:57:20 +08:00
{
2026-04-21 16:01:53 +08:00
// ✅ 当前学生数据
var studentResults = sportsTestResults
.Where(x => x.CategoryValue == item.Id && x.StudentNo == studentNo)
.OrderByDescending(x => x.ScoreTime) // 倒序:最新在前
.ToList();
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var lastResult = studentResults.FirstOrDefault();
var prevResult = studentResults.Skip(1).FirstOrDefault();
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var maxScore = studentResults.Any()
? studentResults.Max(x => x.Score)
: 0;
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var classAvgScore = studentResults.Any()
? studentResults.Average(x => x.Score)
: 0;
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var schoolAvgScore = sportsTestResults
2025-06-06 14:57:20 +08:00
.Where(x => x.CategoryValue == item.Id)
2026-04-21 16:01:53 +08:00
.Select(x => x.Score)
.DefaultIfEmpty(0)
.Average();
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
// 🚀 趋势图(关键:反转集合)
var trendList = studentResults
.OrderBy(x => x.ScoreTime)
.ToList();
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
var trendChart = new ScoreTrendChartDataDto
{
2026-04-24 15:58:55 +08:00
AxisX = trendList.Select(x => x.ScoreTime.ToString("yyyy-MM-dd")).ToList(),
2026-04-21 16:01:53 +08:00
AxisY = trendList.Select(x => x.Score ?? 0f).ToList()
};
2025-06-06 14:57:20 +08:00
res.CategoryScoreList.Add(new CategoryScoreDto()
{
2026-04-21 16:01:53 +08:00
CategoryValue = item.CategoryValue,
2025-06-06 14:57:20 +08:00
Name = item.CategoryName,
2026-04-21 16:01:53 +08:00
PrevScore = prevResult?.Score ?? 0,
LastScore = lastResult?.Score ?? 0,
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
MaxScore = (float)maxScore,
ClassAvgScore = (float)classAvgScore,
SchoolAvgScore = (float)schoolAvgScore,
ScoreTrendChart = trendChart,
2025-06-06 14:57:20 +08:00
2026-04-21 16:01:53 +08:00
ImgUrl = $"{AppSettings.ALiYunOSS.CategoryImgUrl}{item.CategoryEnum}.png"
});
}
2025-06-06 14:57:20 +08:00
return res;
}
/// <summary>
/// 训练记录
/// </summary>
/// <returns></returns>
public async Task<PageDataDto<ExerciseRecordDto>> ExerciseRecord(PageDto dto)
{
var userId = UserLoginContext.Current.UserId;
var query = _userContext.ExerciseData.Where(x => x.UserId == userId);
var totalCount = await query.CountAsync();
var list = await query
.Select(x => new ExerciseRecordDto
{
Id = x.Id,
WorkTypeName = x.WorkTypeName,
WorkModeTypeName = x.WorkModeTypeName,
StartTime = x.StartTime,
EndTime = x.CreateTime,
GroupNumber = x.GroupNumber,
Amount = x.Amount ?? 0,
Duration = x.Duration ?? 0,
Calorie = x.Calorie ?? 0
})
.OrderByDescending(x => x.EndTime)
.Skip((dto.PageIndex - 1) * dto.PageSize)
.Take(dto.PageSize)
.ToListAsync();
2025-08-12 14:14:24 +08:00
2025-06-06 14:57:20 +08:00
return new PageDataDto<ExerciseRecordDto>
{
Total = totalCount,
Datas = list
};
}
}
}