385 lines
15 KiB
C#
385 lines
15 KiB
C#
using AutoMapper;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Newtonsoft.Json;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Globalization;
|
||
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.School;
|
||
using YD_WeChatApplet.Commons.Enum;
|
||
using YD_WeChatApplet.Context;
|
||
using YD_WeChatApplet.Services;
|
||
|
||
namespace YD_WeChatApplet.Api.Services.Impl
|
||
{
|
||
public class HomeWorkService : IHomeWorkService
|
||
{
|
||
public SmartSportsContext _sportsContext;
|
||
public UserContext _userContext;
|
||
private readonly IMapper _mapper;
|
||
private readonly ILogger<HomeWorkService> _logger;
|
||
private readonly IJingShiTiJiaoService _jingShiTiJiaoService;
|
||
|
||
public HomeWorkService(SmartSportsContext sportsContext, UserContext userContext, IMapper mapper, ILogger<HomeWorkService> logger, IJingShiTiJiaoService jingShiTiJiaoService)
|
||
{
|
||
_sportsContext = sportsContext;
|
||
_userContext = userContext;
|
||
_mapper = mapper;
|
||
_logger = logger;
|
||
_jingShiTiJiaoService = jingShiTiJiaoService;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 老师新建作业
|
||
/// </summary>
|
||
/// <param name="paramDto"></param>
|
||
/// <returns></returns>
|
||
public async Task AddHomeWork(AddHomeWorkDto paramDto)
|
||
{
|
||
_logger.LogInformation($"添加作业参数,{JsonConvert.SerializeObject(paramDto)}");
|
||
|
||
List<S_HomeWork> homeWorkEntities = new List<S_HomeWork>();
|
||
|
||
string TrimTimeString(string timeStr)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(timeStr))
|
||
return string.Empty;
|
||
|
||
timeStr = timeStr.Trim();
|
||
return timeStr.Length > 19 ? timeStr.Substring(0, 19) : timeStr;
|
||
}
|
||
|
||
string startmmed = TrimTimeString(paramDto.StartTime);
|
||
string endmmed = TrimTimeString(paramDto.EndTime);
|
||
|
||
DateTime.TryParse(startmmed, out var startDate);
|
||
DateTime.TryParse(endmmed, out var endDate);
|
||
|
||
paramDto.StartTime = startmmed;
|
||
paramDto.EndTime = endmmed;
|
||
|
||
var weekList = paramDto.WeekList;
|
||
|
||
if (!paramDto.IsRepeat)
|
||
{
|
||
var homeWorkEntity = _mapper.Map<S_HomeWork>(paramDto);
|
||
homeWorkEntity.SchoolCode = UserLoginContext.Current.SchoolCode;
|
||
homeWorkEntity.TeacherId = UserLoginContext.Current.UserId;
|
||
homeWorkEntity.TeacherNo = UserLoginContext.Current.UserNo;
|
||
homeWorkEntity.TeacherName = UserLoginContext.Current.UserName;
|
||
homeWorkEntity.WorkStatus = 1;
|
||
homeWorkEntity.CreateTime = DateTime.Now;
|
||
homeWorkEntity.StartTime = startDate;
|
||
homeWorkEntity.EndTime = endDate;
|
||
var workModeTypeText = paramDto.WorkModeType == WorkModeType.TimerCount ? paramDto.Duration + "秒" : paramDto.Amount + "个";
|
||
homeWorkEntity.WorkText = $"{paramDto.WorkModeTypeName} {workModeTypeText} 组数:{paramDto.GroupNumber}组";
|
||
|
||
homeWorkEntities.Add(homeWorkEntity);
|
||
}
|
||
else
|
||
{
|
||
for (var currentDate = startDate; currentDate <= endDate; currentDate = currentDate.AddDays(1))
|
||
{
|
||
if (weekList.Contains((currentDate.DayOfWeek == 0 ? 7 : (int)currentDate.DayOfWeek)))
|
||
{
|
||
var homeWorkEntity = _mapper.Map<S_HomeWork>(paramDto);
|
||
homeWorkEntity.SchoolCode = UserLoginContext.Current.SchoolCode;
|
||
homeWorkEntity.TeacherId = UserLoginContext.Current.UserId;
|
||
homeWorkEntity.TeacherNo = UserLoginContext.Current.UserNo;
|
||
homeWorkEntity.TeacherName = UserLoginContext.Current.UserTrueName;
|
||
//homeWorkEntity.TeacherName = UserLoginContext.Current.UserName;
|
||
homeWorkEntity.WorkStatus = 1;
|
||
homeWorkEntity.CreateTime = DateTime.Now;
|
||
homeWorkEntity.StartTime = currentDate.Date;
|
||
homeWorkEntity.EndTime = currentDate.Date.AddDays(1).AddSeconds(-1);
|
||
var workModeTypeText = paramDto.WorkModeType == WorkModeType.TimerCount ? paramDto.Duration + "秒" : paramDto.Amount + "个";
|
||
homeWorkEntity.WorkText = $"{paramDto.WorkModeTypeName} {workModeTypeText} 组数:{paramDto.GroupNumber}组";
|
||
|
||
homeWorkEntities.Add(homeWorkEntity);
|
||
}
|
||
}
|
||
}
|
||
|
||
await _sportsContext.AddRangeAsync(homeWorkEntities);
|
||
await _sportsContext.SaveChangesAsync();
|
||
|
||
|
||
_ = Task.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
if (homeWorkEntities == null || homeWorkEntities.Count == 0)
|
||
{
|
||
_logger.LogWarning("作业同步任务中,homeWorkEntities 为空");
|
||
return;
|
||
}
|
||
|
||
var pushList = new List<SportsDataPushDto>();
|
||
|
||
foreach (var homeWork in homeWorkEntities)
|
||
{
|
||
if (homeWork.HomeWorkStudents == null || homeWork.HomeWorkStudents.Count == 0)
|
||
{
|
||
_logger.LogWarning($"作业[{homeWork.Id}] 未关联学生");
|
||
continue;
|
||
}
|
||
|
||
foreach (var student in homeWork.HomeWorkStudents)
|
||
{
|
||
// ✅ 核心:student + homework 拍平成一个对象
|
||
var flatObject = new
|
||
{
|
||
// ===== 学生信息 =====
|
||
student.Id,
|
||
student.StudentNo,
|
||
student.StudentName,
|
||
student.Sex,
|
||
student.Age,
|
||
student.Photo,
|
||
student.Value,
|
||
student.WorkStatus,
|
||
|
||
// ===== 作业信息(拍平)=====
|
||
HomeWorkId = homeWork.Id,
|
||
homeWork.WorkName,
|
||
homeWork.WorkText,
|
||
homeWork.WorkType,
|
||
homeWork.WorkTypeName,
|
||
homeWork.WorkModeType,
|
||
homeWork.WorkModeTypeName,
|
||
homeWork.Duration,
|
||
homeWork.Amount,
|
||
homeWork.GroupNumber,
|
||
homeWork.IsRepeat,
|
||
homeWork.StudentScope,
|
||
homeWork.StartTime,
|
||
homeWork.EndTime,
|
||
homeWork.CreateTime,
|
||
homeWork.TeacherId,
|
||
homeWork.TeacherNo,
|
||
homeWork.TeacherName,
|
||
homeWork.GradeId,
|
||
homeWork.GradeName,
|
||
homeWork.ClassId,
|
||
homeWork.ClassName
|
||
};
|
||
|
||
var dto = new SportsDataPushDto
|
||
{
|
||
// 👉 每个学生一条
|
||
StudentNo = student.StudentNo,
|
||
SportsItem = AppSettings.JingShiTiJiao.SportsItem,
|
||
SportsDate = homeWork.StartTime.ToString("yyyy-MM-dd"),
|
||
SportsService = AppSettings.JingShiTiJiao.Channel,
|
||
SportsScene = "addhomework",
|
||
|
||
// 👉 拍平后的 JSON
|
||
SportsDetail = JsonConvert.SerializeObject(flatObject)
|
||
};
|
||
|
||
pushList.Add(dto);
|
||
}
|
||
}
|
||
|
||
if (pushList.Count == 0)
|
||
{
|
||
_logger.LogWarning("作业同步任务中,没有可推送的数据");
|
||
return;
|
||
}
|
||
|
||
var res = await _jingShiTiJiaoService.PushSportsData(pushList);
|
||
|
||
if (res)
|
||
{
|
||
_logger.LogInformation($"作业数据同步成功,共 {pushList.Count} 条");
|
||
}
|
||
else
|
||
{
|
||
_logger.LogError($"作业数据同步失败,共 {pushList.Count} 条");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// ❗ 只记录日志,绝不影响主流程
|
||
_logger.LogError(ex, "作业数据上传失败");
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 老师作业记录
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<PageDataDto<HomeWorkRecordDto>> HomeWorkRecordByTeacher(PatriarchHomeWorkHistoryDto dto)
|
||
{
|
||
var userNo = UserLoginContext.Current.UserNo;
|
||
var currentTime = DateTime.Now;
|
||
|
||
var query = _sportsContext.HomeWork
|
||
.Where(x => x.TeacherNo == 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;
|
||
}
|
||
|
||
var totalCount = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Select(x => new HomeWorkRecordDto()
|
||
{
|
||
Id = x.Id,
|
||
WorkName = x.WorkName,
|
||
WorkTypeName = x.WorkTypeName,
|
||
//WorkStatus = x.EndTime < currentTime ? 3 : (x.StartTime > currentTime ? 1 : 2),
|
||
WorkStatus = dto.WorkStatus,
|
||
StartTime = x.StartTime,
|
||
EndTime = x.EndTime
|
||
})
|
||
.OrderByDescending(x => x.EndTime)
|
||
.Skip((dto.PageIndex - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.ToListAsync();
|
||
|
||
return new PageDataDto<HomeWorkRecordDto>
|
||
{
|
||
Total = totalCount,
|
||
Datas = list
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 老师作业详情
|
||
/// </summary>
|
||
/// <param name="homeWorkId"></param>
|
||
/// <returns></returns>
|
||
public async Task<HomeWorkDetailsDto> HomeWorkDetailsByTeacher(int homeWorkId)
|
||
{
|
||
var res = await _sportsContext.HomeWork.Where(x => x.Id == homeWorkId).Select(x => new HomeWorkDetailsDto()
|
||
{
|
||
Id = x.Id,
|
||
WorkName = $"{x.WorkName}-{x.WorkType.GetDescription()}",
|
||
StartTime = x.StartTime,
|
||
EndTime = x.EndTime,
|
||
StudentScope = x.StudentScope == 1 ? "全部学生" : "部分学生",
|
||
WorkText = x.WorkText,
|
||
WorkModeType = x.WorkModeType,
|
||
HomeWorkStudents = _mapper.Map<List<HomeWorkStudentsDto>>(x.HomeWorkStudents),
|
||
}).FirstAsync();
|
||
|
||
foreach (var item in res.HomeWorkStudents)
|
||
{
|
||
if (res.WorkModeType == WorkModeType.TimerCount)
|
||
item.Result = $"{item.Value}个";
|
||
else
|
||
item.Result = item.Value.ToMinutesSeconds();
|
||
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 学生作业详情
|
||
/// </summary>
|
||
/// <param name="homeWorkId">作业Id</param>
|
||
/// <summary>
|
||
/// 学生作业详情
|
||
/// </summary>
|
||
public async Task<StudentHomeWorkDetailDto> HomeWorkDetailsByStudent(int homeWorkId)
|
||
{
|
||
var studentNo = UserLoginContext.Current.UserNo;
|
||
if (string.IsNullOrEmpty(studentNo))
|
||
throw new Exception("未获取到当前学生信息");
|
||
|
||
// 方案:直接投影到目标 DTO,并处理所有可能为 null 的数据库字段
|
||
var dto = await _sportsContext.HomeWork
|
||
.Where(h => h.Id == homeWorkId)
|
||
.SelectMany(h => h.HomeWorkStudents, (h, hs) => new { h, hs })
|
||
.Where(x => x.hs.StudentNo == studentNo)
|
||
.Select(x => new StudentHomeWorkDetailDto
|
||
{
|
||
Id = x.h.Id,
|
||
WorkName = x.h.WorkName + "-" + x.h.WorkType.GetDescription(),
|
||
WorkText = x.h.WorkText,
|
||
StartTime = x.h.StartTime,
|
||
EndTime = x.h.EndTime,
|
||
StudentScope = x.h.StudentScope == 1 ? "全部学生" : "部分学生",
|
||
WorkModeType = x.h.WorkModeType,
|
||
|
||
StudentNo = x.hs.StudentNo,
|
||
StudentName = x.hs.StudentName ?? "",
|
||
Sex = x.hs.Sex,
|
||
Photo = x.hs.Photo ?? "",
|
||
WorkStatus = x.hs.WorkStatus,
|
||
Value = x.hs.Value
|
||
})
|
||
.FirstOrDefaultAsync();
|
||
|
||
if (dto == null)
|
||
throw new Exception("作业不存在或当前学生无权查看该作业");
|
||
|
||
// 格式化结果(与老师接口逻辑一致)
|
||
if (dto.WorkModeType == WorkModeType.TimerCount)
|
||
dto.Result = $"{dto.Value}个";
|
||
else
|
||
dto.Result = dto.Value.ToMinutesSeconds();
|
||
|
||
return dto;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 作业项目列表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<List<CategoryDto>> HomeWorkCategoryList()
|
||
{
|
||
var res = await _userContext.Category
|
||
.Select(x => new CategoryDto()
|
||
{
|
||
Id = x.Id,
|
||
Name = x.CategoryName,
|
||
CategoryKey = x.CategoryKey,
|
||
KcalIndex = x.KcalIndex
|
||
})
|
||
.ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 星期列表
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<List<ComboBoxDto>> WeekList()
|
||
{
|
||
var res = await _userContext.Week
|
||
.Select(x => new ComboBoxDto()
|
||
{
|
||
Id = x.Id,
|
||
Name = x.Name
|
||
})
|
||
.ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
}
|
||
}
|