You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
Tiobon.Web.Core/Tiobon.Core.Services/Ghre/Ghre_CourseServices.cs

1963 lines
90 KiB

using NPOI.SS.UserModel;
using System.Net;
using static Tiobon.Core.Model.Consts;
namespace Tiobon.Core.Services;
/// <summary>
/// 课程 (服务)
/// </summary>
public class Ghre_CourseServices : BaseServices<Ghre_Course, Ghre_CourseDto, InsertGhre_CourseInput, EditGhre_CourseInput>, IGhre_CourseServices
{
private readonly IBaseRepository<Ghre_Course> _dal;
private IGhre_CourseClassServices _ghre_CourseClassServices;
private IGhre_CourseSnapServices _ghre_CourseSnapServices;
public Ghre_CourseServices(IBaseRepository<Ghre_Course> 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<ServicePageResult<Ghre_CourseDto>> QueryList(QueryBody filter, string status, List<long> ids)
{
RefAsync<int> 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<JsonParam>(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<List<string>>(jsonParam.columnValue.ToString());
conditions += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})";
}
break;
case "NotEqualAny"://
if (jsonParam.columnValue != null)
{
var ids1 = JsonHelper.JsonToObj<List<string>>(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<Ghre_CourseDto>(sql)
.OrderBy(filter.orderBy)
.ToPageListAsync(filter.pageNum, filter.pageSize, totalCount);
var classsIds1 = data.Select(x => x.CourseClassId).Distinct().ToList();
var classsIds = new List<long>();
classsIds1.ForEach(x =>
{
if (!string.IsNullOrWhiteSpace(x))
{
var courseClassIds = JsonConvert.DeserializeObject<List<long>>(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<long>();
courseSceneIds1.ForEach(x =>
{
if (!string.IsNullOrWhiteSpace(x))
courseSceneIds = courseSceneIds.Concat(JsonConvert.DeserializeObject<List<long>>(x)).ToList();
});
//data.ForEach(x =>
//{
// if (x.CourseSceneId != null)
// courseSceneIds.Add(x.CourseSceneId.Value);
//});
courseSceneIds = courseSceneIds.Distinct().ToList();
var courseScenes = await Db.Queryable<Ghre_CourseScene>().Where(x => courseSceneIds.Contains(x.Id)).ToListAsync();
data.ForEach(async x =>
{
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<List<long>>(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);
});
return new ServicePageResult<Ghre_CourseDto>(filter.pageNum, totalCount, filter.pageSize, data);
}
public async Task<ServiceResult<int>> 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<int>.OprateSuccess("查询成功!", id);
}
public async Task<ServiceResult<CommonSelect>> 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<CommonSelect>() { Success = true, Message = "查询成功", Data = result, };
}
public override async Task<ServiceFormResult<Ghre_CourseDto>> 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<List<long>>(examPaperId);
string courseClassId = result.result.DT_TableDataT1[0].CourseClassId;
if (!string.IsNullOrWhiteSpace(courseClassId))
result.result.DT_TableDataT1[0].CourseClassIds = JsonConvert.DeserializeObject<List<long>>(courseClassId);
string courseSceneIds = result.result.DT_TableDataT1[0].CourseSceneIds;
if (!string.IsNullOrWhiteSpace(courseSceneIds))
result.result.DT_TableDataT1[0].CourseSceneIds1 = JsonConvert.DeserializeObject<List<long>>(courseSceneIds);
else result.result.DT_TableDataT1[0].ExamPaperIds = new List<long>();
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<Ghre_CourseDto> QueryById(object objId)
{
var data = await base.QueryById(objId);
if (data == null)
throw new Exception("无效的Id");
var DT_TableDataT1 = Mapper.Map(data).ToANew<Ghre_CourseDto>();
string examPaperId = DT_TableDataT1.ExamPaperId;
var classsIds = new List<long>();
var courseClassIds = JsonConvert.DeserializeObject<List<long>>(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<long>();
if (DT_TableDataT1.CourseSceneIds.IsNotEmptyOrNull())
courseSceneIds = courseSceneIds.Concat(JsonConvert.DeserializeObject<List<long>>(DT_TableDataT1.CourseSceneIds)).ToList();
courseSceneIds = courseSceneIds.Distinct().ToList();
var courseScenes = await Db.Queryable<Ghre_CourseScene>().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<List<long>>(examPaperId);
string courseClassId = DT_TableDataT1.CourseClassId;
if (!string.IsNullOrWhiteSpace(courseClassId))
DT_TableDataT1.CourseClassIds = JsonConvert.DeserializeObject<List<long>>(courseClassId);
string courseSceneIds1 = DT_TableDataT1.CourseSceneIds;
if (!string.IsNullOrWhiteSpace(courseSceneIds1))
DT_TableDataT1.CourseSceneIds1 = JsonConvert.DeserializeObject<List<long>>(courseSceneIds1);
else DT_TableDataT1.ExamPaperIds = new List<long>();
DT_TableDataT1.IsOPenLabel = DT_TableDataT1.IsOpen == "1" ? "是" : "否";
if (DT_TableDataT1.ManagerId != null)
DT_TableDataT1.ManagerStaffName = (await Db.Queryable<Ghra_Staff>().Where(x => x.StaffID == DT_TableDataT1.ManagerId).FirstAsync())?.StaffName;
if (DT_TableDataT1.CourseWareId != null)
DT_TableDataT1.CourseWareName = (await Db.Queryable<Ghre_CourseWare>().Where(x => x.Id == DT_TableDataT1.CourseWareId).FirstAsync())?.CourseWareName;
if (DT_TableDataT1.CreditRuleId != null)
DT_TableDataT1.CreditRuleName = (await Db.Queryable<Ghre_CreditRule>().Where(x => x.Id == DT_TableDataT1.CreditRuleId).FirstAsync())?.RuleName;
return DT_TableDataT1;
}
public async Task<ServiceResult> 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<Ghre_Course>();
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<List<long>>(entity.CourseClassId);
if (CourseClassIds != null && CourseClassIds.Any())
{
for (int i = 0; i < CourseClassIds.Count; i++)
{
if (!await Db.Queryable<Ghre_CourseClass>().AnyAsync(x => x.Id == CourseClassIds[i]))
throw new Exception($"课程关联的课程分类已失效,请修正数据后继续发布!");
}
}
}
if (!entity.CourseSceneId.IsNull())
if (!await Db.Queryable<Ghre_CourseScene>().AnyAsync(x => x.Id == entity.CourseSceneId))
return ServiceResult.OprateFailed($"课程关联的课程场景已失效,请修正数据后继续发布!");
if (!entity.ExamPaperId.IsNull())
{
var ExamPaperIds = JsonConvert.DeserializeObject<List<long>>(entity.ExamPaperId);
if (ExamPaperIds != null && ExamPaperIds.Any())
{
for (int i = 0; i < ExamPaperIds.Count; i++)
{
if (!await Db.Queryable<Ghre_ExamPaper>().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<Ghre_CourseWare>().Where(x => x.CourseIds.Contains(id.ToString()) && x.Id != id).ToListAsync();
for (int j = 0; j < wares.Count; j++)
{
var courseIds2 = new List<long>();
if (!string.IsNullOrWhiteSpace(wares[j].CourseIds))
courseIds2 = JsonConvert.DeserializeObject<List<long>>(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<Ghre_CourseWare>().FirstAsync(x => x.Id == entity.CourseWareId);
if (ware != null)
{
var courseIds2 = new List<long>();
if (!string.IsNullOrWhiteSpace(ware.CourseIds))
courseIds2 = JsonConvert.DeserializeObject<List<long>>(ware.CourseIds);
if (!courseIds2.Any(x => x == id))
{
courseIds2.Add(id);
ware.CourseIds = JsonConvert.SerializeObject(courseIds2);
await Db.Updateable<Ghre_CourseWare>().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<Ghre_CourseWare>().Where(x => x.CourseIds.Contains(id.ToString()) && x.Id != id).ToListAsync();
for (int j = 0; j < wares.Count; j++)
{
var courseIds2 = new List<long>();
if (!string.IsNullOrWhiteSpace(wares[j].CourseIds))
courseIds2 = JsonConvert.DeserializeObject<List<long>>(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<Ghre_ExamPaper>().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<Ghre_ExamPaper>().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<Ghre_StudyRecord>().
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<Ghre_StudyRecord>().
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<Ghre_StudyRecord>().
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<Ghre_StudyRecord>().
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<InsertGhre_CourseSnapInput>();
var courseClassIds = JsonConvert.DeserializeObject<List<long>>(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<Ghre_ExamPaper>().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<Ghre_CourseScene>().Where(x => x.Id == entity.CourseSceneId).FirstAsync();
if (courseScene != null)
{
var courses = await Db.Queryable<Ghre_Course>()
.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<long> 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<Ghre_Teacher>().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<Ghre_CourseClass>().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<bool> 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<List<long>>(editModel.CourseClassId);
if (CourseClassIds != null && CourseClassIds.Any())
{
for (int i = 0; i < CourseClassIds.Count; i++)
{
if (!await Db.Queryable<Ghre_CourseClass>().AnyAsync(x => x.Id == CourseClassIds[i]))
throw new Exception($"课程关联的课程分类已失效,请修正数据后继续发布!");
}
}
}
if (!editModel.CourseSceneId.IsNull())
if (!await Db.Queryable<Ghre_CourseScene>().AnyAsync(x => x.Id == editModel.CourseSceneId))
throw new Exception($"课程关联的课程场景已失效,请修正数据后继续发布!");
if (!editModel.ExamPaperId.IsNull())
{
var ExamPaperIds = JsonConvert.DeserializeObject<List<long>>(editModel.ExamPaperId);
if (ExamPaperIds != null && ExamPaperIds.Any())
{
for (int i = 0; i < ExamPaperIds.Count; i++)
{
if (!await Db.Queryable<Ghre_ExamPaper>().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 获取通用列表下拉
/// <summary>
/// 获取通用列表下拉
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public async Task<ServiceResult<CommonSelect>> 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<CommonSelect>() { Success = true, Message = "查询成功", Data = result, };
}
#endregion
public async Task<ServiceResult<ExcelData>> 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<long>();
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<QueryExportColumn>(sql);
var fieldDescs = new Dictionary<string, string>();
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<ExcelData>.OprateSuccess("导出成功", result);
}
public override async Task<ServiceResult<string>> 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<DataSourceList>(sql);
//if (dataSourceLists.Any())
//{
// var types = new List<string>
// {
// "学习记录"
// };
// 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<string>.OprateSuccess("课程管理_" + DateTimeHelper.ConvertToSecondString1(DateTime.Now) + ".xlsx", physicsPath1);
return result;
}
public override async Task<ServiceResult<ExcelData>> 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<string>();
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<Ghre_CourseScene>().Where(x => x.CourseName == courseScene).FirstAsync();
courseSceneId = (await Db.Queryable<Ghre_CourseScene>().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<long?> courseClassId1 = [courseClassId];
var dict = new Dictionary<string, object>
{
{ "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<ExcelData>.OprateSuccess("导入成功!", data);
}
#region 获取公开课查询条件
public async Task<ServiceResult<CoursePublicSearch>> 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<DT_PageMutiMsg>(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<CoursePublicSearch>.OprateSuccess("", entity);
}
#endregion
#region 获取公开课
public async Task<ServicePageResult<CoursePublic>> QueryPublic(QueryBody filter)
{
int? staffId = GetStaffId();
RefAsync<int> 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}') 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<JsonParam>(value);
conditions += $" AND (CourseNo LIKE '%{jsonParam.columnValue}%' OR CourseName LIKE '%{jsonParam.columnValue}%')";
continue;
}
if (name == "HasStudy")
{
var jsonParam = JsonConvert.DeserializeObject<JsonParam>(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<JsonParam>(value);
conditions += $" AND CourseClassId LIKE '%{jsonParam.columnValue}%' ";
continue;
}
if (name == "KeyWords")
{
var jsonParam = JsonConvert.DeserializeObject<JsonParam>(value);
conditions += $" AND CourseName LIKE '%{jsonParam.columnValue}%' ";
continue;
}
if (!string.IsNullOrWhiteSpace(value))
{
var jsonParam = JsonConvert.DeserializeObject<JsonParam>(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<CoursePublic>(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<CoursePublic>(filter.pageNum, totalCount, filter.pageSize, data);
}
#endregion
#region 场景ID获取课程
public async Task<ServiceResult<List<Ghre_CourseDto>>> 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<Ghre_CourseWareAttachment>().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<List<Ghre_CourseDto>>();
entitys1.ForEach(x =>
{
x.CourseWareName = string.Join(",", attachments.Where(o => o.CourseWareId == x.CourseWareId).OrderBy(x => x.SortNo).Select(o => o.AttachmentName));
});
return ServiceResult<List<Ghre_CourseDto>>.OprateSuccess("查询成功", entitys1);
}
#endregion
#region 修改场景下课程顺序
public async Task<ServiceResult> ModifyCourseSortNo(List<Ghre_Course> courses)
{
await Db.Updateable(courses).UpdateColumns(it => new { it.SortNo }).ExecuteCommandAsync();
return ServiceResult.OprateSuccess("执行成功!");
}
#endregion
#region 查询课程、课程场景
public async Task<ServicePageResult<CourseAndScene>> QueryCourseAndScene(QueryBody filter)
{
RefAsync<int> 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<JsonParam>(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<List<string>>(jsonParam.columnValue.ToString());
conditions += $" AND {name} IN ({string.Join(",", ids1.Select(id => "'" + id + "'"))})";
}
break;
case "NotEqualAny"://
if (jsonParam.columnValue != null)
{
var ids1 = JsonHelper.JsonToObj<List<string>>(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<CourseAndScene>(sql1);
for (int i = 0; i < data.Count; i++)
{
data[i].RequiredCount = await Db.Queryable<Ghre_StudyRecord>()
.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<Ghre_StudyRecord>()
.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<Ghre_StudyRecord>()
.Where(x => (x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id) && x.OpenClassId != null)
.CountAsync();
data[i].CompleteCount = await Db.Queryable<Ghre_StudyRecord>()
.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<Ghre_StudyRecord>()
.Where(x => x.CourseSceneId == data[i].Id || x.CourseId == data[i].Id)
.Select(x => x.Id)
.ToListAsync();
data[i].TotalStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>()
.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<Ghre_ExamRecord>()
.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<Ghre_ExamRecord>()
.Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value))
.CountAsync();
var passCount = await Db.Queryable<Ghre_ExamRecord>()
.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<CourseAndScene>(filter.pageNum, totalCount, filter.pageSize, data);
}
#endregion
#region 课程统计
/// <summary>
/// 课程统计
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<dynamic> 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<Ghre_StudyRecord>().Where(x => x.CourseId == id && (x.CourseType == "ManualRequired" || x.CourseType == "Required")).CountAsync();
data.RequiredCount = RequiredCount;
//选修人次
var ElectiveCount = await Db.Queryable<Ghre_StudyRecord>().Where(x => x.CourseId == id && (x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync();
data.ElectiveCount = ElectiveCount;
var CompleteCount = await Db.Queryable<Ghre_StudyRecord>().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<Ghre_StudyRecord>()
.Where(x => x.CourseId == id && x.OpenClassId != null)
.CountAsync();
data.OpenClassCount = OpenClassCount;
var studyRecordIds = await Db.Queryable<Ghre_StudyRecord>().Where(x => x.CourseId == id).Select(x => x.Id).ToListAsync();
//总学习时长
data.TotalStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).SumAsync(x => x.StudyDuration);
var AvgStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>().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<Ghre_ExamRecord>().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<Ghre_Exam>().Where(x => x.CourseId == id).CountAsync();
//考试人数
data.ExamCount = await Db.Queryable<Ghre_ExamRecord>().Where(x => x.CourseId == id).CountAsync();
//考试人次
data.ExamGroupCount = await Db.Queryable<Ghre_ExamRecordGroup>()
.Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value))
.CountAsync();
//反馈人数
data.FeedbackCount = 0;
#region 课件学习时长
var courseWareStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>()
.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<Ghre_CourseWare>().Where(x => x.Id == courseWareStudyDuration[i].CourseWareId).FirstAsync();
var courseWareAttachment = await Db.Queryable<Ghre_CourseWareAttachment>().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<Ghre_StudyRecordDetail>()
.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<Ghre_CourseWareAttachment>().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<Ghre_Exam>()
.LeftJoin<Ghre_ExamPaper>((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<Ghre_ExamRecordGroup>().Where(x => x.ExamId == exams[i].Id).CountAsync();
var examRecordCount = await Db.Queryable<Ghre_ExamRecord>().Where(x => x.ExamId == exams[i].Id).CountAsync();
var examRecordPassCount = await Db.Queryable<Ghre_ExamRecord>()
.Where(x => x.ExamId == exams[i].Id && x.IsPass == true && x.IsPass != null)
.CountAsync();
var examRecordRetakeCount = await Db.Queryable<Ghre_ExamRecord>()
.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<Ghre_Question>()
.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<Ghre_ExamRecordDetail>()
.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 课程场景统计
/// <summary>
/// 课程场景统计
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<dynamic> QuerySceneStatistic(long id)
{
dynamic obj = new ExpandoObject();
dynamic data = new ExpandoObject();
var entity = await Db.Queryable<Ghre_CourseScene>().Where(x => x.Id == id).FirstAsync();
var Courses = await Db.Queryable<Ghre_Course>()
.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<Ghre_StudyRecord>()
.Where(x => x.CourseSceneId == id && (x.CourseType == "ManualRequired" || x.CourseType == "Required"))
.CountAsync();
data.RequiredCount = RequiredCount;
//选修人次
var ElectiveCount = await Db.Queryable<Ghre_StudyRecord>()
.Where(x => x.CourseSceneId == id && (x.CourseType == "ManualElective" || x.CourseType == "Elective")).CountAsync();
data.ElectiveCount = ElectiveCount;
var CompleteCount = await Db.Queryable<Ghre_StudyRecord>().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<Ghre_StudyRecord>()
.Where(x => x.CourseSceneId == id && x.OpenClassId != null)
.CountAsync();
data.OpenClassCount = OpenClassCount;
var studyRecordIds = await Db.Queryable<Ghre_StudyRecord>().Where(x => x.CourseSceneId == id).Select(x => x.Id).ToListAsync();
//总学习时长
data.TotalStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>().Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value)).SumAsync(x => x.StudyDuration);
var AvgStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>().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<Ghre_ExamRecord>().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<Ghre_Exam>().Where(x => x.CourseSceneId == id).CountAsync();
//考试人数
data.ExamCount = await Db.Queryable<Ghre_ExamRecord>().Where(x => x.CourseSceneId == id).CountAsync();
//考试人次
data.ExamGroupCount = await Db.Queryable<Ghre_ExamRecordGroup>()
.Where(x => x.StudyRecordId != null && studyRecordIds.Contains(x.StudyRecordId.Value))
.CountAsync();
//反馈人数
data.FeedbackCount = 0;
#region 课件学习时长
var courseWareStudyDuration = await Db.Queryable<Ghre_StudyRecordDetail>()
.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<Ghre_CourseWare>().Where(x => x.Id == courseWareStudyDuration[i].CourseWareId).FirstAsync();
var courseWareAttachment = await Db.Queryable<Ghre_CourseWareAttachment>().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<Ghre_StudyRecordDetail>()
.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<Ghre_CourseWareAttachment>().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<Ghre_Exam>()
.LeftJoin<Ghre_ExamPaper>((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<Ghre_ExamRecordGroup>().Where(x => x.ExamId == exams[i].Id).CountAsync();
var examRecordCount = await Db.Queryable<Ghre_ExamRecord>().Where(x => x.ExamId == exams[i].Id).CountAsync();
var examRecordPassCount = await Db.Queryable<Ghre_ExamRecord>()
.Where(x => x.ExamId == exams[i].Id && x.IsPass == true && x.IsPass != null)
.CountAsync();
var examRecordRetakeCount = await Db.Queryable<Ghre_ExamRecord>()
.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<Ghre_Question>();
courseIds.ForEach(id1 =>
{
exp.Or(x => x.CourseId == id1 || x.CourseIds.Contains(id1.ToString()));
});
var questionErrorRankings = await Db.Queryable<Ghre_Question>()
.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<Ghre_ExamRecordDetail>()
.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
}