374 lines
14 KiB
C#
374 lines
14 KiB
C#
using AutoMapper;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Newtonsoft.Json;
|
||
using YD_WeChatApplet.Api.Entitys;
|
||
using YD_WeChatApplet.Api.Services.Interface;
|
||
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.JingShiTiJiao;
|
||
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;
|
||
private readonly ILogger<PatriarchService> _logger;
|
||
private readonly IJingShiTiJiaoService _jingShiTiJiaoService;
|
||
public PatriarchService(UserContext userContext, SmartSportsContext sportsContext, IMapper mapper, ILogger<PatriarchService> logger, IJingShiTiJiaoService jingShiTiJiaoService)
|
||
{
|
||
_userContext = userContext;
|
||
_sportsContext = sportsContext;
|
||
_mapper = mapper;
|
||
_logger = logger;
|
||
_jingShiTiJiaoService = jingShiTiJiaoService;
|
||
}
|
||
|
||
/// <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;
|
||
//}
|
||
|
||
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();
|
||
|
||
_ = Task.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
var list = new List<SportsDataPushDto>
|
||
{
|
||
new SportsDataPushDto
|
||
{
|
||
StudentNo = entity.StudentNo,
|
||
SportsItem = AppSettings.JingShiTiJiao.SportsItem,
|
||
SportsDate = entity.CreateTime.ToString("yyyy-MM-dd"),
|
||
SportsService = AppSettings.JingShiTiJiao.Channel,
|
||
SportsScene = "homework",
|
||
SportsDetail = JsonConvert.SerializeObject(dto)
|
||
}
|
||
};
|
||
|
||
var res = await _jingShiTiJiaoService.PushSportsData(list);
|
||
|
||
if (res)
|
||
{
|
||
_logger.LogInformation($"数据同步成功,{JsonConvert.SerializeObject(list)}");
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError($"数据同步失败,{JsonConvert.SerializeObject(list)}");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// ❗ 只记录日志,绝不抛出
|
||
_logger.LogError(ex,
|
||
"运动数据上传失败,StudentNo={StudentNo}, Id={Id}",
|
||
entity.StudentNo,
|
||
entity.Id);
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <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);
|
||
|
||
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);
|
||
|
||
|
||
var totalCount = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Select(x => new HomeWorkRecordByPatriarchDto
|
||
{
|
||
Id = x.Id,
|
||
WorkName = x.WorkName,
|
||
WorkTypeName = x.WorkTypeName,
|
||
//WorkStatus = x.EndTime < currentTime ? 3 : (x.StartTime > currentTime ? 1 : 2),
|
||
WorkStatus = dto.WorkStatus,
|
||
GroupNumber = x.GroupNumber,
|
||
IsComplete = x.WorkStatus == 2,
|
||
StartTime = x.StartTime,
|
||
EndTime = x.EndTime
|
||
})
|
||
.OrderByDescending(x => x.EndTime)
|
||
.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>
|
||
public async Task<StudentReportDto> StudentReport()
|
||
{
|
||
var res = new StudentReportDto();
|
||
|
||
var studentNo = UserLoginContext.Current.UserNo;
|
||
|
||
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;
|
||
|
||
var categorys = await (
|
||
from g in _sportsContext.GradeAssocCategory
|
||
join s in _sportsContext.SportsTestCategory on g.CategoryValue equals s.CategoryValue
|
||
|
||
where g.GradeId == classInfo.GradeId
|
||
|
||
select new
|
||
{
|
||
s.Id,
|
||
s.CategoryValue,
|
||
s.CategoryName,
|
||
s.CategoryEnum,
|
||
g.Weight
|
||
}).ToListAsync();
|
||
|
||
if (categorys == null)
|
||
return res;
|
||
|
||
var iotQuery = await _sportsContext.SportsTestValue.Where(x => x.IsDisplay && x.SchoolCode == student.SchoolCode && x.StudentNo == studentNo).Select(x => new SportsTestValueModel()
|
||
{
|
||
StudentNo = x.StudentNo,
|
||
Value = x.Value,
|
||
Score = x.Score,
|
||
AdditionalScore = x.AdditionalScore,
|
||
CategoryValue = x.CategoryValue
|
||
}).ToListAsync();
|
||
|
||
var aiQuery = await _sportsContext.SportsTestData.Where(x => x.IsDisplay && x.SchoolCode == student.SchoolCode && x.StudentNo == studentNo).Select(x => new SportsTestValueModel()
|
||
{
|
||
StudentNo = x.StudentNo,
|
||
Value = (float)x.Value,
|
||
Score = x.Score,
|
||
AdditionalScore = x.AdditionalScore,
|
||
CategoryValue = x.CategoryValue
|
||
}).ToListAsync();
|
||
|
||
var sportsTestResults = iotQuery.Concat(aiQuery).ToList();
|
||
|
||
res.CategoryScoreList = new List<CategoryScoreDto>();
|
||
|
||
double totalScore = 0;
|
||
var currentYear = DateTime.Now.Year;
|
||
var currentMonth = DateTime.Now.Month;
|
||
|
||
foreach (var item in categorys)
|
||
{
|
||
var maxResultInMonth = sportsTestResults
|
||
.Where(x => x.CategoryValue == item.Id
|
||
&& x.ScoreTime?.Year == currentYear
|
||
&& x.ScoreTime?.Month == currentMonth)
|
||
.OrderByDescending(x => x.Value)
|
||
.FirstOrDefault();
|
||
|
||
var maxResult = maxResultInMonth ?? sportsTestResults
|
||
.Where(x => x.CategoryValue == item.Id)
|
||
.OrderByDescending(x => x.Value)
|
||
.FirstOrDefault();
|
||
|
||
if (item.CategoryName == "BMI")
|
||
res.BodyShape = maxResult?.Score ?? 0;
|
||
|
||
if (item.CategoryName == "肺活量")
|
||
res.BodyFunction = maxResult?.Score ?? 0;
|
||
|
||
res.CategoryScoreList.Add(new CategoryScoreDto()
|
||
{
|
||
Name = item.CategoryName,
|
||
Score = maxResult?.Score ?? 0,
|
||
ImgUrl = $"{AppSettings.ALiYunOSS.CategoryImgUrl}{item.CategoryEnum}.png"
|
||
});
|
||
|
||
double currentScore = maxResult?.Score ?? 0;
|
||
double currentAdditionalScore = maxResult?.AdditionalScore ?? 0;
|
||
|
||
totalScore += ((currentScore + currentAdditionalScore) * item.Weight);
|
||
}
|
||
res.TotalScore = (float)totalScore;
|
||
|
||
var bodyFunction = res.CategoryScoreList.Where(x => x.Name != "BMI" && x.Name != "肺活量").ToList();
|
||
res.BodyFunction = bodyFunction.Average(x => x.Score);
|
||
|
||
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();
|
||
|
||
|
||
return new PageDataDto<ExerciseRecordDto>
|
||
{
|
||
Total = totalCount,
|
||
Datas = list
|
||
};
|
||
}
|
||
}
|
||
}
|