Compare commits

...

6 Commits

19 changed files with 441 additions and 156 deletions

View File

@@ -0,0 +1,17 @@
package com.xboe.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* 整体系统MySQL数据库schema配置
*/
@ConfigurationProperties(prefix = "mysql.schema")
@Data
public class MySqlSchemaProperties {
/**
* 用户中心数据库schema
*/
private String userCenterSchema;
}

View File

@@ -1324,24 +1324,24 @@ public class CourseManageApi extends ApiBaseController{
boolean isMobile = UserAgentUtil.parse(request.getHeader(Header.USER_AGENT.toString())).isMobile();
String baseUrl = isMobile ? h5PageUrl : pcPageUrl;
String loginUrl = isMobile ? h5LoginUrl : pcLoginUrl;
// String loginUrl = isMobile ? h5LoginUrl : pcLoginUrl;
//
// CurrentUser currentUser;
// try {
// currentUser = getCurrent();
// } catch (Exception e) {
// log.warn("获取当前用户信息异常跳转至登录页。课程ID: {}", courseId, e);
// response.sendRedirect(loginUrl);
// return;
// }
//
// if (currentUser == null) {
// log.info("用户未登录跳转至登录页。课程ID: {}", courseId);
// response.sendRedirect(loginUrl);
// return;
// }
CurrentUser currentUser;
try {
currentUser = getCurrent();
} catch (Exception e) {
log.warn("获取当前用户信息异常跳转至登录页。课程ID: {}", courseId, e);
response.sendRedirect(loginUrl);
return;
}
if (currentUser == null) {
log.info("用户未登录跳转至登录页。课程ID: {}", courseId);
response.sendRedirect(loginUrl);
return;
}
log.info("跳转到课程详情页课程ID: {}, 用户ID: {}", courseId, currentUser.getAccountId());
log.info("跳转到课程详情页课程ID: {}", courseId);
response.sendRedirect(baseUrl + courseId);
}
}

View File

@@ -490,17 +490,21 @@ public class CoursePortalApi extends ApiBaseController{
courseStudyVo.setContentName(s.getName()+"--"+c.getContentName());
courseStudyVo.setStatus(1);
courseStudyVo.setStudyDuration(0);
// 学习时长默认为0
courseStudyVo.setLearningDuration(0);
courseStudyVos.add(courseStudyVo);
}
}
}
// DecimalFormat decimalFormat = new DecimalFormat("#.#");
if(courseStudyVos!=null && !courseStudyVos.isEmpty()){
if (!courseStudyVos.isEmpty()) {
for (StudyCourseItem study:studyItem) {
for (CourseStudyVo cv:courseStudyVos) {
if(study.getContentId().equals(cv.getContentId())){
// 25.11.26标记 这就能硬set么这俩是一个值么
cv.setStudyDuration(study.getProgress());
// 25.11.26新增,添加学习时长字段
// 数据库存储的秒,前端会转为分钟
cv.setLearningDuration(study.getStudyDuration());
//针对考试,文档一类
if(study.getStatus()==null) {
if(study.getProgress()!=null){
@@ -511,16 +515,7 @@ public class CoursePortalApi extends ApiBaseController{
//音视频
}else{
cv.setStatus(study.getStatus());
}
// if(study.getStudyDuration()!=null){
//// Float duration= Float.valueOf(study.getProgress());
//// duration=duration/60;
//
// cv.setStudyDuration();
// }
}
}
}
@@ -528,6 +523,88 @@ public class CoursePortalApi extends ApiBaseController{
return success(courseStudyVos);
}
/**
* 分页获取课程章节学习进度
* 25.11.26新增
*
* @param pager 分页参数
* @param courseId 课程id
* @param aid 用户id
* @return 课程内容学习进度集合
*/
@GetMapping("/detail-study-page")
public JsonResponse<PageList<CourseStudyVo>> detailStudyPage(Pagination pager, String courseId, String aid) {
if (StringUtil.isBlank(courseId)) {
return badRequest("参数异常,未指定课程");
}
if (StringUtil.isBlank(aid)) {
return badRequest("参数异常,未指定用户");
}
PageList<CourseStudyVo> courseStudyVoPage = new PageList<>();
List<CourseStudyVo> courseStudyVos = new ArrayList<>();
// 课程章节
List<CourseSection> sectionlist = sectionService.getByCourseId(courseId);
// 获取课程章节id集合备用
List<String> sectionIdList = sectionlist.stream().map(CourseSection::getId).collect(Collectors.toList());
if (sectionIdList.isEmpty()) {
log.error("【分页获取课程章节学习进度】课程章节为空");
return success(courseStudyVoPage);
}
// 课程内容(分页只查询满足课程章节id条件的数据
PageList<CourseContent> courseContentPageList = contentService.getByCourseIdPage(pager.getPageIndex(), pager.getPageSize(), courseId, sectionIdList);
List<CourseContent> courseContentlist = courseContentPageList.getList();
// 查出课程当前人学习进度
StudyCourse studyCourse = studyCourseService.findByCourseIdAndAid(courseId, aid);
// 查出对应章节学习进度
List<StudyCourseItem> studyItem = studyCourseService.findStudyItem(studyCourse.getId(), aid);
// 先遍历课程章节
// 然后遍历课程内容
for (CourseContent courseContent : courseContentlist) {
CourseStudyVo courseStudyVo = new CourseStudyVo();
courseStudyVo.setContentId(courseContent.getId());
for (CourseSection s : sectionlist) {
if (courseContent.getCsectionId().equals(s.getId())) {
courseStudyVo.setContentName(s.getName() + "--" + courseContent.getContentName());
}
}
courseStudyVo.setStatus(1);
courseStudyVo.setStudyDuration(0);
// 学习时长默认为0
courseStudyVo.setLearningDuration(0);
courseStudyVos.add(courseStudyVo);
}
if (!courseStudyVos.isEmpty()) {
for (StudyCourseItem study : studyItem) {
for (CourseStudyVo cv : courseStudyVos) {
if (study.getContentId().equals(cv.getContentId())) {
// 25.11.26标记 这就能硬set么这俩是一个值么
cv.setStudyDuration(study.getProgress());
// 25.11.26新增,添加学习时长字段
// 数据库存储的秒,前端会转为分钟
cv.setLearningDuration(study.getStudyDuration());
//针对考试,文档一类
if (study.getStatus() == null) {
if (study.getProgress() != null) {
if (study.getProgress() == 100) {
cv.setStatus(9);
}
}
//音视频
} else {
cv.setStatus(study.getStatus());
}
}
}
}
}
// 拼接为分页格式
courseStudyVoPage.setList(courseStudyVos);
courseStudyVoPage.setCount(courseContentPageList.getCount());
courseStudyVoPage.setPageSize(courseContentPageList.getPageSize());
return success(courseStudyVoPage);
}
/**
* 根据课程id查出对应的教师id
* */

View File

@@ -96,7 +96,7 @@ public class CourseDao extends BaseDao<Course> {
*/
public List<CoursePageVo> queryCourse(CoursePageQueryDTO queryDTO,
boolean isSystemAdmin, List<String> orgIds, String currentAccountId,
boolean pageQuery) {
boolean pageQuery, String userCenterSchema) {
// select字段
StringBuilder builder = new StringBuilder("select ");
builder.append("c.id,");
@@ -105,9 +105,9 @@ public class CourseDao extends BaseDao<Course> {
builder.append("c.sys_type1 AS sysType1,");
builder.append("c.sys_type2 AS sysType2,");
builder.append("c.sys_type3 AS sysType3,");
builder.append("c.res_owner1 AS resOwner1,");
builder.append("c.res_owner2 AS resOwner2,");
builder.append("c.res_owner3 AS resOwner3,");
builder.append("c.org_id AS orgId,");
builder.append("org.org_name AS orgName,");
builder.append("org.org_name_path AS orgFullName,");
builder.append("c.sys_create_by AS sysCreateBy,");
builder.append("c.create_from AS createFrom,");
builder.append("c.sys_create_time AS sysCreateTime,");
@@ -124,7 +124,7 @@ public class CourseDao extends BaseDao<Course> {
builder.append("COALESCE(tch.teacher_names, '') AS teacherName,");
builder.append("c.sort_weight AS sortWeight");
// 拼接FROM及查询条件语句
appendFrom(builder, queryDTO, isSystemAdmin, orgIds, currentAccountId);
appendFrom(builder, queryDTO, isSystemAdmin, orgIds, currentAccountId, userCenterSchema);
// 排序语句
appendOrder(builder, queryDTO);
@@ -146,9 +146,9 @@ public class CourseDao extends BaseDao<Course> {
vo.setSysType1((String) row[3]);
vo.setSysType2((String) row[4]);
vo.setSysType3((String) row[5]);
vo.setResOwner1((String) row[6]);
vo.setResOwner2((String) row[7]);
vo.setResOwner3((String) row[8]);
vo.setOrgId((String) row[6]);
vo.setOrgName((String) row[7]);
vo.setOrgFullName((String) row[8]);
vo.setSysCreateBy((String) row[9]);
vo.setCreateFrom((String) row[10]);
@@ -201,11 +201,11 @@ public class CourseDao extends BaseDao<Course> {
}
public long countCourse(CoursePageQueryDTO queryDTO,
boolean isSystemAdmin, List<String> orgIds, String currentAccountId) {
boolean isSystemAdmin, List<String> orgIds, String currentAccountId, String userCenterSchema) {
// select count
StringBuilder builder = new StringBuilder("select count(*)");
// 拼接FROM及查询条件语句
appendFrom(builder, queryDTO, isSystemAdmin, orgIds, currentAccountId);
appendFrom(builder, queryDTO, isSystemAdmin, orgIds, currentAccountId, userCenterSchema);
// 排序语句
appendOrder(builder, queryDTO);
@@ -225,7 +225,7 @@ public class CourseDao extends BaseDao<Course> {
* @param currentAccountId
*/
private void appendFrom(StringBuilder builder, CoursePageQueryDTO queryDTO,
boolean isSystemAdmin, List<String> orgIds, String currentAccountId) {
boolean isSystemAdmin, List<String> orgIds, String currentAccountId, String userCenterSchema) {
// 开头判断课程培训时间的两个参数是否不为null
boolean filterLearningTime = queryDTO.getLearningTimeStart() != null && queryDTO.getLearningTimeEnd() != null;
builder.append(" FROM boe_course c");
@@ -249,6 +249,11 @@ public class CourseDao extends BaseDao<Course> {
// 课件聚合
builder.append(System.lineSeparator());
builder.append("LEFT JOIN (SELECT course_id, SUM(duration) AS duration_sum FROM boe_course_content WHERE deleted = 0 GROUP BY course_id) cc ON c.id = cc.course_id");
// 组织机构聚合
builder.append(System.lineSeparator());
builder.append("LEFT JOIN ").append(userCenterSchema)
.append(".organization org ON c.org_id = org.organization_id AND org.deleted = 0");
// where条件
// 第一个条件deleted = 0
builder.append(System.lineSeparator());
@@ -310,17 +315,9 @@ public class CourseDao extends BaseDao<Course> {
builder.append(System.lineSeparator());
builder.append("AND c.open_course = :openCourse");
}
if (StringUtils.isNotBlank(queryDTO.getResOwner1())) {
if (StringUtils.isNotBlank(queryDTO.getOrgId())) {
builder.append(System.lineSeparator());
builder.append("AND c.res_owner1 = :resOwner1");
}
if (StringUtils.isNotBlank(queryDTO.getResOwner2())) {
builder.append(System.lineSeparator());
builder.append("AND c.res_owner2 = :resOwner2");
}
if (StringUtils.isNotBlank(queryDTO.getResOwner3())) {
builder.append(System.lineSeparator());
builder.append("AND c.res_owner3 = :resOwner3");
builder.append("AND c.org_id = :orgId");
}
if (StringUtils.isNotBlank(queryDTO.getCreateUser())) {
builder.append(System.lineSeparator());
@@ -349,10 +346,12 @@ public class CourseDao extends BaseDao<Course> {
// 排序逻辑
String orderAscStr = orderAsc == null || orderAsc ? "ASC" : "DESC";
// 多字段排序: sysType resOwner
if (StringUtils.equals(orderField, "sysType") || StringUtils.equals(orderField, "resOwner")) {
if (StringUtils.equals(orderField, "sysType")) {
for (int i = 1; i <= 3; i++) {
builder.append("c.").append(orderFieldSql).append(i).append(" ").append(orderAscStr).append(", ");
}
} else if (StringUtils.equals(orderField, "resOwner")) {
builder.append("org.org_name ").append(orderAscStr).append(", ");
} else if (StringUtils.equals(orderField, "studys")) {
builder.append("COALESCE(stu.studys, 0) ").append(orderAscStr).append(", ");
} else if (StringUtils.equals(orderField, "score")) {
@@ -363,7 +362,7 @@ public class CourseDao extends BaseDao<Course> {
builder.append("c.").append(orderFieldSql).append(" ").append(orderAscStr).append(", ");
}
}
builder.append("c.is_top DESC, c.sort_weight ASC, c.sys_create_time DESC");
builder.append("c.sys_create_time DESC");
}
private void setQueryParams(Query query,
@@ -413,13 +412,7 @@ public class CourseDao extends BaseDao<Course> {
query.setParameter("openCourse", queryDTO.getOpenCourse());
}
if (StringUtils.isNotBlank(queryDTO.getResOwner1())) {
query.setParameter("resOwner1", queryDTO.getResOwner1());
}
if (StringUtils.isNotBlank(queryDTO.getResOwner2())) {
query.setParameter("resOwner2", queryDTO.getResOwner2());
}
if (StringUtils.isNotBlank(queryDTO.getResOwner3())) {
query.setParameter("resOwner3", queryDTO.getResOwner3());
query.setParameter("orgId", queryDTO.getResOwner1());
}
if (StringUtils.isNotBlank(queryDTO.getCreateUser())) {
query.setParameter("createUser", queryDTO.getCreateUser());

View File

@@ -20,6 +20,11 @@ public class CoursePageQueryDTO {
/**资源归属三级*/
private String resOwner3;
/**
* 资源归属机构id
*/
private String orgId;
/**是否发布,无就是全部*/
private Boolean publish;

View File

@@ -1,7 +1,6 @@
package com.xboe.module.course.service;
import java.util.List;
import com.xboe.common.PageList;
import com.xboe.module.course.dto.CourseContentDto;
import com.xboe.module.course.dto.SortItem;
import com.xboe.module.course.entity.CourseAssess;
@@ -9,6 +8,8 @@ import com.xboe.module.course.entity.CourseContent;
import com.xboe.module.course.entity.CourseExam;
import com.xboe.module.course.entity.CourseHomeWork;
import java.util.List;
/**
* 课程内容,当前是分着处理,之后看是否与课程服务合并在一起
* */
@@ -54,7 +55,19 @@ public interface ICourseContentService{
* @return
*/
List<CourseContent> getByCourseId(String courseId);
/**
* 根据课程id、章节id得到课程所有目录即章节分页顺序按orderIndex 从小到大的顺序
* 25.11.26新增
*
* @param pageIndex 页码
* @param pageSize 每页数量
* @param courseId 课程id
* @param sectionIdList 章节id集合
* @return 课程章节信息集合分页
*/
PageList<CourseContent> getByCourseIdPage(int pageIndex, int pageSize, String courseId, List<String> sectionIdList);
/**
* 更新内容顺序
* @param courseId

View File

@@ -5,11 +5,12 @@ import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.core.cache.IXaskCache;
import com.xboe.core.cache.XaskCacheProvider;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.IFieldFilter;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.course.dao.*;
import com.xboe.module.course.dto.CourseContentDto;
@@ -141,6 +142,27 @@ public class CourseContentServiceImpl implements ICourseContentService {
return list;
}
/**
* 根据课程id、章节id得到课程所有目录即章节分页顺序按orderIndex 从小到大的顺序
* 25.11.26新增
*
* @param pageIndex 页码
* @param pageSize 每页数量
* @param courseId 课程id
* @param sectionIdList 章节id集合
* @return 课程章节信息集合分页
*/
@Override
public PageList<CourseContent> getByCourseIdPage(int pageIndex, int pageSize, String courseId, List<String> sectionIdList) {
List<IFieldFilter> filters = new ArrayList<>();
filters.add(FieldFilters.eq("courseId", courseId));
filters.add(FieldFilters.eq("deleted", false));
if (sectionIdList != null && !sectionIdList.isEmpty()) {
filters.add(FieldFilters.in("csectionId", sectionIdList));
}
return ccDao.findPage(pageIndex, pageSize, OrderCondition.asc("sortIndex"), filters.toArray(new IFieldFilter[0]));
}
@Override
public CourseHomeWork getHomework(String ccid) {
CourseHomeWork hw=homeworkDao.findOne(FieldFilters.eq("contentId", ccid));

View File

@@ -1,8 +1,10 @@
package com.xboe.module.course.service.impl;
import com.boe.feign.api.usercenter.entity.ApiOrgListVo;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.common.exception.AppException;
import com.xboe.config.MySqlSchemaProperties;
import com.xboe.core.CurrentUser;
import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.IFieldFilter;
@@ -22,24 +24,30 @@ import com.xboe.module.course.service.ICourseFullTextSearch;
import com.xboe.module.course.service.ICoursePageService;
import com.xboe.module.course.vo.CoursePageVo;
import com.xboe.module.excel.ExportsExcelSenderUtil;
import com.xboe.module.type.entity.Type;
import com.xboe.module.type.service.ITypeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@EnableConfigurationProperties({MySqlSchemaProperties.class})
@Service
@Slf4j
public class CoursePageServiceImpl implements ICoursePageService {
@Autowired
private MySqlSchemaProperties mySqlSchemaProperties;
@Resource
private CourseDao courseDao;
@@ -49,6 +57,9 @@ public class CoursePageServiceImpl implements ICoursePageService {
@Autowired
private IOutSideDataService outSideDataService;
@Resource
private ITypeService typeService;
@Autowired(required = false)
private ICourseFullTextSearch fullTextSearch;
@@ -130,8 +141,8 @@ public class CoursePageServiceImpl implements ICoursePageService {
//
// return result;
// 第二版
long total = courseDao.countCourse(coursePageQueryDTO, isSystemAdmin, orgIds, currentAccountId);
List<CoursePageVo> voList = courseDao.queryCourse(coursePageQueryDTO, isSystemAdmin, orgIds, currentAccountId, true);
long total = courseDao.countCourse(coursePageQueryDTO, isSystemAdmin, orgIds, currentAccountId, mySqlSchemaProperties.getUserCenterSchema());
List<CoursePageVo> voList = courseDao.queryCourse(coursePageQueryDTO, isSystemAdmin, orgIds, currentAccountId, true, mySqlSchemaProperties.getUserCenterSchema());
PageList<CoursePageVo> result = new PageList<>();
result.setCount((int) total);
result.setPageSize(coursePageQueryDTO.getPageSize());
@@ -239,7 +250,7 @@ public class CoursePageServiceImpl implements ICoursePageService {
boolean isSystemAdmin = userOrgIds.getPermissions().containsKey(UserOrgIds.IsSystemAdminKey)
&& userOrgIds.getPermissions().get(UserOrgIds.IsSystemAdminKey);
List<CoursePageVo> courseList = courseDao.queryCourse(coursePageQueryDTO, isSystemAdmin, orgIds, null, false);
List<CoursePageVo> courseList = courseDao.queryCourse(coursePageQueryDTO, isSystemAdmin, orgIds, null, false, mySqlSchemaProperties.getUserCenterSchema());
// 导出
LinkedHashMap<String, String> exportMap = new LinkedHashMap<>();
@@ -253,18 +264,39 @@ public class CoursePageServiceImpl implements ICoursePageService {
exportMap.put("发布状态", "published");
exportMap.put("启停用状态", "enabled");
exportMap.put("公开课", "openCourse");
exportMap.put("资源归属", "resOwner");
exportMap.put("资源归属", "orgName");
exportMap.put("创建人", "sysCreateBy");
exportMap.put("创建来源", "createFrom");
exportMap.put("创建时间", "sysCreateTime");
List<Map<String, Object>> dataList = new ArrayList<>();
if (courseList != null && !courseList.isEmpty()) {
// TODO 查询sysType和resOwner
// 查询sysType
Type sysTypeParam = new Type();
sysTypeParam.setSysResType(1);
sysTypeParam.setStatus(1);
List<Type> typeList = typeService.findList(sysTypeParam);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
for (CoursePageVo coursePageVo : courseList) {
Map<String, Object> map = new HashMap<>();
map.put("name", coursePageVo.getName());
map.put("sysType", coursePageVo.getSysType1()); // FIXME 三级分类用/拼接
// 课程分类
StringBuilder sysTypeBuilder = new StringBuilder();
typeList.stream()
.filter(t -> StringUtils.equals(coursePageVo.getSysType1(), t.getId()))
.findFirst().ifPresent(t -> sysTypeBuilder.append(t.getName()));
if (StringUtils.isNotBlank(coursePageVo.getSysType2())) {
typeList.stream()
.filter(t -> StringUtils.equals(coursePageVo.getSysType2(), t.getId()))
.findFirst().ifPresent(t -> sysTypeBuilder.append("/").append(t.getName()));
}
if (StringUtils.isNotBlank(coursePageVo.getSysType3())) {
typeList.stream()
.filter(t -> StringUtils.equals(coursePageVo.getSysType3(), t.getId()))
.findFirst().ifPresent(t -> sysTypeBuilder.append("/").append(t.getName()));
}
map.put("sysType", sysTypeBuilder.toString());
// map.put("sysType", coursePageVo.getSysType1());
map.put("teacherName", coursePageVo.getTeacherName());
// 课程时长:秒转分
map.put("courseDuration", coursePageVo.getCourseDuration() / 60);
@@ -274,7 +306,7 @@ public class CoursePageServiceImpl implements ICoursePageService {
map.put("published", coursePageVo.getPublished() == null || !coursePageVo.getPublished() ? "未发布" : "已发布");
map.put("enabled", coursePageVo.getEnabled() == null || coursePageVo.getEnabled() ? "停用" : "启用");
map.put("openCourse", coursePageVo.getOpenCourse() == null || coursePageVo.getOpenCourse() == 0 ? "" : "");
map.put("resOwner", coursePageVo.getResOwner1()); // FIXME 三级分类用/拼接
map.put("orgName", coursePageVo.getOrgName());
map.put("sysCreateBy", coursePageVo.getSysCreateBy());
map.put("createFrom", CourseCreateFromEnum.getByCode(coursePageVo.getCreateFrom()).getLabel());
map.put("sysCreateTime", formatter.format(coursePageVo.getSysCreateTime()));

View File

@@ -53,6 +53,21 @@ public class CoursePageVo {
* 资源归属三级
*/
private String resOwner3;
/**
* 机构ID
*/
private String orgId;
/**
* 机构名称
*/
private String orgName;
/**
* 机构全名
*/
private String orgFullName;
/**
* 创建人

View File

@@ -8,13 +8,32 @@ import lombok.Data;
@Data
public class CourseStudyVo {
/**
* 内容id
*/
private String contentId;
/**
* 内容名称
*/
private String contentName;
/**
* 学习状态( 1-未学习2-学习中9-学习完成)
*/
private Integer status;
/**
* 学习时长
* 25.11.26新增
* studyDuration字段被占用了换一个
*/
private Integer learningDuration;
/**
* 学习进度(理论上来说这个字段应该是学习时长,但是原接口如此,暂时保留此字段)
*/
private Integer studyDuration;
}

View File

@@ -72,6 +72,9 @@ public class StudyCourseApi extends ApiBaseController{
@Autowired
IStudyExamService studyExamService;
@Autowired
IStudyHomeWorkService studyHomeWorkService;
@Resource
private ThirdApi thirdApi;
@@ -1185,15 +1188,18 @@ public class StudyCourseApi extends ApiBaseController{
return error("查询失败",e.getMessage());
}
}
/**
* 资源学习情况详细信息,此接口用于管理端处理
* @param pager
* @param courseId
* @param contentId
* @return
* 资源学习情况分页查询,此接口用于管理端处理
* 25.11.25修改,修改资源学习情况的查询字段,修改为管理端和教师端均可以查询,并添加部门和工号查询逻辑
*
* @param pager 分页参数
* @param courseId 课程id
* @param contentId 内容id
* @param name 用户名称
* @param status 用户学习状态1-未开始2-已完成3-进行中)
* @return 资源学习情况分页集合
*/
@RequestMapping(value="/contents",method = {RequestMethod.GET,RequestMethod.POST})
public JsonResponse<PageList<StudyCourseItem>> findPage(Pagination pager,String courseId,String contentId,String name,Integer status){
@@ -1201,14 +1207,55 @@ public class StudyCourseApi extends ApiBaseController{
return error("无课程信息");
}
try {
PageList<StudyCourseItem> rs=studyService.findItemPage(pager.getPageIndex(),pager.getPageSize(),contentId,courseId,name,status);
PageList<StudyCourseItem> rs = studyService.findItemPage(pager.getPageIndex(), pager.getPageSize(), null, contentId, courseId, name, status);
return success(rs);
}catch(Exception e) {
log.error("查询课程学习记录错误",e.getMessage());
log.error("【资源学习情况分页查询】错误:{}", e.getMessage());
return error("查询失败",e.getMessage());
}
}
/**
* 资源学习情况分页查询-考试信息
* 此接口只查询考试信息
*
* @param pager 分页参数
* @param courseId 课程id
* @param contentId 内容id
* @param name 用户名称
* @param status 用户学习状态1-未开始2-已完成3-进行中)
* @return 资源学习情况分页集合
*/
@RequestMapping(value = "/contents-exam", method = {RequestMethod.GET, RequestMethod.POST})
public JsonResponse<PageList<StudyCourseItem>> findPageExam(Pagination pager, String courseId, String contentId, String name, Integer status) {
if (StringUtils.isBlank(courseId)) {
return error("无课程信息");
}
try {
// 查询当前课程的考试信息
List<StudyExam> studyExams = studyExamService.getByCourseId(courseId);
// 空值校验
if (studyExams == null || studyExams.isEmpty()) {
return success(new PageList<>());
}
List<String> studyCourseItemIds = studyExams.stream().map(StudyExam::getStudyItemId).collect(Collectors.toList());
// 分页查询资源学习信息
PageList<StudyCourseItem> rs = studyService.findItemPage(pager.getPageIndex(), pager.getPageSize(), studyCourseItemIds, contentId, courseId, name, status);
// 拼接考试信息
List<StudyCourseItem> studyCourseItems = rs.getList();
if (studyCourseItems != null && !studyCourseItems.isEmpty() && !studyExams.isEmpty()) {
for (StudyCourseItem studyCourseItem : studyCourseItems) {
// 获取当前课程的考试信息,并按lastTime字段倒序排列
studyCourseItem.setStudyExams(studyExams.stream().filter(studyExam -> studyExam.getStudyItemId().equals(studyCourseItem.getId())).sorted(Comparator.comparing(StudyExam::getLastTime).reversed()).collect(Collectors.toList()));
}
}
return success(rs);
} catch (Exception e) {
log.error("【资源学习情况分页查询-考试信息】错误:{}", e.getMessage());
return error("查询失败", e.getMessage());
}
}
@RequestMapping(value="/study-course-content",method = {RequestMethod.GET,RequestMethod.POST})
public JsonResponse<StudyCourseItem> findStudyCourseItem(String studyId,String contentId){
if(StringUtils.isBlank(studyId)){

View File

@@ -1,19 +1,18 @@
package com.xboe.school.study.entity;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.IdEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Transient;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xboe.core.SysConstant;
import com.xboe.core.orm.IdEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
/*
* 课程学习记录表,相当于课程学习表的子表
@@ -138,4 +137,11 @@ public class StudyCourseItem extends IdEntity {
@Transient
private BigDecimal progressVideo;
/**
* 考试记录集合
* 仅在资源学习情况分页查询-考试信息接口使用
* 25.11.25新增
*/
@Transient
private List<StudyExam> studyExams;
}

View File

@@ -1,14 +1,14 @@
package com.xboe.school.study.service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import com.xboe.common.PageList;
import com.xboe.school.study.dto.StudyContentDto;
import com.xboe.school.study.entity.StudyCourseItem;
import com.xboe.school.study.entity.StudyTime;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
* 学习情况处理,比较综合一个处理类
* @author seastar
@@ -85,18 +85,21 @@ public interface IStudyService {
* @return
*/
List<StudyCourseItem> findByStudyId(String studyId);
/**
* 查询学习内容记录
* @param pageIndex
* @param pageSize
* @param contentId
* @param courseId
* @param name
* @param status
* @return
* 资源学习情况分页查询,此接口用于管理端处理
* 25.11.25修改,修改资源学习情况的查询字段,修改为管理端和教师端均可以查询,并添加部门和工号查询逻辑
*
* @param ids 资源学习id集合
* @param pageIndex 页码
* @param pageSize 每页数量
* @param courseId 课程id
* @param contentId 内容id
* @param name 用户名称
* @param status 用户学习状态1-未开始2-已完成3-进行中)
* @return 资源学习情况分页集合
*/
PageList<StudyCourseItem> findItemPage(int pageIndex, int pageSize, String contentId, String courseId, String name, Integer status);
PageList<StudyCourseItem> findItemPage(int pageIndex, int pageSize, List<String> ids, String contentId, String courseId, String name, Integer status);
List<StudyCourseItem> getList(String courseId, String contentId, String name, Integer status);

View File

@@ -1,20 +1,5 @@
package com.xboe.school.study.service.impl;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.transaction.Transactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.core.orm.FieldFilters;
@@ -32,8 +17,20 @@ import com.xboe.school.study.entity.StudyTime;
import com.xboe.school.study.service.IStudyService;
import com.xboe.standard.enums.BoedxContentType;
import com.xboe.system.user.dao.UserDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
@Service
public class StudyServiceImpl implements IStudyService{
@@ -223,14 +220,30 @@ public class StudyServiceImpl implements IStudyService{
return list;
}
/**
* 资源学习情况分页查询,此接口用于管理端处理
* 25.11.25修改,修改资源学习情况的查询字段,修改为管理端和教师端均可以查询,并添加部门和工号查询逻辑
*
* @param ids 资源学习id集合
* @param pageIndex 页码
* @param pageSize 每页数量
* @param courseId 课程id
* @param contentId 内容id
* @param name 用户名称
* @param status 用户学习状态1-未开始2-已完成3-进行中)
* @return 资源学习情况分页集合
*/
@Override
public PageList<StudyCourseItem> findItemPage(int pageIndex, int pageSize, String contentId, String courseId,String name,Integer status) {
public PageList<StudyCourseItem> findItemPage(int pageIndex, int pageSize, List<String> ids, String contentId, String courseId,String name,Integer status) {
QueryBuilder query = QueryBuilder.from(StudyCourseItem.class);
query.setPageIndex(pageIndex);
query.setPageSize(pageSize);
OrderCondition oc=OrderCondition.desc("id");
query.addOrder(oc);
if (ids != null && !ids.isEmpty()) {
query.addFilter(FieldFilters.in("id",ids));
}
if(StringUtils.isNotBlank(contentId)) {
query.addFilter(FieldFilters.eq("contentId",contentId));
}
@@ -251,16 +264,22 @@ public class StudyServiceImpl implements IStudyService{
}else if (status == 1) {
String sql = "select bsc.id,bsc.course_id,bsc.course_name,bsc.aname,item.content_id,0 as progress,1 as status from boe_study_course bsc " +
" left join boe_study_course_item item on bsc.course_id = item.course_id and bsc.id = item.study_id" +
" where bsc.course_id = '"+courseId+"' and bsc.aname like '%"+name+"%' and bsc.id not in(" +
" where bsc.course_id = '" + courseId + "'" +
(StringUtils.isBlank(name) ? "" : "and bsc.aname like '%"+name+"%'") + "and bsc.id not in(" +
" select item.study_id from boe_study_course_item item " +
" where item.course_id = '" + courseId + "' and item.content_id = '"+ contentId+"' and item.aname like '%"+name+"%' group by item.study_id" +
" where item.course_id = '" + courseId + "'" +
(StringUtils.isBlank(contentId) ? "" : "and item.content_id = '" + contentId + "'") +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name+"%'") + " group by item.study_id" +
" ) group by bsc.id limit "+ pageIndex2+","+ pageSize+";";
String sql2 = "select count(*) as total from (select bsc.id,bsc.course_id,bsc.course_name,bsc.aname,item.content_id,0 as progress,1 as status from boe_study_course bsc " +
" left join boe_study_course_item item on bsc.course_id = item.course_id and bsc.id = item.study_id" +
" where bsc.course_id = '"+courseId+"' and bsc.aname like '%"+name+"%' and bsc.id not in(" +
" where bsc.course_id = '"+courseId+"'" +
(StringUtils.isBlank(name) ? "" : "and bsc.aname like '%"+name+"%'") + " and bsc.id not in(" +
" select item.study_id from boe_study_course_item item " +
" where item.course_id = '" + courseId + "' and item.content_id = '"+ contentId+"' and item.aname like '%"+name+"%' group by item.study_id" +
" where item.course_id = '" + courseId + "'" +
(StringUtils.isBlank(contentId) ? "" : "and item.content_id = '" + contentId + "'") +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name+"%'") + " group by item.study_id" +
" ) group by bsc.id) as total";
log.info("资源完成情况未开始sql"+sql);
List<Object[]> list = scDao.sqlFindList(sql);
@@ -285,20 +304,23 @@ public class StudyServiceImpl implements IStudyService{
String sql = "select a.id, a.course_id, a.course_name, a.aname, " +
"IFNULL(b.finish_time, '0') as finish_time, IFNULL(b.progress, 0) as progress, IFNULL(b.status, 1) as status,b.score " +
"from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "' and aname like '%"+name+"%') a " +
"from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "'" +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%"+name+"%'") + ") a " +
"left join " +
"(select bsc.id, bsc.course_id, bsc.course_name, bsc.aname, item.finish_time, item.progress, item.status,MAX(item.score) score " +
"from boe_study_course bsc left join boe_study_course_item item on item.course_id = bsc.course_id and item.study_id = bsc.id " +
"where bsc.course_id = '" + courseId + "' and item.content_id = '" + contentId + "' and item.aname like '%"+name+"%' group by bsc.id) b " +
"where bsc.course_id = '" + courseId + "'" +
(StringUtils.isBlank(contentId) ? "" : "and item.content_id = '" + contentId + "'") +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name +"%'") + " group by bsc.id) b " +
"on a.course_id = b.course_id and a.id = b.id " +
"group by a.id limit "+ pageIndex2+","+ pageSize+";";
String sql2 = "select count(*) as total from (select a.id, a.course_id, a.course_name, a.aname, " +
"IFNULL(b.finish_time, 0) as finish_time, IFNULL(b.progress, 0) as progress, IFNULL(b.status, 1) as status " +
"from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "' and aname like '%"+name+"%') a " +
"left join " +
"(select bsc.id, bsc.course_id, bsc.course_name, bsc.aname, item.finish_time, item.progress, item.status " +
"from boe_study_course bsc left join boe_study_course_item item on item.course_id = bsc.course_id and item.study_id = bsc.id " +
"where bsc.course_id = '" + courseId + "' and item.content_id = '" + contentId + "' and item.aname like '%"+name+"%' group by bsc.id) b " +
"from (select id, course_id, course_name, aname, 0, 1 from boe_study_course where course_id = '" + courseId + "'" +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name + "%'") + ") a " + "left join " + "(select bsc.id, bsc.course_id, bsc.course_name, bsc.aname, item.finish_time, item.progress, item.status " + "from boe_study_course bsc left join boe_study_course_item item on item.course_id = bsc.course_id and item.study_id = bsc.id " + "where bsc.course_id = '" + courseId + "'" +
(StringUtils.isBlank(contentId) ? "" : "and item.content_id = '" + contentId + "'") +
(StringUtils.isBlank(name) ? "" : "and item.aname like '%" + name +"%'") +
" group by bsc.id) b " +
"on a.course_id = b.course_id and a.id = b.id " +
"group by a.id) as total";
log.info("资源完成情况全部sql"+sql);

View File

@@ -1,22 +1,5 @@
package com.xboe.school.study.service.impl;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;
import javax.transaction.Transactional;
import com.xboe.module.course.dao.CourseContentDao;
import com.xboe.module.course.dto.CourseContentDto;
import com.xboe.module.course.entity.CourseContent;
import com.xboe.school.study.dao.StudyCourseItemDao;
import com.xboe.school.study.entity.StudyCourseItem;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.xboe.common.OrderCondition;
import com.xboe.common.PageList;
import com.xboe.common.beans.KeyValue;
@@ -24,16 +7,27 @@ import com.xboe.core.orm.FieldFilters;
import com.xboe.core.orm.FieldUpdateType;
import com.xboe.core.orm.QueryBuilder;
import com.xboe.core.orm.UpdateBuilder;
import com.xboe.module.course.dao.CourseContentDao;
import com.xboe.module.course.dao.CourseDao;
import com.xboe.module.course.dto.CourseStudyDto;
import com.xboe.module.course.service.ICourseStudySearch;
import com.xboe.school.study.dao.StudyCourseDao;
import com.xboe.school.study.dao.StudyCourseItemDao;
import com.xboe.school.study.dao.StudySignupDao;
import com.xboe.school.study.entity.StudyCourse;
import com.xboe.school.study.entity.StudyCourseItem;
import com.xboe.school.study.entity.StudySignup;
import com.xboe.school.study.service.IStudySignupService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
@Slf4j
@Service
@@ -232,6 +226,10 @@ public class StudySignupServiceImpl implements IStudySignupService{
if(StringUtils.isNotBlank(ss.getAid())) {
query.addFilter(FieldFilters.eq("aid", ss.getAid()));
}
// 25.11.26新增添加根据报名方式查询1自主报名2管理代报
if (ss.getSignType() != null) {
query.addFilter(FieldFilters.eq("signType", ss.getSignType()));
}
}
return signupDao.findPage(query.builder());
}

View File

@@ -117,4 +117,8 @@ aop-log-record:
password: admin
elasticsearch:
host: 192.168.0.253
port: 9200
port: 9200
mysql:
schema:
user-center-schema: userbasic

View File

@@ -194,4 +194,8 @@ aop-log-record:
password: admin
elasticsearch:
host: 10.251.129.21
port: 9200
port: 9200
mysql:
schema:
user-center-schema: user_basic

View File

@@ -147,4 +147,8 @@ boe:
pcPageUrl: ${boe.domain-name}/pc/course/studyindex?id=
h5PageUrl: ${boe.domain-name}/mobile/pages/study/courseStudy?id=
pcLoginUrl: ${boe.domain-name}/web/
h5LoginUrl: ${boe.domain-name}/m/loginuser
h5LoginUrl: ${boe.domain-name}/m/loginuser
mysql:
schema:
user-center-schema: user_basic

View File

@@ -221,4 +221,8 @@ aop-log-record:
host: 10.251.129.25
port: 9200
user: elastic
password: Boe@es123
password: Boe@es123
mysql:
schema:
user-center-schema: userbasic