using NPOI.SS.UserModel; using System.Net; using static Tiobon.Core.Model.Consts; namespace Tiobon.Core.Services; /// /// 课程 (服务) /// public class Ghre_CourseServices : BaseServices, IGhre_CourseServices { private readonly IBaseRepository _dal; private IGhre_CourseClassServices _ghre_CourseClassServices; private IGhre_CourseSnapServices _ghre_CourseSnapServices; public Ghre_CourseServices(IBaseRepository dal, ICaching caching, IGhre_CourseClassServices ghre_CourseClassServices, IGhre_CourseSnapServices ghre_CourseSnapServices) { this._dal = dal; base.BaseDal = dal; _ghre_CourseClassServices = ghre_CourseClassServices; _ghre_CourseSnapServices = ghre_CourseSnapServices; base._caching = caching; } public async Task> QueryList(QueryBody filter, string status, List ids) { RefAsync totalCount = 0; string sql = @$"SELECT * FROM (SELECT A.*, E.CourseWareName + ' (' + E.CourseWareNo + ')' CourseWareName, F.StaffName + ' (' + F.StaffNo + ')' ManagerStaffName, G.UserName CreateName, H.UserName UpdateName, CASE A.InOrOut WHEN 'In' THEN F.StaffName WHEN 'Out' THEN J.TeacherName END TeacherName, ISNULL (A.UpdateTime, A.CreateTime) CreateTime1 FROM Ghre_Course A LEFT JOIN Ghre_CourseWare E ON A.CourseWareId = E.Id LEFT JOIN Ghra_Staff F ON A.ManagerId = F.StaffID LEFT JOIN Ghrs_User G ON A.CreateBy = G.UserId LEFT JOIN Ghrs_User H ON A.UpdateBy = H.UserId LEFT JOIN Ghra_Staff I ON A.TeacherId = I.StaffID LEFT JOIN Ghre_Teacher J ON A.SchoolTeacherId = I.StaffID WHERE A.IsEnable = 1 AND dbo.FUserDataBelongPriv ({App.User.ID}, A.DataBelongID, NULL) = 1) A"; if (string.IsNullOrWhiteSpace(filter.orderBy)) filter.orderBy = "CourseNo ASC"; string conditions = " WHERE 1=1"; if (!string.IsNullOrWhiteSpace(status)) conditions += $" AND Status ='{status}'"; if (ids != null && ids.Any()) conditions += $" AND Id IN({string.Join(",", ids)})"; if (filter.jsonParam != null) foreach (JProperty jProperty in filter.jsonParam.Properties()) { var name = jProperty.Name; var value = jProperty.Value.ToString(); if (name == "page" || name == "pageSize") continue; if (!string.IsNullOrWhiteSpace(value)) { var jsonParam = JsonConvert.DeserializeObject(value); if (name == "CourseNoOrName") { conditions += $" AND ( CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')"; continue; } switch (jsonParam.operationKey) { case "Include": conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; break; case "NotInclude": conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; break; case "IsNull": conditions += $" AND {name} IS NULL"; break; case "NotNull": conditions += $" AND {name} IS NOT NULL"; break; case "Equal": conditions += $" AND {name} ='{jsonParam.columnValue}'"; break; case "NotEqual": conditions += $" AND {name} !='{jsonParam.columnValue}'"; break; case "GreaterOrEqual"://大于等于 conditions += $" AND {name} >='{jsonParam.columnValue}'"; break; case "Greater"://大于 conditions += $" AND {name} >'{jsonParam.columnValue}'"; break; case "LessOrEqual"://小于等于 conditions += $" AND {name} <='{jsonParam.columnValue}'"; break; case "Less"://小于 conditions += $" AND {name} <'{jsonParam.columnValue}'"; break; case "EqualAny":// if (jsonParam.columnValue != null) { var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString()); conditions += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})"; } break; case "NotEqualAny":// if (jsonParam.columnValue != null) { var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString()); conditions += $" AND ({name} NOT IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))}) OR {name} IS NULL)"; } break; default: break; } } } if (filter.pageSize == 0) filter.pageSize = 10000; sql += conditions; var data = await Db.SqlQueryable(sql) .OrderBy(filter.orderBy) .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount); var classsIds1 = data.Select(x => x.CourseClassId).Distinct().ToList(); var classsIds = new List(); classsIds1.ForEach(x => { if (!string.IsNullOrWhiteSpace(x)) { var courseClassIds = JsonConvert.DeserializeObject>(x); classsIds = classsIds.Concat(courseClassIds).ToList(); } }); classsIds = classsIds.Distinct().ToList(); var classs = await _ghre_CourseClassServices.Query(x => classsIds.Contains(x.Id)); var courseSceneIds1 = data.Select(x => x.CourseSceneIds).Distinct().ToList(); var courseSceneIds = new List(); courseSceneIds1.ForEach(x => { if (!string.IsNullOrWhiteSpace(x)) courseSceneIds = courseSceneIds.Concat(JsonConvert.DeserializeObject>(x)).ToList(); }); //data.ForEach(x => //{ // if (x.CourseSceneId != null) // courseSceneIds.Add(x.CourseSceneId.Value); //}); courseSceneIds = courseSceneIds.Distinct().ToList(); var courseScenes = await Db.Queryable().Where(x => courseSceneIds.Contains(x.Id)).ToListAsync(); for (int i = 0; i < data.Count; i++) { var x = data[i]; x.ChargeMethodLabel = await GetParaLabel("CourseChargeMethod", x.ChargeMethod); x.CourseClass2 = await GetParaLabel("TrainingCourseClass2", x.ChargeMethod); x.InOrOutLabel = await GetParaLabel("CourseInOrOut", x.InOrOut); x.IsOPenLabel = x.IsOpen == "1" ? "是" : "否"; var courseClass = classs.Where(a => x.CourseClassId.Contains(a.Id.ToString())).ToList(); x.CourseClassName = string.Join(",", courseClass.Select(a => a.ClassName + " (" + a.ClassNo + ")")); if (x.CourseSceneIds.IsNotEmptyOrNull()) { x.CourseSceneIds1 = JsonConvert.DeserializeObject>(x.CourseSceneIds); if (x.CourseSceneIds1.Any()) { var courseScene = courseScenes.Where(a => x.CourseSceneIds1.Contains(a.Id)).ToList(); x.CourseSceneName = string.Join(",", courseScene.Select(a => a.SceneName + " (" + a.SceneNo + ")")); } } //else if (x.CourseSceneId != null) //{ // var courseScene = courseScenes.Where(a => a.Id == x.CourseSceneId).ToList(); // x.CourseSceneName = string.Join(",", courseScene.Select(a => a.SceneName + " (" + a.SceneNo + ")")); //} x.BuiltInLabel = x.BuiltIn == 1 ? "是" : "否"; x.DataBelongName = await GetDataBelongName(x.DataBelongID); data[i] = x; } return new ServicePageResult(filter.pageNum, totalCount, filter.pageSize, data); } public async Task> QueryDeptID(int StaffID) { string sql = $"SELECT A.DeptID from Ghra_Staff A LEFT JOIN Ghro_Dept B ON A.DeptID = B.DeptID WHERE A.StaffID='{StaffID}'"; int id = await Db.Ado.GetIntAsync(sql); return ServiceResult.OprateSuccess("查询成功!", id); } public async Task> QueryTeacher(long? linkId) { var result = new CommonSelect(); JArray TableColumn = new JArray(); JArray DT_TablePageInfoT1 = new JArray(); JArray DT_TableDataT1 = new JArray(); JObject searchItem = new JObject(); JObject item; DataTable dt; string sql; searchItem = new JObject { new JProperty("defaultHidden", true), new JProperty("field","value"), new JProperty("label","讲师ID"), }; TableColumn.Add(searchItem); searchItem = new JObject { new JProperty("field","label"), new JProperty("label","讲师名称"), }; TableColumn.Add(searchItem); sql = "SELECT Id, TeacherNo , TeacherName FROM Ghre_Teacher WHERE IsEnable=1 "; if (linkId != null) sql += $"AND SchoolId ='{linkId}'"; dt = await Db.Ado.GetDataTableAsync(sql); for (int i = 0; i < dt.Rows.Count; i++) { item = new JObject { new JProperty("value",long.Parse(dt.Rows[i]["Id"].ToString())), new JProperty("label",dt.Rows[i]["TeacherNo"].ToString()+"-"+dt.Rows[i]["TeacherName"].ToString()) }; DT_TableDataT1.Add(item); } item = new JObject { new JProperty("ListMax",100), new JProperty("ListMin",10), new JProperty("PageNum",1), new JProperty("PageSize",99999), new JProperty("TotalCount",dt.Rows.Count), new JProperty("UIType","Auto") }; DT_TablePageInfoT1.Add(item); result.JM_TableColumnT1.TableColumn = TableColumn; result.DT_TableDataT1 = DT_TableDataT1; result.DT_TablePageInfoT1 = DT_TablePageInfoT1; return new ServiceResult() { Success = true, Message = "查询成功", Data = result, }; } public override async Task> QueryForm(QueryForm body) { var result = await base.QueryForm(body); string examPaperId = result.result.DT_TableDataT1[0].ExamPaperId; if (!string.IsNullOrWhiteSpace(examPaperId)) result.result.DT_TableDataT1[0].ExamPaperIds = JsonConvert.DeserializeObject>(examPaperId); string courseClassId = result.result.DT_TableDataT1[0].CourseClassId; if (!string.IsNullOrWhiteSpace(courseClassId)) result.result.DT_TableDataT1[0].CourseClassIds = JsonConvert.DeserializeObject>(courseClassId); string courseSceneIds = result.result.DT_TableDataT1[0].CourseSceneIds; if (!string.IsNullOrWhiteSpace(courseSceneIds)) result.result.DT_TableDataT1[0].CourseSceneIds1 = JsonConvert.DeserializeObject>(courseSceneIds); else result.result.DT_TableDataT1[0].ExamPaperIds = new List(); if (body.doType == "Copy") { result.result.DT_TableDataT1[0].CourseNo = null; result.result.DT_TableDataT1[0].CourseName = null; } result.result.DT_TableDataT1[0].IsOPenLabel = result.result.DT_TableDataT1[0].IsOpen == "1" ? "是" : "否"; return result; } public override async Task QueryById(object objId) { var data = await base.QueryById(objId); if (data == null) throw new Exception("无效的Id"); var DT_TableDataT1 = Mapper.Map(data).ToANew(); string examPaperId = DT_TableDataT1.ExamPaperId; var classsIds = new List(); var courseClassIds = JsonConvert.DeserializeObject>(DT_TableDataT1.CourseClassId); classsIds = classsIds.Concat(courseClassIds).ToList(); classsIds = classsIds.Distinct().ToList(); var classs = await _ghre_CourseClassServices.Query(x => classsIds.Contains(x.Id)); var courseSceneIds = new List(); if (DT_TableDataT1.CourseSceneIds.IsNotEmptyOrNull()) courseSceneIds = courseSceneIds.Concat(JsonConvert.DeserializeObject>(DT_TableDataT1.CourseSceneIds)).ToList(); courseSceneIds = courseSceneIds.Distinct().ToList(); var courseScenes = await Db.Queryable().Where(x => courseSceneIds.Contains(x.Id)).ToListAsync(); DT_TableDataT1.ChargeMethodLabel = await GetParaLabel("CourseChargeMethod", DT_TableDataT1.ChargeMethod); DT_TableDataT1.InOrOutLabel = await GetParaLabel("CourseInOrOut", DT_TableDataT1.InOrOut); DT_TableDataT1.IsOPenLabel = DT_TableDataT1.IsOpen == "1" ? "是" : "否"; var courseClass = classs.Where(a => DT_TableDataT1.CourseClassId.Contains(a.Id.ToString())).ToList(); DT_TableDataT1.CourseClassName = string.Join(",", courseClass.Select(a => a.ClassName + " (" + a.ClassNo + ")")); if (DT_TableDataT1.CourseSceneIds.IsNotEmptyOrNull()) { var courseScene = courseScenes.Where(a => DT_TableDataT1.CourseSceneIds.Contains(a.Id.ToString())).ToList(); DT_TableDataT1.CourseSceneName = string.Join(",", courseScene.Select(a => a.SceneName + " (" + a.SceneNo + ")")); } if (!string.IsNullOrWhiteSpace(examPaperId)) DT_TableDataT1.ExamPaperIds = JsonConvert.DeserializeObject>(examPaperId); string courseClassId = DT_TableDataT1.CourseClassId; if (!string.IsNullOrWhiteSpace(courseClassId)) DT_TableDataT1.CourseClassIds = JsonConvert.DeserializeObject>(courseClassId); string courseSceneIds1 = DT_TableDataT1.CourseSceneIds; if (!string.IsNullOrWhiteSpace(courseSceneIds1)) DT_TableDataT1.CourseSceneIds1 = JsonConvert.DeserializeObject>(courseSceneIds1); else DT_TableDataT1.ExamPaperIds = new List(); DT_TableDataT1.IsOPenLabel = DT_TableDataT1.IsOpen == "1" ? "是" : "否"; if (DT_TableDataT1.ManagerId != null) DT_TableDataT1.ManagerStaffName = (await Db.Queryable().Where(x => x.StaffID == DT_TableDataT1.ManagerId).FirstAsync())?.StaffName; if (DT_TableDataT1.CourseWareId != null) DT_TableDataT1.CourseWareName = (await Db.Queryable().Where(x => x.Id == DT_TableDataT1.CourseWareId).FirstAsync())?.CourseWareName; if (DT_TableDataT1.CreditRuleId != null) DT_TableDataT1.CreditRuleName = (await Db.Queryable().Where(x => x.Id == DT_TableDataT1.CreditRuleId).FirstAsync())?.RuleName; return DT_TableDataT1; } public async Task UpdateStatus(long[] ids, string status) { if (status != DIC_COURSE_STATUS.RELEASED && status != DIC_COURSE_STATUS.DISABLED && status != DIC_COURSE_STATUS.DRAFT) throw new Exception("无效的状态"); HttpRequest request = UserContext.Context.Request; var api = request.Path.ObjToString().TrimEnd('/').ToLower(); var ip = GetUserIp(UserContext.Context); var entities = new List(); foreach (var id in ids) { if (id == null || !BaseDal.Any(id)) continue; var entity = await BaseDal.QueryById(id); #region 关联数据有效性验证 if (entity.Status == DIC_COURSE_STATUS.DRAFT && status == DIC_COURSE_STATUS.RELEASED) { if (!entity.CourseClassId.IsNull()) { var CourseClassIds = JsonConvert.DeserializeObject>(entity.CourseClassId); if (CourseClassIds != null && CourseClassIds.Any()) { for (int i = 0; i < CourseClassIds.Count; i++) { if (!await Db.Queryable().AnyAsync(x => x.Id == CourseClassIds[i])) throw new Exception($"课程关联的课程分类已失效,请修正数据后继续发布!"); } } } if (!entity.CourseSceneId.IsNull()) if (!await Db.Queryable().AnyAsync(x => x.Id == entity.CourseSceneId)) return ServiceResult.OprateFailed($"课程关联的课程场景已失效,请修正数据后继续发布!"); if (!entity.ExamPaperId.IsNull()) { var ExamPaperIds = JsonConvert.DeserializeObject>(entity.ExamPaperId); if (ExamPaperIds != null && ExamPaperIds.Any()) { for (int i = 0; i < ExamPaperIds.Count; i++) { if (!await Db.Queryable().AnyAsync(x => x.Id == ExamPaperIds[0] && x.Status == DIC_EXAM_PAPER_STATUS.RELEASED)) return ServiceResult.OprateFailed($"课程关联的试卷已失效,请修正数据后继续发布!"); } } } #region 课程ID 同步至课件 if (!entity.CourseWareId.IsNull()) { var wares = await Db.Queryable().Where(x => x.CourseIds.Contains(id.ToString()) && x.Id != id).ToListAsync(); for (int j = 0; j < wares.Count; j++) { var courseIds2 = new List(); if (!string.IsNullOrWhiteSpace(wares[j].CourseIds)) courseIds2 = JsonConvert.DeserializeObject>(wares[j].CourseIds); courseIds2 = courseIds2.Where(x => x != id).ToList(); wares[j].CourseIds = JsonConvert.SerializeObject(courseIds2); } await Db.Updateable(wares).UpdateColumns(it => new { it.CourseIds }).ExecuteCommandAsync(); var ware = await Db.Queryable().FirstAsync(x => x.Id == entity.CourseWareId); if (ware != null) { var courseIds2 = new List(); if (!string.IsNullOrWhiteSpace(ware.CourseIds)) courseIds2 = JsonConvert.DeserializeObject>(ware.CourseIds); if (!courseIds2.Any(x => x == id)) { courseIds2.Add(id); ware.CourseIds = JsonConvert.SerializeObject(courseIds2); await Db.Updateable().SetColumns(it => it.CourseIds == ware.CourseIds).Where(it => it.Id == ware.Id).ExecuteCommandAsync(); } } } #endregion entity.PublishTime = DateTime.Now; } else if (status == DIC_COURSE_STATUS.DRAFT && entity.Status == DIC_COURSE_STATUS.RELEASED) { #region 课程ID 同步至课件 if (!entity.CourseWareId.IsNull()) { var wares = await Db.Queryable().Where(x => x.CourseIds.Contains(id.ToString()) && x.Id != id).ToListAsync(); for (int j = 0; j < wares.Count; j++) { var courseIds2 = new List(); if (!string.IsNullOrWhiteSpace(wares[j].CourseIds)) courseIds2 = JsonConvert.DeserializeObject>(wares[j].CourseIds); courseIds2 = courseIds2.Where(x => x != id).ToList(); wares[j].CourseIds = JsonConvert.SerializeObject(courseIds2); } await Db.Updateable(wares).UpdateColumns(it => new { it.CourseIds }).ExecuteCommandAsync(); } #endregion } #endregion //没有任何人学习(没点过学习入口,即学习时长=0)可以取消发布; //已经有人开始学习:不可以取消,不可以停用; //所有人学完:不可以取消,只可以停用; if (entity.Status == DIC_COURSE_STATUS.RELEASED) { var examPaper = await Db.Queryable().FirstAsync(x => x.LinkId == id && x.LinkType == "CourseId" && x.Status != DIC_COURSE_STATUS.DISABLED); if (examPaper is null && entity.CourseSceneId != null) examPaper = await Db.Queryable().FirstAsync(x => x.LinkId == entity.CourseSceneId && x.LinkType == "CourseSceneId" && x.Status != DIC_COURSE_STATUS.DISABLED); if (examPaper != null) return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】已与试卷【{examPaper.PaperName}({examPaper.PaperName})】关联,暂不可{(status == DIC_COURSE_STATUS.DRAFT ? "取消发布" : "停用")}"); if (entity.CourseWareId.IsNullOrEmpty()) { if (status == DIC_COURSE_STATUS.DRAFT && await Db.Queryable(). AnyAsync(x => x.CourseId == id && (x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.NO_FINISH || x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.HAS_FINISH) && x.CourseEndTime != null && x.CourseEndTime.Value.Date >= DateTime.Now.Date)) return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】有学员正在学习中,暂不可取消发布!"); if (status == DIC_COURSE_STATUS.DISABLED && await Db.Queryable(). AnyAsync(x => x.CourseId == id && x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.NO_FINISH && x.CourseEndTime != null && x.CourseEndTime.Value.Date >= DateTime.Now.Date)) return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】有学员正在学习中,暂不可停用!"); } else { if (status == DIC_COURSE_STATUS.DRAFT && await Db.Queryable(). AnyAsync(x => x.CourseSceneId == entity.CourseWareId && (x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.NO_FINISH || x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.HAS_FINISH) && x.CourseEndTime != null && x.CourseEndTime.Value.Date >= DateTime.Now.Date)) return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】有学员正在学习中,暂不可取消发布!"); if (status == DIC_COURSE_STATUS.DISABLED && await Db.Queryable(). AnyAsync(x => x.CourseSceneId == entity.CourseWareId && x.StudyStatus == DIC_STUDY_RECORD_STUDY_STATUS.NO_FINISH && x.CourseEndTime != null && x.CourseEndTime.Value.Date >= DateTime.Now.Date)) return ServiceResult.OprateFailed($"课程【{entity.CourseName}({entity.CourseNo})】有学员正在学习中,暂不可停用!"); } } entity.UpdateIP = ip; entity.UpdateProg = api; if (status == DIC_COURSE_STATUS.RELEASED || status == DIC_COURSE_STATUS.DISABLED || status == DIC_COURSE_STATUS.DRAFT) { entity.Status = status; entities.Add(entity); } #region 生成课程快照 if (status == DIC_COURSE_STATUS.RELEASED) { CheckCodeExist("Ghre_Course", "CourseNo", entity.CourseNo, ModifyType.Add, "【已发布】中课程编号", id, $"Status='{DIC_COURSE_STATUS.RELEASED}'"); var sql = $"UPDATE Ghre_CourseSnap SET IsEnable = 0 WHERE CourseId = '{id}' AND IsEnable = 1"; await Db.Ado.ExecuteCommandAsync(sql); var entity1 = Mapper.Map(entity).ToANew(); var courseClassIds = JsonConvert.DeserializeObject>(entity1.CourseClassId); var classs = await _ghre_CourseClassServices.Query(x => courseClassIds.Contains(x.Id)); entity1.CourseClass = string.Join("、", classs.Select(o => o.ClassName)); entity1.CourseClass1 = string.Join("、", classs.Select(o => o.ClassName + "(" + o.ClassNo + ")")); entity1.CourseId = id; var examPaper = await Db.Queryable().FirstAsync(x => x.LinkId == id && x.LinkType == "CourseId" && x.Status != DIC_COURSE_STATUS.DISABLED); await _ghre_CourseSnapServices.Add(entity1); } #endregion #region 处理对应场景标准课时、学分等 if (entity.CourseSceneId.IsNotEmptyOrNull()) { var courseScene = await Db.Queryable().Where(x => x.Id == entity.CourseSceneId).FirstAsync(); if (courseScene != null) { var courses = await Db.Queryable() .WhereIF(status == DIC_COURSE_STATUS.RELEASED, x => x.Id == id || (x.CourseSceneId == entity.CourseSceneId && x.Status == DIC_COURSE_STATUS.RELEASED)) .WhereIF(status != DIC_COURSE_STATUS.RELEASED, x => x.Id != id || (x.CourseSceneId == entity.CourseSceneId && x.Status == DIC_COURSE_STATUS.RELEASED)) .ToListAsync(); courseScene.StandardHour = courses.Sum(x => x.StandardHour); courseScene.CreditPoints = courses.Sum(x => x.CreditPoints); if (courses.Any()) { courseScene.CoverUrl = courses.First()?.CoverUrl; courseScene.UseDefaultCoverImage = courses.First()?.UseDefaultCoverImage; courseScene.DefaultCoverImageName = courses.First()?.DefaultCoverImageName; } await Db.Updateable(courseScene).UpdateColumns(it => new { it.StandardHour, it.CreditPoints, it.CoverUrl, it.UseDefaultCoverImage, it.DefaultCoverImageName }).ExecuteCommandAsync(); } } #endregion } var result = await BaseDal.Update(entities); if (status == DIC_COURSE_STATUS.RELEASED) return ServiceResult.OprateSuccess("发布成功!"); else if (status == DIC_COURSE_STATUS.DRAFT) return ServiceResult.OprateSuccess("已启用成功,请进入草稿箱查看!"); else return ServiceResult.OprateSuccess("停用成功!"); } public override async Task Add(InsertGhre_CourseInput entity) { entity.ExamPaperId = JsonHelper.ObjToJson(entity.ExamPaperIds); if (entity.CourseClassIds != null) entity.CourseClassId = JsonHelper.ObjToJson(entity.CourseClassIds); entity.CourseSceneIds = JsonHelper.ObjToJson(entity.CourseSceneIds1); entity.Status = DIC_COURSE_STATUS.DRAFT; entity.DefaultCoverImageName = entity.DefaultCoverImageName ?? "defaultCourseCover1"; entity.UseDefaultCoverImage = entity.UseDefaultCoverImage ?? true; //entity.IsOpen = entity.IsOPenLabel == true ? "1" : "0"; if (entity.ClassId != null) { entity.CourseClassIds = [entity.ClassId.Value]; entity.CourseClassId = JsonHelper.ObjToJson(entity.CourseClassIds); } if (entity.InOrOut == "In") { var teacher = await Db.Queryable().FirstAsync(x => x.StaffId == entity.TeacherId); if (!teacher.IsNull()) { entity.SchoolTeacherId = teacher.Id; } else entity.SchoolTeacherId = null; } if (await QueryCompanyCode() == "Ushio") { var courseClass = await Db.Queryable().Where(x => x.Id == entity.CourseClassIds[0]).Select(x => x.ClassNo).FirstAsync(); var prefixTemp = courseClass + entity.CourseClass2.Substring(1, entity.CourseClass2.Length - 1); entity.CourseNo = await GenerateContinuousSequence("Ghre_Course", "CourseNo", prefixTemp, prefixTemp.Length + 2, 2); } var result = await base.Add(entity); return result; } public override async Task Update(long Id, EditGhre_CourseInput editModel) { editModel.ExamPaperId = JsonHelper.ObjToJson(editModel.ExamPaperIds); if (editModel.CourseClassIds != null) editModel.CourseClassId = JsonHelper.ObjToJson(editModel.CourseClassIds); editModel.CourseSceneIds = JsonHelper.ObjToJson(editModel.CourseSceneIds1); if (editModel.ClassId != null) { editModel.CourseClassIds = [editModel.ClassId.Value]; editModel.CourseClassId = JsonHelper.ObjToJson(editModel.CourseClassIds); } if (!editModel.CourseClassId.IsNull()) { var CourseClassIds = JsonConvert.DeserializeObject>(editModel.CourseClassId); if (CourseClassIds != null && CourseClassIds.Any()) { for (int i = 0; i < CourseClassIds.Count; i++) { if (!await Db.Queryable().AnyAsync(x => x.Id == CourseClassIds[i])) throw new Exception($"课程关联的课程分类已失效,请修正数据后继续发布!"); } } } if (!editModel.CourseSceneId.IsNull()) if (!await Db.Queryable().AnyAsync(x => x.Id == editModel.CourseSceneId)) throw new Exception($"课程关联的课程场景已失效,请修正数据后继续发布!"); if (!editModel.ExamPaperId.IsNull()) { var ExamPaperIds = JsonConvert.DeserializeObject>(editModel.ExamPaperId); if (ExamPaperIds != null && ExamPaperIds.Any()) { for (int i = 0; i < ExamPaperIds.Count; i++) { if (!await Db.Queryable().AnyAsync(x => x.Id == ExamPaperIds[i] && x.Status == DIC_EXAM_PAPER_STATUS.RELEASED)) throw new Exception($"课程关联的试卷已失效,请修正数据后继续发布!"); } } } //editModel.IsOpen = editModel.IsOPenLabel == true ? "1" : "0"; var result = await base.Update(Id, editModel); return result; } #region 获取通用列表下拉 /// /// 获取通用列表下拉 /// /// /// public async Task> GetSelectAsync(long? linkId, string keyWords) { var result = new CommonSelect(); var TableColumn = new JArray(); var DT_TablePageInfoT1 = new JArray(); var DT_TableDataT1 = new JArray(); var searchItem = new JObject(); JObject item; DataTable dt; string sql; searchItem = new JObject { new JProperty("defaultHidden", true), new JProperty("field","value"), new JProperty("label","课程ID") }; TableColumn.Add(searchItem); searchItem = new JObject { new JProperty("field","label"), new JProperty("label","课程名称") }; TableColumn.Add(searchItem); sql = $"SELECT Id, CourseNo , CourseName FROM Ghre_Course WHERE Status ='{Consts.DIC_COURSE_STATUS.RELEASED}' AND IsEnable=1"; if (!string.IsNullOrWhiteSpace(keyWords)) sql += $"AND ( CourseNo like '%{keyWords}%' or CourseName like '%{keyWords}%')"; if (linkId.HasValue) sql += $" AND (CourseSceneId='{linkId}' or CourseSceneIds like '%{linkId}%')"; sql += $" ORDER BY UpdateTime DESC, CreateTime DESC"; dt = await Db.Ado.GetDataTableAsync(sql); for (int i = 0; i < dt.Rows.Count; i++) { item = new JObject { new JProperty("value",long.Parse(dt.Rows[i]["Id"].ToString())), new JProperty("label", dt.Rows[i]["CourseName"].ToString() + "("+dt.Rows[i]["CourseNo"].ToString()+")") }; DT_TableDataT1.Add(item); } item = new JObject { new JProperty("ListMax",100), new JProperty("ListMin",10), new JProperty("PageNum",1), new JProperty("PageSize",99999), new JProperty("TotalCount",dt.Rows.Count), new JProperty("UIType","Auto") }; DT_TablePageInfoT1.Add(item); result.JM_TableColumnT1.TableColumn = TableColumn; result.DT_TableDataT1 = DT_TableDataT1; result.DT_TablePageInfoT1 = DT_TablePageInfoT1; return new ServiceResult() { Success = true, Message = "查询成功", Data = result, }; } #endregion public async Task> ExportExcel(QueryExport body, string status) { QueryBody filter = new QueryBody(); filter.pageNum = 1; filter.pageSize = 1000000; filter.langId = body.langId; var condition = "1=1"; var ids = new List(); if (body.exportSet.SelectRowKeys != null && body.exportSet.SelectRowKeys.Any()) ids = body.exportSet.SelectRowKeys; var data = await QueryList(filter, status, ids); string sql = $@"SELECT * FROM Ghrs_PageSettingQuery WHERE IsEnable = 1 AND PageNo = '{body.menuName}' AND (defaultHidden = 'false' or defaultHidden is null) ORDER BY SortNo ASC"; var columns = await Db.Ado.SqlQueryAsync(sql); var fieldDescs = new Dictionary(); if (body.exportSet.ExFields.Any()) body.exportSet.ExFields.ForEach(x => { if (columns.Any(o => o.field == x)) fieldDescs.Add(x, columns.FirstOrDefault(o => o.field == x)?.label); }); else fieldDescs = columns.ToDictionary(item => item.field, item => item.label); var dt = ToDataTable(data.result.DT_TableDataT1, fieldDescs, null); // 获取所有列名 var dtColumns = dt.Columns; var id = SnowFlakeSingle.instance.getID(); var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}export{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}"; if (!Directory.Exists(physicsPath + path)) Directory.CreateDirectory(physicsPath + path); path = path + body.exportSet.TitleName + ".xlsx"; NPOIHelper.ExportExcel(dt, body.exportSet.TitleName, "sheet1", physicsPath + path); var result = new ExcelData(); result.filePath = "/Advanced" + path; result.fileName = body.exportSet.TitleName + ".xlsx"; return ServiceResult.OprateSuccess("导出成功", result); } public override async Task> DownloadExcel(string menuName) { var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}ExcelTemplate{Path.DirectorySeparatorChar}"}"; if (!Directory.Exists(physicsPath + path)) Directory.CreateDirectory(physicsPath + path); Type entityType = typeof(Ghre_Course); var fileName = entityType.GetEntityTableName() + ".xlsx"; //physicsPath = physicsPath + path + fileName; IWorkbook hssfworkbook; ISheet sheet; using (FileStream file = new FileStream(physicsPath + path + fileName, FileMode.Open, FileAccess.Read)) { //hssfworkbook = new HSSFWorkbook(file); //hssfworkbook = new XSSFWorkbook(file); hssfworkbook = WorkbookFactory.Create(file); } ISheet sheet2 = hssfworkbook.CreateSheet("下拉数据"); var newFileName = Guid.NewGuid() + ".xlsx"; int listColIndex = 0; //string sql = @"select 'Course' field, Id id, CourseNo no, CourseName name from Ghre_Course where IsEnable=1 and Status='Released'"; //var dataSourceLists = await Db.Ado.SqlQueryAsync(sql); //if (dataSourceLists.Any()) //{ // var types = new List // { // "学习记录" // }; // types.ForEach(sheetName => // { // int sheetIndex = hssfworkbook.GetSheetIndex(sheetName); // if (sheetIndex >= 0) // { // sheet = hssfworkbook.GetSheetAt(sheetIndex); // SetCellDropdownList(sheet, 0, 0, dataSourceLists.Select(x => x.name).ToArray()); // } // }); // MemoryStream ms; // using (ms = new MemoryStream()) // { // hssfworkbook.Write(ms); // ms.Flush(); // hssfworkbook.Dispose(); // //ms.Position = 0; // //return ms; // } // using (FileStream fs = new FileStream(physicsPath + path + newFileName, FileMode.Create, FileAccess.Write)) // { // byte[] data = ms.ToArray(); // fs.Write(data, 0, data.Length); // fs.Flush(); // } //} var physicsPath1 = physicsPath + path + fileName; //if (dataSourceLists.Any()) // physicsPath1 = physicsPath + path + newFileName; var result = ServiceResult.OprateSuccess("课程管理_" + DateTimeHelper.ConvertToSecondString1(DateTime.Now) + ".xlsx", physicsPath1); return result; } public override async Task> ImportExcel(IFormFile file, string menuName = null, long? MasterId = null) { var data = new ExcelData(); long id = SnowFlakeSingle.instance.getID(); var physicsPath = $"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}wwwroot"; var path = $"{$"{Path.DirectorySeparatorChar}files{Path.DirectorySeparatorChar}import{Path.DirectorySeparatorChar}{id}{Path.DirectorySeparatorChar}"}"; if (!Directory.Exists(physicsPath + path)) Directory.CreateDirectory(physicsPath + path); var filepath = physicsPath + path + file.FileName; using (var stream = File.Create(filepath)) { await file.CopyToAsync(stream); } string extension = Path.GetExtension(filepath); bool isExistError = false; var id1 = SnowFlakeSingle.instance.getID(); string errorFileName = path + SnowFlakeSingle.instance.getID() + extension; var dt = NPOIHelper.ImportExcel(filepath, "课程管理"); if (dt.Columns["Comments"] == null) dt.Columns.Add("Comments", typeof(string)); for (int i = 0; i < dt.Rows.Count; i++) { var comments = new List(); if (!dt.Columns.Contains("课程编号(必填)")) { comments.Add("未查询到【课程编号】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("课程名称(必填)")) { comments.Add("未查询到【课程名称】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("课程分类(必填)")) { comments.Add("未查询到【课程分类】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("课程场景")) { comments.Add("未查询到【课程场景】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("标准课时(必填)")) { comments.Add("未查询到【标准课时】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("学分(必填)")) { comments.Add("未查询到【学分】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("内/外训")) { comments.Add("未查询到【内/外训】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("是否公开课(必填)")) { comments.Add("未查询到【是否公开课】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("培训有效期(月)")) { comments.Add("未查询到【培训有效期(月)】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("课程大纲")) { comments.Add("未查询到【课程大纲】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("课前准备")) { comments.Add("未查询到【课前准备】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (!dt.Columns.Contains("备注")) { comments.Add("未查询到【备注】列!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } var courseNo = dt.Rows[i]["课程编号(必填)"].ToString(); long? courseClassId = null; var courseClass = dt.Rows[i]["课程分类(必填)"].ToString(); var courseName = dt.Rows[i]["课程名称(必填)"].ToString(); long? courseSceneId = null; var courseScene = dt.Rows[i]["课程场景"].ToString(); var standardHour = dt.Rows[i]["标准课时(必填)"].ToString(); var creditPoints = dt.Rows[i]["学分(必填)"].ToString(); var inOrOut = dt.Rows[i]["内/外训"].ToString(); var isOPen = dt.Rows[i]["是否公开课(必填)"].ToString(); var validityPeriod = dt.Rows[i]["培训有效期(月)"].ToString(); var outline = dt.Rows[i]["课程大纲"].ToString(); var beforeReady = dt.Rows[i]["课前准备"].ToString(); var remarkSz = dt.Rows[i]["备注"].ToString(); if (await base.AnyAsync(x => x.CourseNo == courseNo && x.CourseName == courseName)) { comments.Add($"系统已存在相同编号名称课程数据!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (courseClass.IsNotEmptyOrNull()) { courseClassId = (await _ghre_CourseClassServices.QuerySingle(x => x.ClassName == courseClass))?.Id; if (courseClassId is null) courseClassId = await _ghre_CourseClassServices.Add(new InsertGhre_CourseClassInput() { ClassNo = courseClass, ClassName = courseClass }); } else { comments.Add($"课程分类为空!"); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } if (courseScene.IsNotEmptyOrNull()) { await Db.Queryable().Where(x => x.CourseName == courseScene).FirstAsync(); courseSceneId = (await Db.Queryable().Where(x => x.CourseName == courseScene).FirstAsync())?.Id; } if (standardHour.IsNullOrEmpty()) standardHour = "0"; if (creditPoints.IsNullOrEmpty()) creditPoints = "0"; if (inOrOut.IsNotEmptyOrNull()) { var items = await GetParaList("CourseInOrOut"); inOrOut = items.Where(x => x.ParaDetailName == inOrOut).FirstOrDefault()?.ParaDetailNo ?? "In"; } if (isOPen.IsNullOrEmpty()) isOPen = "是"; List courseClassId1 = [courseClassId]; var dict = new Dictionary { { "Id", SnowFlakeSingle.Instance.NextId() }, { "CreateBy", App.User.ID }, { "CreateTime", DateTime.Now }, { "CourseClassId",JsonHelper.ObjToJson(courseClassId1) }, { "CourseNo", courseNo }, { "CourseName", courseName }, { "CourseSceneId",courseSceneId }, { "StandardHour", standardHour }, { "CreditPoints", creditPoints }, { "InOrOut", inOrOut }, { "IsOPen", isOPen=="是" ? true:false }, { "ValidityPeriod", validityPeriod }, { "Outline", outline }, { "BeforeReady", beforeReady }, { "Status", "Draft" }, { "UseDefaultCoverImage", true }, { "DefaultCoverImageName", "defaultCourseCover1" }, { "RemarkSz", remarkSz } }; try { await Db.Insertable(dict).AS("Ghre_Course").ExecuteCommandAsync(); data.SuccessCount++; //data.SuccessCount += list.Count; } catch (Exception E) { comments.Add(E.Message); data.ErrorCount++; dt.Rows[i]["Comments"] = string.Join(";", comments.Select(a => a)); isExistError = true; continue; } } if (isExistError) { NPOIHelper.ExportExcel(dt, null, "课程管理", physicsPath + errorFileName); data.filePath = "/Advanced" + errorFileName; } return ServiceResult.OprateSuccess("导入成功!", data); } #region 获取公开课查询条件 public async Task> QueryPublicSearchFields(QueryBody body) { var entity = new CoursePublicSearch(); string sql = @"SELECT Langkey field, CASE {2} WHEN 1 THEN isnull (Value01, LangValue) WHEN 2 THEN isnull (Value02, LangValue) WHEN 3 THEN isnull (Value03, LangValue) WHEN 4 THEN isnull (Value04, LangValue) WHEN 5 THEN isnull (Value05, LangValue) WHEN 6 THEN isnull (Value06, LangValue) WHEN 7 THEN isnull (Value07, LangValue) WHEN 8 THEN isnull (Value08, LangValue) WHEN 9 THEN isnull (Value09, LangValue) WHEN 10 THEN isnull (Value10, LangValue) END label FROM Ghrs_LangKey WHERE IsEnable = 1 AND (LangKey LIKE 'GHR_Page%' OR LangKey LIKE 'GHR_Common%')"; sql = string.Format(sql, body.menuName, App.User.ID, body.langId); entity.DT_PageMutiMsg = await Db.Ado.SqlQueryAsync(sql); entity.SearchFields.Add(new CoursePublicSearchField() { label = "课程编号/名称", field = "CourseNoOrName", elementType = "Input", editable = true, required = false, multipleSelect = false, }); entity.SearchFields.Add(new CoursePublicSearchField() { label = "课程分类", field = "CourseClassId", elementType = "ApiSelect", dataSource = "CommonList_TrainingCourseClass", editable = true, required = false, multipleSelect = false, }); entity.SearchFields.Add(new CoursePublicSearchField() { label = "课程场景", field = "CourseSceneId", elementType = "ApiSelect", dataSource = "CommonList_TrainingCourseScene", editable = true, required = false, multipleSelect = false, }); entity.SearchFields.Add(new CoursePublicSearchField() { label = "是否学过", field = "HasStudy", elementType = "ApiSelect", dataSource = "TBParaDetail_Train_CourseIsOpen", editable = true, required = false, multipleSelect = false, }); return ServiceResult.OprateSuccess("", entity); } #endregion #region 获取公开课 public async Task> QueryPublic(QueryBody filter) { int? staffId = GetStaffId(); RefAsync totalCount = 0; var dt = DateTime.Now.Date; string sql = @$"SELECT * FROM (SELECT A.Id, A.CoverUrl, A.PublishTime, A.CourseNo, A.UseDefaultCoverImage, A.DefaultCoverImageName, A.CourseSceneId, A.CourseClassId, A.CourseName + ' (' + A.CourseNo + ')' CourseName, ISNULL (A.StandardHour, 0) StandardHour, ISNULL (A.CreditPoints, 0) CreditPoints, NULL ExamDate, B.BeginTime ExamBeginDate, B.EndTime ExamEndDate, CAST ('0' AS BIT) DisableBtn, B.DateType, B.AfterHowLong, C.Id StudyRecordId, C.BeginTime StudyBeginTime FROM Ghre_Course A LEFT JOIN Ghre_Exam B ON A.Id = B.CourseId AND B.Status = '{DIC_EXAM_STATUS.RELEASED}' AND B.IsEnable =1 AND ( ( B.DateType = '{DicExamDateType.EXAM_DATE}' AND B.BeginTime <= '{dt}' AND B.EndTime >= '{dt}') OR B.DateType = '{DicExamDateType.AFTER_HOW_LONG}') LEFT JOIN Ghre_StudyRecord C ON A.Id = C.CourseId AND C.IsEnable = 1 AND C.StaffId = '{staffId}' AND C.CourseBeginTime <= '{dt}' AND C.CourseEndTime >= '{dt}' WHERE A.IsOpen = 1 AND A.IsEnable = 1 AND A.Status = '{DIC_COURSE_STATUS.RELEASED}' and dbo.FUserDataBelongPriv({App.User.ID},A.DataBelongID,null)=1) A"; //if (await QueryCompanyCode() == "Ushio" && string.IsNullOrWhiteSpace(filter.orderBy)) //{ // filter.orderBy = "PublishTime DESC"; //} //else if (string.IsNullOrWhiteSpace(filter.orderBy)) filter.orderBy = "PublishTime DESC"; string conditions = " WHERE 1=1"; if (filter.jsonParam != null) foreach (JProperty jProperty in filter.jsonParam.Properties()) { var name = jProperty.Name; var value = jProperty.Value.ToString(); if (name == "page" || name == "pageSize") continue; if (name == "CourseNoOrName") { var jsonParam = JsonConvert.DeserializeObject(value); conditions += $" AND (CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')"; continue; } if (name == "HasStudy") { var jsonParam = JsonConvert.DeserializeObject(value); if (jsonParam.columnValue != null) if (jsonParam.columnValue.ToString() == "1") conditions += $" AND (StudyRecordId IS NOT NULL AND StudyBeginTime IS NOT NULL)"; else conditions += $" AND (StudyRecordId IS NULL OR StudyBeginTime IS NULL)"; continue; } if (name == "CourseClassId") { var jsonParam = JsonConvert.DeserializeObject(value); conditions += $" AND CourseClassId LIKE '%{jsonParam.columnValue}%' "; continue; } if (name == "KeyWords") { var jsonParam = JsonConvert.DeserializeObject(value); conditions += $" AND CourseName LIKE '%{jsonParam.columnValue}%' "; continue; } if (!string.IsNullOrWhiteSpace(value)) { var jsonParam = JsonConvert.DeserializeObject(value); switch (jsonParam.operationKey) { case "Include": conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; break; case "NotInclude": conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; break; case "IsNull": conditions += $" AND {name} IS NULL"; break; case "NotNull": conditions += $" AND {name} IS NOT NULL"; break; case "Equal": conditions += $" AND {name} ='{jsonParam.columnValue}'"; break; case "NotEqual": conditions += $" AND {name} !='{jsonParam.columnValue}'"; break; default: break; } } } //if (ids != null && ids.Any()) // conditions += $" AND Id IN({string.Join(",", ids)})"; sql += conditions; if (filter.pageSize == 0) filter.pageSize = 10000; var data = await Db.SqlQueryable(sql) .OrderBy(filter.orderBy) .ToPageListAsync(filter.pageNum, filter.pageSize, totalCount); data.ForEach(x => { if (!x.ExamId.IsNull()) { if (x.ExamBeginDate != null && x.ExamEndDate != null && x.DateType == DicExamDateType.EXAM_DATE) x.ExamDateString = DateTimeHelper.ConvertToDayString(x.ExamBeginDate) + " ~ " + DateTimeHelper.ConvertToDayString(x.ExamEndDate); else if (x.DateType == DicExamDateType.AFTER_HOW_LONG) x.ExamDateString = $"学完{x.AfterHowLong}天"; } if (!x.StudyRecordId.IsNull()) x.DisableBtn = true; }); return new ServicePageResult(filter.pageNum, totalCount, filter.pageSize, data); } #endregion #region 场景ID获取课程 public async Task>> QueryBySceneId(long courseSceneId) { var entitys = await base.Query(x => x.CourseSceneId != null && x.CourseSceneIds.Contains(courseSceneId.ObjToString()) && x.Status == Consts.DIC_COURSE_STATUS.RELEASED); var courseWareIds = entitys.Select(x => x.CourseWareId).Distinct().ToList(); var attachments = await Db.Queryable().Where(x => courseWareIds.Contains(x.CourseWareId)).ToListAsync(); //var attachments = await _ghre_CourseWareAttachmentServices.Query(x => x.CourseWareId != null && attachmentIds.Contains(x.CourseWareId.Value)); var entitys1 = Mapper.Map(entitys).ToANew>(); entitys1.ForEach(x => { x.CourseWareName = string.Join(",", attachments.Where(o => o.CourseWareId == x.CourseWareId).OrderBy(x => x.SortNo).Select(o => o.AttachmentName)); }); return ServiceResult>.OprateSuccess("查询成功", entitys1); } #endregion #region 修改场景下课程顺序 public async Task ModifyCourseSortNo(List courses) { await Db.Updateable(courses).UpdateColumns(it => new { it.SortNo }).ExecuteCommandAsync(); return ServiceResult.OprateSuccess("执行成功!"); } #endregion #region 查询课程、课程场景 public async Task> QueryCourseAndScene(QueryBody filter) { RefAsync totalCount = 0; string sql = @"SELECT Id, CourseNo, CourseName, Type from Ghre_CourseScene_V A"; if (string.IsNullOrWhiteSpace(filter.orderBy)) filter.orderBy = "CourseNo ASC"; string conditions = " WHERE 1=1"; conditions += $"AND dbo.FUserDataBelongPriv ({App.User.ID}, A.DataBelongID, NULL) = 1"; if (filter.jsonParam != null) foreach (JProperty jProperty in filter.jsonParam.Properties()) { var name = jProperty.Name; var value = jProperty.Value.ToString(); if (name == "page" || name == "pageSize") continue; if (!string.IsNullOrWhiteSpace(value)) { var jsonParam = JsonConvert.DeserializeObject(value); if (name == "CourseNoOrName") { conditions += $" AND ( CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')"; continue; } switch (jsonParam.operationKey) { case "Include": conditions += $" AND {name} LIKE '%{jsonParam.columnValue}%'"; break; case "NotInclude": conditions += $" AND {name} NOT LIKE '%{jsonParam.columnValue}%'"; break; case "IsNull": conditions += $" AND {name} IS NULL"; break; case "NotNull": conditions += $" AND {name} IS NOT NULL"; break; case "Equal": conditions += $" AND {name} ='{jsonParam.columnValue}'"; break; case "NotEqual": conditions += $" AND {name} !='{jsonParam.columnValue}'"; break; case "GreaterOrEqual"://大于等于 conditions += $" AND {name} >='{jsonParam.columnValue}'"; break; case "Greater"://大于 conditions += $" AND {name} >'{jsonParam.columnValue}'"; break; case "LessOrEqual"://小于等于 conditions += $" AND {name} <='{jsonParam.columnValue}'"; break; case "Less"://小于 conditions += $" AND {name} <'{jsonParam.columnValue}'"; break; case "EqualAny":// if (jsonParam.columnValue != null) { var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString()); conditions += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})"; } break; case "NotEqualAny":// if (jsonParam.columnValue != null) { var ids1 = JsonHelper.JsonToObj>(jsonParam.columnValue.ToString()); conditions += $" AND ({name} NOT IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))}) OR {name} IS NULL)"; } break; default: break; } } } if (filter.pageSize == 0) filter.pageSize = 10000; sql += conditions; totalCount = await Db.Ado.GetIntAsync($"SELECT COUNT(0) from ({sql}) A WHERE 1=1"); var sql1 = GetQueryString(sql, filter.pageNum, filter.pageSize, filter.orderBy); var data = DbAccess.QueryList(sql1); for (int i = 0; i < data.Count; i++) { data[i].RequiredCount = await Db.Queryable() .Where(x => (x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) && x.OpenClassId == null && x.CourseType.Contains("Required")) .CountAsync(); data[i].ElectiveCount = await Db.Queryable() .Where(x => (x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) && x.OpenClassId == null && x.CourseType.Contains("Elective")) .CountAsync(); data[i].OpenClassCount = await Db.Queryable() .Where(x => (x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) && x.OpenClassId != null) .CountAsync(); data[i].CompleteCount = await Db.Queryable() .Where(x => (x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) && x.CompleteStatus == DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED) .CountAsync(); var studyRecordIds = await Db.Queryable() .Where(x => x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) .Select(x => x.Id) .ToListAsync(); data[i].TotalStudyDuration = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)) .SumAsync(x => x.StudyDuration); data[i].TotalStudyDuration = data[i].TotalStudyDuration ?? 0; if (data[i].TotalStudyDuration > 0) { var avgStudyDuration = data[i].TotalStudyDuration / (studyRecordIds.Count); data[i].AvgStudyDuration = avgStudyDuration.TrimDecimalString(2); } data[i].AvgScore = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)) .AvgAsync(x => x.Score); data[i].AvgScore = data[i].AvgScore ?? 0; if (data[i].AvgScore > 0) data[i].AvgScore = data[i].AvgScore.TrimDecimal(2); var examCount = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)) .CountAsync(); var passCount = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value) && x.IsPass == true) .CountAsync(); if (passCount > 0 && examCount > 0) data[i].PassPercent = passCount / examCount; } return new ServicePageResult(filter.pageNum, totalCount, filter.pageSize, data); } #endregion #region 课程统计 /// /// 课程统计 /// /// /// public async Task QueryStatistic(long id) { if (!await AnyAsync(x => x.Id == id)) return await QuerySceneStatistic(id); dynamic obj = new ExpandoObject(); dynamic data = new ExpandoObject(); var entity = await QueryById(id); data.CourseClassName = entity.CourseClassName; data.StandardHour = entity.StandardHour; data.CreditPoints = entity.CreditPoints; data.ManagerStaffName = entity.ManagerStaffName; data.InOrOut = entity.InOrOutLabel; data.IsOpen = entity.IsOPenLabel; data.ValidityPeriod = entity.ValidityPeriod; data.CourseSceneName = entity.CourseSceneName; data.TeacherName = entity.TeacherName; data.Type = "Course"; //必修人数 var RequiredCount = await Db.Queryable().Where(x => x.CourseId == id && (x.CourseType == "ManualRequired" || x.CourseType == "Required")).CountAsync(); data.RequiredCount = RequiredCount; //选修人次 var ElectiveCount = await Db.Queryable().Where(x => x.CourseId == id && (x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync(); data.ElectiveCount = ElectiveCount; var CompleteCount = await Db.Queryable().Where(x => x.CourseId == id && x.CompleteStatus == DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED && (x.CourseType == "ManualElective" || x.CourseType == "Elective" || x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync(); //完成人数 data.CompleteCount = CompleteCount; //开班人数 var OpenClassCount = await Db.Queryable() .Where(x => x.CourseId == id && x.OpenClassId != null) .CountAsync(); data.OpenClassCount = OpenClassCount; var studyRecordIds = await Db.Queryable().Where(x => x.CourseId == id).Select(x => x.Id).ToListAsync(); //总学习时长 data.TotalStudyDuration = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).SumAsync(x => x.StudyDuration); var AvgStudyDuration = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).GroupBy(x => x.StaffId) .Select(m => new { m.StaffId, StudyDuration = SqlFunc.AggregateSum(m.StudyDuration) }).ToListAsync(); //平均学习时长 var AvgStudyDuration1 = AvgStudyDuration.Average(x => x.StudyDuration); if (AvgStudyDuration1 != null) { var AvgStudyDuration2 = AvgStudyDuration1.TrimDecimalString(2); data.AvgStudyDuration = UtilHelper.RemoveZero(Convert.ToDecimal(AvgStudyDuration2)); } else data.AvgStudyDuration = 0; //平均分 var AvgScore = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).AvgAsync(x => x.FinallyScore ?? (x.Score + x.AdjustScore)); data.AvgScore = AvgScore ?? 0; //通过率 var passPercent = 0; if (CompleteCount > 0 && (RequiredCount + ElectiveCount + OpenClassCount) > 0) passPercent = CompleteCount / (RequiredCount + ElectiveCount + OpenClassCount); data.PassPercent = passPercent; //考试安排次数 data.ExamScheduleCount = await Db.Queryable().Where(x => x.CourseId == id).CountAsync(); //考试人数 data.ExamCount = await Db.Queryable().Where(x => x.CourseId == id).CountAsync(); //考试人次 data.ExamGroupCount = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)) .CountAsync(); //反馈人数 data.FeedbackCount = 0; #region 课件学习时长 var courseWareStudyDuration = await Db.Queryable() .Where(a => a.StudyRecordId != null && studyRecordIds.Contains(a.StudyRecordId.Value)) .GroupBy(a => new { a.CourseWareId, a.CourseWareAttachmentId }) .Select(a => new { a.CourseWareId, a.CourseWareAttachmentId, StudyDuration = SqlFunc.AggregateSum(a.StudyDuration) }) .ToListAsync(); var courseWareStudyDurations = new JArray(); for (int i = 0; i < courseWareStudyDuration.Count; i++) { var courseWare = await Db.Queryable().Where(x => x.Id == courseWareStudyDuration[i].CourseWareId).FirstAsync(); var courseWareAttachment = await Db.Queryable().Where(x => x.Id == courseWareStudyDuration[i].CourseWareAttachmentId).FirstAsync(); var item = new JObject { new JProperty("CourseWareId", courseWareStudyDuration[i].CourseWareAttachmentId), new JProperty("CourseWareAttachmentId", courseWareStudyDuration[i].CourseWareAttachmentId), new JProperty("StudyDuration", courseWareStudyDuration[i].StudyDuration), new JProperty("CourseWareName", courseWare?.CourseWareNo+courseWare?.CourseWareName+courseWare?.VersionNo+courseWareAttachment.AttachmentName), }; courseWareStudyDurations.Add(item); } data.CourseWareStudyDurations = courseWareStudyDurations; #endregion #region 课件学习人数占比 var courseWareStudyCount1 = await Db.Queryable() .Where(a => a.StudyRecordId != null && studyRecordIds.Contains(a.StudyRecordId.Value)) .Select(a => new { a.CourseWareAttachmentId, a.StaffId }) .Distinct().ToListAsync(); var courseWareStudyCount = courseWareStudyCount1 .GroupBy(a => a.CourseWareAttachmentId) .Select(a => new { CourseWareAttachmentId = a.Key, Count = a.Count() }) .ToList(); var courseWareStudyCounts = new JArray(); for (int i = 0; i < courseWareStudyCount.Count; i++) { var courseWareAttachment = await Db.Queryable().Where(x => x.Id == courseWareStudyCount[i].CourseWareAttachmentId).FirstAsync(); var item = new JObject { new JProperty("CourseWareAttachmentId", courseWareStudyCount[i].CourseWareAttachmentId), new JProperty("CourseWareName", courseWareAttachment.AttachmentName), new JProperty("Count", courseWareStudyCount[i].Count), }; courseWareStudyCounts.Add(item); } data.CourseWareStudyCounts = courseWareStudyCounts; #endregion #region 关联的考试排行 var exams = await Db.Queryable() .LeftJoin((a, b) => a.ExamPaperId == b.Id)//多个条件用&& .Where(a => a.CourseId == id && a.Status != "Draft") .Select((a, b) => new { a.Id, a.ExamNo, a.ExamName, b.PaperName }) .ToListAsync(); var examRankings = new JArray(); for (int i = 0; i < exams.Count; i++) { var groups = await Db.Queryable().Where(x => x.ExamId == exams[i].Id).CountAsync(); var examRecordCount = await Db.Queryable().Where(x => x.ExamId == exams[i].Id).CountAsync(); var examRecordPassCount = await Db.Queryable() .Where(x => x.ExamId == exams[i].Id && x.IsPass == true && x.IsPass != null) .CountAsync(); var examRecordRetakeCount = await Db.Queryable() .Where(x => x.ExamId == exams[i].Id && x.RetakeTimes > 0 && x.RetakeTimes != null) .CountAsync(); passPercent = 0; var retakePercent = 0; if (examRecordCount > 0) { if (examRecordPassCount > 0) passPercent = (examRecordPassCount / examRecordCount) * 100; if (examRecordRetakeCount > 0) retakePercent = (examRecordRetakeCount / examRecordCount) * 100; } var item = new JObject { new JProperty("ExamName", $"{exams[i].ExamName}({exams[i].ExamNo})" ), new JProperty("PaperName", exams[i].PaperName), new JProperty("Attempts", groups), new JProperty("PassPercent", passPercent), new JProperty("RetakePercent", retakePercent), //new JProperty("CourseWareName", courseWareAttachment.AttachmentName), }; examRankings.Add(item); } data.ExamRankings = examRankings; #endregion #region 错误率排名 var questionErrorRankings = await Db.Queryable() .Where(x => x.CourseId == id || x.CourseIds.Contains(id.ToString())) .Select(x => new QuestionErrorRanking { Id = x.Id, QuestionNo = x.QuestionNo, QuestionContent = x.QuestionContent }) .ToListAsync(); var questionIds = questionErrorRankings.Select(x => x.Id).ToList(); var recordDetails = await Db.Queryable() .Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)) .ToListAsync(); for (int i = 0; i < questionErrorRankings.Count; i++) { questionErrorRankings[i].QuestionContent = WebUtility.HtmlDecode(questionErrorRankings[i].QuestionContent); questionErrorRankings[i].TotalCount = recordDetails.Where(x => x.QuestionId == questionErrorRankings[i].Id).Count(); questionErrorRankings[i].ErrorCount = recordDetails.Where(x => x.QuestionId == questionErrorRankings[i].Id && x.IsCorrect != true).Count(); if (questionErrorRankings[i].ErrorCount > 0 && questionErrorRankings[i].TotalCount > 0) { decimal? Percent1 = questionErrorRankings[i].ErrorCount / questionErrorRankings[i].TotalCount; questionErrorRankings[i].Percent1 = Percent1.TrimDecimalString(2); questionErrorRankings[i].Percent = Convert.ToDecimal((Percent1 * 100).TrimDecimalString(0)); } } questionErrorRankings = questionErrorRankings.OrderByDescending(x => x.Percent).ToList(); data.QuestionErrorRankings = questionErrorRankings; #endregion obj.Data = data; obj.Success = true; obj.Status = 200; obj.Message = "查询成功!"; return obj; } #endregion #region 课程场景统计 /// /// 课程场景统计 /// /// /// public async Task QuerySceneStatistic(long id) { dynamic obj = new ExpandoObject(); dynamic data = new ExpandoObject(); var entity = await Db.Queryable().Where(x => x.Id == id).FirstAsync(); var Courses = await Db.Queryable() .Where(x => x.CourseSceneId == id || x.CourseSceneIds.Contains(id.ToString())) .Select(x => new { x.Id, x.CourseNo, x.CourseName }) .ToListAsync(); var courseIds = Courses.Select(x => x.Id).ToList(); data.Courses = Courses; data.StandardHour = entity.StandardHour; data.CreditPoints = entity.CreditPoints; data.Type = "CourseScene"; //必修人数 var RequiredCount = await Db.Queryable() .Where(x => x.CourseSceneId == id && (x.CourseType == "ManualRequired" || x.CourseType == "Required")) .CountAsync(); data.RequiredCount = RequiredCount; //选修人次 var ElectiveCount = await Db.Queryable() .Where(x => x.CourseSceneId == id && (x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync(); data.ElectiveCount = ElectiveCount; var CompleteCount = await Db.Queryable().Where(x => x.CourseSceneId == id && x.CompleteStatus == DIC_STUDY_RECORD_STUDY_COMPLETE_STATUS.FINISHED && (x.CourseType == "ManualElective" || x.CourseType == "Elective" || x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync(); //完成人数 data.CompleteCount = CompleteCount; //开班人数 var OpenClassCount = await Db.Queryable() .Where(x => x.CourseSceneId == id && x.OpenClassId != null) .CountAsync(); data.OpenClassCount = OpenClassCount; var studyRecordIds = await Db.Queryable().Where(x => x.CourseSceneId == id).Select(x => x.Id).ToListAsync(); //总学习时长 data.TotalStudyDuration = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).SumAsync(x => x.StudyDuration); var AvgStudyDuration = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).GroupBy(x => x.StaffId) .Select(m => new { m.StaffId, StudyDuration = SqlFunc.AggregateSum(m.StudyDuration) }).ToListAsync(); //平均学习时长 //平均学习时长 var AvgStudyDuration1 = AvgStudyDuration.Average(x => x.StudyDuration); if (AvgStudyDuration1 != null) { var AvgStudyDuration2 = AvgStudyDuration1.TrimDecimalString(2); data.AvgStudyDuration = UtilHelper.RemoveZero(Convert.ToDecimal(AvgStudyDuration2)); } else data.AvgStudyDuration = 0; //平均分 var AvgScore = await Db.Queryable().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).AvgAsync(x => x.FinallyScore ?? (x.Score + x.AdjustScore)); data.AvgScore = AvgScore ?? 0; //通过率 var passPercent = 0; if (CompleteCount > 0 && (RequiredCount + ElectiveCount + OpenClassCount) > 0) passPercent = CompleteCount / (RequiredCount + ElectiveCount + OpenClassCount); data.PassPercent = passPercent; //考试安排次数 data.ExamScheduleCount = await Db.Queryable().Where(x => x.CourseSceneId == id).CountAsync(); //考试人数 data.ExamCount = await Db.Queryable().Where(x => x.CourseSceneId == id).CountAsync(); //考试人次 data.ExamGroupCount = await Db.Queryable() .Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)) .CountAsync(); //反馈人数 data.FeedbackCount = 0; #region 课件学习时长 var courseWareStudyDuration = await Db.Queryable() .Where(a => a.StudyRecordId != null && studyRecordIds.Contains(a.StudyRecordId.Value)) .GroupBy(a => new { a.CourseWareId, a.CourseWareAttachmentId }) .Select(a => new { a.CourseWareId, a.CourseWareAttachmentId, StudyDuration = SqlFunc.AggregateSum(a.StudyDuration) }) .ToListAsync(); var courseWareStudyDurations = new JArray(); for (int i = 0; i < courseWareStudyDuration.Count; i++) { var courseWare = await Db.Queryable().Where(x => x.Id == courseWareStudyDuration[i].CourseWareId).FirstAsync(); var courseWareAttachment = await Db.Queryable().Where(x => x.Id == courseWareStudyDuration[i].CourseWareAttachmentId).FirstAsync(); var item = new JObject { new JProperty("CourseWareId", courseWareStudyDuration[i].CourseWareAttachmentId), new JProperty("CourseWareAttachmentId", courseWareStudyDuration[i].CourseWareAttachmentId), new JProperty("StudyDuration", courseWareStudyDuration[i].StudyDuration), new JProperty("CourseWareName", courseWare?.CourseWareNo+courseWare?.CourseWareName+courseWare?.VersionNo+courseWareAttachment.AttachmentName), }; courseWareStudyDurations.Add(item); } data.CourseWareStudyDurations = courseWareStudyDurations; #endregion #region 课件学习人数占比 var courseWareStudyCount1 = await Db.Queryable() .Where(a => a.StudyRecordId != null && studyRecordIds.Contains(a.StudyRecordId.Value)) .Select(a => new { a.CourseWareAttachmentId, a.StaffId }) .Distinct().ToListAsync(); var courseWareStudyCount = courseWareStudyCount1 .GroupBy(a => a.CourseWareAttachmentId) .Select(a => new { CourseWareAttachmentId = a.Key, Count = a.Count() }) .ToList(); var courseWareStudyCounts = new JArray(); for (int i = 0; i < courseWareStudyCount.Count; i++) { var courseWareAttachment = await Db.Queryable().Where(x => x.Id == courseWareStudyCount[i].CourseWareAttachmentId).FirstAsync(); var item = new JObject { new JProperty("CourseWareAttachmentId", courseWareStudyCount[i].CourseWareAttachmentId), new JProperty("CourseWareName", courseWareAttachment.AttachmentName), new JProperty("Count", courseWareStudyCount[i].Count), }; courseWareStudyCounts.Add(item); } data.CourseWareStudyCounts = courseWareStudyCounts; #endregion #region 关联的考试排行 var exams = await Db.Queryable() .LeftJoin((a, b) => a.ExamPaperId == b.Id)//多个条件用&& .Where(a => a.CourseSceneId == id && a.Status != "Draft") .Select((a, b) => new { a.Id, a.ExamNo, a.ExamName, b.PaperName }) .ToListAsync(); var examRankings = new JArray(); for (int i = 0; i < exams.Count; i++) { var groups = await Db.Queryable().Where(x => x.ExamId == exams[i].Id).CountAsync(); var examRecordCount = await Db.Queryable().Where(x => x.ExamId == exams[i].Id).CountAsync(); var examRecordPassCount = await Db.Queryable() .Where(x => x.ExamId == exams[i].Id && x.IsPass == true && x.IsPass != null) .CountAsync(); var examRecordRetakeCount = await Db.Queryable() .Where(x => x.ExamId == exams[i].Id && x.RetakeTimes > 0 && x.RetakeTimes != null) .CountAsync(); passPercent = 0; var retakePercent = 0; if (examRecordCount > 0) { if (examRecordPassCount > 0) passPercent = (examRecordPassCount / examRecordCount) * 100; if (examRecordRetakeCount > 0) retakePercent = (examRecordRetakeCount / examRecordCount) * 100; } var item = new JObject { new JProperty("ExamName", $"{exams[i].ExamName}({exams[i].ExamNo})" ), new JProperty("PaperName", exams[i].PaperName), new JProperty("Attempts", groups), new JProperty("PassPercent", passPercent), new JProperty("RetakePercent", retakePercent), //new JProperty("CourseWareName", courseWareAttachment.AttachmentName), }; examRankings.Add(item); } data.ExamRankings = examRankings; #endregion #region 错误率排名 var exp = Expressionable.Create(); courseIds.ForEach(id1 => { exp.Or(x => x.CourseId == id1 || x.CourseIds.Contains(id1.ToString())); }); var questionErrorRankings = await Db.Queryable() .Where(exp.ToExpression()) .Select(x => new QuestionErrorRanking { Id = x.Id, QuestionNo = x.QuestionNo, QuestionContent = x.QuestionContent }) .ToListAsync(); var questionIds = questionErrorRankings.Select(x => x.Id).ToList(); var recordDetails = await Db.Queryable() .Where(x => x.QuestionId != null && questionIds.Contains(x.QuestionId.Value)) .ToListAsync(); for (int i = 0; i < questionErrorRankings.Count; i++) { questionErrorRankings[i].QuestionContent = WebUtility.HtmlDecode(questionErrorRankings[i].QuestionContent); questionErrorRankings[i].TotalCount = recordDetails.Where(x => x.QuestionId == questionErrorRankings[i].Id).Count(); questionErrorRankings[i].ErrorCount = recordDetails.Where(x => x.QuestionId == questionErrorRankings[i].Id && x.IsCorrect != true).Count(); if (questionErrorRankings[i].ErrorCount > 0 && questionErrorRankings[i].TotalCount > 0) { decimal? Percent1 = questionErrorRankings[i].ErrorCount / questionErrorRankings[i].TotalCount; questionErrorRankings[i].Percent1 = Percent1.TrimDecimalString(2); questionErrorRankings[i].Percent = Convert.ToDecimal((Percent1 * 100).TrimDecimalString(0)); } } questionErrorRankings = questionErrorRankings.OrderByDescending(x => x.Percent).ToList(); data.QuestionErrorRankings = questionErrorRankings; #endregion obj.Data = data; obj.Success = true; obj.Status = 200; obj.Message = "查询成功!"; return obj; } #endregion }