12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655 |
- 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
- {
- private readonly IRepository<NceeScore> _rep = rep;
- private readonly List<short> _chooseCourses = [5, 6, 7, 9];
- /// <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 (!_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 (!_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.Any())
- {
- 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 = 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;
- }
- courses.Add(gi, courseDict[cn]);
- 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}]班号错误");
- }
- // 取各科成绩
- List<NceeScoreImportDto> courseScores = new();
- 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);
- }
- else
- {
- 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)
- {
- // 计算单科有效分
- 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 = 1, LineScoreX = cline.YuwenScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = 2, LineScoreX = cline.ShuxueScoreX });
- courseLineScores.Add(new() { NceePlanId = nceePlanId, DirectionCourseId = line.DirectionCourseId, NceeLineLevel = line.NceeLineLevel, CourseId = 3, 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 = 101, LineScoreX = cline.ZongheScoreX });
- }
- }
- await _rep.Change<NceeCourseLineScore>().Where(t => t.NceePlanId == nceePlanId).ExecuteDeleteAsync();
- List<NceeCourseLineScore> totalLines = new();
- 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 == 101)
- {
- 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 _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}
- ;
- -- 更新排名
- 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
- ;
- ");
- }
- /// <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
- ");
- }
- /// <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为转换分
- // 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
- }
|