| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689 |
- using Furion.JsonSerialization;
- using NPOI.SS.UserModel;
- using YBEE.EQM.Core;
- namespace YBEE.EQM.Application;
- /// <summary>
- /// 高中成绩管理服务
- /// </summary>
- public class NceeScoreService(IRepository<NceeScore> rep) : INceeScoreService, ITransient
- {
- /// <summary>
- /// 上传成绩(仅原始分,适用于五区联考或本区独立赋分)
- /// </summary>
- /// <param name="filePath"></param>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- public async Task UploadOnlyRawScore(string filePath, int nceePlanId)
- {
- /* ----------------------------------------------------------
- * 处理步骤:
- * 1.验证表头
- * 2.读取数据
- * 3.处理学生
- * 4.批量插入
- ---------------------------------------------------------- */
- try
- {
- #region 1.验证表结构
- using FileStream fs = new(filePath, FileMode.Open, FileAccess.Read);
- IWorkbook workbook = ExcelUtil.GetWorkbook(filePath, fs);
- var sheet = workbook.GetSheetAt(0);
- var rows = sheet.GetRowEnumerator();
- var evaluator = ExcelUtil.GetEvaluator(workbook);
- // 少于2行验证
- if (sheet.LastRowNum < 2)
- {
- //"第一行应为填写说明,第二行应为标题行,请勿修改模板结构。"
- return;
- }
- // 读取表头
- rows.MoveNext();
- IRow headerRow = (IRow)rows.Current;
- int index = 0;
- int ORG_ID = index++;
- int ORG_NAME = index++;
- int NAME_INDEX = index++;
- int EXAM_NUMBER_INDEX = index++;
- int CLASS_INDEX = index++;
- int DIRECTION_INDEX = index++;
- int DIRECTION_ID_INDEX = index++;
- int COURSE_COMB_INDEX = index++;
- int COURSE_COMB_ID_INDEX = index++;
- int COURSE_START_INDEX = index;
- Dictionary<int, string> headers = new()
- {
- { ORG_ID, "机构ID" },
- { ORG_NAME, "机构" },
- { NAME_INDEX, "姓名" },
- { EXAM_NUMBER_INDEX, "考号" },
- { CLASS_INDEX, "班级号" },
- { DIRECTION_INDEX, "选择方向" },
- { DIRECTION_ID_INDEX, "选择方向科目ID" },
- { COURSE_COMB_INDEX, "选科组合" },
- { COURSE_COMB_ID_INDEX, "选科组合ID" },
- };
- List<string> headerErrors = [];
- for (int i = 0; i < COURSE_START_INDEX; i++)
- {
- if (headerRow.GetCell(i)?.ToString() != headers[i])
- {
- char letter = (char)('A' + i);
- headerErrors.Add(letter.ToString());
- }
- }
- if (headerErrors.Count != 0)
- {
- string columnErrors = string.Join("、", headerErrors);
- //result.ErrorMessage.Add($"第1行标题行{columnErrors}列名错误。从A列开始依次应为抽样类型、学校ID、学校、姓名、证件类型、证件号码、考号、年级、班级。");
- //return result;
- throw new Exception("列头错误");
- }
- //result.StructureCorrect = true;
- #endregion
- #region 2.读取数据
- var plan = await rep.Change<NceePlan>().DetachedEntities.FirstOrDefaultAsync(t => t.Id == nceePlanId) ?? throw Oops.Oh(ErrorCode.E2001, "计划");
- var courseDict = (await rep.Change<Course>().DetachedEntities.ToListAsync()).ToDictionary(t => t.Name);
- //var orgs = await _rep.Change<SysOrg>().DetachedEntities.Where(t => t.EducationStage == EducationStage.SENIOR_HIGH_SCHOOL_STAGE).ToListAsync();
- var courseCombs = await rep.Change<NceeCourseComb>().DetachedEntities.ToListAsync();
- var courseCombDict = courseCombs.ToDictionary(t => t.Id, t => t);
- // 获取需要导入的科目列表
- Dictionary<int, Course> courses = [];
- int validCellNum = COURSE_START_INDEX;
- for (int gi = COURSE_START_INDEX; gi < headerRow.LastCellNum; gi++)
- {
- var cn = headerRow.GetCell(gi)?.ToString()?.Trim() ?? "";
- if (string.IsNullOrEmpty(cn))
- {
- continue;
- }
- courses.Add(gi, courseDict[cn]);
- validCellNum = gi + 1;
- }
- int rn = 1;
- List<NceeStudentImportDto> students = [];
- List<NceeScoreImportDto> scores = [];
- while (rows.MoveNext())
- {
- rn++;
- IRow row = (IRow)rows.Current;
- string rv = row.GetCell(0)?.ToString().Trim() ?? "";
- if (rv == "")
- {
- break;
- }
- NceeStudentImportDto stu = new();
- // 机构ID
- if (short.TryParse(row.GetCell(ORG_ID)?.ToString(), out short orgId))
- {
- stu.SysOrgId = orgId;
- }
- else
- {
- throw new Exception($"[{rn}]机构ID错误");
- }
- // 姓名
- stu.Name = row.GetCell(NAME_INDEX)?.ToString();
- // 考号
- stu.ExamNumber = row.GetCell(EXAM_NUMBER_INDEX)?.ToString();
- // 班号
- if (short.TryParse(row.GetCell(CLASS_INDEX)?.ToString(), out short cn))
- {
- stu.ClassNumber = cn;
- }
- else
- {
- throw new Exception($"[{rn}]班号错误");
- }
- // 方向ID
- if (short.TryParse(row.GetCell(DIRECTION_ID_INDEX)?.ToString(), out short directionId))
- {
- stu.DirectionCourseId = directionId;
- }
- //else
- //{
- // throw new Exception($"[{rn}]方向ID错误");
- //}
- // 组合ID
- if (short.TryParse(row.GetCell(COURSE_COMB_ID_INDEX)?.ToString(), out short courseCombId))
- {
- stu.NceeCourseCombId = courseCombId;
- }
- //else
- //{
- // throw new Exception($"[{rn}]组合ID错误");
- //}
- // 取各科成绩
- int sc = 0;
- for (int gi = COURSE_START_INDEX; gi < validCellNum; gi++)
- {
- var cell = row.GetCell(gi);
- if (cell == null || cell.ToString().Trim() == "")
- {
- continue;
- }
- if (!courses.ContainsKey(gi)) { continue; }
- var course = courses[gi];
- NceeScoreImportDto item = new()
- {
- NceeStudentId = stu.Id,
- CourseId = course.Id,
- };
- if (cell.CellType == CellType.Numeric)
- {
- item.Score = (decimal)cell.NumericCellValue;
- }
- else if (cell.CellType == CellType.Formula)
- {
- var cv = evaluator.Evaluate(cell);
- if (cv.CellType == CellType.Numeric)
- {
- item.Score = (decimal)cv.NumberValue;
- }
- else
- {
- continue;
- }
- }
- if (item.Score > 0)
- {
- if (!NceeUtil.ChooseCourses.Any(t => t == course.Id))
- {
- item.ScoreX = item.Score;
- }
- scores.Add(item);
- sc++;
- }
- }
- if (sc > 0)
- {
- students.Add(stu);
- }
- }
- workbook.Close();
- fs.Close();
- #endregion
- #region 3.处理学生
- // 清理学生
- string deleteStudentSql = $"DELETE FROM ncee_student WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteStudentSql);
- var uid = CurrentSysUserInfo.SysUserId;
- if (uid == 0)
- {
- uid = 1;
- }
- List<string> insertValues = [];
- int scount = students.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = students[i];
- string dcid = "NULL";
- if (t.DirectionCourseId.HasValue)
- {
- dcid = t.DirectionCourseId.Value.ToString();
- }
- string nccid = "NULL";
- if (t.NceeCourseCombId.HasValue)
- {
- nccid = t.NceeCourseCombId.Value.ToString();
- }
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.SysOrgId}, {plan.GradeId}, {t.ClassNumber}, '{t.ExamNumber}', '{t.Name}', {dcid}, {nccid}, 0, 0)");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_student(id, ncee_plan_id, sys_org_id, grade_id, class_number, exam_number, `name`, direction_course_id, ncee_course_comb_id, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- #region 4.批量导入
- // 清理成绩
- string deleteScoreSql = $"DELETE FROM ncee_score WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteScoreSql);
- insertValues.Clear();
- scount = scores.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = scores[i];
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.NceeStudentId}, {t.CourseId}, {t.Score}, {t.ScoreX})");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_score(id, ncee_plan_id, ncee_student_id, course_id, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- finally
- {
- File.Delete(filePath);
- }
- }
- /// <summary>
- /// 上传成绩(带转换分和等级,适用于六校联考)
- /// </summary>
- /// <param name="filePath"></param>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- public async Task UploadWithConvertScore(string filePath, int nceePlanId)
- {
- /* ----------------------------------------------------------
- * 处理步骤:
- * 1.验证表头
- * 2.读取数据
- * 3.处理学生
- * 4.批量插入
- ---------------------------------------------------------- */
- try
- {
- #region 1.验证表结构
- using FileStream fs = new(filePath, FileMode.Open, FileAccess.Read);
- IWorkbook workbook = ExcelUtil.GetWorkbook(filePath, fs);
- var sheet = workbook.GetSheetAt(0);
- var rows = sheet.GetRowEnumerator();
- var evaluator = ExcelUtil.GetEvaluator(workbook);
- // 少于2行验证
- if (sheet.LastRowNum < 2)
- {
- //"第一行应为填写说明,第二行应为标题行,请勿修改模板结构。"
- return;
- }
- // 读取表头
- rows.MoveNext();
- IRow headerRow = (IRow)rows.Current;
- int index = 0;
- int ORG_ID = index++;
- int ORG_NAME = index++;
- int NAME_INDEX = index++;
- int EXAM_NUMBER_INDEX = index++;
- int CLASS_INDEX = index++;
- int DIRECTION_INDEX = index++;
- int DIRECTION_ID_INDEX = index++;
- int COURSE_COMB_INDEX = index++;
- int COURSE_COMB_ID_INDEX = index++;
- int COURSE_START_INDEX = index;
- Dictionary<int, string> headers = new()
- {
- { ORG_ID, "机构ID" },
- { ORG_NAME, "机构" },
- { NAME_INDEX, "姓名" },
- { EXAM_NUMBER_INDEX, "考号" },
- { CLASS_INDEX, "班级号" },
- { DIRECTION_INDEX, "选择方向" },
- { DIRECTION_ID_INDEX, "选择方向科目ID" },
- { COURSE_COMB_INDEX, "选科组合" },
- { COURSE_COMB_ID_INDEX, "选科组合ID" },
- };
- List<string> headerErrors = [];
- for (int i = 0; i < COURSE_START_INDEX; i++)
- {
- if (headerRow.GetCell(i)?.ToString() != headers[i])
- {
- char letter = (char)('A' + i);
- headerErrors.Add(letter.ToString());
- }
- }
- if (headerErrors.Count != 0)
- {
- string columnErrors = string.Join("、", headerErrors);
- //result.ErrorMessage.Add($"第1行标题行{columnErrors}列名错误。从A列开始依次应为抽样类型、学校ID、学校、姓名、证件类型、证件号码、考号、年级、班级。");
- //return result;
- throw new Exception("列头错误");
- }
- //result.StructureCorrect = true;
- #endregion
- #region 2.读取数据
- var plan = await rep.Change<NceePlan>().DetachedEntities.FirstOrDefaultAsync(t => t.Id == nceePlanId) ?? throw Oops.Oh(ErrorCode.E2001, "计划");
- var courseDict = (await rep.Change<Course>().DetachedEntities.ToListAsync()).ToDictionary(t => t.Name);
- //var orgs = await _rep.Change<SysOrg>().DetachedEntities.Where(t => t.EducationStage == EducationStage.SENIOR_HIGH_SCHOOL_STAGE).ToListAsync();
- var courseCombs = await rep.Change<NceeCourseComb>().DetachedEntities.ToListAsync();
- var courseCombDict = courseCombs.ToDictionary(t => t.Id, t => t);
- var convertGrades = await rep.Change<NceeConvertGrade>().DetachedEntities.ToListAsync();
- var convertGradeDict = convertGrades.ToDictionary(t => t.Name);
- // 获取需要导入的科目列表
- Dictionary<int, NceeScoreImportCourseDto> courses = new();
- int validCellNum = COURSE_START_INDEX;
- for (int gi = COURSE_START_INDEX; gi < headerRow.LastCellNum; gi++)
- {
- var cn = headerRow.GetCell(gi)?.ToString()?.Trim() ?? "";
- if (string.IsNullOrEmpty(cn))
- {
- continue;
- }
- string tm = cn[^1..].ToUpper();
- var cnn = cn;
- if (tm == "X" || tm == "G")
- {
- cnn = cn[..^1];
- }
- courses.Add(gi, new()
- {
- CourseName = cn,
- Course = courseDict[cnn],
- IsRawScore = tm != "X" && tm != "G",
- IsConvertGrade = tm == "G",
- IsConvertScore = tm == "X",
- });
- validCellNum = gi + 1;
- }
- int rn = 1;
- List<NceeStudentImportDto> students = new();
- List<NceeScoreImportDto> scores = new();
- while (rows.MoveNext())
- {
- rn++;
- IRow row = (IRow)rows.Current;
- string rv = row.GetCell(0)?.ToString().Trim() ?? "";
- if (rv == "")
- {
- break;
- }
- NceeStudentImportDto stu = new();
- // 机构ID
- if (short.TryParse(row.GetCell(ORG_ID)?.ToString(), out short orgId))
- {
- stu.SysOrgId = orgId;
- }
- else
- {
- throw new Exception($"[{rn}]机构ID错误");
- }
- // 姓名
- stu.Name = row.GetCell(NAME_INDEX)?.ToString();
- // 考号
- stu.ExamNumber = row.GetCell(EXAM_NUMBER_INDEX)?.ToString();
- // 班号
- if (short.TryParse(row.GetCell(CLASS_INDEX)?.ToString(), out short cn))
- {
- stu.ClassNumber = cn;
- }
- else
- {
- throw new Exception($"[{rn}]班号错误");
- }
- // 方向ID
- if (short.TryParse(row.GetCell(DIRECTION_ID_INDEX)?.ToString(), out short directionId))
- {
- stu.DirectionCourseId = directionId;
- }
- //else
- //{
- // throw new Exception($"[{rn}]方向ID错误");
- //}
- // 组合ID
- if (short.TryParse(row.GetCell(COURSE_COMB_ID_INDEX)?.ToString(), out short courseCombId))
- {
- stu.NceeCourseCombId = courseCombId;
- }
- //else
- //{
- // throw new Exception($"[{rn}]组合ID错误");
- //}
- // 取各科成绩
- List<NceeScoreImportDto> courseScores = [];
- for (int gi = COURSE_START_INDEX; gi < validCellNum; gi++)
- {
- var cell = row.GetCell(gi);
- if (cell == null || cell.ToString().Trim() == "")
- {
- continue;
- }
- if (!courses.ContainsKey(gi)) { continue; }
- var course = courses[gi];
- NceeScoreImportDto item;
- if (course.IsConvertScore || course.IsConvertGrade)
- {
- item = courseScores.FirstOrDefault(t => t.CourseId == course.Course.Id);
- }
- else
- {
- item = new()
- {
- NceeStudentId = stu.Id,
- CourseId = course.Course.Id,
- };
- }
- if (course.IsConvertGrade == false)
- {
- decimal score = 0;
- if (cell.CellType == CellType.Numeric)
- {
- score = (decimal)cell.NumericCellValue;
- }
- else if (cell.CellType == CellType.Formula)
- {
- var cv = evaluator.Evaluate(cell);
- if (cv.CellType == CellType.Numeric)
- {
- score = (decimal)cv.NumberValue;
- }
- else
- {
- continue;
- }
- }
- if (score > 0)
- {
- if (course.IsRawScore == true)
- {
- item.Score = score;
- if (!NceeUtil.ChooseCourses.Any(t => t == course.Course.Id))
- {
- item.ScoreX = score;
- }
- courseScores.Add(item);
- }
- else if (course.IsConvertScore == true)
- {
- item.ScoreX = score;
- }
- }
- }
- else
- {
- var gn = cell.ToString().Trim().ToUpper();
- var g = convertGradeDict[gn];
- item.NceeConvertGradeId = g.Id;
- item.NceeConvertGradeName = g.Name;
- }
- }
- if (courseScores.Count > 0)
- {
- stu.Score = courseScores.Sum(t => t.Score);
- stu.ScoreX = courseScores.Sum(t => t.ScoreX);
- students.Add(stu);
- scores.AddRange(courseScores);
- }
- }
- workbook.Close();
- fs.Close();
- #endregion
- #region 3.处理学生
- // 清理学生
- string deleteStudentSql = $"DELETE FROM ncee_student WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteStudentSql);
- var uid = CurrentSysUserInfo.SysUserId;
- if (uid == 0)
- {
- uid = 1;
- }
- List<string> insertValues = new();
- int scount = students.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = students[i];
- string dcid = "NULL";
- if (t.DirectionCourseId.HasValue)
- {
- dcid = t.DirectionCourseId.Value.ToString();
- }
- string nccid = "NULL";
- if (t.NceeCourseCombId.HasValue)
- {
- nccid = t.NceeCourseCombId.Value.ToString();
- }
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.SysOrgId}, {plan.GradeId}, {t.ClassNumber}, '{t.ExamNumber}', '{t.Name}', {dcid}, {nccid}, {t.Score}, {t.ScoreX})");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_student(id, ncee_plan_id, sys_org_id, grade_id, class_number, exam_number, `name`, direction_course_id, ncee_course_comb_id, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- #region 4.批量导入
- // 清理成绩
- string deleteScoreSql = $"DELETE FROM ncee_score WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteScoreSql);
- insertValues.Clear();
- scount = scores.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = scores[i];
- string ncgid = "NULL";
- if (t.NceeConvertGradeId.HasValue)
- {
- ncgid = t.NceeConvertGradeId.Value.ToString();
- }
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.NceeStudentId}, {t.CourseId}, {ncgid}, '{t.NceeConvertGradeName}', {t.Score}, {t.ScoreX})");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_score(id, ncee_plan_id, ncee_student_id, course_id, ncee_convert_grade_id, ncee_convert_grade_name, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- finally
- {
- File.Delete(filePath);
- }
- }
- /// <summary>
- /// 上传未选科原始成绩(适用于高一未选科)
- /// </summary>
- /// <param name="filePath"></param>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- /// <exception cref="Exception"></exception>
- public async Task UploadNoDirectionCourse(string filePath, int nceePlanId)
- {
- /* ----------------------------------------------------------
- * 处理步骤:
- * 1.验证表头
- * 2.读取数据
- * 3.处理学生
- * 4.批量插入
- ---------------------------------------------------------- */
- try
- {
- #region 1.验证表结构
- using FileStream fs = new(filePath, FileMode.Open, FileAccess.Read);
- IWorkbook workbook = ExcelUtil.GetWorkbook(filePath, fs);
- var sheet = workbook.GetSheetAt(0);
- var rows = sheet.GetRowEnumerator();
- var evaluator = ExcelUtil.GetEvaluator(workbook);
- // 少于2行验证
- if (sheet.LastRowNum < 2)
- {
- //"第一行应为填写说明,第二行应为标题行,请勿修改模板结构。"
- return;
- }
- // 读取表头
- rows.MoveNext();
- IRow headerRow = (IRow)rows.Current;
- int index = 0;
- int ORG_ID = index++;
- int ORG_NAME = index++;
- int NAME_INDEX = index++;
- int EXAM_NUMBER_INDEX = index++;
- int CLASS_INDEX = index++;
- int COURSE_START_INDEX = index;
- Dictionary<int, string> headers = new()
- {
- { ORG_ID, "机构ID" },
- { ORG_NAME, "机构" },
- { NAME_INDEX, "姓名" },
- { EXAM_NUMBER_INDEX, "考号" },
- { CLASS_INDEX, "班级号" },
- };
- List<string> headerErrors = [];
- for (int i = 0; i < COURSE_START_INDEX; i++)
- {
- if (headerRow.GetCell(i)?.ToString() != headers[i])
- {
- char letter = (char)('A' + i);
- headerErrors.Add(letter.ToString());
- }
- }
- if (headerErrors.Count != 0)
- {
- string columnErrors = string.Join("、", headerErrors);
- //result.ErrorMessage.Add($"第1行标题行{columnErrors}列名错误。从A列开始依次应为抽样类型、学校ID、学校、姓名、证件类型、证件号码、考号、年级、班级。");
- //return result;
- throw new Exception("列头错误");
- }
- //result.StructureCorrect = true;
- #endregion
- #region 2.读取数据
- var plan = await rep.Change<NceePlan>().DetachedEntities.FirstOrDefaultAsync(t => t.Id == nceePlanId) ?? throw Oops.Oh(ErrorCode.E2001, "计划");
- var courseDict = (await rep.Change<Course>().DetachedEntities.ToListAsync()).ToDictionary(t => t.Name);
- // 获取需要导入的科目列表
- Dictionary<int, Course> courses = [];
- int validCellNum = COURSE_START_INDEX;
- for (int gi = COURSE_START_INDEX; gi < headerRow.LastCellNum; gi++)
- {
- var cn = headerRow.GetCell(gi)?.ToString()?.Trim() ?? "";
- if (string.IsNullOrEmpty(cn))
- {
- continue;
- }
- courses.Add(gi, courseDict[cn]);
- validCellNum = gi + 1;
- }
- int rn = 1;
- List<NceeStudentImportDto> students = [];
- List<NceeScoreImportDto> scores = [];
- while (rows.MoveNext())
- {
- rn++;
- IRow row = (IRow)rows.Current;
- string rv = row.GetCell(0)?.ToString().Trim() ?? "";
- if (rv == "")
- {
- break;
- }
- NceeStudentImportDto stu = new();
- // 机构ID
- if (short.TryParse(row.GetCell(ORG_ID)?.ToString(), out short orgId))
- {
- stu.SysOrgId = orgId;
- }
- else
- {
- throw new Exception($"[{rn}]机构ID错误");
- }
- // 姓名
- stu.Name = row.GetCell(NAME_INDEX)?.ToString();
- // 考号
- stu.ExamNumber = row.GetCell(EXAM_NUMBER_INDEX)?.ToString();
- // 班号
- if (short.TryParse(row.GetCell(CLASS_INDEX)?.ToString(), out short cn))
- {
- stu.ClassNumber = cn;
- }
- else
- {
- throw new Exception($"[{rn}]班号错误");
- }
- // 取各科成绩
- List<NceeScoreImportDto> courseScores = [];
- for (int gi = COURSE_START_INDEX; gi < validCellNum; gi++)
- {
- var cell = row.GetCell(gi);
- if (cell == null || cell.ToString().Trim() == "")
- {
- continue;
- }
- if (!courses.ContainsKey(gi)) { continue; }
- var course = courses[gi];
- NceeScoreImportDto item = new()
- {
- NceeStudentId = stu.Id,
- CourseId = course.Id,
- };
- decimal score = 0;
- if (cell.CellType == CellType.Numeric)
- {
- score = (decimal)cell.NumericCellValue;
- }
- else if (cell.CellType == CellType.Formula)
- {
- var cv = evaluator.Evaluate(cell);
- if (cv.CellType == CellType.Numeric)
- {
- score = (decimal)cv.NumberValue;
- }
- else
- {
- continue;
- }
- }
- if (score > 0)
- {
- item.Score = score;
- item.ScoreX = score;
- courseScores.Add(item);
- }
- }
- if (courseScores.Count > 0)
- {
- stu.Score = courseScores.Sum(t => t.Score);
- stu.ScoreX = courseScores.Sum(t => t.ScoreX);
- students.Add(stu);
- scores.AddRange(courseScores);
- }
- }
- workbook.Close();
- fs.Close();
- #endregion
- #region 3.处理学生
- // 清理学生
- string deleteStudentSql = $"DELETE FROM ncee_student WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteStudentSql);
- var uid = CurrentSysUserInfo.SysUserId;
- if (uid == 0)
- {
- uid = 1;
- }
- List<string> insertValues = new();
- int scount = students.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = students[i];
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.SysOrgId}, {plan.GradeId}, {t.ClassNumber}, '{t.ExamNumber}', '{t.Name}', 99, 0, {t.Score}, {t.ScoreX})");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_student(id, ncee_plan_id, sys_org_id, grade_id, class_number, exam_number, `name`, direction_course_id, ncee_course_comb_id, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- #region 4.批量导入
- // 清理成绩
- string deleteScoreSql = $"DELETE FROM ncee_score WHERE ncee_plan_id = {nceePlanId};";
- await rep.SqlNonQueryAsync(deleteScoreSql);
- insertValues.Clear();
- scount = scores.Count;
- for (int i = 0; i < scount; i++)
- {
- var t = scores[i];
- insertValues.Add($"({t.Id}, {nceePlanId}, {t.NceeStudentId}, {t.CourseId}, NULL, '', {t.Score}, {t.ScoreX})");
- if ((i + 1) % 1000 == 0 || i == scount - 1)
- {
- string insertSql = $@"
- INSERT INTO ncee_score(id, ncee_plan_id, ncee_student_id, course_id, ncee_convert_grade_id, ncee_convert_grade_name, score, score_x) VALUES
- {string.Join(",", insertValues)}
- ";
- await rep.SqlNonQueryAsync(insertSql);
- insertValues.Clear();
- }
- }
- #endregion
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- finally
- {
- File.Delete(filePath);
- }
- }
- /// <summary>
- /// 执行模拟划线
- /// </summary>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- public async Task Execute(int nceePlanId)
- {
- var nceePlan = await rep.Change<NceePlan>().FirstOrDefaultAsync(t => t.Id == nceePlanId) ?? throw Oops.Oh(ErrorCode.E2001);
- var nceePlanConfig = JSON.Deserialize<NceePlanConfig>(nceePlan.Config);
- // 执行分数转换
- if (nceePlanConfig.ConvertEnabled)
- {
- await ExecuteScoreConvert(nceePlanId);
- }
- // 更新学生排名
- await ExecuteUpdateOrder(nceePlanId);
- // 执行划线
- await ExecuteLine(nceePlanId, nceePlanConfig);
- }
- #region 私有方法
- /// <summary>
- /// 执行划线
- /// </summary>
- /// <param name="nceePlanId"></param>
- /// <param name="config"></param>
- /// <returns></returns>
- private async Task ExecuteLine(int nceePlanId, NceePlanConfig config)
- {
- var baseLines = await rep.Change<NceeBaseLine>().Where(t => t.NceePlanId == nceePlanId).OrderBy(t => t.NceeLineLevel).ToListAsync();
- // 单科有效分
- List<NceeCourseLineScore> courseLineScores = [];
- #region 计算总有效分(通过比例计算)
- if (config.CalcTotalLineScoreEnabled)
- {
- foreach (var line in baseLines)
- {
- // 计算总有效分
- var lineScoreX = await rep.SqlScalarAsync<decimal>(@$"
- SELECT MIN(score_x) AS score_x
- FROM
- (
- SELECT ROW_NUMBER() OVER(ORDER BY score_x DESC) AS rn, score_x
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId
- ) AS T1
- WHERE T1.rn <= (SELECT COUNT(1) FROM ncee_student WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId) * @lineRate
- ", new { NceePlanId = nceePlanId, line.DirectionCourseId, line.LineRate });
- line.LineScoreX = lineScoreX;
- }
- await rep.Change<NceeBaseLine>().UpdateNowAsync(baseLines);
- }
- #endregion
- #region 计算单科有效分
- if (config.CalcCourseLineScoreEnabled)
- {
- // 1.总分排序,合并单科独立排序
- // 2.取总分上线分对应行的单科成绩为有效分
- foreach (var line in baseLines)
- {
- if (!config.DirectionUnseleted)
- {
- // 计算单科有效分
- var courseLineScoreX = await rep.SqlQueryAsync<NceeCourseLineScoreCalcDto>($@"
- SELECT
- MIN(T1.yuwen_score_x) AS yuwen_score_x, -- 语文
- MIN(T1.shuxue_score_x) AS shuxue_score_x, -- 数学
- MIN(T1.yingyu_score_x) AS yingyu_score_x, -- 英语
- MIN(T1.fangxiang_score_x) AS fangxiang_score_x, -- 方向(物理或历史)
- MIN(T1.zonghe_score_x) AS zonghe_score_x -- 综合
- FROM
- (
- SELECT T1.rn,
- T2.score_x AS yuwen_score_x,
- T3.score_x AS shuxue_score_x,
- T4.score_x AS yingyu_score_x,
- T5.score_x AS fangxiang_score_x,
- T6.score_x AS zonghe_score_x,
- IFNULL(T2.score_x, 0) + IFNULL(T3.score_x, 0) + IFNULL(T4.score_x, 0) + IFNULL(T5.score_x, 0) + IFNULL(T6.score_x, 0) AS score_x
- FROM
- (
- SELECT ROW_NUMBER() OVER(ORDER BY score_x DESC) AS rn
- FROM ncee_student AS T1
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId
- ) AS T1
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T2.score_x DESC) AS rn, T2.score_x
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id = 1
- ) AS T2 ON T1.rn = T2.rn
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T2.score_x DESC) AS rn, T2.score_x
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id = 2
- ) AS T3 ON T1.rn = T3.rn
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T2.score_x DESC) AS rn, T2.score_x
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id = 3
- ) AS T4 ON T1.rn = T4.rn
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T2.score_x DESC) AS rn, T2.score_x
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id = @directionCourseId
- ) AS T5 ON T1.rn = T5.rn
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T1.score_x DESC) AS rn, t1.score_x
- FROM
- (
- SELECT T2.ncee_student_id, SUM(T2.score_x) AS score_x
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id IN(5, 6, 7, 9)
- GROUP BY T2.ncee_student_id
- ) AS T1
- ) AS T6 ON T1.rn = T6.rn
- ) AS T1
- WHERE T1.score_x >= @totalLineScoreX
- ", new { NceePlanId = nceePlanId, line.DirectionCourseId, TotalLineScoreX = line.LineScoreX });
- var cline = courseLineScoreX.FirstOrDefault();
- if (cline != null)
- {
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = CourseConst.YU_WEN, LineScoreX = cline.YuwenScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = CourseConst.SHU_XUE, LineScoreX = cline.ShuxueScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = CourseConst.YING_YU, LineScoreX = cline.YingyuScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = line.DirectionCourseId, LineScoreX = cline.FangxiangScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = CourseConst.ZONG_HE, LineScoreX = cline.ZongheScoreX });
- }
- }
- else
- {
- List<string> minFields = [];
- List<string> scoreFields = [];
- List<string> totalScore = [];
- List<string> courseSelects = [];
- for (short c = 1; c < 10; c++)
- {
- minFields.Add($"MIN(T1.score_{c}) AS score_{c}");
- scoreFields.Add($"T{c}.score AS score_{c}");
- totalScore.Add($"IFNULL(T{c}.score, 0)");
- courseSelects.Add(@$"
- LEFT JOIN
- (
- SELECT ROW_NUMBER() OVER(ORDER BY T2.score DESC) AS rn, T2.score
- FROM ncee_student AS T1
- JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.course_id = {c}
- ) AS T{c} ON T0.rn = T{c}.rn
- ");
- }
- // 计算单科有效分
- var courseLineScoreX = await rep.SqlQueryAsync($@"
- SELECT
- {string.Join(", ", minFields)}
- FROM
- (
- SELECT
- T0.rn,
- {string.Join(", ", scoreFields)},
- {string.Join(" + ", totalScore)} AS score
- FROM
- (
- SELECT ROW_NUMBER() OVER(ORDER BY score DESC) AS rn
- FROM ncee_student AS T1
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId
- ) AS T0
- {string.Join("", courseSelects)}
- ) AS T1
- WHERE T1.score >= @totalLineScoreX
- ", new { NceePlanId = nceePlanId, line.DirectionCourseId, TotalLineScoreX = line.LineScoreX });
- if (courseLineScoreX.Rows.Count > 0)
- {
- var dr = courseLineScoreX.Rows[0];
- for (short c = 1; c < 10; c++)
- {
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = c, LineScoreX = (decimal)dr[$"score_{c}"] });
- }
- }
- }
- }
- await rep.Change<NceeCourseLineScore>().Where(t => t.NceePlanId == nceePlanId).ExecuteDeleteAsync();
- List<NceeCourseLineScore> totalLines = [];
- foreach (var line in baseLines)
- {
- totalLines.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = 100, LineScoreX = line.LineScoreX });
- }
- await rep.Change<NceeCourseLineScore>().InsertNowAsync(totalLines);
- await rep.Change<NceeCourseLineScore>().InsertNowAsync(courseLineScores);
- }
- else
- {
- courseLineScores = await rep.Change<NceeCourseLineScore>().Where(t => t.NceePlanId == nceePlanId).ToListAsync();
- }
- #endregion
- #region 计算总分上线
- // 清除数据
- await rep.Change<NceeLineTotal>().Where(t => t.NceePlanId == nceePlanId).ExecuteDeleteAsync();
- // 总分划线
- foreach (var line in baseLines)
- {
- // 整体 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_total(type, ncee_plan_id, ncee_line_level, direction_course_id, grade_id, line_count, total_count, line_rate)
- SELECT {(short)NceeDataScopeType.TOTAL}, @nceePlanId, @nceeLineLevel, T1.*, T1.line_count / T1.total_count AS line_rate
- FROM
- (
- SELECT
- T1.direction_course_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- (
- SELECT COUNT(1) AS total_count
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId AND score_x > 0
- ) AS total_count
- FROM ncee_student AS T1
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T1.score_x >= @lineScoreX
- GROUP BY T1.direction_course_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX });
- // 机构 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_total(type, ncee_plan_id, ncee_line_level, direction_course_id, sys_org_id, grade_id, line_count, total_count, line_rate)
- SELECT {(short)NceeDataScopeType.ORG}, @nceePlanId, @nceeLineLevel, T1.*, T1.line_count / T1.total_count AS line_rate
- FROM
- (
- SELECT
- T1.direction_course_id,
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM ncee_student AS T1
- JOIN
- (
- SELECT sys_org_id, COUNT(1) AS total_count
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId AND score_x > 0
- GROUP BY sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T1.score_x >= @lineScoreX
- GROUP BY T1.direction_course_id, T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX });
- // 机构 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_total(type, ncee_plan_id, ncee_line_level, direction_course_id, ncee_course_comb_id, sys_org_id, grade_id, line_count, total_count, line_rate)
- SELECT {(short)NceeDataScopeType.COMB}, @nceePlanId, @nceeLineLevel, T1.*, T1.line_count / T1.total_count AS line_rate
- FROM
- (
- SELECT
- T1.direction_course_id,
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM ncee_student AS T1
- JOIN
- (
- SELECT ncee_course_comb_id, sys_org_id, COUNT(1) AS total_count
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId AND score_x > 0
- GROUP BY ncee_course_comb_id, sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T1.ncee_course_comb_id = T2.ncee_course_comb_id AND T1.score_x >= @lineScoreX
- GROUP BY T1.direction_course_id, T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX });
- // 机构 - 班级 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_total(type, ncee_plan_id, ncee_line_level, direction_course_id, ncee_course_comb_id, sys_org_id, grade_id, class_number, line_count, total_count, line_rate)
- SELECT {(short)NceeDataScopeType.CLASS}, @nceePlanId, @nceeLineLevel, T1.*, T1.line_count / T1.total_count AS line_rate
- FROM
- (
- SELECT
- T1.direction_course_id,
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- T1.class_number,
- COUNT(1) AS line_count,
- T2.total_count
- FROM ncee_student AS T1
- JOIN
- (
- SELECT ncee_course_comb_id, sys_org_id, class_number, COUNT(1) AS total_count
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId AND direction_course_id = @directionCourseId AND score_x > 0
- GROUP BY ncee_course_comb_id, sys_org_id, class_number
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T1.ncee_course_comb_id = T2.ncee_course_comb_id AND T1.class_number = T2.class_number AND T1.score_x >= @lineScoreX
- GROUP BY T1.direction_course_id, T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX });
- }
- #endregion
- #region 计算科目有效分上线
- // 清除数据
- await rep.Change<NceeLineCourse>().Where(t => t.NceePlanId == nceePlanId).ExecuteDeleteAsync();
- // 总分划线
- foreach (var line in baseLines)
- {
- var courseLines = courseLineScores.Where(t => t.DirectionCourseId == line.DirectionCourseId && t.NceeLineLevel == line.NceeLineLevel).ToList();
- foreach (var courseLine in courseLines)
- {
- string inCourses = courseLine.CourseId.ToString();
- if (courseLine.CourseId == CourseConst.ZONG_HE)
- {
- inCourses = "5, 6, 7, 9";
- }
- // 单上线:整体 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.TOTAL}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 0
- FROM
- (
- SELECT
- T1.grade_id,
- COUNT(1) AS line_count,
- (
- SELECT COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.grade_id, T2.ncee_student_id
- ) AS T1
- ) AS total_count
- FROM
- (
- SELECT T1.grade_id, T2.ncee_student_id, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.grade_id, T2.ncee_student_id
- ) AS T1
- WHERE T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 双上线:整体 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.TOTAL}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 1
- FROM
- (
- SELECT
- T1.grade_id,
- COUNT(1) AS line_count,
- (
- SELECT COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.grade_id, T2.ncee_student_id
- ) AS T1
- ) AS total_count
- FROM
- (
- SELECT T1.grade_id, T2.ncee_student_id, MAX(T1.score_x) AS score_x, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.grade_id, T2.ncee_student_id
- ) AS T1
- WHERE T1.score_x >= @lineScoreX AND T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 单上线:机构 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, sys_org_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.ORG}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 0
- FROM
- (
- SELECT
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.sys_org_id, T1.grade_id, T2.ncee_student_id, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.sys_org_id, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id
- WHERE T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 双上线:机构 - 方向
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, sys_org_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.ORG}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 1
- FROM
- (
- SELECT
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.sys_org_id, T1.grade_id, T2.ncee_student_id, MAX(T1.score_x) AS score_x, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.sys_org_id, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id
- WHERE T1.score_x >= @lineScoreX AND T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 单上线:机构 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, ncee_course_comb_id, sys_org_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.COMB}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 0
- FROM
- (
- SELECT
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id AND T1.ncee_course_comb_id = T2.ncee_course_comb_id
- WHERE T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 双上线:机构 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, ncee_course_comb_id, sys_org_id, grade_id, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.COMB}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 1
- FROM
- (
- SELECT
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id, MAX(T1.score_x) AS score_x, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id AND T1.ncee_course_comb_id = T2.ncee_course_comb_id
- WHERE T1.score_x >= @lineScoreX AND T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 机构 - 班级 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, ncee_course_comb_id, sys_org_id, grade_id, class_number, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.CLASS}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 0
- FROM
- (
- SELECT
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- T1.class_number,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.class_number, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.class_number
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id AND T1.ncee_course_comb_id = T2.ncee_course_comb_id AND T1.class_number = T2.class_number
- WHERE T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- // 机构 - 班级 - 方向 - 组合
- await rep.SqlNonQueryAsync($@"
- INSERT INTO ncee_line_course(type, ncee_plan_id, ncee_line_level, direction_course_id, course_id, ncee_course_comb_id, sys_org_id, grade_id, class_number, line_count, total_count, line_rate, is_double_line)
- SELECT {(short)NceeDataScopeType.CLASS}, @nceePlanId, @nceeLineLevel, @directionCourseId, @courseId, T1.*, T1.line_count / T1.total_count AS line_rate, 1
- FROM
- (
- SELECT
- T1.ncee_course_comb_id,
- T1.sys_org_id,
- T1.grade_id,
- T1.class_number,
- COUNT(1) AS line_count,
- T2.total_count
- FROM
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id, MAX(T1.score_x) AS score_x, SUM(T2.score_x) AS course_score_x
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- ) AS T1
- JOIN
- (
- SELECT T1.ncee_course_comb_id, T1.sys_org_id, T1.class_number, COUNT(1) AS total_count
- FROM
- (
- SELECT DISTINCT T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- FROM ncee_student AS T1
- LEFT JOIN ncee_score AS T2 ON T1.id = T2.ncee_student_id
- WHERE T1.ncee_plan_id = @nceePlanId AND T1.direction_course_id = @directionCourseId AND T2.score > 0 AND T2.course_id IN({inCourses})
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number, T2.ncee_student_id
- ) AS T1
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.class_number
- ) AS T2 ON T1.sys_org_id = T2.sys_org_id AND T1.ncee_course_comb_id = T2.ncee_course_comb_id AND T1.class_number = T2.class_number
- WHERE T1.score_x >= @lineScoreX AND T1.course_score_x >= @courseLineScoreX
- GROUP BY T1.ncee_course_comb_id, T1.sys_org_id, T1.grade_id, T1.class_number
- ) AS T1
- ", new { NceePlanId = nceePlanId, line.NceeLineLevel, line.DirectionCourseId, line.LineScoreX, courseLine.CourseId, CourseLineScoreX = courseLine.LineScoreX });
- }
- }
- #endregion
- }
- /// <summary>
- /// 执行分数转换
- /// </summary>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- private async Task ExecuteScoreConvert(int nceePlanId)
- {
- await rep.Change<NceeConvertRange>().Where(t => t.NceePlanId == nceePlanId).ExecuteDeleteAsync();
- var convertGrades = await rep.Change<NceeConvertGrade>().DetachedEntities.OrderBy(t => t.Sequence).ToListAsync();
- var convertGradeDict = convertGrades.ToDictionary(t => t.Id, t => t);
- // 分科转换
- foreach (var courseId in NceeUtil.ChooseCourses)
- {
- var scores = await rep.DetachedEntities.Where(t => t.NceeStudent.NceePlanId == nceePlanId && t.CourseId == courseId && t.Score > 0).OrderByDescending(t => t.Score).ToListAsync();
- if (scores.Count == 0)
- {
- continue;
- }
- var convertRanges = GetConvertRange(nceePlanId, courseId, convertGrades, scores);
- // 更新转换区间
- await rep.Change<NceeConvertRange>().Where(t => t.NceePlanId == nceePlanId && t.CourseId == courseId).ExecuteDeleteAsync();
- await rep.Change<NceeConvertRange>().InsertNowAsync(convertRanges);
- // 更新转换分
- List<string> replaceValues = [];
- int cscount = scores.Count;
- for (int i = 0; i < cscount; i++)
- {
- var s = scores[i];
- var cr = convertRanges.FirstOrDefault(t => s.Score >= t.MinScore && s.Score <= t.MaxScore);
- var cg = convertGradeDict[cr.NceeConvertGradeId];
- var scoreX = GetScoreX(s.Score, cg, cr);
- replaceValues.Add($"({s.Id}, {nceePlanId}, {s.NceeStudentId}, {s.CourseId}, {s.Score}, {scoreX}, {cr.NceeConvertGradeId}, '{cg.Name}')");
- if ((i + 1) % 1000 == 0 || i == cscount - 1)
- {
- string replaceSql = $@"
- REPLACE INTO ncee_score(id, ncee_plan_id, ncee_student_id, course_id, score, score_x, ncee_convert_grade_id, ncee_convert_grade_name) VALUES
- {string.Join(",", replaceValues)}
- ";
- await rep.SqlNonQueryAsync(replaceSql);
- replaceValues.Clear();
- }
- }
- }
- // 更新总分
- await rep.SqlNonQueryAsync($@"
- -- 更新总分
- UPDATE ncee_student AS T1
- JOIN
- (
- SELECT ncee_student_id, SUM(score) AS score, SUM(score_x) AS score_x
- FROM ncee_score
- WHERE ncee_plan_id = @nceePlanId
- GROUP BY ncee_student_id
- ) AS T2 ON T1.id = T2.ncee_student_id
- SET T1.score = T2.score, T1.score_x = T2.score_x
- WHERE T1.ncee_plan_id = @nceePlanId
- ;", new { NceePlanId = nceePlanId });
- }
- /// <summary>
- /// 更新排名(在整体中的排名和在机构内的排名)
- /// </summary>
- /// <param name="nceePlanId"></param>
- /// <returns></returns>
- private async Task ExecuteUpdateOrder(int nceePlanId)
- {
- await rep.SqlNonQueryAsync($@"
- UPDATE ncee_student AS T1
- JOIN
- (
- SELECT id,
- RANK() OVER(PARTITION BY direction_course_id ORDER BY score DESC) AS order_in_total,
- RANK() OVER(PARTITION BY direction_course_id ORDER BY score_x DESC) AS order_in_total_x,
- RANK() OVER(PARTITION BY direction_course_id, sys_org_id ORDER BY score DESC) AS order_in_org,
- RANK() OVER(PARTITION BY direction_course_id, sys_org_id ORDER BY score_x DESC) AS order_in_org_x
- FROM ncee_student
- WHERE ncee_plan_id = @nceePlanId
- ) AS T2 ON T1.id = T2.id
- SET T1.order_in_total = T2.order_in_total,
- T1.order_in_total_x = T2.order_in_total_x,
- T1.order_in_org = T2.order_in_org,
- T1.order_in_org_x = T2.order_in_org_x
- ;", new { NceePlanId = nceePlanId });
- }
- /// <summary>
- /// 获取转换区间
- /// </summary>
- /// <param name="nceePlanId"></param>
- /// <param name="courseId"></param>
- /// <param name="convertGrades"></param>
- /// <param name="nceeScores"></param>
- /// <returns></returns>
- private static List<NceeConvertRange> GetConvertRange(int nceePlanId, short courseId, List<NceeConvertGrade> convertGrades, List<NceeScore> nceeScores)
- {
- int scount = nceeScores.Count;
- var totalMaxScore = nceeScores.Select(t => t.Score).Max();
- var totalMinScore = nceeScores.Select(t => t.Score).Min();
- var cgs = convertGrades.OrderBy(t => t.Id).ToList();
- var scores = nceeScores.OrderByDescending(t => t.Score).ToList();
- List<NceeConvertRange> ncrs = [];
- decimal lastMinScore = decimal.MaxValue;
- foreach (var cg in cgs)
- {
- NceeConvertRange range = new()
- {
- NceePlanId = nceePlanId,
- NceeConvertGradeId = cg.Id,
- CourseId = courseId,
- };
- var i = (int)Math.Min(Math.Floor(cg.EndRate * scount), scount - 1);
- if (cg.BeginRate == 0)
- {
- range.MaxScore = totalMaxScore;
- }
- else
- {
- range.MaxScore = scores.Where(t => t.Score < lastMinScore).Select(t => t.Score).Max();
- }
- if (cg.EndRate == 1)
- {
- range.MinScore = totalMinScore;
- }
- else
- {
- range.MinScore = scores[i].Score;
- }
- lastMinScore = range.MinScore;
- ncrs.Add(range);
- }
- return ncrs;
- }
- /// <summary>
- /// 获取转换分
- /// </summary>
- /// <param name="score"></param>
- /// <param name="convertGrade"></param>
- /// <param name="convertRange"></param>
- /// <returns></returns>
- private static decimal GetScoreX(decimal score, NceeConvertGrade convertGrade, NceeConvertRange convertRange)
- {
- // (Y2 - Y) / (Y- Y1) = (X2 - X) / (X - X1)
- // Y1,Y2为原始分区间下限和上限
- // X1,X2为转换分区间下限和上限
- // Y为原始分
- // X为转换分
- //// X = ((Y - Y1) * X2 + (Y2 - Y) * X1) / (Y2 - Y1)
- //var y = score;
- //var y1 = convertRange.MinScore;
- //var y2 = convertRange.MaxScore;
- //var x1 = convertGrade.MinScore;
- //var x2 = convertGrade.MaxScore;
- //var x = ((y - y1) * x2 + (y2 - y) * x1) / (y2 - y1);
- //return x;
- // a = Y2 - Y
- var a = (convertRange.MaxScore - score);
- // b = Y - Y1
- var b = (score - convertRange.MinScore);
- return Math.Round((b * convertGrade.MaxScore + a * convertGrade.MinScore) / (a + b));
- }
- #endregion
- }
|