using Learn.Archives.API.Controllers.Dto;
using Learn.Archives.API.Expand;
using Learn.Archives.Core.Common;
using Learn.Archives.Core.Common.Expand;
using Learn.Archives.Core.Model;
using Learn.Archives.Core.Model.Dto;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using System.Diagnostics;
using System.Security.Claims;
using UserCenter.Model;
using UserCenter.Model.Common;
using UserCenter.Model.Enum;
namespace Learn.Archives.API.Controllers
{
///
/// 年级控制器
///
public class ExamClassInfoController : BackController
{
readonly Repository baseService;
readonly Repository examService;
readonly Repository schoolService;
readonly Repository examUserInfoService;
readonly LiveUserInfo userInfo;
readonly IHttpContextAccessor accessor;
public ExamClassInfoController(Repository baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContext, Repository examUserInfoService, Repository examService, Repository schoolService) : base(baseService)
{
this.baseService = baseService;
this.userInfo = userInfo;
this.accessor = httpContext;
this.examUserInfoService = examUserInfoService;
this.examService = examService;
this.schoolService = schoolService;
}
[NonAction]
private Dictionary? ImportExamInfoSubjectDic(ImportExamInfo info)
{
return new Dictionary()
{
{ SubjectEnum.语文, info.语文},
{ SubjectEnum.数学, info.数学},
{ SubjectEnum.英语, info.英语},
{ SubjectEnum.物理, info.物理},
{ SubjectEnum.化学, info.化学},
{ SubjectEnum.生物, info.生物},
{ SubjectEnum.政治, info.政治},
{ SubjectEnum.历史, info.历史},
{ SubjectEnum.地理, info.地理},
};
}
///
/// 导入考试信息
///
///
///
[HttpPost, ResultIgnore]
[HttpLogEnable]
public async Task Import(ImportExamDto dto)
{
var exam = await examService.GetByIdAsync(dto.eId);
var fl = dto.File!=null? dto .File: accessor.HttpContext?.Request.Form.Files[0];
if (exam == null || fl == null) Oh.ModelError("为传入有效的数据");
if (!Path.GetExtension(fl.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
Oh.ModelError("请选择导入文件为.xlsx的后缀名!");
//分析excel
IEnumerable dataList;
using var stream = new MemoryStream();
{
await fl.CopyToAsync(stream);
dataList = stream.Query()
.Where(s => !string.IsNullOrEmpty(s.Student));
}
if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据");
//todo
//处理数据
var errorExcelInfo = new List();
var insertUserInfo = new List();
var insertClassInfo = new List();
var db = schoolService.Context;
SqlSugarExpand.SetDbAop(db);
foreach (var schoolArr in dataList.GroupBy(s => s.School))
{
var school = await schoolService.GetFirstAsync(s => s.Name == schoolArr.Key);
if (school == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 未找到!");
var gradeInfo = GradeHelper.GetStudentGradeBaseByGrade(schoolArr.First().Grade);
if (gradeInfo == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 年级[{schoolArr.First().Grade}]不符合规范!");
//学校下的所属班级
var classArr = await db.Queryable().Where(c => c.SchoolId == school.Id &&
c.GradeLevel == gradeInfo.GradeLevel &&
c.GraduationYear == gradeInfo.GradeYear && !c.DeleteState).ToArrayAsync();
var userDic = await db.Queryable()
.LeftJoin((s, c) => c.SchoolId == s.Id)
.LeftJoin((s, c, p) => p.ClassId == c.Id)
.LeftJoin((s, c, p, pr) => pr.PositionId == p.Id)
.LeftJoin((s, c, p, pr, u) => u.Id == pr.UserId)
.Where((s, c, p, pr, u) =>
s.Id == school.Id &&
c.GradeLevel == gradeInfo.GradeLevel &&
c.GraduationYear == gradeInfo.GradeYear &&
u.UserType == UserTypeEnum.学生.GetHashCode() &&
s.Enable && p.Enable && pr.Enable &&
!p.DeleteState && !c.DeleteState && !u.DeleteState && !s.DeleteState)
.Select((s, c, p, pr, u) => new
{
Name = c.Name + c.Type.ToString() + u.RealName,
u.Id,
}).ToDictionaryAsync(s => s.Name, s => s.Id);
//处理学生成绩数据
var userList = dataList.Select(s =>
{
var classInfo = classArr
.FirstOrDefault(x => x.Name == s.Class && x.Type == s.ClassType.ToEnum());
if (classInfo == null)
{
s.Error = "未能匹配班级";
errorExcelInfo.Add(s);
return null;
}
var grade = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var sub = ImportExamInfoSubjectDic(s);
var name = s.Class + s.ClassType.ToEnum().GetHashCode() + s.Student;
if (!userDic.ContainsKey(name))
{
s.Error = "未能匹配到年级班级下对应的学生";
errorExcelInfo.Add(s);
return null;
}
var uid = userDic[name];
return new ExamUserInfo()
{
ExamId = exam.Id,
ExamName = exam.Name,
GradeYear = grade.GradeYear,
GradeLevel = grade.GradeLevel,
TestPaperType = exam.TestPaperType,
UserId = (long)userDic[name],
UserName = s.Student,
ClassId = classInfo.Id,
SchoolId = classInfo.SchoolId,
Type = exam.Type,
SubjectDic = sub,
AssignScore = s.赋分后总分,
AssignRanking = 0,
};
}).ToList();
insertUserInfo.AddRange(userList);
insertUserInfo = insertUserInfo.Where(s => s != null).ToList();
foreach (var classUserArr in insertUserInfo.GroupBy(s => s.ClassId))
{
var classInfo = classArr.First(s => s.Id == classUserArr.Key);
var eCInfo = new ExamClassInfo()
{
ExamId = exam.Id,
ExamName = exam.Name,
SchoolId = classInfo.SchoolId,
SchoolName = school.Name,
ClassId = classInfo.Id,
ClassName = classInfo.Name,
GradeLevel = classInfo.GradeLevel,
GradeYear = classInfo.GraduationYear,
PeopleCount = classUserArr.Count(),
MinScore = int.MaxValue,
EntryPersonId = userInfo.Id,
BaseSchoolScore = exam.BaseSchoolScore,
EntryPerson = userInfo.Name,
TestPaperType = exam.TestPaperType,
Type = exam.Type,
Average1 = exam.BaseSchoolScore,
};
insertClassInfo.Add(eCInfo);
var avgTotal = 0m;
foreach (var eUserInfo in classUserArr)
{
var v = eUserInfo.AssignScore;
//上线人数
if (v>=exam.ScoreLine)
eCInfo.OnLineCount ++;
//最大小分
if (v < eCInfo.MinScore)
eCInfo.MinScore = v;
else if(v > eCInfo.MaxScore)
eCInfo.MaxScore = v;
avgTotal += v;//追加得分
}
//总分平均分
eCInfo.Average = avgTotal / eCInfo.PeopleCount;
//计算上线率
eCInfo.OnLineRate = (decimal)eCInfo.OnLineCount / (decimal)eCInfo.PeopleCount;
//处理学生班级排名
var i = 0;
foreach (var item in classUserArr.OrderByDescending(s => s.AssignScore)
.GroupBy(s => s.AssignScore))
{
foreach (var u in item)
u.AssignRanking =++ i;
}
}
};
{ //计算年级上线率排名
var i = 0;
foreach (var item in insertClassInfo.OrderByDescending(s => s.OnLineRate)
.GroupBy(s => s.OnLineRate))
{
foreach (var u in item)
u.OnLineRanking = ++i;
}
//计算年级平均分排名
i = 0;
foreach (var item in insertClassInfo.OrderByDescending(s => s.Average)
.GroupBy(s => s.Average))
{
foreach (var u in item)
u.AverageRank = ++i;
}
}
if (errorExcelInfo.Count != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"错误考试信息{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//写入数据库
var baseDB = baseService.Context;
baseDB.Ado.BeginTran();
try
{
await baseDB.Insertable(insertUserInfo).ExecuteCommandAsync();
await baseDB.Insertable(insertClassInfo).ExecuteCommandAsync();
baseDB.Ado.CommitTran();
}
catch (Exception ex)
{
baseDB.Ado.RollbackTran();
Oh.ModelError($"导入失败:写入数据时候出现了异常 [{ex.Message}] !");
}
return Ok();
}
///
/// 下载导入成绩模板
///
///
[HttpGet, ResultIgnore, AllowAnonymous]
public IActionResult DwImportTemplate()
{
List resultList = new List() { new ImportExamInfo()
{
School="例子学校[导入时候请删除]",
Class="测试班级",
ClassType="普通班级",
Grade="高2028",
Student="学生姓名",
语文=80.5m,
化学=80.5m,
数学=80m,
历史 = 80m,
地理 = 80m,
政治 = 80m,
物理 = 80m,
生物 = 80m,
英语 = 80.5m,
赋分后总分=721.5m
} };
return File(resultList.ExportExcel(), "application/ms-excel",
$"导入成绩模板{DateTime.Now.ToString("MMddHHmm")}.xlsx");
}
///
/// 删除班级考试信息
///
///
///
[HttpPost]
public async Task DeleteExamInfo(RestartEntryDto dto)
{
if (dto.ClassId == 0 || dto.ExamId == 0)
Oh.ModelError("传入了异常参数");
var exam = examService.GetById(dto.ExamId);
if (exam is null)
Oh.ModelError("传入了无效的考试");
var dCount = await baseService.AsDeleteable().Where(s => s.ClassId == dto.ClassId)
.ExecuteCommandAsync();
var dCount1 = await examUserInfoService.AsDeleteable().Where(s => s.ClassId == dto.ClassId)
.ExecuteCommandAsync();
return Ok();
}
public override Task PageList([FromBody] QueryRequestBase model)
{
var c = model.Conditions.FirstOrDefault(s => s.FieldName == "Grade");
if (c != null)
{
var gInfo = GradeHelper.GetStudentGradeBaseByGrade(c.FieldValue);
if (gInfo != null)
{
model.Conditions = model.Conditions.Where(s => s != c).ToList();
model.Conditions.Add(new SqlSugar.ConditionalModel()
{
FieldName = "GradeLevel",
FieldValue = gInfo.GradeLevel,
});
model.Conditions.Add(new SqlSugar.ConditionalModel()
{
FieldName = "GradeYear",
FieldValue = gInfo.GradeYear.ToString(),
CSharpTypeName="int"
});
}
}
return base.PageList(model);
}
}
}