using AutoMapper;
using Microsoft.EntityFrameworkCore;
using VOL.Entity.DomainModels.XinWei;
using VOL.Entity.Enum;
using YD_XinWei.Api.Context;
using YD_XinWei.Api.Services.Interface;
using YD_XinWei.Api.SmartSportsEntitys;
using YD_XinWei.Api.Utilities;
using YD_XinWei.Commons.Dto.Common;
using YD_XinWei.Commons.Dto.LargeScreen;
using YD_XinWei.Commons.Enum;
using YD_XinWei.Commons.MemoryCaches;
namespace YD_XinWei.Api.Services.Impl
{
///
/// 大屏服务
///
public class LargeScreenService : ILargeScreenService
{
public SmartSportsContext _sportsContext;
private readonly IMapper _mapper;
private readonly ICacheService _caching;
///
/// 构造
///
///
///
public LargeScreenService(SmartSportsContext sportsContext, IMapper mapper, ICacheService caching)
{
_sportsContext = sportsContext;
_mapper = mapper;
_caching = caching;
}
///
/// 获取项目列表
///
///
///
public async Task> SportsProjectList(int orgId)
{
var testingProjectKey = $"TestingProject_{orgId}";
var res = _caching.Get>(testingProjectKey);
if (res == null || res.Count == 0)
{
res = await _sportsContext.XW_TestingProject.Where(x => x.OrgId == orgId)
.Select(x => new SportsProjectListDto()
{
ProjectId = x.ProjectId,
ProjectName = x.ProjectName,
CategoryValue = x.CategoryValue,
CategoryEnum = x.CategoryEnum,
Unit = ((SportsTestItemType)x.CategoryValue).GetUnit()
}).ToListAsync();
}
return res;
}
///
/// 项目成绩大屏数据
///
///
///
public async Task ItemResultLargeScreenData(int orgId)
{
var res = new LargeScreenDto();
var schoolKeyKey = $"School_{orgId}";
var schoolCode = _caching.Get(schoolKeyKey);
if (string.IsNullOrWhiteSpace(schoolCode))
{
schoolCode = await _sportsContext.School.Where(x => x.Id == orgId).Select(x => x.SchoolCode).FirstAsync();
_caching.Add(schoolKeyKey, schoolCode);
}
var sportsTestDataKey = $"SportsTestData_{schoolCode}";
var studentListKey = $"StudentList_{schoolCode}";
var studentList = _caching.Get>(studentListKey);
if (studentList == null || studentList.Count == 0)
{
studentList = await _sportsContext.Student.Where(x => x.SchoolCode == schoolCode).Select(x => new StudentListDto
{
StudentNo = x.StudentNo,
Sex = x.Sex,
Photo = x.Photo ?? ""
}).ToListAsync();
_caching.AddObject(studentListKey, studentList, 3600);
}
res.BasicInfo.FemaleCount = studentList.Count(x => x.Sex == 2);
res.BasicInfo.MaleCount = studentList.Count(x => x.Sex == 1);
var sportsTestData = _caching.Get>(sportsTestDataKey);
if (sportsTestData == null || sportsTestData.Count == 0)
{
sportsTestData = await _sportsContext.SportsTestValue.Where(x => x.SchoolCode == schoolCode && x.DataSource == DataSource.XW)
.Select(x => new SportsTestDataDto()
{
SchoolCode = x.SchoolCode,
CategoryValue = x.CategoryValue,
ClassId = x.ClassId,
ClassName = x.ClassName,
GradeId = x.GradeId,
GradeName = x.GradeName,
TeacherId = x.TeacherId,
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Sex = x.Sex,
ScoreTime = x.ScoreTime,
Height = x.Height,
Weight = x.Weight,
Value = x.Value,
Score = x.Score,
Rank = x.Rank
}).ToListAsync();
_caching.AddObject(sportsTestDataKey, sportsTestData, 3600);
}
var bestScoreData = sportsTestData
.GroupBy(x => x.StudentNo)
.Select(g => g.OrderByDescending(x => x.Score).First())
.ToList();
var projectResults = bestScoreData
.GroupBy(x => x.CategoryValue)
.Select(g => new ItemDataDto
{
CategoryValue = g.Key,
// 优良率计算:分数 > 80 的人数 ÷ 总人数
ExcellentRate = g.Count(x => x.Score > 80) * 100.0 / Math.Max(g.Count(), 1),
// 男生前十名
MaleRankList = g.Where(x => x.Sex == 1)
.OrderByDescending(x => x.Value)
.Take(10)
.Select((x, index) => new StudentScoreRankingDto
{
Rank = index + 1,
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Value = x.Value
}).ToList(),
// 女生前十名
FemaleRankList = g.Where(x => x.Sex == 2)
.OrderByDescending(x => x.Value)
.Take(10)
.Select((x, index) => new StudentScoreRankingDto
{
Rank = index + 1,
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Value = x.Value
}).ToList()
})
.ToList();
res.ItemDatalist = projectResults;
var classListKey = $"ClassList_{schoolCode}";
var classList = _caching.Get>(classListKey);
if (classList == null || classList.Count == 0)
{
classList = await _sportsContext.Class.Where(x => x.SchoolCode == schoolCode).ToListAsync();
_caching.AddObject(classListKey, classList, 3600);
}
var classRankingList = sportsTestData
.GroupBy(x => new { x.ClassId })
.Select(g => new ClassSportsRankingDto
{
ClassId = g.Key.ClassId,
ClassName = classList.Where(c => c.Id == g.Key.ClassId).Select(x => $"{x.GradeName}-{x.ClassName}").FirstOrDefault() ?? "",
Count = g.Count()
})
.OrderByDescending(x => x.Count)
.Take(5)
.Select((x, index) =>
{
x.Rank = index + 1;
return x;
})
.ToList();
res.ClassSportsRankList = classRankingList;
var testingProjectKey = $"TestingProject_{orgId}";
var testingProjects = _caching.Get>(testingProjectKey) ?? new List();
var projectNameDict = testingProjects.ToDictionary(t => t.CategoryValue, t => t.ProjectName);
var studentPhotoDict = studentList.Where(s => !string.IsNullOrEmpty(s.StudentNo)).ToDictionary(s => s.StudentNo, s => s.Photo ?? string.Empty);
var latestPerStudent = sportsTestData
.GroupBy(x => x.StudentNo)
.Select(g => g.OrderByDescending(x => x.ScoreTime).First())
.ToList();
var realTimeResults = latestPerStudent
.OrderByDescending(x => x.ScoreTime)
.Take(50)
.Select(x => new ItemRealTimeResultDto
{
StudentNo = x.StudentNo,
StudentName = x.StudentName,
Photo = studentPhotoDict.TryGetValue(x.StudentNo, out var photo) ? photo : string.Empty,
GradeAndClassName = $"{x.GradeName}-{x.ClassName}",
ProjectName = projectNameDict.TryGetValue(x.CategoryValue, out var projectName) ? projectName : string.Empty,
Value = x.Value,
Score = x.Score,
Rank = x.Rank ?? "不及格",
ScoreTime = x.ScoreTime.ToString("yyyy-MM-dd HH:mm:ss")
})
.ToList();
res.ItemRealTimeResultList = realTimeResults;
return res;
}
}
}