235 lines
9.3 KiB
C#
235 lines
9.3 KiB
C#
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
|
|
{
|
|
/// <summary>
|
|
/// 大屏服务
|
|
/// </summary>
|
|
public class LargeScreenService : ILargeScreenService
|
|
{
|
|
public SmartSportsContext _sportsContext;
|
|
private readonly IMapper _mapper;
|
|
private readonly ICacheService _caching;
|
|
|
|
/// <summary>
|
|
/// 构造
|
|
/// </summary>
|
|
/// <param name="sportsContext"></param>
|
|
/// <param name="mapper"></param>
|
|
public LargeScreenService(SmartSportsContext sportsContext, IMapper mapper, ICacheService caching)
|
|
{
|
|
_sportsContext = sportsContext;
|
|
_mapper = mapper;
|
|
_caching = caching;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取项目列表
|
|
/// </summary>
|
|
/// <param name="orgId"></param>
|
|
/// <returns></returns>
|
|
public async Task<List<SportsProjectListDto>> SportsProjectList(int orgId)
|
|
{
|
|
var testingProjectKey = $"TestingProject_{orgId}";
|
|
|
|
var res = _caching.Get<List<SportsProjectListDto>>(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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 项目成绩大屏数据
|
|
/// </summary>
|
|
/// <param name="orgId"></param>
|
|
/// <returns></returns>
|
|
public async Task<LargeScreenDto> 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<List<StudentListDto>>(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<List<SportsTestDataDto>>(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<List<S_Class>>(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<List<SportsProjectListDto>>(testingProjectKey) ?? new List<SportsProjectListDto>();
|
|
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;
|
|
}
|
|
}
|
|
}
|