dev #9

Merged
hy merged 11 commits from dev into master 2025-08-26 20:11:08 +08:00
16 changed files with 302 additions and 79 deletions

View File

@ -17,7 +17,7 @@ namespace Learn.Archives.API.Controllers.Dto
/// <summary> /// <summary>
/// 导入的错误结果 /// 导入的错误结果
/// </summary> /// </summary>
public class ImportExamInfoError: ImportExamInfo public class ImportExamInfoError : ImportExamInfo
{ {
/// <summary> /// <summary>
/// 学校 /// 学校
@ -25,10 +25,10 @@ namespace Learn.Archives.API.Controllers.Dto
[ExcelColumnName("错误信息")] [ExcelColumnName("错误信息")]
public string? Error { get; set; } public string? Error { get; set; }
} }
/// <summary> /// <summary>
/// 导入考试成绩 /// 导入考试成绩
/// </summary> /// </summary>
public class ImportExamInfo public class ImportExamInfo
{ {
/// <summary> /// <summary>
/// 学校 /// 学校
@ -117,6 +117,12 @@ namespace Learn.Archives.API.Controllers.Dto
/// </summary> /// </summary>
[ExcelColumnName("赋分后总分")] [ExcelColumnName("赋分后总分")]
public decimal { get; set; } public decimal { get; set; }
/// <summary>
/// 总分资源校排名
/// </summary>
[ExcelColumn(Name="赋分总分资源校排名",Width =20)]
public int { get; set; }
} }
public class RestartEntryDto public class RestartEntryDto

View File

@ -7,11 +7,13 @@ using Learn.Archives.Core.Model.Dto;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs; using MiniExcelLibs;
using System.Buffers.Text;
using System.Diagnostics; using System.Diagnostics;
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; using UserCenter.Model.Enum;
using static System.Net.Mime.MediaTypeNames;
namespace Learn.Archives.API.Controllers namespace Learn.Archives.API.Controllers
{ {
@ -79,19 +81,24 @@ namespace Learn.Archives.API.Controllers
if (dataList == null || dataList.Count() == 0) if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据"); Oh.ModelError("导入失败:无有效数据");
//todo
//处理数据 //处理数据
var errorExcelInfo = new List<ImportExamInfoError>(); var errorExcelInfo = new List<ImportExamInfoError>();
var insertUserInfo = new List<ExamUserInfo>(); var insertUserInfo = new List<ExamUserInfo>();
var insertClassInfo = new List<ExamClassInfo>(); var insertClassInfo = new List<ExamClassInfo>();
var oldUidAr = await examUserInfoService.AsQueryable()
.Where(s => s.ExamId == exam.Id)
.Select(s=>s.UserId)
.ToArrayAsync();
var oldUidHash = oldUidAr.ToHashSet();
var db = schoolService.Context; var db = schoolService.Context;
SqlSugarExpand.SetDbAop(db);
foreach (var schoolArr in dataList.GroupBy(s => s.School)) foreach (var schoolArr in dataList.GroupBy(s => s.School))
{ {
var school = await schoolService.GetFirstAsync(s => s.Name == schoolArr.Key); var school = await schoolService.GetFirstAsync(s => s.Name == schoolArr.Key);
if (school == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 未找到!"); if (school == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 未找到!");
var gradeInfo = GradeHelper.GetStudentGradeBaseByGrade(schoolArr.First().Grade); var gradeInfo = GradeHelper.GetStudentGradeBaseByGrade(schoolArr.First().Grade);
if (gradeInfo == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 年级[{schoolArr.First().Grade}]不符合规范!"); if (gradeInfo == null) Oh.ModelError($"导入失败:学校 [{schoolArr.Key}] 年级[{schoolArr.First().Grade}]不符合规范!");
if(exam.GradeLevel != gradeInfo.GradeLevel || exam.GradeYear != gradeInfo.GradeYear)
Oh.ModelError($"导入失败:导入年级[{schoolArr.First().Grade}] 与 考试年级不匹配!");
//学校下的所属班级 //学校下的所属班级
var classArr = await db.Queryable<Classes>().Where(c => c.SchoolId == school.Id && var classArr = await db.Queryable<Classes>().Where(c => c.SchoolId == school.Id &&
c.GradeLevel == gradeInfo.GradeLevel && c.GradeLevel == gradeInfo.GradeLevel &&
@ -135,6 +142,12 @@ namespace Learn.Archives.API.Controllers
return null; return null;
} }
var uid = userDic[name]; var uid = userDic[name];
if(oldUidHash!=null &&oldUidHash.Contains((long)uid))
{
s.Error = "此学生已经在考试中已经录入过成绩";
errorExcelInfo.Add(s);
return null;
}
return new ExamUserInfo() return new ExamUserInfo()
{ {
ExamId = exam.Id, ExamId = exam.Id,
@ -149,13 +162,50 @@ namespace Learn.Archives.API.Controllers
Type = exam.Type, Type = exam.Type,
SubjectDic = sub, SubjectDic = sub,
AssignScore = s., AssignScore = s.,
AssignRanking = 0, AssignRanking = s.,
}; };
}).ToList(); }).ToList();
insertUserInfo.AddRange(userList); insertUserInfo.AddRange(userList);
insertUserInfo = insertUserInfo.Where(s => s != null).ToList(); insertUserInfo = insertUserInfo.Where(s => s != null).ToList();
foreach (var classUserArr in insertUserInfo.GroupBy(s => s.ClassId)) };
if (errorExcelInfo.Count != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"错误考试信息{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//写入数据库
await examUserInfoService.AsInsertable(insertUserInfo).ExecuteCommandAsync();
await CalculatingTestResults(exam,examUserInfoService,schoolService);
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 classInfo = classArr.First(s => s.Id == classUserArr.Key);
var eCInfo = new ExamClassInfo() var eCInfo = new ExamClassInfo()
@ -170,9 +220,8 @@ namespace Learn.Archives.API.Controllers
GradeYear = classInfo.GraduationYear, GradeYear = classInfo.GraduationYear,
PeopleCount = classUserArr.Count(), PeopleCount = classUserArr.Count(),
MinScore = int.MaxValue, MinScore = int.MaxValue,
EntryPersonId = userInfo.Id, MaxScore = -99,
BaseSchoolScore = exam.BaseSchoolScore, BaseSchoolScore = exam.BaseSchoolScore,
EntryPerson = userInfo.Name,
TestPaperType = exam.TestPaperType, TestPaperType = exam.TestPaperType,
Type = exam.Type, Type = exam.Type,
Average1 = exam.BaseSchoolScore, Average1 = exam.BaseSchoolScore,
@ -183,12 +232,12 @@ namespace Learn.Archives.API.Controllers
{ {
var v = eUserInfo.AssignScore; var v = eUserInfo.AssignScore;
//上线人数 //上线人数
if (v>=exam.ScoreLine) if (v >= exam.ScoreLine)
eCInfo.OnLineCount ++; eCInfo.OnLineCount++;
//最大小分 //最大小分
if (v < eCInfo.MinScore) if (v < eCInfo.MinScore)
eCInfo.MinScore = v; eCInfo.MinScore = v;
else if(v > eCInfo.MaxScore) if (v > eCInfo.MaxScore)
eCInfo.MaxScore = v; eCInfo.MaxScore = v;
avgTotal += v;//追加得分 avgTotal += v;//追加得分
} }
@ -196,22 +245,14 @@ namespace Learn.Archives.API.Controllers
eCInfo.Average = avgTotal / eCInfo.PeopleCount; eCInfo.Average = avgTotal / eCInfo.PeopleCount;
//计算上线率 //计算上线率
eCInfo.OnLineRate = (decimal)eCInfo.OnLineCount / (decimal)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;
}
} }
}; insertTotalClassInfo.AddRange(insertClassInfo);
}
{ //计算年级上线率排名 { //计算年级上线率排名
var i = 0; var i = 0;
foreach (var item in insertClassInfo.OrderByDescending(s => s.OnLineRate) foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.OnLineRate)
.GroupBy(s => s.OnLineRate)) .GroupBy(s => s.OnLineRate))
{ {
foreach (var u in item) foreach (var u in item)
@ -220,25 +261,21 @@ namespace Learn.Archives.API.Controllers
//计算年级平均分排名 //计算年级平均分排名
i = 0; i = 0;
foreach (var item in insertClassInfo.OrderByDescending(s => s.Average) foreach (var item in insertTotalClassInfo.OrderByDescending(s => s.Average)
.GroupBy(s => s.Average)) .GroupBy(s => s.Average))
{ {
foreach (var u in item) foreach (var u in item)
u.AverageRank = ++i; u.AverageRank = ++i;
} }
} }
if (errorExcelInfo.Count != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"错误考试信息{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//写入数据库 //写入数据库
var baseDB = baseService.Context; var baseDB = eUService.Context;
baseDB.Ado.BeginTran(); baseDB.Ado.BeginTran();
try try
{ {
await baseDB.Insertable(insertUserInfo).ExecuteCommandAsync(); await baseDB.Deleteable<ExamClassInfo>().Where(s=>s.ExamId==exam.Id).ExecuteCommandAsync();
await baseDB.Insertable(insertClassInfo).ExecuteCommandAsync(); await baseDB.Insertable(insertTotalClassInfo).ExecuteCommandAsync();
baseDB.Ado.CommitTran(); baseDB.Ado.CommitTran();
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -246,7 +283,6 @@ namespace Learn.Archives.API.Controllers
Oh.ModelError($"导入失败:写入数据时候出现了异常 [{ex.Message}] !"); Oh.ModelError($"导入失败:写入数据时候出现了异常 [{ex.Message}] !");
} }
return Ok();
} }
/// <summary> /// <summary>

View File

@ -3,11 +3,13 @@ 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 Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Diagnostics; using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
using UserCenter.Model; using UserCenter.Model;
using UserCenter.Model.Common;
namespace Learn.Archives.API.Controllers namespace Learn.Archives.API.Controllers
{ {
@ -17,17 +19,59 @@ namespace Learn.Archives.API.Controllers
public class ExamController : BackController<Exam> public class ExamController : BackController<Exam>
{ {
readonly Repository<Exam> baseService; readonly Repository<Exam> baseService;
readonly Repository<School> schoolService;
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, Repository<ExamClassInfo> examClassInfoService, Repository<ExamUserInfo> examUserInfoService) : base(baseService) public ExamController(Repository<Exam> baseService, LiveUserInfo userInfo,
Repository<ExamClassInfo> examClassInfoService, Repository<ExamUserInfo> examUserInfoService,
Repository<School> schoolService) : 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;
} }
public override Task<dynamic> 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);
}
public override async Task<bool> Edit([FromBody] Exam model)
{
if (!string.IsNullOrEmpty(model._grade))
{
var g = GradeHelper.GetStudentGradeBaseByGrade(model._grade);
model.GradeLevel = g.GradeLevel;
model.GradeYear = g.GradeYear;
}
var res =await base.Edit(model);
if (res)
await ExamClassInfoController.CalculatingTestResults(model, examUserInfoService, schoolService);
return res ;
}
public override async Task<bool> Del([FromBody] params long[] ids) public override async Task<bool> Del([FromBody] params long[] ids)
{ {
if (ids.Length > 1) if (ids.Length > 1)

View File

@ -2,11 +2,13 @@
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 Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Diagnostics; using System.Diagnostics;
using System.Security.Claims; using System.Security.Claims;
using UserCenter.Model; using UserCenter.Model;
using UserCenter.Model.Common;
namespace Learn.Archives.API.Controllers namespace Learn.Archives.API.Controllers
{ {
@ -22,5 +24,29 @@ 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)
{
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);
}
} }
} }

View File

@ -165,6 +165,12 @@ namespace Learn.Archives.API.Controllers
var adminArr = await adminService.AsQueryable() var adminArr = await adminService.AsQueryable()
.Where(s => adminNameArr.Contains(s.Name)) .Where(s => adminNameArr.Contains(s.Name))
.Select(s => s.Name).ToArrayAsync(); .Select(s => s.Name).ToArrayAsync();
if (adminArr == null || adminArr.Length!= adminNameArr.Length)
{
imp.Error = $"赴校人员未能完全识别成功";
errorExcelInfo.Add(imp);
continue;
}
var qStr = new Dictionary<FeedbackQuestionTypeEnum, (string Questions, string Solutions)>() var qStr = new Dictionary<FeedbackQuestionTypeEnum, (string Questions, string Solutions)>()
{ {
{FeedbackQuestionTypeEnum.,(imp.Q学校领导班子,imp.P学校领导班子) }, {FeedbackQuestionTypeEnum.,(imp.Q学校领导班子,imp.P学校领导班子) },
@ -255,8 +261,6 @@ namespace Learn.Archives.API.Controllers
}; };
business.SolutionEnd = business.SolutionRecord.EndRecordTime != null; business.SolutionEnd = business.SolutionRecord.EndRecordTime != null;
insertInfo.Add(business); insertInfo.Add(business);
}; };
if (errorExcelInfo.Count != 0) if (errorExcelInfo.Count != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel" return File(errorExcelInfo.ExportExcel(), "application/ms-excel"
@ -292,7 +296,22 @@ namespace Learn.Archives.API.Controllers
//todo完善数据转换 //todo完善数据转换
var resultList = new List<SchoolBusinessImport>() { new SchoolBusinessImport() { } }; var resultList = new List<SchoolBusinessImport>() { new SchoolBusinessImport()
{
School="必填 与系统对应",
Grade="必填 : 初一/高一/初2025",
IsDiscussion="是/否",
IsClassMeeting="是/否",
Remark="选填 备注",
ClassMeeting ="选填 开展班会情况",
Discussion ="选填 开展会谈情况",
Solution="选填 需求/方案的描述",
Users="必填: 例 用户1,用户2 与系统中用户名称对应",
Record="选填 格式[时间:记录内容;] \r\n 例 2025年9月11日执行了第一次沟通\r\n2025年9月12日执行了第二次沟通沟通非常顺畅",
EndRecord="选填 格式 [时间:记录内容]\r\n 例 2025年9月13日已经顺利落地了解决方案",
Q学校领导班子="例子: 问题1问题内容问题2问题内容2",
P学校领导班子="例子: 问题1问题解决方法问题2问题解决方法2",
} };
return File(resultList.ExportExcel(), "application/ms-excel", "导入赴校信息模板.xlsx"); return File(resultList.ExportExcel(), "application/ms-excel", "导入赴校信息模板.xlsx");
} }

View File

@ -1,4 +1,5 @@
using Aliyun.OSS; using Aliyun.OSS;
using Dm;
using Learn.Archives.API.Controllers.Dto; 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;
@ -97,8 +98,8 @@ namespace Learn.Archives.API.Controllers
if (!exDataDic.ContainsKey(item.Id)) continue; if (!exDataDic.ContainsKey(item.Id)) continue;
var ex = exDataDic[item.Id].First(); var ex = exDataDic[item.Id].First();
item.Status = ex.Status; item.Status = ex.Status;
item.ExitTime = ex.ExitTime?.ToString("yyyy-MM-dd")??string.Empty; item.ExitTime = ex.ExitTime==null? string.Empty : ex.ExitTime?.ToString("yyyy-MM-dd");
item.JoinTime = ex.JoinTime?.ToString("yyyy-MM-dd") ?? string.Empty; item.JoinTime = ex.JoinTime == null ? string.Empty : ex.JoinTime?.ToString("yyyy-MM-dd");
item.AmountRelief = ex.AmountRelief; item.AmountRelief = ex.AmountRelief;
item.ReliefApplication = ex.ReliefApplication; item.ReliefApplication = ex.ReliefApplication;
@ -138,9 +139,19 @@ namespace Learn.Archives.API.Controllers
if (dataList == null || dataList.Count() == 0) if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据"); Oh.ModelError("导入失败:无有效数据");
var insertInfo = new List<Student>(); var insertInfo = new List<Student>();
var impError = new List<TeacherInfoImportError>();
var userCenterImp = new List<UserExcelExportData>(); var userCenterImp = new List<UserExcelExportData>();
foreach (var s in dataList) foreach (var s in dataList)
{ {
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum<GradeEnum>() == null) //无效的传入年级
{
s.ErrorMsg = "无效的年级 例如[初一/初2028] [年级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
userCenterImp.Add(new UserExcelExportData() userCenterImp.Add(new UserExcelExportData()
{ {
UserType = s.UserType, UserType = s.UserType,
@ -148,7 +159,7 @@ namespace Learn.Archives.API.Controllers
Subject = s.Subject, Subject = s.Subject,
ExamNo = s.ExamNo, ExamNo = s.ExamNo,
School = s.School, School = s.School,
Grade = s.Grade, Grade = gStr,
Class = s.Class, Class = s.Class,
ClassType = s.ClassType, ClassType = s.ClassType,
Phone = s.Phone, Phone = s.Phone,
@ -157,11 +168,14 @@ namespace Learn.Archives.API.Controllers
}); });
} }
//如果有错误数据则返回excel
if (impError.Count() != 0)
return File(impError.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//调用 用户中心 导入接口 //调用 用户中心 导入接口
var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp); var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp);
//处理数据 //处理数据
var errorExcelInfo = importRes.ErrorExcelExport.Select(s => s.Adapt<StudentInfoImportError>()); var errorExcelInfo = importRes.ErrorExcelExport.Select(s => s.Adapt<TeacherInfoImportError>());
//如果有错误数据则返回excel //如果有错误数据则返回excel
if (errorExcelInfo.Count() != 0) if (errorExcelInfo.Count() != 0)
return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx"); return File(errorExcelInfo.ExportExcel(), "application/ms-excel", $"导入错误的老师{DateTime.Now.ToString("MMddHHmm")}.xlsx");
@ -196,9 +210,18 @@ namespace Learn.Archives.API.Controllers
if (dataList == null || dataList.Count() == 0) if (dataList == null || dataList.Count() == 0)
Oh.ModelError("导入失败:无有效数据"); Oh.ModelError("导入失败:无有效数据");
var insertInfo = new List<Student>(); var insertInfo = new List<Student>();
var impError = new List<StudentInfoImportError>();
var userCenterImp = new List<UserExcelExportData>(); var userCenterImp = new List<UserExcelExportData>();
foreach (var s in dataList) foreach (var s in dataList)
{ {
var ginfo = GradeHelper.GetStudentGradeBaseByGrade(s.Grade);
var gStr = GradeHelper.GetGrade(ginfo.GradeLevel, ginfo.GradeYear);
if (gStr.ToEnum<GradeEnum>() == null) //无效的传入年级
{
s.ErrorMsg = "无效的年级 例如[初一/初2028] [年级范围应当是当前有效的就读年级]";
impError.Add(s);
continue;
}
insertInfo.Add(new Student() insertInfo.Add(new Student()
{ {
AmountRelief = decimal.TryParse(s.AmountRelief,out decimal v)?v:0, AmountRelief = decimal.TryParse(s.AmountRelief,out decimal v)?v:0,
@ -210,13 +233,14 @@ namespace Learn.Archives.API.Controllers
ReliefApplication=s.ReliefApplication?.Contains("已申请")??false, ReliefApplication=s.ReliefApplication?.Contains("已申请")??false,
ReliefSubTime = s.ReliefSubTime, ReliefSubTime = s.ReliefSubTime,
ReliefType =s.ReliefType, ReliefType =s.ReliefType,
StudentType =s.StudentType.ToEnum<StudentTypeEnum>(),
}); });
userCenterImp.Add(new UserExcelExportData() userCenterImp.Add(new UserExcelExportData()
{ {
UserType = "学生", UserType = "学生",
Account = s.Id.ToString(), Account = s.Id.ToString(),
School = s.School, School = s.School,
Grade = s.Grade, Grade = gStr,
Class = s.Class, Class = s.Class,
ClassType = s.ClassType??ClassTypeEnum..ToString(), ClassType = s.ClassType??ClassTypeEnum..ToString(),
ExamNo = s.Id.ToString(), ExamNo = s.Id.ToString(),
@ -226,6 +250,9 @@ namespace Learn.Archives.API.Controllers
}); });
} }
//如果有错误数据则返回excel
if (impError.Count() != 0)
return File(impError.ExportExcel(), "application/ms-excel", $"导入错误学生{DateTime.Now.ToString("MMddHHmm")}.xlsx");
//调用 用户中心 导入接口 //调用 用户中心 导入接口
var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp); var importRes = await _userCenterService.CallAPI_ImportJsonData(_httpContextAccessor.HttpContext, userCenterImp);
@ -269,8 +296,9 @@ namespace Learn.Archives.API.Controllers
ClassType = "必填:可选值\r\n[云校班 海豚智学班 蓝鲸智库班 中职班 其他 雅思班 点阵笔班级 移动校园班级 智学班 ...]", ClassType = "必填:可选值\r\n[云校班 海豚智学班 蓝鲸智库班 中职班 其他 雅思班 点阵笔班级 移动校园班级 智学班 ...]",
Status = "选填 可选值\r\n[就读,退出]", Status = "选填 可选值\r\n[就读,退出]",
AmountRelief ="选填: 为0则视为 '未申请减免'", AmountRelief ="选填: 为0则视为 '未申请减免'",
ReliefType ="选填: 1.建卡贫困户\r\n2.低保户\r\n3.教师子女 \r\n4.孤儿\r\n5.艺体生\r\n6.残疾学生\r\n7.领导特殊承诺减免\r\n8.领导同意的特殊贫困减免", ReliefType ="选填: 建卡贫困户\r\n低保户\r\n教师子女 \r\n孤儿\r\n艺体生\r\n残疾学生\r\n领导特殊承诺减免\r\n领导同意的特殊贫困减免",
ReliefApplication ="选填: [已申请, 未申请]", ReliefApplication ="选填: [已申请, 未申请]",
StudentType = "选填: 可选值:\r\n复读生\r\n艺术生\r\n春招生\r\n领导承诺批准全免\r\n资源班\r\n国际班\r\n合同制收费学校\r\n渠道商家属\r\n新开班但领导承诺第一学期不收费",
Phone="选填", Phone="选填",
Remark="选填", Remark="选填",
} }; } };

View File

@ -0,0 +1,15 @@
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS publish
WORKDIR /src
COPY . .
WORKDIR "/src/Learn.Archives.API"
ENV NUGET_XMLDOC_MODE none
RUN dotnet nuget add source --name marking https://gitea.23544.com/api/packages/marking/nuget/index.json
RUN dotnet publish "Learn.Archives.API.csproj" -c Release -o /app
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
WORKDIR /app
COPY --from=publish /app .
ENV ASPNETCORE_ENVIRONMENT=Production
ENV TZ=Asia/Shanghai
EXPOSE 8080
ENTRYPOINT ["dotnet", "Learn.Archives.API.dll"]

View File

@ -6,11 +6,11 @@
} }
}, },
"Redis": { "Redis": {
"ConnectionString": "redis-external.23544.com:16379,password=poiuyt)(*&^%,defaultDatabase=3" "ConnectionString": "r-2vc07uq6kgm580hxeu.redis.cn-chengdu.rds.aliyuncs.com:6379,password=r-2vc07uq6kgm580hxeu:JyFQa8MeZ4ndxVbdhUc6,defaultDatabase=3"
}, },
"DB": { "DB": {
//"ConnectionString": "AllowLoadLocalInfile=true;Server=10.255.255.3;Port=3306;Database=learn.videoanalysis;User ID=marking;Password=qwe123!@#;CharSet=utf8mb4;pooling=true;SslMode=None", "ConnectionString": "AllowLoadLocalInfile=true;Server=rm-2vc20nd3d11g0oh6g2o.rwlb.cn-chengdu.rds.aliyuncs.com;User ID=marking;Password=poiuytPOIUYT098765)(*&^%;Port=3306;Database=learn.archives;CharSet=utf8mb4;pooling=true;SslMode=None",
"ConnectionString": "AllowLoadLocalInfile=true;Server=rm-2vc20nd3d11g0oh6g2o.rwlb.cn-chengdu.rds.aliyuncs.com;User ID=marking;Password=poiuytPOIUYT098765)(*&^%;Port=3306;Database=learn.videoanalysis;CharSet=utf8mb4;pooling=true;SslMode=None",
"SqlType": "MySql", "SqlType": "MySql",
"UpdateTable": false "UpdateTable": false
}, },

View File

@ -64,13 +64,13 @@ namespace Learn.Archives.Core.Common.Expand
/// <param name="setOrgEntityFilter">配置 学校数据 sql过滤 <para>默认true</para></param> /// <param name="setOrgEntityFilter">配置 学校数据 sql过滤 <para>默认true</para></param>
public static void SetDbAop(ISqlSugarClient db) public static void SetDbAop(ISqlSugarClient db)
{ {
if (db.Ado.CommandTimeOut == 61) //if (db.Ado.CommandTimeOut == 61)
{ //{
return; // return;
} //}
var config = db.CurrentConnectionConfig; var config = db.CurrentConnectionConfig;
// 设置超时时间 //设置超时时间
db.Ado.CommandTimeOut = 61; //db.Ado.CommandTimeOut = 61;
#if DEBUG #if DEBUG
// 打印SQL语句 // 打印SQL语句
db.Aop.OnLogExecuting = (sql, pars) => db.Aop.OnLogExecuting = (sql, pars) =>
@ -105,11 +105,6 @@ namespace Learn.Archives.Core.Common.Expand
} }
}; };
// 超管时排除各种过滤器
//if (App.User?.FindFirst(ClaimEnum.Role)?.Value == "1")
//return;
// 配置用户机构(数据范围)过滤器
//SetOrgEntityFilter(db);
} }
@ -161,13 +156,13 @@ namespace Learn.Archives.Core.Common.Expand
if (!AppCommon.Config.DB.UpdateTable) if (!AppCommon.Config.DB.UpdateTable)
{ {
Console.WriteLine($"【1】初始化主库表 跳过...."); Console.WriteLine($"【1】初始化主库表 跳过....");
//ShowSQL = true; ShowSQL = true;
return; return;
} }
Console.WriteLine($"【1】初始化主库表 执行中...."); Console.WriteLine($"【1】初始化主库表 执行中....");
var entityTypes = AppCommon.DbMatserType; var entityTypes = AppCommon.DbMatserType;
Console.WriteLine($"【1】数量{entityTypes.Count()} ...."); Console.WriteLine($"【1】数量{entityTypes.Count()} ....");
if (!entityTypes.Any()) return; if (!entityTypes.Any()) { ShowSQL = true; return; };
var i = 0; var i = 0;
var totalCount = entityTypes.Count().ToString().Length; var totalCount = entityTypes.Count().ToString().Length;
foreach (var t in entityTypes) foreach (var t in entityTypes)

View File

@ -20,10 +20,12 @@ namespace Learn.Archives.Core.Common
public void SwitchConnection() public void SwitchConnection()
{ {
var t = typeof(T); var t = typeof(T);
if (AppCommon.DbMatserType.Contains(t)) ISqlSugarClient d;
base.Context = DbScoped.SugarScope; if (AppCommon.UserCenterType.Contains(t))
else if (AppCommon.UserCenterType.Contains(t)) d = DbScoped.SugarScope.GetConnectionScope(1001);
base.Context = DbScoped.SugarScope.GetConnectionScope(1001); else
d = DbScoped.SugarScope;
base.Context = d;
SqlSugarExpand.SetDbAop(base.Context); SqlSugarExpand.SetDbAop(base.Context);
} }
} }

View File

@ -50,6 +50,10 @@ namespace Learn.Archives.Core.Model.Dto
/// 执行时间 /// 执行时间
/// </summary> /// </summary>
public DateTime? ExecutionTime { get; set; } public DateTime? ExecutionTime { get; set; }
/// <summary>
/// 操作人 [后台自动赋值提交人名称]
/// </summary>
public string? Operator { get; set; }
public string? ExecutionTimeStr => ExecutionTime?.ToString("yyyy-MM-dd"); public string? ExecutionTimeStr => ExecutionTime?.ToString("yyyy-MM-dd");

View File

@ -162,6 +162,12 @@ namespace Learn.Archives.Core.Model.Dto
/// <summary>
/// 学生类型
/// </summary>
[ExcelColumn(Name = "学生类型", Width = 20)]
public string StudentType { get; set; }
/// <summary> /// <summary>
/// 学生状态[就读/退出] /// 学生状态[就读/退出]
/// </summary> /// </summary>

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Learn.Archives.Core.Model.Enum
{
/// <summary>
/// 学生类型
/// </summary>
public enum StudentTypeEnum
{
= 1,
= 10,
= 20,
= 30,
= 40,
= 50,
= 60,
= 70,
= 80,
}
}

View File

@ -5,6 +5,7 @@ using System.ComponentModel.DataAnnotations;
using System.Net; using System.Net;
using System.Text.Json; using System.Text.Json;
using UserCenter.Model; using UserCenter.Model;
using UserCenter.Model.Common;
using UserCenter.Model.Enum; using UserCenter.Model.Enum;
using UserCenter.Model.Interface; using UserCenter.Model.Interface;
@ -24,8 +25,27 @@ namespace Learn.Archives.Core.Model
/// <summary> /// <summary>
/// 年级 /// 年级
/// </summary> /// </summary>
[SugarColumn(Length = 12)] [SugarColumn(Length = 2)]
public GradeEnum Level { get; set; } public string? GradeLevel { get; set; }
/// <summary>
/// 毕业届
/// </summary>
[SugarColumn(Length = 2)]
public int GradeYear { get; set; }
/// <summary>
/// dto 处理的grade
/// </summary>
public string? _grade;
/// <summary>
/// 年级
/// </summary>
[SugarColumn(IsIgnore = true)]
public string Grade
{
get => GradeHelper.GetGrade(GradeLevel, GradeYear);
set => _grade = value;
}
/// <summary> /// <summary>
/// 试卷类型 /// 试卷类型
/// </summary> /// </summary>

View File

@ -61,6 +61,7 @@ namespace Learn.Archives.Core.Model
[SugarColumn(IsIgnore = true)] [SugarColumn(IsIgnore = true)]
public string Grade => GradeHelper.GetGrade(GradeLevel, GradeYear); public string Grade => GradeHelper.GetGrade(GradeLevel, GradeYear);
/// <summary> /// <summary>
/// 年级 /// 年级
/// </summary> /// </summary>
@ -119,15 +120,6 @@ namespace Learn.Archives.Core.Model
public decimal BaseSchoolScore { get; set; } public decimal BaseSchoolScore { get; set; }
/// <summary>
/// 录入人Id
/// </summary>
public long EntryPersonId { get; set; }
/// <summary>
/// 录入人名称
/// </summary>
public string EntryPerson { get; set; } = string.Empty;
/// <summary> /// <summary>
/// 创建时间 /// 创建时间
/// </summary> /// </summary>

View File

@ -36,6 +36,12 @@ namespace Learn.Archives.Core.Model
/// </summary> /// </summary>
[SugarColumn(IsNullable = true, Length = 20)] [SugarColumn(IsNullable = true, Length = 20)]
public string? ReliefType { get; set; } public string? ReliefType { get; set; }
/// <summary>
/// 学生类型
/// </summary>
[SugarColumn(IsNullable = true)]
public StudentTypeEnum? StudentType { get; set; }
/// <summary> /// <summary>
/// 减免申请时间 /// 减免申请时间
/// </summary> /// </summary>
@ -58,13 +64,13 @@ namespace Learn.Archives.Core.Model
/// 退出时间 /// 退出时间
/// </summary> /// </summary>
[SugarColumn(IsNullable = true)] [SugarColumn(IsNullable = true)]
public DateTime? ExitTime { get; set; } = DateTime.Now; public DateTime? ExitTime { get; set; }
/// <summary> /// <summary>
/// 退出时间 /// 退出时间
/// </summary> /// </summary>
[SugarColumn(IsNullable = true)] [SugarColumn(IsNullable = true)]
public DateTime? JoinTime { get; set; } = DateTime.Now; public DateTime? JoinTime { get; set; }
/// <summary> /// <summary>
/// 创建时间 /// 创建时间