Compare commits
25 Commits
314e169171
...
8135ee0f4c
| Author | SHA1 | Date |
|---|---|---|
|
|
8135ee0f4c | |
|
|
628c1c5b3c | |
|
|
12c022e05c | |
|
|
07967f1390 | |
|
|
7c46a2f49e | |
|
|
218bf66fc6 | |
|
|
90a6815c7a | |
|
|
d31c898d35 | |
|
|
db0e5905fa | |
|
|
fb6147ecbf | |
|
|
43a16815ca | |
|
|
67363cd50d | |
|
|
abcdad03b0 | |
|
|
d0638bcfd4 | |
|
|
9dbd3e4900 | |
|
|
a1a6324b8b | |
|
|
12ffbe5754 | |
|
|
ab5fc42607 | |
|
|
a5e044ca7e | |
|
|
ae5d2a8293 | |
|
|
119576da72 | |
|
|
57e98333cf | |
|
|
d22e07353d | |
|
|
aa7b035eb6 | |
|
|
520a3ef59f |
|
|
@ -3,10 +3,16 @@ using Learn.Archives.API.Controllers.Dto;
|
||||||
using Learn.Archives.API.Expand;
|
using Learn.Archives.API.Expand;
|
||||||
using Learn.Archives.Core.Common;
|
using Learn.Archives.Core.Common;
|
||||||
using Learn.Archives.Core.Model;
|
using Learn.Archives.Core.Model;
|
||||||
|
using Learn.Archives.Core.Model.Dto;
|
||||||
|
using Learn.Archives.Core.Model.Enum;
|
||||||
|
using Mapster;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using MiniExcelLibs;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using UserCenter.Model.Common;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Controllers
|
namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -15,11 +21,17 @@ namespace Learn.Archives.API.Controllers
|
||||||
readonly Repository<Admin> baseService;
|
readonly Repository<Admin> baseService;
|
||||||
readonly Repository<MenuRelation> menuRelationDB;
|
readonly Repository<MenuRelation> menuRelationDB;
|
||||||
readonly Repository<Menu> menuDB;
|
readonly Repository<Menu> menuDB;
|
||||||
public AdminController(Repository<Admin> baseService, Repository<MenuRelation> menuRelationDB, Repository<Menu> menuDB) : base(baseService)
|
readonly Repository<AdminRole> roleDB;
|
||||||
|
readonly LiveUserInfo userInfo;
|
||||||
|
readonly IHttpContextAccessor accessor;
|
||||||
|
public AdminController(Repository<Admin> baseService, Repository<MenuRelation> menuRelationDB, Repository<Menu> menuDB, IHttpContextAccessor accessor, Repository<AdminRole> roleDB, LiveUserInfo userInfo = null) : base(baseService)
|
||||||
{
|
{
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
this.menuRelationDB = menuRelationDB;
|
this.menuRelationDB = menuRelationDB;
|
||||||
this.menuDB = menuDB;
|
this.menuDB = menuDB;
|
||||||
|
this.accessor = accessor;
|
||||||
|
this.roleDB = roleDB;
|
||||||
|
this.userInfo = userInfo;
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 管理员登录
|
/// 管理员登录
|
||||||
|
|
@ -73,12 +85,107 @@ namespace Learn.Archives.API.Controllers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override Task<bool> Edit([FromBody] Admin model)
|
public override async Task<bool> Edit([FromBody] Admin model)
|
||||||
{
|
{
|
||||||
//创建用户时 密码加密
|
//创建用户时 密码加密
|
||||||
if (model.Id == 0)
|
if (model.Id == 0)
|
||||||
model.Password = model.Password.GetMD5();
|
model.Password = model.Password.GetMD5();
|
||||||
return base.Edit(model);
|
if (string.IsNullOrEmpty(model.Account) || model.Account.Length < 2 ||
|
||||||
|
string.IsNullOrEmpty(model.Phone) || model.Phone.Length < 11 ||
|
||||||
|
string.IsNullOrEmpty(model.Name) || model.Phone.Length < 2)
|
||||||
|
{
|
||||||
|
Oh.ModelError("账号/手机号/名称 不合法");
|
||||||
|
}
|
||||||
|
if (await baseService.IsAnyAsync(s => s.Account == model.Account && s.Id != model.Id))
|
||||||
|
Oh.ModelError($"账号 {model.Account} 已被使用!");
|
||||||
|
return await base.Edit(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 下载导入模板
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet, ResultIgnore, AllowAnonymous]
|
||||||
|
public IActionResult DwImportTemplate()
|
||||||
|
{
|
||||||
|
var resultList = new List<AdminImport>() { new AdminImport()
|
||||||
|
{
|
||||||
|
Account = "登录账号[建议使用手机号]",
|
||||||
|
Name = "必填:用户名称",
|
||||||
|
Phone = "联系方式",
|
||||||
|
Role = "必填:与系统的角色名称匹配\r\n普通成员 管理员",
|
||||||
|
Password = "必填: 登录密码",
|
||||||
|
} };
|
||||||
|
return File(resultList.ExportExcel(), "application/ms-excel",
|
||||||
|
$"导入管理员模板{DateTime.Now.ToString("MMddHHmm")}.xlsx");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 导入考试信息
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost, ResultIgnore]
|
||||||
|
[HttpLogEnable]
|
||||||
|
public async Task<IActionResult> Import(IFormFile? file)
|
||||||
|
{
|
||||||
|
if(!userInfo.IsSa)
|
||||||
|
Oh.ModelError("只允许管理员使用本功能!");
|
||||||
|
var fl = file != null ? file : accessor.HttpContext?.Request.Form.Files[0];
|
||||||
|
if (fl == null) Oh.ModelError("传入无效的数据");
|
||||||
|
if (!Path.GetExtension(fl.FileName).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
|
||||||
|
Oh.ModelError("请选择导入文件为.xlsx的后缀名!");
|
||||||
|
//分析excel
|
||||||
|
IEnumerable<AdminImportError> dataList;
|
||||||
|
using var stream = new MemoryStream();
|
||||||
|
{
|
||||||
|
await fl.CopyToAsync(stream);
|
||||||
|
dataList = stream.Query<AdminImportError>()
|
||||||
|
.Where(s => !string.IsNullOrEmpty(s.Account));
|
||||||
|
}
|
||||||
|
if (dataList == null || dataList.Count() == 0)
|
||||||
|
Oh.ModelError("导入失败:无有效数据");
|
||||||
|
|
||||||
|
//处理数据
|
||||||
|
var accountArr = await baseService.AsQueryable()
|
||||||
|
.Select(s => s.Account).Distinct()
|
||||||
|
.ToArrayAsync();
|
||||||
|
var accountH = accountArr.ToHashSet();
|
||||||
|
var roleDic = await roleDB.AsQueryable()
|
||||||
|
.ToDictionaryAsync(s => s.Name, s => s.Id);
|
||||||
|
var errorExcelInfo = new List<AdminImportError>();
|
||||||
|
var insertInfo = new List<Admin>();
|
||||||
|
foreach (var imp in dataList)
|
||||||
|
{
|
||||||
|
imp.Account = imp.Account.Trim();
|
||||||
|
imp.Phone = imp.Phone.Trim();
|
||||||
|
imp.Name = imp.Name.Trim();
|
||||||
|
imp.Role = imp.Role.Trim();
|
||||||
|
if (accountH.Contains(imp.Account))
|
||||||
|
{
|
||||||
|
imp.Error = $"导入失败:账号已被使用!";
|
||||||
|
errorExcelInfo.Add(imp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (!roleDic.ContainsKey(imp.Role))
|
||||||
|
{
|
||||||
|
imp.Error = $"导入失败:无效的 角色名称!";
|
||||||
|
errorExcelInfo.Add(imp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var admin = imp.Adapt<Admin>();
|
||||||
|
admin.Enable = true;
|
||||||
|
admin.RoleId = (long)roleDic[imp.Role];
|
||||||
|
admin.Password = imp.Password.Trim().GetMD5();
|
||||||
|
insertInfo.Add(admin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errorExcelInfo.Count != 0)
|
||||||
|
return File(errorExcelInfo.ExportExcel(), "application/ms-excel"
|
||||||
|
, $"错误管理员信息{DateTime.Now.ToString("MMddHHmm")}.xlsx");
|
||||||
|
//写入数据库
|
||||||
|
await baseService.InsertRangeAsync(insertInfo);
|
||||||
|
return Ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
using UserCenter.Model;
|
||||||
|
using UserCenter.Model.Common;
|
||||||
|
|
||||||
|
namespace Learn.Archives.API.Controllers.Dto
|
||||||
|
{
|
||||||
|
public class ClassDto:Classes
|
||||||
|
{
|
||||||
|
public string Grade => GradeHelper.GetGrade(this.GradeLevel, GraduationYear);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,37 @@
|
||||||
using UserCenter.Model;
|
using MiniExcelLibs.Attributes;
|
||||||
|
using UserCenter.Model;
|
||||||
using UserCenter.Model.Common;
|
using UserCenter.Model.Common;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Controllers.Dto
|
namespace Learn.Archives.API.Controllers.Dto
|
||||||
{
|
{
|
||||||
public class ClassDto:Classes
|
|
||||||
|
|
||||||
|
public class AdminImportError : AdminImport
|
||||||
{
|
{
|
||||||
public string Grade => GradeHelper.GetGrade(this.GradeLevel, GraduationYear);
|
|
||||||
|
[ExcelColumn(Name = "错误原因", Width = 25)]
|
||||||
|
public string Error { get; set; }
|
||||||
|
}
|
||||||
|
public class AdminImport
|
||||||
|
{
|
||||||
|
|
||||||
|
[ExcelColumn(Name = "账号", Width = 30)]
|
||||||
|
public string Account { get; set; }
|
||||||
|
|
||||||
|
[ExcelColumn(Name = "名称", Width = 15)]
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
[ExcelColumn(Name = "电话号码", Width = 30)]
|
||||||
|
public string Phone { get; set; }
|
||||||
|
|
||||||
|
[ExcelColumn(Name = "角色", Width = 30)]
|
||||||
|
public string Role { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 密码
|
||||||
|
/// </summary>
|
||||||
|
[ExcelColumn(Name = "密码", Width = 20)]
|
||||||
|
public string Password { get; set; }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,15 @@
|
||||||
using MiniExcelLibs.Attributes;
|
using Learn.Archives.Core.Model;
|
||||||
|
using MiniExcelLibs.Attributes;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Controllers.Dto
|
namespace Learn.Archives.API.Controllers.Dto
|
||||||
{
|
{
|
||||||
|
public class ExamClassTagReq : ExamClassTag
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 学科类型
|
||||||
|
/// </summary>
|
||||||
|
public string SubjectStr => SubjectId?.ToString() ?? "总分";
|
||||||
|
}
|
||||||
public class ImportExamDto
|
public class ImportExamDto
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -46,11 +54,6 @@ namespace Learn.Archives.API.Controllers.Dto
|
||||||
[ExcelColumnName("云校班级号")]
|
[ExcelColumnName("云校班级号")]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
[ExcelColumnName("班级类型")]
|
|
||||||
public string ClassType { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 学生姓名
|
/// 学生姓名
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcelColumnName("学生姓名")]
|
[ExcelColumnName("学生姓名")]
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
using System.Buffers.Text;
|
using System.Buffers.Text;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using UserCenter.Model;
|
using UserCenter.Model;
|
||||||
|
|
@ -25,10 +26,15 @@ namespace Learn.Archives.API.Controllers
|
||||||
readonly Repository<ExamClassInfo> baseService;
|
readonly Repository<ExamClassInfo> baseService;
|
||||||
readonly Repository<Exam> examService;
|
readonly Repository<Exam> examService;
|
||||||
readonly Repository<School> schoolService;
|
readonly Repository<School> schoolService;
|
||||||
|
readonly Repository<ExamTags> tagService;
|
||||||
|
readonly Repository<ExamClassTag> classTagService;
|
||||||
readonly Repository<ExamUserInfo> examUserInfoService;
|
readonly Repository<ExamUserInfo> examUserInfoService;
|
||||||
readonly LiveUserInfo userInfo;
|
readonly LiveUserInfo userInfo;
|
||||||
readonly IHttpContextAccessor accessor;
|
readonly IHttpContextAccessor accessor;
|
||||||
public ExamClassInfoController(Repository<ExamClassInfo> baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContext, Repository<ExamUserInfo> examUserInfoService, Repository<Exam> examService, Repository<School> schoolService) : base(baseService)
|
public ExamClassInfoController(Repository<ExamClassInfo> baseService, LiveUserInfo userInfo,
|
||||||
|
IHttpContextAccessor httpContext, Repository<ExamUserInfo> examUserInfoService,
|
||||||
|
Repository<Exam> examService, Repository<School> schoolService,
|
||||||
|
Repository<ExamTags> tagService, Repository<ExamClassTag> classTagService) : base(baseService)
|
||||||
{
|
{
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
|
|
@ -36,23 +42,8 @@ namespace Learn.Archives.API.Controllers
|
||||||
this.examUserInfoService = examUserInfoService;
|
this.examUserInfoService = examUserInfoService;
|
||||||
this.examService = examService;
|
this.examService = examService;
|
||||||
this.schoolService = schoolService;
|
this.schoolService = schoolService;
|
||||||
}
|
this.tagService = tagService;
|
||||||
|
this.classTagService = classTagService;
|
||||||
[NonAction]
|
|
||||||
private Dictionary<SubjectEnum, decimal>? ImportExamInfoSubjectDic(ImportExamInfo info)
|
|
||||||
{
|
|
||||||
return new Dictionary<SubjectEnum, decimal>()
|
|
||||||
{
|
|
||||||
{ SubjectEnum.语文, info.语文},
|
|
||||||
{ SubjectEnum.数学, info.数学},
|
|
||||||
{ SubjectEnum.英语, info.英语},
|
|
||||||
{ SubjectEnum.物理, info.物理},
|
|
||||||
{ SubjectEnum.化学, info.化学},
|
|
||||||
{ SubjectEnum.生物, info.生物},
|
|
||||||
{ SubjectEnum.政治, info.政治},
|
|
||||||
{ SubjectEnum.历史, info.历史},
|
|
||||||
{ SubjectEnum.地理, info.地理},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -118,14 +109,14 @@ namespace Learn.Archives.API.Controllers
|
||||||
!p.DeleteState && !c.DeleteState && !u.DeleteState && !s.DeleteState)
|
!p.DeleteState && !c.DeleteState && !u.DeleteState && !s.DeleteState)
|
||||||
.Select((s, c, p, pr, u) => new
|
.Select((s, c, p, pr, u) => new
|
||||||
{
|
{
|
||||||
Name = c.Name + c.Type.ToString() + u.RealName,
|
Name = c.Name + u.RealName,
|
||||||
u.Id,
|
u.Id,
|
||||||
}).ToDictionaryAsync(s => s.Name, s => s.Id);
|
}).ToDictionaryAsync(s => s.Name, s => s.Id);
|
||||||
//处理学生成绩数据
|
//处理学生成绩数据
|
||||||
var userList = dataList.Select(s =>
|
var userList = dataList.Select(s =>
|
||||||
{
|
{
|
||||||
var classInfo = classArr
|
var classInfo = classArr
|
||||||
.FirstOrDefault(x => x.Name == s.Class && x.Type == s.ClassType.ToEnum<ClassTypeEnum>());
|
.FirstOrDefault(x => x.Name == s.Class );
|
||||||
if (classInfo == null)
|
if (classInfo == null)
|
||||||
{
|
{
|
||||||
s.Error = "未能匹配班级";
|
s.Error = "未能匹配班级";
|
||||||
|
|
@ -134,7 +125,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
}
|
}
|
||||||
var grade = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
|
var grade = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
|
||||||
var sub = ImportExamInfoSubjectDic(s);
|
var sub = ImportExamInfoSubjectDic(s);
|
||||||
var name = s.Class + s.ClassType.ToEnum<ClassTypeEnum>().GetHashCode() + s.Student;
|
var name = s.Class + s.Student;
|
||||||
if (!userDic.ContainsKey(name))
|
if (!userDic.ContainsKey(name))
|
||||||
{
|
{
|
||||||
s.Error = "未能匹配到年级班级下对应的学生";
|
s.Error = "未能匹配到年级班级下对应的学生";
|
||||||
|
|
@ -175,115 +166,11 @@ namespace Learn.Archives.API.Controllers
|
||||||
//写入数据库
|
//写入数据库
|
||||||
await examUserInfoService.AsInsertable(insertUserInfo).ExecuteCommandAsync();
|
await examUserInfoService.AsInsertable(insertUserInfo).ExecuteCommandAsync();
|
||||||
|
|
||||||
await CalculatingTestResults(exam,examUserInfoService,schoolService);
|
await CalculatingTestResults(exam,examUserInfoService,schoolService, tagService);
|
||||||
|
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 计算考试成绩
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="exam"></param>
|
|
||||||
/// <param name="examUserInfoService"></param>
|
|
||||||
/// <param name="schoolService"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[NonAction]
|
|
||||||
public static async Task CalculatingTestResults(Exam exam, Repository<ExamUserInfo> eUService, Repository<School> sService)
|
|
||||||
{
|
|
||||||
var userInfoArr = await eUService.AsQueryable()
|
|
||||||
.Where(s => s.ExamId == exam.Id)
|
|
||||||
.ToArrayAsync();
|
|
||||||
|
|
||||||
var insertTotalClassInfo = new List<ExamClassInfo>();
|
|
||||||
var db = sService.Context;
|
|
||||||
foreach (var schoolArr in userInfoArr.GroupBy(s => s.SchoolId))
|
|
||||||
{
|
|
||||||
|
|
||||||
var insertClassInfo = new List<ExamClassInfo>();
|
|
||||||
var school = await sService.GetFirstAsync(s => s.Id == schoolArr.Key);
|
|
||||||
var classArr = await db.Queryable<Classes>().Where(c => c.SchoolId == school.Id &&
|
|
||||||
c.GradeLevel == exam.GradeLevel &&
|
|
||||||
c.GraduationYear == exam.GradeYear && !c.DeleteState).ToArrayAsync();
|
|
||||||
|
|
||||||
foreach (var classUserArr in userInfoArr.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,
|
|
||||||
MaxScore = -99,
|
|
||||||
BaseSchoolScore = exam.BaseSchoolScore,
|
|
||||||
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;
|
|
||||||
if (v > eCInfo.MaxScore)
|
|
||||||
eCInfo.MaxScore = v;
|
|
||||||
avgTotal += v;//追加得分
|
|
||||||
}
|
|
||||||
//总分平均分
|
|
||||||
eCInfo.Average = avgTotal / eCInfo.PeopleCount;
|
|
||||||
//计算上线率
|
|
||||||
eCInfo.OnLineRate = (decimal)eCInfo.OnLineCount / (decimal)eCInfo.PeopleCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
insertTotalClassInfo.AddRange(insertClassInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
{ //计算年级上线率排名
|
|
||||||
var i = 0;
|
|
||||||
foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.OnLineRate)
|
|
||||||
.GroupBy(s => s.OnLineRate))
|
|
||||||
{
|
|
||||||
foreach (var u in item)
|
|
||||||
u.OnLineRanking = ++i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//计算年级平均分排名
|
|
||||||
i = 0;
|
|
||||||
foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.Average)
|
|
||||||
.GroupBy(s => s.Average))
|
|
||||||
{
|
|
||||||
foreach (var u in item)
|
|
||||||
u.AverageRank = ++i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//写入数据库
|
|
||||||
var baseDB = eUService.Context;
|
|
||||||
baseDB.Ado.BeginTran();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await baseDB.Deleteable<ExamClassInfo>().Where(s=>s.ExamId==exam.Id).ExecuteCommandAsync();
|
|
||||||
await baseDB.Insertable(insertTotalClassInfo).ExecuteCommandAsync();
|
|
||||||
baseDB.Ado.CommitTran();
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
baseDB.Ado.RollbackTran();
|
|
||||||
Oh.ModelError($"导入失败:写入数据时候出现了异常 [{ex.Message}] !");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 下载导入成绩模板
|
/// 下载导入成绩模板
|
||||||
|
|
@ -296,7 +183,6 @@ namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
School="例子学校[导入时候请删除]",
|
School="例子学校[导入时候请删除]",
|
||||||
Class="测试班级",
|
Class="测试班级",
|
||||||
ClassType="普通班级",
|
|
||||||
Grade="高2028",
|
Grade="高2028",
|
||||||
Student="学生姓名",
|
Student="学生姓名",
|
||||||
语文=80.5m,
|
语文=80.5m,
|
||||||
|
|
@ -359,5 +245,217 @@ namespace Learn.Archives.API.Controllers
|
||||||
}
|
}
|
||||||
return base.PageList(model);
|
return base.PageList(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 重新计算考试成绩排名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="examId">考试id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> RecalculateExamRankings(long examId)
|
||||||
|
{
|
||||||
|
if (examId == 0)
|
||||||
|
Oh.ModelError("传入了异常参数");
|
||||||
|
var exam = examService.GetById(examId);
|
||||||
|
if (exam is null)
|
||||||
|
Oh.ModelError("无效的考试");
|
||||||
|
await CalculatingTestResults(exam, examUserInfoService, schoolService, tagService);
|
||||||
|
return Ok();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取班级考试分段排名
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="examId">考试id</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IEnumerable<ExamClassTagReq>> ClassRanking(long examId,long classId)
|
||||||
|
{
|
||||||
|
if (examId == 0)
|
||||||
|
Oh.ModelError("传入异常参数");
|
||||||
|
if (! await examService.IsAnyAsync(s => s.Id == examId))
|
||||||
|
Oh.ModelError("无效的考试");
|
||||||
|
var arr = await classTagService.AsQueryable().Where(s => s.ExamId == examId && s.ClassId == classId)
|
||||||
|
.Select<ExamClassTagReq>()
|
||||||
|
.ToArrayAsync();
|
||||||
|
return arr.OrderBy(s => s.SubjectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[NonAction]
|
||||||
|
private Dictionary<SubjectEnum, decimal>? ImportExamInfoSubjectDic(ImportExamInfo info)
|
||||||
|
{
|
||||||
|
return new Dictionary<SubjectEnum, decimal>()
|
||||||
|
{
|
||||||
|
{ SubjectEnum.语文, info.语文},
|
||||||
|
{ SubjectEnum.数学, info.数学},
|
||||||
|
{ SubjectEnum.英语, info.英语},
|
||||||
|
{ SubjectEnum.物理, info.物理},
|
||||||
|
{ SubjectEnum.化学, info.化学},
|
||||||
|
{ SubjectEnum.生物, info.生物},
|
||||||
|
{ SubjectEnum.政治, info.政治},
|
||||||
|
{ SubjectEnum.历史, info.历史},
|
||||||
|
{ SubjectEnum.地理, info.地理},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
[NonAction]
|
||||||
|
private static decimal? SubjectScore(ExamUserInfo info, SubjectEnum? s)
|
||||||
|
{
|
||||||
|
switch (s)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
return info.AssignScore;
|
||||||
|
default:
|
||||||
|
if (info?.SubjectDic is null)
|
||||||
|
return -999;
|
||||||
|
return info.SubjectDic.ContainsKey(s.Value) ? info.SubjectDic?[s.Value] : -999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算考试成绩
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="exam"></param>
|
||||||
|
/// <param name="examUserInfoService"></param>
|
||||||
|
/// <param name="schoolService"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[NonAction]
|
||||||
|
public static async Task CalculatingTestResults(Exam exam, Repository<ExamUserInfo> eUService,
|
||||||
|
Repository<School> sService, Repository<ExamTags> tagService)
|
||||||
|
{
|
||||||
|
var userInfoArr = await eUService.AsQueryable()
|
||||||
|
.Where(s => s.ExamId == exam.Id)
|
||||||
|
.ToArrayAsync();
|
||||||
|
|
||||||
|
var insertTotalClassInfo = new List<ExamClassInfo>();
|
||||||
|
var insertTotalClassTag = new List<ExamClassTag>();
|
||||||
|
var eTagArr = await tagService.AsQueryable().Where(s => s.ExamId == exam.Id)
|
||||||
|
.ToArrayAsync();
|
||||||
|
var db = sService.Context;
|
||||||
|
foreach (var schoolArr in userInfoArr.GroupBy(s => s.SchoolId))
|
||||||
|
{
|
||||||
|
|
||||||
|
var school = await sService.GetFirstAsync(s => s.Id == schoolArr.Key);
|
||||||
|
var classArr = await db.Queryable<Classes>().Where(c => c.SchoolId == school.Id &&
|
||||||
|
c.GradeLevel == exam.GradeLevel &&
|
||||||
|
c.GraduationYear == exam.GradeYear && !c.DeleteState).ToArrayAsync();
|
||||||
|
|
||||||
|
foreach (var classUserArr in userInfoArr.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,
|
||||||
|
MaxScore = -99,
|
||||||
|
BaseSchoolScore = exam.BaseSchoolScore,
|
||||||
|
TestPaperType = exam.TestPaperType,
|
||||||
|
Type = exam.Type,
|
||||||
|
Average1 = exam.BaseSchoolScore,
|
||||||
|
};
|
||||||
|
insertTotalClassInfo.Add(eCInfo);
|
||||||
|
var avgTotal = 0m;
|
||||||
|
|
||||||
|
//todo 班级分段分析
|
||||||
|
var classTagDic = new Dictionary<long, ExamClassTag>();
|
||||||
|
foreach (var eUserInfo in classUserArr)
|
||||||
|
{
|
||||||
|
//上线人数
|
||||||
|
foreach (var item in eTagArr)
|
||||||
|
{
|
||||||
|
var subV = SubjectScore(eUserInfo, item.SubjectId);
|
||||||
|
if (!classTagDic.TryGetValue(item.Id, out ExamClassTag? tag))
|
||||||
|
{
|
||||||
|
tag = new ExamClassTag()
|
||||||
|
{
|
||||||
|
MaxScore = item.MaxScore,
|
||||||
|
MinScore = item.MinScore,
|
||||||
|
ClassId = classInfo.Id,
|
||||||
|
PeopleCount = eCInfo.PeopleCount,
|
||||||
|
ExamId = exam.Id,
|
||||||
|
ExamTagId = item.Id,
|
||||||
|
Name = item.TagName,
|
||||||
|
SubjectId = item.SubjectId
|
||||||
|
};
|
||||||
|
insertTotalClassTag.Add(tag);
|
||||||
|
classTagDic.Add(item.Id, tag);
|
||||||
|
}
|
||||||
|
//总分分段
|
||||||
|
if (subV >= item.MinScore && subV <= item.MaxScore)
|
||||||
|
{
|
||||||
|
tag.OnLineCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
var v = eUserInfo.AssignScore;
|
||||||
|
//最大小分
|
||||||
|
if (v < eCInfo.MinScore)
|
||||||
|
eCInfo.MinScore = v;
|
||||||
|
if (v > eCInfo.MaxScore)
|
||||||
|
eCInfo.MaxScore = v;
|
||||||
|
avgTotal += v;//追加得分
|
||||||
|
}
|
||||||
|
//总分平均分
|
||||||
|
eCInfo.Average = avgTotal / eCInfo.PeopleCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
//计算班级上线率排名
|
||||||
|
foreach (var examTagArr in insertTotalClassTag.GroupBy(s => s.ExamTagId))
|
||||||
|
{
|
||||||
|
i = 0;
|
||||||
|
foreach (var item in examTagArr.OrderByDescending(s => s.OnLineRate)
|
||||||
|
.GroupBy(s => s.OnLineRate))
|
||||||
|
{
|
||||||
|
foreach (var u in item)
|
||||||
|
u.OnLineRanking = ++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算年级平均分排名
|
||||||
|
i = 0;
|
||||||
|
foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.Average)
|
||||||
|
.GroupBy(s => s.Average))
|
||||||
|
{
|
||||||
|
foreach (var u in item)
|
||||||
|
u.AverageRank = ++i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//写入数据库
|
||||||
|
var baseDB = eUService.Context;
|
||||||
|
baseDB.Ado.BeginTran();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await baseDB.Deleteable<ExamClassInfo>().Where(s => s.ExamId == exam.Id).ExecuteCommandAsync();
|
||||||
|
await baseDB.Deleteable<ExamClassTag>().Where(s => s.ExamId == exam.Id).ExecuteCommandAsync();
|
||||||
|
await baseDB.Insertable(insertTotalClassInfo).ExecuteCommandAsync();
|
||||||
|
await baseDB.Insertable(insertTotalClassTag).ExecuteCommandAsync();
|
||||||
|
baseDB.Ado.CommitTran();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
baseDB.Ado.RollbackTran();
|
||||||
|
Oh.ModelError($"导入失败:写入数据时候出现了异常 [{ex.Message}] !");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,20 @@ namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
readonly Repository<Exam> baseService;
|
readonly Repository<Exam> baseService;
|
||||||
readonly Repository<School> schoolService;
|
readonly Repository<School> schoolService;
|
||||||
|
readonly Repository<ExamTags> tagService;
|
||||||
readonly Repository<ExamClassInfo> examClassInfoService;
|
readonly Repository<ExamClassInfo> examClassInfoService;
|
||||||
readonly Repository<ExamUserInfo> examUserInfoService;
|
readonly Repository<ExamUserInfo> examUserInfoService;
|
||||||
readonly LiveUserInfo userInfo;
|
readonly LiveUserInfo userInfo;
|
||||||
public ExamController(Repository<Exam> baseService, LiveUserInfo userInfo,
|
public ExamController(Repository<Exam> baseService, LiveUserInfo userInfo,
|
||||||
Repository<ExamClassInfo> examClassInfoService, Repository<ExamUserInfo> examUserInfoService,
|
Repository<ExamClassInfo> examClassInfoService, Repository<ExamUserInfo> examUserInfoService,
|
||||||
Repository<School> schoolService) : base(baseService)
|
Repository<School> schoolService, Repository<ExamTags> tagService) : base(baseService)
|
||||||
{
|
{
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
this.examClassInfoService = examClassInfoService;
|
this.examClassInfoService = examClassInfoService;
|
||||||
this.examUserInfoService = examUserInfoService;
|
this.examUserInfoService = examUserInfoService;
|
||||||
this.schoolService = schoolService;
|
this.schoolService = schoolService;
|
||||||
|
this.tagService = tagService;
|
||||||
}
|
}
|
||||||
public override Task<dynamic> PageList([FromBody] QueryRequestBase model)
|
public override Task<dynamic> PageList([FromBody] QueryRequestBase model)
|
||||||
{
|
{
|
||||||
|
|
@ -69,7 +71,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
}
|
}
|
||||||
var res =await base.Edit(model);
|
var res =await base.Edit(model);
|
||||||
if (res)
|
if (res)
|
||||||
await ExamClassInfoController.CalculatingTestResults(model, examUserInfoService, schoolService);
|
await ExamClassInfoController.CalculatingTestResults(model, examUserInfoService, schoolService, tagService);
|
||||||
return res ;
|
return res ;
|
||||||
}
|
}
|
||||||
public override async Task<bool> Del([FromBody] params long[] ids)
|
public override async Task<bool> Del([FromBody] params long[] ids)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
using Learn.Archives.API.Controllers.Dto;
|
||||||
|
using Learn.Archives.API.Expand;
|
||||||
|
using Learn.Archives.Core.Common;
|
||||||
|
using Learn.Archives.Core.Model;
|
||||||
|
using Learn.Archives.Core.Model.Dto;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
|
using UserCenter.Model;
|
||||||
|
using UserCenter.Model.Common;
|
||||||
|
using UserCenter.Model.Enum;
|
||||||
|
|
||||||
|
namespace Learn.Archives.API.Controllers
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 年级控制器
|
||||||
|
/// </summary>
|
||||||
|
public class ExamTagsController : BackController<ExamTags>
|
||||||
|
{
|
||||||
|
readonly Repository<ExamTags> baseService;
|
||||||
|
public ExamTagsController(Repository<ExamTags> baseService) : base(baseService)
|
||||||
|
{
|
||||||
|
this.baseService = baseService;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,9 +6,11 @@ using Learn.Archives.Core.Model.Dto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using UserCenter.Model;
|
using UserCenter.Model;
|
||||||
using UserCenter.Model.Common;
|
using UserCenter.Model.Common;
|
||||||
|
using UserCenter.Model.Enum;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Controllers
|
namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
|
|
@ -24,7 +26,7 @@ namespace Learn.Archives.API.Controllers
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
}
|
}
|
||||||
public override Task<dynamic> PageList([FromBody] QueryRequestBase model)
|
public override async Task<dynamic> PageList([FromBody] QueryRequestBase model)
|
||||||
{
|
{
|
||||||
var c = model.Conditions.FirstOrDefault(s => s.FieldName == "Grade");
|
var c = model.Conditions.FirstOrDefault(s => s.FieldName == "Grade");
|
||||||
if (c != null)
|
if (c != null)
|
||||||
|
|
@ -46,7 +48,18 @@ namespace Learn.Archives.API.Controllers
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return base.PageList(model);
|
var oldSer = model.OrderBy.ToEnum<SubjectEnum>();
|
||||||
|
if (oldSer != null)
|
||||||
|
{
|
||||||
|
model.OrderBy = "id";
|
||||||
|
var res = (PageResult<ExamUserInfo>)await base.PageList(model);
|
||||||
|
if (model.OrderByType == SqlSugar.OrderByType.Asc)
|
||||||
|
res.Data = res.Data.OrderBy(s => s.SubjectDic?[oldSer.Value]).ToList();
|
||||||
|
else
|
||||||
|
res.Data = res.Data.OrderByDescending(s => s.SubjectDic?[oldSer.Value]).ToList();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
return await base.PageList(model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,9 @@ using Mapster;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using MiniExcelLibs;
|
using MiniExcelLibs;
|
||||||
|
using SqlSugar;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using UserCenter.Model;
|
using UserCenter.Model;
|
||||||
|
|
@ -20,20 +22,22 @@ using UserCenter.Model.Enum;
|
||||||
namespace Learn.Archives.API.Controllers
|
namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 年级控制器
|
/// 学生接口
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class StudentController : BackController<Student>
|
public class StudentController : BackController<Student>
|
||||||
{
|
{
|
||||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||||
readonly Repository<Student> baseService;
|
readonly Repository<Student> baseService;
|
||||||
|
readonly Repository<Position> positionService;
|
||||||
readonly UserCenterService _userCenterService;
|
readonly UserCenterService _userCenterService;
|
||||||
readonly LiveUserInfo userInfo;
|
readonly LiveUserInfo userInfo;
|
||||||
public StudentController(Repository<Student> baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContextAccessor, UserCenterService userCenterService) : base(baseService)
|
public StudentController(Repository<Student> baseService, LiveUserInfo userInfo, IHttpContextAccessor httpContextAccessor, UserCenterService userCenterService, Repository<Position> positionService) : base(baseService)
|
||||||
{
|
{
|
||||||
this.baseService = baseService;
|
this.baseService = baseService;
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
_httpContextAccessor = httpContextAccessor;
|
_httpContextAccessor = httpContextAccessor;
|
||||||
_userCenterService = userCenterService;
|
_userCenterService = userCenterService;
|
||||||
|
this.positionService = positionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[NonAction]
|
[NonAction]
|
||||||
|
|
@ -54,6 +58,42 @@ namespace Learn.Archives.API.Controllers
|
||||||
Oh.ModelError("无效数据");
|
Oh.ModelError("无效数据");
|
||||||
return await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == uid);
|
return await baseService.AsQueryable().FirstAsync(s => s.UserCenterId == uid);
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取职位id
|
||||||
|
/// <para> 调用流程 用户中心->档案系统</para>
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<long[]> PosititonIds(PositionIdsReq[] data)
|
||||||
|
{
|
||||||
|
if (data == null || data.Count()==0)
|
||||||
|
Oh.ModelError("无效数据");
|
||||||
|
var query = new Expressionable<Position>();
|
||||||
|
foreach (var pos in data)
|
||||||
|
{
|
||||||
|
query = query.Or(q =>
|
||||||
|
q.SchoolId == pos.SchoolId &&
|
||||||
|
q.PositionType == pos.PositionType &&
|
||||||
|
q.GradeLevel == pos.GradeLevel &&
|
||||||
|
q.GraduationYear == pos.GraduationYear &&
|
||||||
|
q.PositionLevel == pos.PositionLevel
|
||||||
|
&&
|
||||||
|
(
|
||||||
|
// PositionLevel == 3:只匹配前三个字段
|
||||||
|
(pos.PositionLevel == 3) ||
|
||||||
|
// PositionLevel == 4:再加上 ClassId
|
||||||
|
(pos.PositionLevel == 4 && q.ClassId == pos.ClassId) ||
|
||||||
|
|
||||||
|
// PositionLevel == 5:再加上 ClassId + SubjectId
|
||||||
|
(pos.PositionLevel == 5 && q.ClassId == pos.ClassId && q.SubjectId == pos.SubjectId)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return await positionService.AsQueryable()
|
||||||
|
.Where(query.ToExpression())
|
||||||
|
.Select(p => p.Id).ToArrayAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 修改用户信息
|
/// 修改用户信息
|
||||||
|
|
@ -181,7 +221,6 @@ namespace Learn.Archives.API.Controllers
|
||||||
School = s.School,
|
School = s.School,
|
||||||
Grade = gStr,
|
Grade = gStr,
|
||||||
Class = s.Class,
|
Class = s.Class,
|
||||||
ClassType = s.ClassType??ClassTypeEnum.云校班.ToString(),
|
|
||||||
Phone = s.Phone,
|
Phone = s.Phone,
|
||||||
RealName = s.RealName,
|
RealName = s.RealName,
|
||||||
Stages = s.Grade.Contains("初") ? StudentStagesEnum.初中.ToString() : StudentStagesEnum.高中.ToString()
|
Stages = s.Grade.Contains("初") ? StudentStagesEnum.初中.ToString() : StudentStagesEnum.高中.ToString()
|
||||||
|
|
@ -262,7 +301,6 @@ namespace Learn.Archives.API.Controllers
|
||||||
School = s.School,
|
School = s.School,
|
||||||
Grade = gStr,
|
Grade = gStr,
|
||||||
Class = s.Class,
|
Class = s.Class,
|
||||||
ClassType = s.ClassType??ClassTypeEnum.云校班.ToString(),
|
|
||||||
ExamNo = s.Id.ToString(),
|
ExamNo = s.Id.ToString(),
|
||||||
Phone = s.Phone,
|
Phone = s.Phone,
|
||||||
RealName = s.RealName,
|
RealName = s.RealName,
|
||||||
|
|
@ -309,11 +347,10 @@ namespace Learn.Archives.API.Controllers
|
||||||
{
|
{
|
||||||
var resultList = new List<StudentInfoImport>() { new StudentInfoImport()
|
var resultList = new List<StudentInfoImport>() { new StudentInfoImport()
|
||||||
{
|
{
|
||||||
RealName = "导入规范[导入时请删除本列]",
|
RealName = "导入规范[导入时请删除本行]",
|
||||||
School = "必填:与系统匹配",
|
School = "必填:与系统匹配",
|
||||||
Grade = "必填:可选值\r\n[初一初二初三,高一高二高山]",
|
Grade = "必填:可选值\r\n[初一初二初三,高一高二高山]",
|
||||||
Class = "必填:与系统匹配\r\n格式:10班[数字+班]",
|
Class = "必填:与系统匹配\r\n格式:10班[数字+班]",
|
||||||
ClassType = "必填:可选值\r\n[云校班 海豚智学班 蓝鲸智库班 中职班 其他 雅思班 点阵笔班级 移动校园班级 智学班 ...]",
|
|
||||||
Status = "选填 可选值\r\n[就读,退出]",
|
Status = "选填 可选值\r\n[就读,退出]",
|
||||||
AmountRelief ="选填: 为0则视为 '未申请减免'",
|
AmountRelief ="选填: 为0则视为 '未申请减免'",
|
||||||
ReliefType ="选填: 建卡贫困户\r\n低保户\r\n教师子女 \r\n孤儿\r\n艺体生\r\n残疾学生\r\n领导特殊承诺减免\r\n领导同意的特殊贫困减免",
|
ReliefType ="选填: 建卡贫困户\r\n低保户\r\n教师子女 \r\n孤儿\r\n艺体生\r\n残疾学生\r\n领导特殊承诺减免\r\n领导同意的特殊贫困减免",
|
||||||
|
|
@ -340,12 +377,11 @@ namespace Learn.Archives.API.Controllers
|
||||||
new TeacherInfoImport()
|
new TeacherInfoImport()
|
||||||
{
|
{
|
||||||
Phone="必填",
|
Phone="必填",
|
||||||
RealName = "导入规范[导入时请删除本列]",
|
RealName = "导入规范[导入时请删除本行]",
|
||||||
UserType = "必填 可选值\r\n[年级主任,班主任,教师]",
|
UserType = "必填 可选值\r\n[年级主任,班主任,教师]",
|
||||||
School = "必填:与系统匹配",
|
School = "必填:与系统匹配",
|
||||||
Grade = "必填:可选值\r\n[初一初二初三,高一高二高山]",
|
Grade = "必填:可选值\r\n[初一初二初三,高一高二高山]",
|
||||||
Class = "必填:与系统匹配\r\n格式:10班[数字+班]\r\n任教类型是年级主任时不填",
|
Class = "必填:与系统匹配\r\n格式:10班[数字+班]\r\n任教类型是年级主任时不填",
|
||||||
ClassType = "必填:可选值\r\n[云校班 海豚智学班 蓝鲸智库班 中职班 其他 雅思班 点阵笔班级 移动校园班级 智学班 ...]\r\n任教类型是年级主任时不填",
|
|
||||||
Subject = "选填学科",
|
Subject = "选填学科",
|
||||||
ExamNo ="选填: 填写老师任职信息[不在授课架构中的职务]",
|
ExamNo ="选填: 填写老师任职信息[不在授课架构中的职务]",
|
||||||
}};
|
}};
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ using Learn.Archives.Core.Common;
|
||||||
using Learn.Archives.Core.Model.Dto;
|
using Learn.Archives.Core.Model.Dto;
|
||||||
using Learn.Archives.Core.Model;
|
using Learn.Archives.Core.Model;
|
||||||
using SqlSugar.IOC;
|
using SqlSugar.IOC;
|
||||||
|
using static System.Net.Mime.MediaTypeNames;
|
||||||
|
|
||||||
namespace Learn.Archives.API.Expand
|
namespace Learn.Archives.API.Expand
|
||||||
{
|
{
|
||||||
|
|
@ -50,8 +51,32 @@ namespace Learn.Archives.API.Expand
|
||||||
this.userInfo = userInfo;
|
this.userInfo = userInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 执行接口前文件做缓存处理
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="context"></param>
|
||||||
|
/// <exception cref="CustomException"></exception>
|
||||||
|
public void ExecutingFileCached(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
//特殊处理:ResultIgnore,不进行返回结果包装,原样输出
|
||||||
|
var endpoint = context.HttpContext.GetEndpoint();
|
||||||
|
// 直接返回原始结果,不封装
|
||||||
|
if (endpoint?.Metadata.GetMetadata<HttpLogEnable>() == null) return;
|
||||||
|
if (context.HttpContext.Request.HasFormContentType &&
|
||||||
|
context.HttpContext.Request.Form.Files != null &&
|
||||||
|
context.HttpContext.Request.Form.Files.Count() > 0)
|
||||||
|
{
|
||||||
|
context.HttpContext.Items["FileCached"]=
|
||||||
|
context.HttpContext.Request.Form.Files.Select(s =>
|
||||||
|
{
|
||||||
|
var stream = new MemoryStream();
|
||||||
|
s.CopyTo(stream);
|
||||||
|
stream.Position = 0;
|
||||||
|
return (s, stream);
|
||||||
|
}).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 执行接口前400 处理
|
/// 执行接口前400 处理
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
@ -132,43 +157,43 @@ namespace Learn.Archives.API.Expand
|
||||||
|
|
||||||
string request = null;
|
string request = null;
|
||||||
var logId = Yitter.IdGenerator.YitIdHelper.NextId();
|
var logId = Yitter.IdGenerator.YitIdHelper.NextId();
|
||||||
if (!context.Request.Method
|
if (!context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
|
||||||
.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
|
|
||||||
{
|
{
|
||||||
context.Request.EnableBuffering();
|
|
||||||
//记录请求参数
|
//记录请求参数
|
||||||
if (context.Request.Body.CanSeek)
|
if (context.Request.Body.CanSeek)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (context.Request.HasFormContentType && context.Request?.Form?.Files?.Count() > 0)
|
var fileArr = context.Items.ContainsKey("FileCached") ? context.Items["FileCached"] as (IFormFile file, MemoryStream stream)[] : null;
|
||||||
|
if (context.Request.HasFormContentType && fileArr != null)
|
||||||
{
|
{
|
||||||
// 设置保存目录(例如:项目根目录下的Uploads文件夹)
|
// 设置保存目录(例如:项目根目录下的Uploads文件夹)
|
||||||
string uploadsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadLogs", logId.ToString());
|
string uploadsFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UploadLogs", logId.ToString());
|
||||||
// 创建目录(如果不存在)
|
// 创建目录(如果不存在)
|
||||||
if (!Directory.Exists(uploadsFolder))
|
if (!Directory.Exists(uploadsFolder))
|
||||||
Directory.CreateDirectory(uploadsFolder);
|
Directory.CreateDirectory(uploadsFolder);
|
||||||
foreach (var file in context.Request.Form.Files)
|
foreach (var fileInfo in fileArr)
|
||||||
{
|
{
|
||||||
// 生成安全文件名(防止路径遍历攻击)
|
// 生成安全文件名(防止路径遍历攻击)
|
||||||
string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 5) + "_" + Path.GetFileName(file.FileName);
|
string uniqueFileName = Guid.NewGuid().ToString().Substring(0, 5) + "_" + Path.GetFileName(fileInfo.file.FileName);
|
||||||
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
|
|
||||||
// 保存文件
|
// 保存文件
|
||||||
using var stream = new FileStream(filePath, FileMode.Create);
|
using var stream = new FileStream(Path.Combine(uploadsFolder, uniqueFileName), FileMode.Create, FileAccess.Write);
|
||||||
await file.CopyToAsync(stream);
|
fileInfo.stream.Position = 0;
|
||||||
|
await fileInfo.stream.CopyToAsync(stream);
|
||||||
|
fileInfo.stream.Dispose();
|
||||||
}
|
}
|
||||||
request = $"请求体包含{context.Request.Form.Files.Count()}个文件 目录 {uploadsFolder}";
|
request = $"请求体包含{context.Request.Form.Files.Count()}个文件 目录 {uploadsFolder}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
context.Request.Body.Position = 0;
|
context.Request.Body.Position = 0;
|
||||||
using var sr = new StreamReader(context.Request.Body);
|
using var sr = new System.IO.StreamReader(context.Request.Body);
|
||||||
request = await sr.ReadToEndAsync();
|
request = await sr.ReadToEndAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
request = "处理请求日志时发生了错误 \r\n" + ex.ToString();
|
request = "处理请求入参时发生了错误 \r\n" + ex.ToString() + "\r\n 原有请求数据 " + request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +206,7 @@ namespace Learn.Archives.API.Expand
|
||||||
Request = request,
|
Request = request,
|
||||||
IP = context.Connection?.RemoteIpAddress?.ToString(),
|
IP = context.Connection?.RemoteIpAddress?.ToString(),
|
||||||
ResponseCode = result?.Code ?? -1,
|
ResponseCode = result?.Code ?? -1,
|
||||||
Response = result != null ? JsonSerializer.Serialize(result) : null,
|
Response = (result != null ? JsonSerializer.Serialize(result) : null) ,
|
||||||
Authorization = context.Request.Headers.ContainsKey("Authorization")
|
Authorization = context.Request.Headers.ContainsKey("Authorization")
|
||||||
? context.Request.Headers["Authorization"].ToString()
|
? context.Request.Headers["Authorization"].ToString()
|
||||||
: string.Empty,
|
: string.Empty,
|
||||||
|
|
@ -193,18 +218,12 @@ namespace Learn.Archives.API.Expand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override async void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 在Controller的Action执行前执行
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
public override void OnActionExecuting(ActionExecutingContext context)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
Executing400(context);
|
Executing400(context);
|
||||||
|
ExecutingFileCached(context);
|
||||||
base.OnActionExecuting(context);
|
base.OnActionExecuting(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,6 +233,8 @@ namespace Learn.Archives.API.Expand
|
||||||
/// <param name="context"></param>
|
/// <param name="context"></param>
|
||||||
public override async void OnActionExecuted(ActionExecutedContext context)
|
public override async void OnActionExecuted(ActionExecutedContext context)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BaseReturn<object>? res = ApiResultFormatting(context);
|
BaseReturn<object>? res = ApiResultFormatting(context);
|
||||||
|
|
|
||||||
|
|
@ -17,17 +17,6 @@ builder.Services.AddLogging(loggingBuilder =>
|
||||||
loggingBuilder.SetMinimumLevel(LogLevel.Warning); // 设置最小日志级别为 Warning
|
loggingBuilder.SetMinimumLevel(LogLevel.Warning); // 设置最小日志级别为 Warning
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddControllers(options =>
|
|
||||||
{
|
|
||||||
// 全局模型赋值默认值 和 统一返回格式处理
|
|
||||||
options.Filters.Add<HttpLogAttribute>();
|
|
||||||
})
|
|
||||||
.AddJsonOptions(options =>
|
|
||||||
{
|
|
||||||
|
|
||||||
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode
|
|
||||||
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰
|
|
||||||
});
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
builder.Services.AddSwaggerExpand("学校档案系统");
|
builder.Services.AddSwaggerExpand("学校档案系统");
|
||||||
builder.Configuration.AddAppConfig(args);
|
builder.Configuration.AddAppConfig(args);
|
||||||
|
|
@ -43,6 +32,17 @@ builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
builder.Services.AddControllers(options =>
|
||||||
|
{
|
||||||
|
// 全局模型赋值默认值 和 统一返回格式处理
|
||||||
|
options.Filters.Add<HttpLogAttribute>();
|
||||||
|
})
|
||||||
|
.AddJsonOptions(options =>
|
||||||
|
{
|
||||||
|
|
||||||
|
options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);//中文转换时不使用Unicode
|
||||||
|
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;// 默认小驼峰 null 大驼峰
|
||||||
|
});
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
AppCommon.Services = app.Services;
|
AppCommon.Services = app.Services;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
"OtherDBArr": [
|
"OtherDBArr": [
|
||||||
{
|
{
|
||||||
"ConfigId": 1001, //用户中心
|
"ConfigId": 1001, //用户中心
|
||||||
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=usercenter;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=usercenter_v1;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
||||||
"SqlType": "MySql"
|
"SqlType": "MySql"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
"DB": {
|
"DB": {
|
||||||
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=learn.archives;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=learn.archives;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
||||||
"SqlType": "MySql",
|
"SqlType": "MySql",
|
||||||
"UpdateTable": false
|
"UpdateTable": true
|
||||||
},
|
},
|
||||||
"AuthKey": {
|
"AuthKey": {
|
||||||
"Secret": "9FAB7AC7-F1DB-4C56-B84F-044055A34AF2",
|
"Secret": "9FAB7AC7-F1DB-4C56-B84F-044055A34AF2",
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
{
|
{
|
||||||
"ConfigId": 1001, //用户中心
|
"ConfigId": 1001, //用户中心
|
||||||
//"ConnectionString": "AllowLoadLocalInfile=true;Server=192.168.2.9;User ID=root;Password=qwe123!@#;Port=3306;Database=usercenter;CharSet=utf8mb4;pooling=true;SslMode=None;",
|
//"ConnectionString": "AllowLoadLocalInfile=true;Server=192.168.2.9;User ID=root;Password=qwe123!@#;Port=3306;Database=usercenter;CharSet=utf8mb4;pooling=true;SslMode=None;",
|
||||||
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=usercenter;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
"ConnectionString": "AllowLoadLocalInfile=true;Server=58.17.132.2;User ID=marking;Password=qwe123!@#;Port=3306;Database=usercenter_v1;CharSet=utf8mb4;Port=43306;pooling=true;SslMode=None;",
|
||||||
"SqlType": "MySql"
|
"SqlType": "MySql"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ namespace Learn.Archives.Core.Common
|
||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context)
|
public async Task InvokeAsync(HttpContext context)
|
||||||
{
|
{
|
||||||
|
if (!context.Request.Body.CanSeek)
|
||||||
|
context.Request.EnableBuffering(); // 允许重新读取请求体
|
||||||
|
|
||||||
if (context.Request.Path.StartsWithSegments("/swagger")
|
if (context.Request.Path.StartsWithSegments("/swagger")
|
||||||
&& (context.Request.Path.Value?.Contains("swagger.json") ?? true))
|
&& (context.Request.Path.Value?.Contains("swagger.json") ?? true))
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +39,6 @@ namespace Learn.Archives.Core.Common
|
||||||
|
|
||||||
if (await IsAuthorized(usernamePassword[0], usernamePassword[1]))
|
if (await IsAuthorized(usernamePassword[0], usernamePassword[1]))
|
||||||
{
|
{
|
||||||
|
|
||||||
await _next(context);
|
await _next(context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,6 @@
|
||||||
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
<PackageReference Include="SqlSugar.IOC" Version="2.0.0" />
|
||||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
|
<PackageReference Include="SqlSugarCore" Version="5.1.4.170" />
|
||||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||||
<PackageReference Include="UserCenter.Model" Version="1.4.3" />
|
<PackageReference Include="UserCenter.Model" Version="1.4.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Learn.Archives.Core.Model.Dto
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -51,7 +51,7 @@ namespace Learn.Archives.Core.Model.Dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? ExecutionTime { get; set; }
|
public DateTime? ExecutionTime { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 操作人 [后台自动赋值提交人名称]
|
/// 操作人
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string? Operator { get; set; }
|
public string? Operator { get; set; }
|
||||||
public string? ExecutionTimeStr => ExecutionTime?.ToString("yyyy-MM-dd");
|
public string? ExecutionTimeStr => ExecutionTime?.ToString("yyyy-MM-dd");
|
||||||
|
|
@ -86,6 +86,10 @@ namespace Learn.Archives.Core.Model.Dto
|
||||||
/// 解决时间
|
/// 解决时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTime? EndTime { get; set; }
|
public DateTime? EndTime { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 反馈问题的执行记录
|
||||||
|
/// </summary>
|
||||||
|
public RecordDto[]? RecordArr { get; set; }
|
||||||
public string? EndTimeStr=> EndTime?.ToString("yyyy-MM-dd");
|
public string? EndTimeStr=> EndTime?.ToString("yyyy-MM-dd");
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,38 @@ using UserCenter.Model;
|
||||||
|
|
||||||
namespace Learn.Archives.Core.Model.Dto
|
namespace Learn.Archives.Core.Model.Dto
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
public class PositionIdsReq
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 学校编号
|
||||||
|
/// </summary>
|
||||||
|
public long SchoolId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 年级
|
||||||
|
/// </summary>
|
||||||
|
public string GradeLevel { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 毕业届
|
||||||
|
/// </summary>
|
||||||
|
public int GraduationYear { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 班级编号
|
||||||
|
/// </summary>
|
||||||
|
public long? ClassId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 职级
|
||||||
|
/// </summary>
|
||||||
|
public int PositionLevel { get; set; }
|
||||||
|
public int? PositionType { get; set; } = 2;
|
||||||
|
/// <summary>
|
||||||
|
/// 科目
|
||||||
|
/// </summary>
|
||||||
|
public int? SubjectId { get; set; }
|
||||||
|
}
|
||||||
public class TeacherInfoImportError : TeacherInfoImport
|
public class TeacherInfoImportError : TeacherInfoImport
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -51,11 +83,6 @@ namespace Learn.Archives.Core.Model.Dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcelColumn(Name = "班级", Width = 15)]
|
[ExcelColumn(Name = "班级", Width = 15)]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 班级类型
|
|
||||||
/// </summary>
|
|
||||||
[ExcelColumn(Name = "班级类型", Width = 20)]
|
|
||||||
public string ClassType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 科目
|
/// 科目
|
||||||
|
|
@ -129,11 +156,6 @@ namespace Learn.Archives.Core.Model.Dto
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcelColumn(Name="班级", Width = 15)]
|
[ExcelColumn(Name="班级", Width = 15)]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 班级
|
|
||||||
/// </summary>
|
|
||||||
[ExcelColumn(Name="班级类型", Width = 20)]
|
|
||||||
public string ClassType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 减免金额
|
/// 减免金额
|
||||||
|
|
@ -263,11 +285,6 @@ namespace Learn.Archives.Core.Model.Dto
|
||||||
[ExcelColumn(Name="班级")]
|
[ExcelColumn(Name="班级")]
|
||||||
public string Class { get; set; }
|
public string Class { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 班级
|
|
||||||
/// </summary>
|
|
||||||
[ExcelColumn(Name="班级类型")]
|
|
||||||
public string ClassType { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 科目
|
/// 科目
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ExcelColumn(Name="科目")]
|
[ExcelColumn(Name="科目")]
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@ namespace Learn.Archives.Core.Model
|
||||||
public string? _grade;
|
public string? _grade;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 年级
|
/// 年级
|
||||||
|
/// <para>AOP自动转换年级</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[SugarColumn(IsIgnore = true)]
|
[SugarColumn(IsIgnore = true)]
|
||||||
public string Grade
|
public string Grade
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Learn.Archives.Core.Model.Enum;
|
using Learn.Archives.Core.Model.Dto;
|
||||||
|
using Learn.Archives.Core.Model.Enum;
|
||||||
using Learn.Archives.Core.Model.Interface;
|
using Learn.Archives.Core.Model.Interface;
|
||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
@ -71,18 +72,19 @@ namespace Learn.Archives.Core.Model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int GradeYear { get; set; }
|
public int GradeYear { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 上线率 考试排名
|
///// 上线率 考试排名
|
||||||
/// </summary>
|
///// </summary>
|
||||||
public decimal OnLineRanking { get; set; }
|
//public decimal OnLineRanking { get; set; }
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 上线率
|
///// 上线率
|
||||||
/// </summary>
|
///// </summary>
|
||||||
public decimal OnLineRate { get; set; }
|
//public decimal OnLineRate { get; set; }
|
||||||
/// <summary>
|
///// <summary>
|
||||||
/// 上线人数
|
///// 上线人数
|
||||||
/// </summary>
|
///// </summary>
|
||||||
public int OnLineCount { get; set; }
|
//public int OnLineCount { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 参加人数
|
/// 参加人数
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
using Learn.Archives.Core.Model.Dto;
|
||||||
|
using Learn.Archives.Core.Model.Enum;
|
||||||
|
using Learn.Archives.Core.Model.Interface;
|
||||||
|
using SqlSugar;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text.Json;
|
||||||
|
using UserCenter.Model;
|
||||||
|
using UserCenter.Model.Common;
|
||||||
|
using UserCenter.Model.Enum;
|
||||||
|
using UserCenter.Model.Interface;
|
||||||
|
|
||||||
|
namespace Learn.Archives.Core.Model
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 班级考试详情
|
||||||
|
/// </summary>
|
||||||
|
[SugarTable("examclasstag")]
|
||||||
|
public class ExamClassTag : EntityBaseId, IDB
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 考试Id
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 20)]
|
||||||
|
public long ExamId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 班级id
|
||||||
|
/// </summary>
|
||||||
|
public long ClassId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 考试标签id
|
||||||
|
/// </summary>
|
||||||
|
public long ExamTagId { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 标签名称
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分段所属学科
|
||||||
|
/// <para>可空 空即为总分分段</para>
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public SubjectEnum? SubjectId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最小分值
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(DecimalDigits = 2)]
|
||||||
|
public decimal MinScore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大分值
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(DecimalDigits = 2)]
|
||||||
|
public decimal MaxScore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 上线率 考试排名
|
||||||
|
/// </summary>
|
||||||
|
public int OnLineRanking { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 上线率
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsIgnore = true)]
|
||||||
|
public decimal OnLineRate => (decimal)OnLineCount / (decimal)PeopleCount;
|
||||||
|
/// <summary>
|
||||||
|
/// 总人数
|
||||||
|
/// </summary>
|
||||||
|
public int PeopleCount { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 上线人数
|
||||||
|
/// </summary>
|
||||||
|
public int OnLineCount { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; } = DateTime.Now;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using UserCenter.Model;
|
||||||
|
using UserCenter.Model.Interface;
|
||||||
|
using SqlSugar;
|
||||||
|
using UserCenter.Model.Enum;
|
||||||
|
using Learn.Archives.Core.Model.Interface;
|
||||||
|
|
||||||
|
namespace Learn.Archives.Core.Model
|
||||||
|
{
|
||||||
|
///<summary>
|
||||||
|
/// 考试成绩分段表
|
||||||
|
///</summary>
|
||||||
|
[SugarTable("examtags")]
|
||||||
|
public partial class ExamTags : EntityBaseId, IDB
|
||||||
|
{
|
||||||
|
public ExamTags()
|
||||||
|
{
|
||||||
|
|
||||||
|
this.IsDefault = Convert.ToInt32("0");
|
||||||
|
this.CreateTime = DateTime.Now;
|
||||||
|
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsPrimaryKey = true, IsIdentity = true)]
|
||||||
|
public override long Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 考试编号
|
||||||
|
/// </summary>
|
||||||
|
public long ExamId { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 分段所属学科
|
||||||
|
/// <para>可空 空即为总分分段</para>
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public SubjectEnum? SubjectId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最小分值
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(DecimalDigits = 2)]
|
||||||
|
public decimal MinScore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大分值
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(DecimalDigits = 2)]
|
||||||
|
public decimal MaxScore { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 标签名称
|
||||||
|
/// </summary>
|
||||||
|
public string TagName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 是否为默认标签 0:否 1:是
|
||||||
|
/// </summary>
|
||||||
|
public int IsDefault { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime CreateTime { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -89,6 +89,12 @@ namespace Learn.Archives.Core.Model
|
||||||
[SugarColumn(IsNullable = true, Length = 1000)]
|
[SugarColumn(IsNullable = true, Length = 1000)]
|
||||||
public string? ClassMeeting { get; set; }
|
public string? ClassMeeting { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 预计解决时间
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public DateTime? EndTime { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 反馈问题数量
|
/// 反馈问题数量
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue