|
|
@@ -0,0 +1,243 @@
|
|
|
+package org.dromara.main.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
+import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.dromara.main.domain.MainTraining;
|
|
|
+import org.dromara.main.domain.MainTrainingVideo;
|
|
|
+import org.dromara.main.domain.bo.MainTrainingBo;
|
|
|
+import org.dromara.main.domain.vo.MainTrainingLearnRecordVo;
|
|
|
+import org.dromara.main.domain.vo.MainTrainingParticipantVo;
|
|
|
+import org.dromara.main.domain.vo.MainTrainingVo;
|
|
|
+import org.dromara.main.domain.vo.MainTrainingVideoVo;
|
|
|
+import org.dromara.main.mapper.MainTrainingMapper;
|
|
|
+import org.dromara.main.mapper.MainTrainingVideoMapper;
|
|
|
+import org.dromara.main.service.IMainTrainingService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.util.Collection;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Objects;
|
|
|
+
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class MainTrainingServiceImpl implements IMainTrainingService {
|
|
|
+
|
|
|
+ private final MainTrainingMapper baseMapper;
|
|
|
+ private final MainTrainingVideoMapper videoMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public MainTrainingVo queryById(Long id) {
|
|
|
+ MainTrainingVo vo = baseMapper.selectVoById(id);
|
|
|
+ if (vo != null) {
|
|
|
+ // 查询关联视频列表
|
|
|
+ List<MainTrainingVideoVo> videoList = videoMapper.selectVoList(
|
|
|
+ new LambdaQueryWrapper<MainTrainingVideo>()
|
|
|
+ .eq(MainTrainingVideo::getTrainingId, id)
|
|
|
+ .orderByAsc(MainTrainingVideo::getSortOrder)
|
|
|
+ );
|
|
|
+ vo.setVideoList(videoList);
|
|
|
+ fillExtraInfo(vo);
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<MainTrainingVo> queryPageList(MainTrainingBo bo, PageQuery pageQuery) {
|
|
|
+ LambdaQueryWrapper<MainTraining> lqw = buildQueryWrapper(bo);
|
|
|
+ Page<MainTrainingVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
|
+
|
|
|
+ // 填充额外信息
|
|
|
+ for (MainTrainingVo vo : result.getRecords()) {
|
|
|
+ fillExtraInfo(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return TableDataInfo.build(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<MainTrainingVo> queryOfflinePageList(MainTrainingBo bo, PageQuery pageQuery) {
|
|
|
+ bo.setTrainingType("offline");
|
|
|
+ return queryPageList(bo, pageQuery);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MainTrainingVo> queryList(MainTrainingBo bo) {
|
|
|
+ LambdaQueryWrapper<MainTraining> lqw = buildQueryWrapper(bo);
|
|
|
+ return baseMapper.selectVoList(lqw);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public MainTrainingVo queryOfflineById(Long id) {
|
|
|
+ MainTrainingVo vo = queryById(id);
|
|
|
+ if (vo == null || !"offline".equals(vo.getTrainingType())) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<MainTrainingLearnRecordVo> queryLearnRecordPage(Long trainingId, PageQuery pageQuery) {
|
|
|
+ Page<MainTrainingLearnRecordVo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
|
|
|
+ return TableDataInfo.build(baseMapper.selectLearnRecordPage(page, trainingId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<MainTrainingParticipantVo> queryOfflineParticipantPage(Long trainingId, PageQuery pageQuery) {
|
|
|
+ Page<MainTrainingParticipantVo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
|
|
|
+ return TableDataInfo.build(baseMapper.selectOfflineParticipantPage(page, trainingId));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MainTrainingLearnRecordVo> queryLearnRecordExportList(Long trainingId, List<Long> studentIds) {
|
|
|
+ List<Long> validIds = studentIds.stream().filter(Objects::nonNull).toList();
|
|
|
+ if (validIds.isEmpty()) {
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+ return baseMapper.selectLearnRecordListByStudentIds(trainingId, validIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<MainTrainingParticipantVo> queryOfflineParticipantExportList(Long trainingId, List<Long> studentIds) {
|
|
|
+ List<Long> validIds = studentIds.stream().filter(Objects::nonNull).toList();
|
|
|
+ if (validIds.isEmpty()) {
|
|
|
+ return List.of();
|
|
|
+ }
|
|
|
+ return baseMapper.selectOfflineParticipantListByStudentIds(trainingId, validIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ private LambdaQueryWrapper<MainTraining> buildQueryWrapper(MainTrainingBo bo) {
|
|
|
+ LambdaQueryWrapper<MainTraining> lqw = Wrappers.lambdaQuery();
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getTrainingType()), MainTraining::getTrainingType, bo.getTrainingType());
|
|
|
+ lqw.like(StringUtils.isNotBlank(bo.getName()), MainTraining::getName, bo.getName());
|
|
|
+ lqw.eq(ObjectUtil.isNotNull(bo.getStatus()), MainTraining::getStatus, bo.getStatus());
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getJobType()), MainTraining::getJobType, bo.getJobType());
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getJobLevel()), MainTraining::getJobLevel, bo.getJobLevel());
|
|
|
+ lqw.orderByAsc(MainTraining::getSortOrder);
|
|
|
+ lqw.orderByDesc(MainTraining::getCreateTime);
|
|
|
+ return lqw;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充额外统计信息
|
|
|
+ */
|
|
|
+ private void fillExtraInfo(MainTrainingVo vo) {
|
|
|
+ if ("video".equals(vo.getTrainingType())) {
|
|
|
+ Long count = baseMapper.countLearnRecords(vo.getId());
|
|
|
+ vo.setLearnCount(count != null ? count.intValue() : 0);
|
|
|
+ } else if ("offline".equals(vo.getTrainingType())) {
|
|
|
+ Long count = baseMapper.countEnrollments(vo.getId());
|
|
|
+ vo.setParticipantCount(count != null ? count.intValue() : 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean insertByBo(MainTrainingBo bo) {
|
|
|
+ MainTraining add = BeanUtil.toBean(bo, MainTraining.class);
|
|
|
+ // 如果上架,设置上架时间
|
|
|
+ if (add.getStatus() != null && add.getStatus() == 1) {
|
|
|
+ add.setPublishTime(new Date());
|
|
|
+ }
|
|
|
+ boolean flag = baseMapper.insert(add) > 0;
|
|
|
+ if (flag) {
|
|
|
+ bo.setId(add.getId());
|
|
|
+ // 保存视频子表
|
|
|
+ saveVideoList(add.getId(), bo.getVideoList());
|
|
|
+ }
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean updateByBo(MainTrainingBo bo) {
|
|
|
+ MainTraining update = BeanUtil.toBean(bo, MainTraining.class);
|
|
|
+ boolean flag = baseMapper.updateById(update) > 0;
|
|
|
+ if (flag && bo.getVideoList() != null) {
|
|
|
+ // 先删除旧视频,再插入新视频
|
|
|
+ videoMapper.delete(
|
|
|
+ new LambdaQueryWrapper<MainTrainingVideo>()
|
|
|
+ .eq(MainTrainingVideo::getTrainingId, bo.getId())
|
|
|
+ );
|
|
|
+ saveVideoList(bo.getId(), bo.getVideoList());
|
|
|
+ }
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存视频子表
|
|
|
+ */
|
|
|
+ private void saveVideoList(Long trainingId, List<MainTrainingBo.TrainingVideoBo> videoList) {
|
|
|
+ if (videoList == null || videoList.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < videoList.size(); i++) {
|
|
|
+ MainTrainingBo.TrainingVideoBo videoBo = videoList.get(i);
|
|
|
+ MainTrainingVideo video = new MainTrainingVideo();
|
|
|
+ video.setTrainingId(trainingId);
|
|
|
+ video.setName(videoBo.getName());
|
|
|
+ video.setOssId(videoBo.getOssId());
|
|
|
+ video.setFileUrl(videoBo.getFileUrl());
|
|
|
+ video.setFileSize(videoBo.getFileSize());
|
|
|
+ video.setFileType(videoBo.getFileType());
|
|
|
+ video.setDuration(videoBo.getDuration());
|
|
|
+ video.setSortOrder(videoBo.getSortOrder() != null ? videoBo.getSortOrder() : i + 1);
|
|
|
+ videoMapper.insert(video);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
+ if (isValid) {
|
|
|
+ // 业务校验
|
|
|
+ }
|
|
|
+ // 同时删除视频子表
|
|
|
+ for (Long id : ids) {
|
|
|
+ videoMapper.delete(
|
|
|
+ new LambdaQueryWrapper<MainTrainingVideo>()
|
|
|
+ .eq(MainTrainingVideo::getTrainingId, id)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ return baseMapper.deleteBatchIds(ids) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean deleteOfflineById(Long id) {
|
|
|
+ MainTraining training = baseMapper.selectById(id);
|
|
|
+ if (training == null || !"offline".equals(training.getTrainingType())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return deleteWithValidByIds(List.of(id), true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean updateStatus(Long id, Integer status) {
|
|
|
+ MainTraining training = new MainTraining();
|
|
|
+ training.setId(id);
|
|
|
+ training.setStatus(status);
|
|
|
+ // 上架时设置上架时间
|
|
|
+ if (status != null && status == 1) {
|
|
|
+ training.setPublishTime(new Date());
|
|
|
+ }
|
|
|
+ return baseMapper.updateById(training) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean updateOfflineStatus(Long id, Integer status) {
|
|
|
+ MainTraining training = baseMapper.selectById(id);
|
|
|
+ if (training == null || !"offline".equals(training.getTrainingType())) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return updateStatus(id, status);
|
|
|
+ }
|
|
|
+}
|