1345 lines
52 KiB
C#
1345 lines
52 KiB
C#
using AutoMapper;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Newtonsoft.Json;
|
||
using System.Collections.Generic;
|
||
using System.Security.Cryptography;
|
||
using VOL.Entity.DomainModels.XinWei;
|
||
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.Open;
|
||
using YD_XinWei.Commons.Dto.School;
|
||
using YD_XinWei.Commons;
|
||
using YD_XinWei.Commons.Utils;
|
||
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
|
||
using Newtonsoft.Json.Linq;
|
||
using VOL.Entity.Enum;
|
||
using System.Text.Json;
|
||
|
||
namespace YD_XinWei.Api.Services.Impl
|
||
{
|
||
/// <summary>
|
||
/// 服务实现
|
||
/// </summary>
|
||
public class XinWeiService : IXinWeiService
|
||
{
|
||
public SmartSportsContext _sportsContext;
|
||
private readonly IMapper _mapper;
|
||
|
||
/// <summary>
|
||
/// 构造
|
||
/// </summary>
|
||
/// <param name="sportsContext"></param>
|
||
/// <param name="mapper"></param>
|
||
public XinWeiService(SmartSportsContext sportsContext, IMapper mapper)
|
||
{
|
||
_sportsContext = sportsContext;
|
||
_mapper = mapper;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取设备信息
|
||
/// </summary>
|
||
/// <param name="deviceSerial"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
public async Task<DeviceInfoDto> DeviceInfo(string deviceSerial)
|
||
{
|
||
var deviceInfo = await _sportsContext.XW_Device.FirstOrDefaultAsync(x => x.DeviceSerial == deviceSerial);
|
||
var res = _mapper.Map<DeviceInfoDto>(deviceInfo);
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 项目模式
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public async Task<List<ProjectModeDto>> SportsModelTypeList()
|
||
{
|
||
var res = await _sportsContext.XW_ProjectMode.Select(x => new ProjectModeDto()
|
||
{
|
||
Id = x.Id,
|
||
ProjectKind = x.ProjectKind,
|
||
Name = x.Name
|
||
}).ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 体育项目
|
||
/// </summary>
|
||
/// <param name="orgId">学校Id</param>
|
||
/// <returns></returns>
|
||
|
||
public async Task<List<TestingProjectDto>> OrgSportsProjectList(int orgId)
|
||
{
|
||
//var res = await _sportsContext.XW_TestingProject.Where(x => x.OrgId == orgId).Select(x => new TestingProjectDto()
|
||
var res = await _sportsContext.XW_TestingProject.Where(x => x.OrgId == orgId).Select(x => new TestingProjectDto()
|
||
{
|
||
ProjectId = x.ProjectId,
|
||
IsOpen = x.IsOpen,
|
||
IsShow = x.IsShow,
|
||
ProjectName = x.ProjectName
|
||
}).ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取学生信息
|
||
/// </summary>
|
||
/// <param name="orgId">学校Id</param>
|
||
/// <returns></returns>
|
||
public async Task<List<StudentInfoDto>> MinimumOfStudentInfoList(int orgId)
|
||
{
|
||
string schoolCode = await _sportsContext.School.Where(x => x.Id == orgId).Select(x => x.SchoolCode).FirstAsync();
|
||
|
||
var res = await (from s in _sportsContext.Student
|
||
join c in _sportsContext.Class on s.ClassId equals c.Id
|
||
join g in _sportsContext.Grade on c.GradeId equals g.Id
|
||
where s.SchoolCode == schoolCode
|
||
select new StudentInfoDto()
|
||
{
|
||
Id = s.Id,
|
||
OrgId = orgId,
|
||
UserId = s.Id,
|
||
StudentNo = s.StudentNo,
|
||
Name = s.StudentName,
|
||
Sex = s.Sex == 1 ? "男" : "女",
|
||
ClassId = c.Id,
|
||
GradeId = g.Id,
|
||
RuleGradeId = g.Id,
|
||
GradeName = g.GradeName,
|
||
ClassName = $"{g.GradeName}-{c.ClassName}",
|
||
CardNo = new List<string>()
|
||
}).ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取名单列表
|
||
/// </summary>
|
||
/// <param name="orgId"></param>
|
||
/// <param name="userId"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="NotImplementedException"></exception>
|
||
public async Task<List<SportsRosterDto>> SportsRosterList(int orgId, int userId = 0)
|
||
{
|
||
string schoolCode = await _sportsContext.School.Where(x => x.Id == orgId).Select(x => x.SchoolCode).FirstAsync();
|
||
var studentList = await _sportsContext.Student.Where(x => x.SchoolCode == schoolCode).ToListAsync();
|
||
|
||
var list = await (from c in _sportsContext.Class
|
||
join g in _sportsContext.Grade on c.GradeId equals g.Id
|
||
where c.SchoolCode == schoolCode
|
||
select new SportsRosterDto()
|
||
{
|
||
Id = c.Id,
|
||
OrgId = orgId,
|
||
Name = c.ClassName,
|
||
GradeId = g.Id,
|
||
RuleGradeId = g.Id,
|
||
GradeName = g.GradeName,
|
||
Status = 1,
|
||
Type = 1
|
||
}).ToListAsync();
|
||
|
||
|
||
foreach (var item in list)
|
||
{
|
||
var stuList = studentList.Where(x => x.ClassId == item.Id).ToList();
|
||
List<SportsRosterStudentDto> sportList1 = new List<SportsRosterStudentDto>();
|
||
|
||
foreach (var sport in stuList)
|
||
{
|
||
sportList1.Add(new SportsRosterStudentDto()
|
||
{
|
||
Id = sport.Id,
|
||
GroupName = item.Name,
|
||
ClassId = item.Id,
|
||
ClassName = item.Name,
|
||
GradeId = item.GradeId,
|
||
GradeName = item.GradeName,
|
||
OrgId = orgId,
|
||
Sex = sport.Sex,
|
||
UserName = sport.StudentName,
|
||
StudentNo = sport.StudentNo,
|
||
UserId = sport.Id,
|
||
GroupOrder = sport.Id,
|
||
RosterId = 1,
|
||
});
|
||
}
|
||
|
||
item.RosterGroupList.Add(new SportsRosterGroupDto()
|
||
{
|
||
GroupName = item.Name,
|
||
RosterStudentList = sportList1
|
||
});
|
||
}
|
||
|
||
//var list1 = list.Select(x => new SportsRosterDto
|
||
//{
|
||
// Type = 2
|
||
//}).ToList();
|
||
|
||
|
||
//var mergedList = list.Concat(list1).ToList();
|
||
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取人脸信息
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<FaceListOfDevicePageDto> FaceListOfDevicePage(FaceListOfDeviceDto dto)
|
||
{
|
||
//Console.WriteLine($"获取人脸信息 OrgId:{dto.OrgId}");
|
||
|
||
string schoolCode = await _sportsContext.School.Where(x => x.Id == dto.OrgId).Select(x => x.SchoolCode).FirstAsync();
|
||
|
||
var total = await _sportsContext.Student.CountAsync(x => x.SchoolCode == schoolCode && !string.IsNullOrWhiteSpace(x.Photo));
|
||
|
||
var list = await _sportsContext.Student
|
||
.Where(x => x.SchoolCode == schoolCode && !string.IsNullOrWhiteSpace(x.Photo))
|
||
.Select(s => new DeviceUserFaceVo()
|
||
{
|
||
FaceId = s.StudentNo,
|
||
FaceType = 1,
|
||
FaceUrl = s.Photo,
|
||
PersonId = s.StudentNo,
|
||
UserId = s.Id
|
||
})
|
||
.Skip((dto.PageNo - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.ToListAsync();
|
||
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(list, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/获取人脸信息{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
return new FaceListOfDevicePageDto()
|
||
{
|
||
Total = total,
|
||
PageNum = dto.PageNo,
|
||
PageSize = dto.PageSize,
|
||
Pages = (int)Math.Ceiling((double)total / dto.PageSize),
|
||
List = list
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取训练评分规则
|
||
/// </summary>
|
||
/// <param name="orgId">学校Id</param>
|
||
/// <returns></returns>
|
||
public async Task<List<ScoreRuleDto>> ScoreRules(int orgId)
|
||
{
|
||
var scoreRules = await _sportsContext.HealthStandards.ToListAsync();
|
||
var projects = await _sportsContext.XW_TestingProject.ToListAsync();
|
||
var projectModels = await _sportsContext.XW_ProjectMode.ToListAsync();
|
||
|
||
var scoreRuleItemsByType = scoreRules
|
||
.GroupBy(x => x.CategoryEnum)
|
||
.ToDictionary(g => g.Key, g => g.ToList());
|
||
|
||
List<ScoreRuleDto> res = new List<ScoreRuleDto>();
|
||
|
||
foreach (var projectModel in projectModels)
|
||
{
|
||
var project = projects.FirstOrDefault(x => x.ProjectId == projectModel.ProjectKind);
|
||
if (project == null) continue; // Skip if project doesn't exist
|
||
|
||
var scoreRuleTypes = projectModel.CategoryEnum.Split(',');
|
||
var scoreRuleItems = scoreRuleTypes.SelectMany(type => scoreRuleItemsByType.GetValueOrDefault(type, new List<N_HealthStandards>())).ToList();
|
||
|
||
var groupedItemsData = scoreRuleItems.GroupBy(x => x.GradeId).ToList();
|
||
|
||
foreach (var grouped in groupedItemsData)
|
||
{
|
||
var maleItems = grouped.Where(x => x.Sex == 1).ToList();
|
||
var femaleItems = grouped.Where(x => x.Sex == 2).ToList();
|
||
|
||
var maleMax = maleItems.DefaultIfEmpty().Max(x => x?.MaxValue ?? 0);
|
||
var maleMin = maleItems.DefaultIfEmpty().Max(x => x?.MinValue ?? 0);
|
||
var maleMaxScore = maleItems.DefaultIfEmpty().Max(x => x?.Score ?? 0);
|
||
|
||
var femaleMax = femaleItems.DefaultIfEmpty().Max(x => x?.MaxValue ?? 0);
|
||
var femaleMin = femaleItems.DefaultIfEmpty().Max(x => x?.MinValue ?? 0);
|
||
var femaleMaxScore = femaleItems.DefaultIfEmpty().Max(x => x?.Score ?? 0);
|
||
|
||
ScoreRuleDto scoreRuleDto = new ScoreRuleDto
|
||
{
|
||
GradeId = grouped.Key,
|
||
OrgId = orgId,
|
||
ProjectKind = project.ProjectId,
|
||
ProjectName = project.ProjectName,
|
||
ModelType = projectModel.Id,
|
||
RuleType = 1,
|
||
ProjectId = project.ProjectId,
|
||
Items = grouped.Select(item => new ScoreRuleItemDto
|
||
{
|
||
Id = item.Id,
|
||
Sex = item.Sex,
|
||
Name = item.Score.GetRank().ToString(),
|
||
Score = item.Score,
|
||
Max = item.MaxValue,
|
||
Min = item.MinValue
|
||
}).OrderByDescending(x => x.Min).ToList()
|
||
};
|
||
|
||
scoreRuleDto.Pluses = new List<ScoreRulePlusDto>
|
||
{
|
||
//new ScoreRulePlusDto()
|
||
//{
|
||
// Id = grouped.FirstOrDefault()?.Id ?? 0,
|
||
// Sex = 1,
|
||
// Max = maleMax,
|
||
// Min = maleMin,
|
||
// MaxScore = maleMaxScore,
|
||
// Score = maleMaxScore
|
||
//},
|
||
//new ScoreRulePlusDto()
|
||
//{
|
||
// Id = grouped.FirstOrDefault()?.Id ?? 0,
|
||
// Sex = 2,
|
||
// Max = femaleMax,
|
||
// Min = femaleMin,
|
||
// MaxScore = femaleMaxScore,
|
||
// Score = femaleMaxScore
|
||
//}
|
||
};
|
||
|
||
scoreRuleDto.ScoreScopes = new List<ScoreScope>
|
||
{
|
||
//new ScoreScope()
|
||
//{
|
||
// Gender = 1,
|
||
// MaxScore = maleMaxScore,
|
||
// MaxCount = maleMax
|
||
//},
|
||
//new ScoreScope()
|
||
//{
|
||
// Gender = 2,
|
||
// MaxScore = femaleMaxScore,
|
||
// MaxCount = femaleMax
|
||
//}
|
||
};
|
||
|
||
res.Add(scoreRuleDto);
|
||
}
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增训练
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TrainDto> AddTrain(AddTrainDto dto)
|
||
{
|
||
var jsonOptions = new JsonSerializerOptions
|
||
{
|
||
WriteIndented = true,
|
||
Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/add_train_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
|
||
string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
var logDir = "/tmp/xwlog";
|
||
|
||
Directory.CreateDirectory(logDir);
|
||
|
||
await File.WriteAllTextAsync(
|
||
$"{logDir}/add_train_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
dtoJson
|
||
);
|
||
|
||
var xwProject = await _sportsContext.XW_TestingProject.Where(x => x.OrgId == dto.OrgId).ToListAsync();
|
||
var healthStandards = await _sportsContext.HealthStandards.ToListAsync();
|
||
|
||
try
|
||
{
|
||
var entity = _mapper.Map<XW_SportsTestData>(dto);
|
||
|
||
entity.StudentList.ForEach(stu =>
|
||
{
|
||
var project = xwProject.Where(x => x.ProjectId == dto.ProjectId).FirstOrDefault();
|
||
string categoryEnum = project?.CategoryEnum ?? "";
|
||
|
||
if (dto.ProjectId == 4 || dto.ProjectId == 11)
|
||
{
|
||
// 只除以10,保留两位小数
|
||
stu.Achievement = stu.Achievement.HasValue ? Math.Round(stu.Achievement.Value / 10.0, 2) : 0;
|
||
stu.Achievement2 = stu.Achievement2.HasValue ? Math.Round(stu.Achievement2.Value / 10.0, 2) : 0;
|
||
}
|
||
|
||
if (dto.ProjectId == 3)
|
||
{
|
||
// 除以1000再除以10,即除以10000,保留两位小数
|
||
stu.Achievement = stu.Achievement.HasValue ? Math.Round(stu.Achievement.Value / 1000.0, 2) - 0.5 : 0;
|
||
}
|
||
|
||
if (dto.ProjectId == 2)
|
||
{
|
||
// 除以1000再除以60,保留两位小数
|
||
stu.Achievement = stu.Achievement.HasValue ? Math.Round(stu.Achievement.Value / 1000.0 / 60, 2) : 0;
|
||
}
|
||
|
||
if (dto.ProjectId == 21)
|
||
{
|
||
var value = stu.Achievement2;
|
||
|
||
var standard = healthStandards.Where(x =>
|
||
x.CategoryEnum.Equals(categoryEnum) &&
|
||
x.GradeId == x.GradeId &&
|
||
x.Sex == x.Sex &&
|
||
value >= x.MinValue &&
|
||
value < x.MaxValue
|
||
).FirstOrDefault();
|
||
|
||
if (standard != null)
|
||
{
|
||
stu.Score = standard.Score;
|
||
stu.Rating = standard.Score.GetRank();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
var standard = healthStandards.Where(x =>
|
||
x.CategoryEnum.Equals(categoryEnum) &&
|
||
x.GradeId == x.GradeId &&
|
||
x.Sex == x.Sex &&
|
||
stu.Achievement >= x.MinValue &&
|
||
stu.Achievement < x.MaxValue
|
||
).FirstOrDefault();
|
||
|
||
if (standard != null)
|
||
{
|
||
stu.Score = standard.Score;
|
||
stu.Rating = standard.Score.GetRank();
|
||
}
|
||
}
|
||
|
||
stu.OrgId = dto.OrgId;
|
||
stu.CreateTime = dto.EndTime;
|
||
});
|
||
|
||
|
||
await _sportsContext.XW_SportsTestData.AddAsync(entity);
|
||
|
||
var sportsTestValueEntinys = await AddSportsTestValueEntity(dto, healthStandards, xwProject);
|
||
await _sportsContext.SportsTestValue.AddRangeAsync(sportsTestValueEntinys);
|
||
|
||
await _sportsContext.SaveChangesAsync();
|
||
|
||
var res = _mapper.Map<TrainDto>(entity);
|
||
|
||
Console.WriteLine("新增成功");
|
||
|
||
return res;
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
Console.WriteLine(e.Message + "/n" + e.InnerException);
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private async Task<List<N_SportsTestValue>> AddSportsTestValueEntity(AddTrainDto dto, List<N_HealthStandards> healthStandards, List<XW_TestingProject> xwProject)
|
||
{
|
||
var sportsTestValueEntinys = new List<N_SportsTestValue>();
|
||
|
||
string schoolCode = await _sportsContext.School.Where(x => x.Id == dto.OrgId).Select(x => x.SchoolCode).FirstAsync();
|
||
|
||
var nowTime = DateTime.Now;
|
||
|
||
foreach (var data in dto.StudentList)
|
||
{
|
||
if (data.Achievement == 0)
|
||
continue;
|
||
|
||
var sportsTestValueEntity = new N_SportsTestValue();
|
||
|
||
var project = xwProject.Where(x => x.ProjectId == dto.ProjectId).FirstOrDefault();
|
||
|
||
string categoryEnum = project?.CategoryEnum ?? "";
|
||
|
||
float value = data.Achievement ?? 0;
|
||
|
||
if (dto.ProjectId == 4 || dto.ProjectId == 11)
|
||
{
|
||
// 只除以10,保留两位小数
|
||
value = (float)(data.Achievement.HasValue ? Math.Round(data.Achievement.Value / 10.0, 2) : 0);
|
||
}
|
||
|
||
if (dto.ProjectId == 3)
|
||
{
|
||
// 除以1000再除以10,即除以10000,保留两位小数,再减0.5
|
||
value = (float)((data.Achievement.HasValue ? Math.Round(data.Achievement.Value / 1000.0, 2) : 0) - 0.5);
|
||
}
|
||
|
||
if (dto.ProjectId == 21)
|
||
{
|
||
// Achievement2 除以10,保留两位小数
|
||
value = (float)(data.Achievement2.HasValue ? Math.Round(data.Achievement2.Value / 10.0, 2) : 0);
|
||
// Height 除以10
|
||
sportsTestValueEntity.Height = (float)(data.Achievement.HasValue ? Math.Round(data.Achievement.Value / 10.0, 2) : 0);
|
||
// Weight 除以100
|
||
sportsTestValueEntity.Weight = (float)(data.OriginalAchievement.HasValue ? Math.Round(data.OriginalAchievement.Value / 100.0, 2) : 0);
|
||
}
|
||
|
||
//中长跑
|
||
if (dto.ProjectId == 2)
|
||
{
|
||
// 只除以1000,保留两位小数
|
||
value = (float)(data.Achievement.HasValue ? Math.Round(data.Achievement.Value / 1000.0, 2) : 0);
|
||
|
||
if (data.Sex == 1)
|
||
|
||
categoryEnum = "MeterRun_1000";
|
||
else
|
||
categoryEnum = "MeterRun_800";
|
||
}
|
||
|
||
|
||
var standard = healthStandards.Where(x =>
|
||
x.CategoryEnum.Equals(categoryEnum) &&
|
||
x.GradeId == data.GradeId &&
|
||
x.Sex == data.Sex &&
|
||
value >= x.MinValue &&
|
||
value < x.MaxValue
|
||
).FirstOrDefault();
|
||
|
||
if (standard != null)
|
||
{
|
||
sportsTestValueEntity.Score = standard.Score;
|
||
sportsTestValueEntity.Rank = standard.Rank;
|
||
}
|
||
|
||
|
||
//sportsTestValueEntity.Score = (float)(data.Score ?? 0);
|
||
sportsTestValueEntity.SchoolCode = schoolCode;
|
||
sportsTestValueEntity.Sex = (int)data.Sex;
|
||
sportsTestValueEntity.DataSource = DataSource.XW;
|
||
sportsTestValueEntity.CategoryValue = project?.CategoryValue ?? 0;
|
||
sportsTestValueEntity.CategoryEnum = categoryEnum;
|
||
sportsTestValueEntity.GradeId = data.GradeId;
|
||
sportsTestValueEntity.GradeName = data.GradeName;
|
||
sportsTestValueEntity.ClassId = data.ClassId;
|
||
sportsTestValueEntity.ClassName = data.ClassName;
|
||
sportsTestValueEntity.TeacherId = data.TeacherId ?? 0;
|
||
sportsTestValueEntity.TeacherName = data.Teacher;
|
||
sportsTestValueEntity.StudentNo = data.StudentNo;
|
||
sportsTestValueEntity.StudentName = data.StudentName;
|
||
sportsTestValueEntity.Value = value;
|
||
sportsTestValueEntity.Creator = dto.OrgId ?? 0;
|
||
sportsTestValueEntity.CreateDate = nowTime;
|
||
sportsTestValueEntity.ScoreTime = Convert.ToDateTime(dto.EndTime);
|
||
sportsTestValueEntity.AdditionalScore = (float)(data.PlusesScore ?? 0);
|
||
|
||
SemesterDto semesterDto = new SemesterDto();
|
||
sportsTestValueEntity.Year = semesterDto.Year;
|
||
sportsTestValueEntity.Semester = semesterDto.Semester;
|
||
sportsTestValueEntity.IsDisplay = true;
|
||
|
||
sportsTestValueEntinys.Add(sportsTestValueEntity);
|
||
}
|
||
|
||
return sportsTestValueEntinys;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 年级排名
|
||
/// </summary>
|
||
/// <param name="studentId"></param>
|
||
/// <param name="trainId"></param>
|
||
/// <returns></returns>
|
||
public async Task<GradeRankingVo> GradeRankingGet(int studentId, int trainId)
|
||
{
|
||
var res = new GradeRankingVo();
|
||
|
||
Console.WriteLine($"GradeRankingGet:{studentId},{trainId}");
|
||
|
||
var now = DateTime.UtcNow;
|
||
var firstDayOfMonth = new DateTime(now.Year, now.Month, 1);
|
||
var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
|
||
|
||
var studentResults = await _sportsContext.XW_TrainStudents.Where(x => x.XW_SportsTestDataId == trainId)
|
||
.Select(x => new
|
||
{
|
||
x.GradeId,
|
||
x.StudentId,
|
||
x.StudentName,
|
||
x.Rating,
|
||
x.CreateTime,
|
||
x.Score
|
||
}).ToListAsync();
|
||
|
||
var student = studentResults.FirstOrDefault(x => x.StudentId == studentId);
|
||
|
||
if (student == null)
|
||
{
|
||
return res;
|
||
}
|
||
|
||
|
||
var rankedResults = studentResults
|
||
.Where(x => x.GradeId == student.GradeId &&
|
||
DateTime.TryParse(x.CreateTime, out var createTime) &&
|
||
createTime >= firstDayOfMonth && createTime <= lastDayOfMonth)
|
||
.OrderByDescending(x => x.Score)
|
||
.Select((x, index) => new { x.StudentId, Rank = index + 1 })
|
||
.ToList();
|
||
|
||
var studentRank = rankedResults.FirstOrDefault(x => x.StudentId == student.StudentId)?.Rank.ToString() ?? "无数据";
|
||
|
||
res.Rating = student.Score.GetRankStr();
|
||
res.MonthRanking = studentRank;
|
||
res.Score = student.Score.ToString();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 全部历史记录
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TrainHistoryResponseDto> HistoryGet(HistoryGetDto dto)
|
||
{
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/HistoryGet_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
var res = new TrainHistoryResponseDto();
|
||
|
||
var trainList = await _sportsContext.XW_SportsTestData
|
||
.Where(x =>
|
||
x.OrgId == dto.OrgId &&
|
||
x.ProjectKind == Convert.ToInt32(dto.ProjectKind) &&
|
||
x.ModelType == dto.ModelType)
|
||
.ToListAsync();
|
||
|
||
if (trainList == null || !trainList.Any())
|
||
return res;
|
||
|
||
var trainIds = trainList.Select(t => t.Id).ToList();
|
||
|
||
var query = _sportsContext.XW_TrainStudents
|
||
.Where(x => trainIds.Contains(x.XW_SportsTestDataId))
|
||
.AsQueryable();
|
||
|
||
// 动态排序
|
||
if (!string.IsNullOrEmpty(dto.OrderByColumn))
|
||
{
|
||
bool isAsc = dto.IsAsc?.ToLower() == "asc";
|
||
query = isAsc
|
||
? query.OrderBy(x => EF.Property<object>(x, dto.OrderByColumn))
|
||
: query.OrderByDescending(x => EF.Property<object>(x, dto.OrderByColumn));
|
||
}
|
||
else
|
||
{
|
||
query = query.OrderByDescending(x => x.Id); // 默认排序
|
||
}
|
||
|
||
var total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Skip((dto.PageNo - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.Select(x => new TrainHistoryVo()
|
||
{
|
||
TrainStudentId = x.Id,
|
||
ClassName = x.ClassName,
|
||
CreateTime = x.CreateTime ?? "无数据",
|
||
Achievement = x.Achievement.ToString() ?? "无数据",
|
||
Rating = x.Score.GetRankStr(),
|
||
Score = x.Score.ToString() ?? "无数据",
|
||
Sex = x.Sex == 1 ? "男" : "女",
|
||
StudentName = x.StudentName,
|
||
TouristFlag = false,
|
||
DoubleFlag = false,
|
||
}).OrderByDescending(x => x.CreateTime)
|
||
.ToListAsync();
|
||
|
||
res.Total = total;
|
||
res.Rows = list;
|
||
|
||
return res;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 历史记录详细
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TrainAnalusisVo> TrainAnalysisHistoryDetail(HistoryDetailRequestDto dto)
|
||
{
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/TrainAnalysisHistoryDetail_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
var trainModel = await _sportsContext.XW_TrainStudents.Where(x => x.Id == dto.TrainStudentId).Select(x => new { x.XW_SportsTestDataId, x.StudentId, x.GradeId }).FirstAsync();
|
||
|
||
var stuHeadUrl = await _sportsContext.Student.Where(x => x.Id == trainModel.StudentId).Select(x => x.Photo).FirstOrDefaultAsync();
|
||
|
||
var train = await _sportsContext.XW_SportsTestData.Where(x => x.Id == trainModel.XW_SportsTestDataId).Select(x => new { x.ProjectName, x.ProjectId }).FirstOrDefaultAsync();
|
||
|
||
var now = DateTime.UtcNow;
|
||
var firstDayOfMonth = new DateTime(now.Year, now.Month, 1);
|
||
var lastDayOfMonth = firstDayOfMonth.AddMonths(1).AddDays(-1);
|
||
var trainIds = await _sportsContext.XW_SportsTestData.Where(x => x.ProjectId == train.ProjectId).Select(x => x.Id).ToListAsync();
|
||
|
||
var studentResults = await _sportsContext.XW_TrainStudents.Where(x => trainIds.Contains(x.XW_SportsTestDataId))
|
||
.Select(x => new
|
||
{
|
||
x.Id,
|
||
x.GradeId,
|
||
x.StudentId,
|
||
x.StudentName,
|
||
x.Rating,
|
||
x.CreateTime,
|
||
x.Score,
|
||
x.Achievement
|
||
}).ToListAsync();
|
||
|
||
var student = studentResults.Where(x => x.Id == dto.TrainStudentId).OrderByDescending(x => x.Score).FirstOrDefault();
|
||
|
||
if (student == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
var rankedResults = studentResults
|
||
.Where(x => x.GradeId == student.GradeId &&
|
||
DateTime.TryParse(x.CreateTime, out var createTime) &&
|
||
createTime >= firstDayOfMonth && createTime <= lastDayOfMonth)
|
||
.OrderByDescending(x => x.Achievement)
|
||
.Select((x, index) => new { x.Id, Rank = index + 1 })
|
||
.ToList();
|
||
|
||
var studentRank = rankedResults.FirstOrDefault(x => x.Id == dto.TrainStudentId)?.Rank.ToString() ?? "无数据";
|
||
|
||
var res = await _sportsContext.XW_TrainStudents.Where(x => x.Id == dto.TrainStudentId).Include(x => x.TrainViolationsBO).Select(x => new TrainAnalusisVo()
|
||
{
|
||
Achievement = x.Achievement.ToString() ?? "无数据",
|
||
ClassName = x.ClassName,
|
||
GradeRanking = studentRank,
|
||
HeadImgUrl = stuHeadUrl,
|
||
ProjectName = train.ProjectName,
|
||
Rating = x.Score.GetRankStr(),
|
||
Score = x.Score.ToString() ?? "无数据",
|
||
Sex = x.Sex == 1 ? "男" : "女",
|
||
StudentName = x.StudentName,
|
||
Times = x.Times.ToString(),
|
||
VideoRecord = x.VideoRecord,
|
||
ViolationsNumber = x.TrainViolationsBO.Count(),
|
||
TrainViolationsVo = x.TrainViolationsBO.Select(x => new TrainViolationsVo()
|
||
{
|
||
CreateTime = x.TrainTime,
|
||
TrainTime = x.TrainTime,
|
||
PicUrl = x.PicUrl,
|
||
ViolationId = x.ViolationId,
|
||
ViolationName = "",
|
||
}).ToList(),
|
||
|
||
}).FirstOrDefaultAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 个人历史记录-历史成绩
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TrainHistoryPersonVo> HistoryPersonGet(HistoryPersonGetDto dto)
|
||
{
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/HistoryPersonGet_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
// 1️⃣ 获取该机构、项目、模型类型的训练数据
|
||
var trainList = await _sportsContext.XW_SportsTestData
|
||
.Where(x =>
|
||
x.OrgId == dto.OrgId &&
|
||
x.ProjectKind == Convert.ToInt32(dto.ProjectKind) &&
|
||
x.ModelType == dto.ModelType)
|
||
.ToListAsync();
|
||
|
||
if (!trainList.Any())
|
||
return new TrainHistoryPersonVo();
|
||
|
||
var trainIds = trainList.Select(t => t.Id).ToList();
|
||
|
||
// 2️⃣ 获取学生成绩数据
|
||
var studentResults = await _sportsContext.XW_TrainStudents
|
||
.Where(x => trainIds.Contains(x.XW_SportsTestDataId))
|
||
.Select(x => new
|
||
{
|
||
x.Id,
|
||
x.ClassName,
|
||
x.StudentId,
|
||
x.StudentName,
|
||
x.GradeId,
|
||
x.Sex,
|
||
x.Score,
|
||
x.Achievement,
|
||
x.CreateTime
|
||
})
|
||
.ToListAsync();
|
||
|
||
if (!studentResults.Any())
|
||
return new TrainHistoryPersonVo();
|
||
|
||
// ⭐ 是否按升序(ModelType = 7)
|
||
bool isAsc = dto.ModelType == 7;
|
||
|
||
// 3️⃣ 获取指定学生(按成绩最优的一次)
|
||
var student = isAsc
|
||
? studentResults
|
||
.Where(x => x.StudentId == dto.StudentId)
|
||
.OrderBy(x => x.Achievement)
|
||
.FirstOrDefault()
|
||
: studentResults
|
||
.Where(x => x.StudentId == dto.StudentId)
|
||
.OrderByDescending(x => x.Achievement)
|
||
.FirstOrDefault();
|
||
|
||
if (student == null)
|
||
return new TrainHistoryPersonVo();
|
||
|
||
// 4️⃣ 历史排名
|
||
var rankedResults = (isAsc
|
||
? studentResults
|
||
.Where(x => x.GradeId == student.GradeId)
|
||
.OrderBy(x => x.Achievement)
|
||
: studentResults
|
||
.Where(x => x.GradeId == student.GradeId)
|
||
.OrderByDescending(x => x.Achievement)
|
||
)
|
||
.Select((x, index) => new { x, Rank = index + 1 })
|
||
.ToList();
|
||
|
||
// 5️⃣ 当月数据
|
||
var monthList = studentResults
|
||
.Where(x => DateTime.TryParse(x.CreateTime, out var date)
|
||
&& date.Year == DateTime.Now.Year
|
||
&& date.Month == DateTime.Now.Month)
|
||
.ToList();
|
||
|
||
// 6️⃣ 当月排名
|
||
var monthRankedResults = (isAsc
|
||
? monthList
|
||
.Where(x => x.GradeId == student.GradeId)
|
||
.OrderBy(x => x.Achievement)
|
||
: monthList
|
||
.Where(x => x.GradeId == student.GradeId)
|
||
.OrderByDescending(x => x.Achievement)
|
||
)
|
||
.Select((x, index) => new { x, Rank = index + 1 })
|
||
.ToList();
|
||
|
||
// 7️⃣ 获取学生头像
|
||
var stuHeadUrl = await _sportsContext.Student
|
||
.Where(x => x.Id == student.StudentId)
|
||
.Select(x => x.Photo)
|
||
.FirstOrDefaultAsync();
|
||
|
||
// 8️⃣ 历史最佳成绩
|
||
var bestStudentOverall = isAsc
|
||
? studentResults.OrderBy(x => x.Achievement).FirstOrDefault()
|
||
: studentResults.OrderByDescending(x => x.Achievement).FirstOrDefault();
|
||
|
||
// 9️⃣ 当月最佳成绩
|
||
var bestStudentMonth = isAsc
|
||
? monthList.OrderBy(x => x.Achievement).FirstOrDefault()
|
||
: monthList.OrderByDescending(x => x.Achievement).FirstOrDefault();
|
||
|
||
// 🔟 构建返回对象
|
||
return new TrainHistoryPersonVo
|
||
{
|
||
ClassName = student.ClassName,
|
||
HeadImgUrl = stuHeadUrl,
|
||
Sex = student.Sex == 1 ? "男" : "女",
|
||
StudentName = student.StudentName,
|
||
|
||
// 历史最佳成绩
|
||
HistoryBestScore = bestStudentOverall?.Achievement?.ToString("0.###") ?? "无数据",
|
||
|
||
// 历史排名
|
||
HistoryRanking = rankedResults
|
||
.FirstOrDefault(x => x.x.Id == student.Id)?.Rank.ToString() ?? "1",
|
||
|
||
// 当月最佳成绩
|
||
MonthBestScore = bestStudentMonth?.Achievement?.ToString("0.###") ?? "无数据",
|
||
|
||
// 当月排名
|
||
MonthRanking = monthRankedResults
|
||
.FirstOrDefault(x => x.x.Id == student.Id)?.Rank.ToString() ?? "1"
|
||
};
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 个人历史记录-记录列表
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TableDataPersonAnalysisVo> HistoryPersonListGet(HistoryPersonListDto dto)
|
||
{
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/HistoryPersonListGet_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
var res = new TableDataPersonAnalysisVo();
|
||
|
||
var trainList = await _sportsContext.XW_SportsTestData
|
||
.Where(x =>
|
||
x.OrgId == dto.OrgId &&
|
||
x.ProjectKind == Convert.ToInt32(dto.ProjectKind) &&
|
||
x.ModelType == dto.ModelType)
|
||
.ToListAsync();
|
||
|
||
if (trainList == null || !trainList.Any())
|
||
return res;
|
||
|
||
var trainIds = trainList.Select(t => t.Id).ToList();
|
||
|
||
var query = _sportsContext.XW_TrainStudents
|
||
.Where(x => trainIds.Contains(x.XW_SportsTestDataId) && x.StudentId == dto.StudentId)
|
||
.AsQueryable();
|
||
|
||
// 动态排序
|
||
if (!string.IsNullOrEmpty(dto.OrderByColumn))
|
||
{
|
||
bool isAsc = dto.IsAsc?.ToLower() == "asc";
|
||
query = isAsc
|
||
? query.OrderBy(x => EF.Property<object>(x, dto.OrderByColumn))
|
||
: query.OrderByDescending(x => EF.Property<object>(x, dto.OrderByColumn));
|
||
}
|
||
else
|
||
{
|
||
query = query.OrderByDescending(x => x.Id); // 默认排序
|
||
}
|
||
|
||
var total = await query.CountAsync();
|
||
|
||
var list = await query
|
||
.Skip((dto.PageNo - 1) * dto.PageSize)
|
||
.Take(dto.PageSize)
|
||
.Select(x => new PersonAnalysisVo()
|
||
{
|
||
TrainStudentId = x.Id,
|
||
ClassName = x.ClassName,
|
||
CreateTime = x.CreateTime ?? "无数据",
|
||
//Achievement = dto.ModelType == 7 ? (x.Achievement.HasValue ? $"{x.Achievement.Value / 1000}.{x.Achievement.Value % 1000}" : "无数据") : (x.Achievement.HasValue ? x.Achievement.Value.ToString() : "无数据"),
|
||
Achievement = x.Achievement.HasValue ? x.Achievement.Value.ToString("0.###") : "无数据",
|
||
Rating = x.Score.GetRankStr(),
|
||
Score = x.Score.ToString() ?? "无数据",
|
||
Sex = x.Sex == 1 ? "男" : "女",
|
||
StudentName = x.StudentName,
|
||
DoubleFlag = false,
|
||
}).OrderByDescending(x => x.CreateTime)
|
||
.ToListAsync();
|
||
|
||
res.Total = total;
|
||
res.Rows = list;
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 成绩榜-年级列表
|
||
/// </summary>
|
||
/// <param name="orgId"></param>
|
||
/// <returns></returns>
|
||
public async Task<List<GradeVo>> GetGradeListByOrg(int orgId)
|
||
{
|
||
string schoolCode = await _sportsContext.School.Where(x => x.Id == orgId).Select(x => x.SchoolCode).FirstAsync();
|
||
|
||
var res = await (from s in _sportsContext.SchoolAssocGrade
|
||
join g in _sportsContext.Grade on s.GradeId equals g.Id
|
||
where s.SchoolCode == schoolCode
|
||
select new GradeVo()
|
||
{
|
||
GradeId = g.Id,
|
||
GradeName = g.GradeName
|
||
}).ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 成绩榜-年级列表
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<ScoreRankingVo> ScoreRanking(ScoreRankingDto dto)
|
||
{
|
||
//var jsonOptions = new JsonSerializerOptions
|
||
//{
|
||
// WriteIndented = true,
|
||
// Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
|
||
//};
|
||
|
||
//string dtoJson = System.Text.Json.JsonSerializer.Serialize(dto, jsonOptions);
|
||
|
||
//await File.WriteAllTextAsync(
|
||
// $"/tmp/xwlog/ScoreRanking_{DateTime.Now:yyyyMMdd_HHmmss}.json",
|
||
// dtoJson
|
||
//);
|
||
|
||
var res = new ScoreRankingVo();
|
||
|
||
var trainList = await _sportsContext.XW_SportsTestData
|
||
.Where(x =>
|
||
x.OrgId == dto.OrgId &&
|
||
x.ProjectKind == Convert.ToInt32(dto.ProjectKind) &&
|
||
x.ModelType == Convert.ToInt32(dto.ModelType))
|
||
.ToListAsync();
|
||
|
||
var trainIds = trainList.Select(t => t.Id).ToList();
|
||
|
||
var today = DateTime.UtcNow.Date;
|
||
var (startDate, endDate) = dto.Times switch
|
||
{
|
||
"1" => (today.AddDays(-(int)today.DayOfWeek + 1), today.AddDays(7 - (int)today.DayOfWeek)),
|
||
"2" => (new DateTime(today.Year, today.Month, 1), new DateTime(today.Year, today.Month, 1).AddMonths(1).AddDays(-1)),
|
||
"3" =>
|
||
today.Month >= 9 || today.Month <= 2
|
||
? (new DateTime(today.Month >= 9 ? today.Year : today.Year - 1, 9, 1),
|
||
new DateTime(today.Month >= 9 ? today.Year + 1 : today.Year, 2, DateTime.DaysInMonth(today.Month >= 9 ? today.Year + 1 : today.Year, 2)))
|
||
: (new DateTime(today.Year, 3, 1),
|
||
new DateTime(today.Year, 8, DateTime.DaysInMonth(today.Year, 8))),
|
||
_ => (DateTime.MinValue, DateTime.MaxValue)
|
||
};
|
||
|
||
// 基础数据
|
||
var rawResults = await _sportsContext.XW_TrainStudents
|
||
.Where(x => trainIds.Contains(x.XW_SportsTestDataId) && x.GradeId == dto.GradeId)
|
||
.Select(x => new
|
||
{
|
||
x.StudentName,
|
||
x.ClassName,
|
||
x.Achievement,
|
||
x.CreateTime,
|
||
x.Sex
|
||
})
|
||
.ToListAsync();
|
||
|
||
// 过滤时间与性别
|
||
var filtered = rawResults
|
||
.Where(x => DateTime.TryParse(x.CreateTime, out var date) && date >= startDate && date <= endDate)
|
||
.Where(x => dto.Sex == "1" ? x.Sex == 1 : dto.Sex == "2" ? x.Sex == 2 : true)
|
||
.ToList();
|
||
|
||
// ⭐ 根据 ModelType == 7 决定排序方式 ⭐
|
||
var sorted = (dto.ModelType == 7
|
||
? filtered.OrderBy(x => x.Achievement ?? int.MaxValue)
|
||
: filtered.OrderByDescending(x => x.Achievement ?? int.MinValue)
|
||
).ToList();
|
||
|
||
if (dto.ProjectKind == 3)
|
||
{
|
||
sorted = filtered.OrderBy(x => x.Achievement ?? int.MaxValue).ToList();
|
||
}
|
||
|
||
// ⭐ 输出格式处理 ⭐
|
||
var studentResults = sorted.Select(x => new RankingVo()
|
||
{
|
||
Name = x.StudentName,
|
||
ClassName = x.ClassName,
|
||
//Achievement = dto.ModelType == 7
|
||
// ? (x.Achievement.HasValue
|
||
// ? $"{x.Achievement.Value / 1000}"
|
||
// : "无数据")
|
||
// : (x.Achievement.HasValue
|
||
// ? x.Achievement.Value.ToString()
|
||
// : "无数据")
|
||
|
||
Achievement = x.Achievement.HasValue ? x.Achievement.Value.ToString("0.###") : "无数据"
|
||
|
||
}).ToList();
|
||
|
||
res.Times = dto.Times;
|
||
res.Lists = studentResults;
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取成绩榜中显示的体育项目
|
||
/// </summary>
|
||
/// <param name="orgId"></param>
|
||
/// <returns></returns>
|
||
public async Task<List<ProjectVo>> GetProjectInfo(int orgId)
|
||
{
|
||
var res = await _sportsContext.XW_ProjectMode.Select(x => new ProjectVo()
|
||
{
|
||
ProjectKind = x.ProjectKind,
|
||
ProjectId = x.ProjectKind,
|
||
ModelType = x.Id,
|
||
ProjectName = x.Name
|
||
}).ToListAsync();
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设备端人脸录入
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<bool> AddWeBankUserFace(AddWeBankUserFaceDto dto)
|
||
{
|
||
if (dto == null || dto.UserId <= 0 || dto.PicUrlA == null || dto.PicUrlA.Length == 0)
|
||
return false;
|
||
|
||
var student = await _sportsContext.Student
|
||
.FirstOrDefaultAsync(x => x.Id == dto.UserId);
|
||
|
||
if (student == null)
|
||
return false;
|
||
|
||
var gradeId = await _sportsContext.Class
|
||
.Where(x => x.Id == student.ClassId)
|
||
.Select(x => x.GradeId)
|
||
.FirstOrDefaultAsync();
|
||
|
||
// 文件名:学号 + 时间戳 + GUID(防重名)
|
||
var fileName = $"{student.StudentNo}_{DateTime.Now:yyyyMMddHHmmssfff}";
|
||
|
||
var folder = $"Upload/{student.SchoolCode}/Photo/Student/{gradeId}/{student.ClassId}/";
|
||
|
||
var url = ALiYunOss.Upload(dto.PicUrlA, folder, fileName);
|
||
|
||
student.Photo = url;
|
||
|
||
_sportsContext.Student.Update(student);
|
||
|
||
return await _sportsContext.SaveChangesAsync() > 0;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传抓拍图片
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<bool> UploadDeviceImage(UploadDeviceImageDto dto)
|
||
{
|
||
if (dto == null || dto.File == null || dto.File.Length == 0)
|
||
return false;
|
||
|
||
var folder = NormalizeOssFolder(dto.Path);
|
||
var fileName = BuildDeviceImageFileName(dto);
|
||
var imageUrl = ALiYunOss.Upload(dto.File, folder, fileName);
|
||
|
||
var entity = new XW_DeviceImage
|
||
{
|
||
Path = dto.Path,
|
||
ImageUrl = imageUrl,
|
||
DeviceNum = dto.DeviceNum,
|
||
Timestamp = dto.Timestamp,
|
||
StudentId = dto.StudentId,
|
||
FileName = dto.File.FileName,
|
||
CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||
};
|
||
|
||
await _sportsContext.XW_DeviceImage.AddAsync(entity);
|
||
|
||
return await _sportsContext.SaveChangesAsync() > 0;
|
||
}
|
||
|
||
private static string NormalizeOssFolder(string? path)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(path))
|
||
return "Upload/DeviceImage/";
|
||
|
||
var folder = path.Trim().Replace("\\", "/").Trim('/');
|
||
|
||
return $"{folder}/";
|
||
}
|
||
|
||
private static string BuildDeviceImageFileName(UploadDeviceImageDto dto)
|
||
{
|
||
var deviceNum = NormalizeFileNamePart(dto.DeviceNum, "device");
|
||
var studentId = NormalizeFileNamePart(dto.StudentId, "student");
|
||
var timestamp = NormalizeFileNamePart(dto.Timestamp, DateTime.Now.ToString("yyyyMMddHHmmssfff"));
|
||
|
||
return $"{deviceNum}_{studentId}_{timestamp}_{Guid.NewGuid():N}";
|
||
}
|
||
|
||
private static string NormalizeFileNamePart(string? value, string defaultValue)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(value))
|
||
return defaultValue;
|
||
|
||
var invalidChars = Path.GetInvalidFileNameChars();
|
||
var chars = value.Trim().Select(x => invalidChars.Contains(x) ? '_' : x).ToArray();
|
||
|
||
return new string(chars);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 阳光跑-数据推送
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<TrainDto> AddSunshineRunTrain(List<AddSunshineRunTrainDto> dto)
|
||
{
|
||
if (dto == null || !dto.Any())
|
||
return null;
|
||
|
||
var entities = dto.Select(x => new XW_SunshineRunTrain
|
||
{
|
||
OrgId = x.OrgId,
|
||
GradeName = x.GradeName,
|
||
GradeId = x.GradeId,
|
||
ClassName = x.ClassName,
|
||
ClassId = x.ClassId,
|
||
StudentId = x.StudentId,
|
||
StudentName = x.StudentName,
|
||
Sex = x.Sex,
|
||
EffectiveDistance = x.EffectiveDistance,
|
||
InvalidDistance = x.InvalidDistance,
|
||
Times = x.Times,
|
||
InvalidTimes = x.InvalidTimes,
|
||
|
||
CreateTime = string.IsNullOrWhiteSpace(x.CreateTime)
|
||
? DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||
: x.CreateTime,
|
||
|
||
DetailInfo = x.DetailInfo?.Select(d => new XW_SunshineRunTrainDetail
|
||
{
|
||
Point = d.Point,
|
||
Distance = d.Distance,
|
||
LapSpeed = d.LapSpeed,
|
||
CameraName = d.CameraName,
|
||
Trigger = d.Trigger,
|
||
SnapPath = d.SnapPath,
|
||
ValidFlag = d.ValidFlag,
|
||
Remark = d.Remark
|
||
}).ToList() ?? new List<XW_SunshineRunTrainDetail>()
|
||
}).ToList();
|
||
|
||
await _sportsContext.XW_SunshineRunTrain.AddRangeAsync(entities);
|
||
|
||
await _sportsContext.SaveChangesAsync();
|
||
|
||
var entity = entities[0];
|
||
var res = _mapper.Map<TrainDto>(entity);
|
||
|
||
Console.WriteLine("新增成功");
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 上传阳光跑经过点位信息
|
||
/// </summary>
|
||
/// <param name="dto"></param>
|
||
/// <returns></returns>
|
||
public async Task<bool> UploadSunshinePoint(UploadSunshinePointDto dto)
|
||
{
|
||
if (dto == null || dto.Image == null || dto.Image.Length == 0)
|
||
return false;
|
||
|
||
var folder = "Upload/SunshineRun/Point/";
|
||
var fileName = BuildSunshinePointFileName(dto);
|
||
var imageUrl = ALiYunOss.Upload(dto.Image, folder, fileName);
|
||
|
||
var entity = new XW_SunshinePoint
|
||
{
|
||
ImageUrl = imageUrl,
|
||
FileName = dto.Image.FileName,
|
||
DeviceNum = dto.DeviceNum,
|
||
Timestamp = dto.Timestamp,
|
||
StudentNo = dto.StudentNo,
|
||
PointName = dto.PointName,
|
||
CameraIp = dto.CameraIp,
|
||
EffectiveDistance = dto.EffectiveDistance,
|
||
SumDistance = dto.SumDistance,
|
||
CreateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
|
||
};
|
||
|
||
await _sportsContext.XW_SunshinePoint.AddAsync(entity);
|
||
|
||
return await _sportsContext.SaveChangesAsync() > 0;
|
||
}
|
||
|
||
private static string BuildSunshinePointFileName(UploadSunshinePointDto dto)
|
||
{
|
||
var deviceNum = NormalizeFileNamePart(dto.DeviceNum, "device");
|
||
var studentNo = NormalizeFileNamePart(dto.StudentNo, "student");
|
||
var pointName = NormalizeFileNamePart(dto.PointName, "point");
|
||
var timestamp = NormalizeFileNamePart(dto.Timestamp, DateTime.Now.ToString("yyyyMMddHHmmssfff"));
|
||
|
||
return $"{deviceNum}_{studentNo}_{pointName}_{timestamp}_{Guid.NewGuid():N}";
|
||
}
|
||
}
|
||
}
|