diff --git a/src/main/java/cn/soul2/demo/JavaDemoApplication.java b/src/main/java/cn/soul2/demo/JavaDemoApplication.java index f39beff..8868612 100644 --- a/src/main/java/cn/soul2/demo/JavaDemoApplication.java +++ b/src/main/java/cn/soul2/demo/JavaDemoApplication.java @@ -1,9 +1,11 @@ package cn.soul2.demo; +import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication +@MapperScan("cn.soul2.demo.mapper") public class JavaDemoApplication { public static void main(String[] args) { diff --git a/src/main/java/cn/soul2/demo/controller/QuestionnaireController.java b/src/main/java/cn/soul2/demo/controller/QuestionnaireController.java index 9160b2f..cfcb4ae 100644 --- a/src/main/java/cn/soul2/demo/controller/QuestionnaireController.java +++ b/src/main/java/cn/soul2/demo/controller/QuestionnaireController.java @@ -1,8 +1,10 @@ package cn.soul2.demo.controller; +import cn.soul2.demo.dto.QnSubjectRefSaveDTO; import cn.soul2.demo.dto.QuestionnaireDTO; import cn.soul2.demo.dto.base.UpdateStatusDTO; import cn.soul2.demo.repository.IQuestionnaireRepository; +import cn.soul2.demo.repository.IRefQuestionnaireSubjectRepository; import cn.soul2.demo.utils.base.BackUtils; import cn.soul2.demo.vo.QuestionnaireVO; import cn.soul2.demo.vo.base.Back; @@ -29,6 +31,9 @@ public class QuestionnaireController { @Autowired private IQuestionnaireRepository questionnaireRepository; + @Autowired + private IRefQuestionnaireSubjectRepository refQuestionnaireSubjectRepository; + @PostMapping("saveOrUpdate") public Back saveOrUpdate(@RequestBody QuestionnaireDTO dto) { return BackUtils.success(questionnaireRepository.saveOrUpdate(dto)); @@ -49,5 +54,9 @@ public class QuestionnaireController { return BackUtils.success(questionnaireRepository.updateStatus(dto)); } + @PostMapping("ref") + public Back ref(@RequestBody QnSubjectRefSaveDTO dto) { + return BackUtils.success(refQuestionnaireSubjectRepository.updateRefSubjects(dto)); + } } diff --git a/src/main/java/cn/soul2/demo/controller/SubjectController.java b/src/main/java/cn/soul2/demo/controller/SubjectController.java new file mode 100644 index 0000000..823cfaf --- /dev/null +++ b/src/main/java/cn/soul2/demo/controller/SubjectController.java @@ -0,0 +1,84 @@ +package cn.soul2.demo.controller; + +import cn.soul2.demo.dto.QnSubjectRefItemDTO; +import cn.soul2.demo.dto.SubjectDTO; +import cn.soul2.demo.dto.base.UpdateStatusDTO; +import cn.soul2.demo.entity.SubjectItemsDO; +import cn.soul2.demo.entity.sqlresult.SubjectChooseListDO; +import cn.soul2.demo.repository.IRefSubjectItemsRepository; +import cn.soul2.demo.repository.ISubjectItemsRepository; +import cn.soul2.demo.repository.ISubjectRepository; +import cn.soul2.demo.utils.base.BackUtils; +import cn.soul2.demo.vo.SubjectItemVO; +import cn.soul2.demo.vo.SubjectVO; +import cn.soul2.demo.vo.base.Back; +import cn.soul2.demo.vo.base.VPage; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Soul2 + * @date 2024-03-14 17:36 + */ + +@Slf4j +@RestController +@RequestMapping("/subject") +public class SubjectController { + + @Autowired + private ISubjectRepository subjectRepository; + + @Autowired + private ISubjectItemsRepository itemsRepository; + + @Autowired + private IRefSubjectItemsRepository refSubjectItemsRepository; + + @PostMapping("saveOrUpdate") + public Back saveOrUpdate(@RequestBody SubjectDTO dto) { + return BackUtils.success(subjectRepository.saveOrUpdate(dto)); + } + + @PostMapping("page") + public Back> page(@RequestBody SubjectDTO dto) { + return BackUtils.success(subjectRepository.page(dto)); + } + + @PostMapping("remove") + public Back remove(Collection ids) { + return BackUtils.success(subjectRepository.removeAndItems(ids)); + } + + @PostMapping("status") + public Back status(@RequestBody UpdateStatusDTO dto) { + return BackUtils.success(subjectRepository.status(dto)); + } + + @PostMapping("items") + public Back item(@RequestBody SubjectDTO dto) { + SubjectVO vo = new SubjectVO(); + BeanUtils.copyProperties(dto, vo); + List items = itemsRepository.listBySubjectId(dto.getId()); + return BackUtils.success(vo.setItems(items.stream().map(o -> { + SubjectItemVO itemVo = new SubjectItemVO(); + BeanUtils.copyProperties(o, itemVo); + return itemVo; + }).collect(Collectors.toList()))); + } + + @PostMapping("chooseList") + public Back> chooseList(@RequestBody QnSubjectRefItemDTO dto) { + return BackUtils.success(subjectRepository.chooseList(dto)); + } + +} diff --git a/src/main/java/cn/soul2/demo/dto/QnSubjectRefItemDTO.java b/src/main/java/cn/soul2/demo/dto/QnSubjectRefItemDTO.java new file mode 100644 index 0000000..b976195 --- /dev/null +++ b/src/main/java/cn/soul2/demo/dto/QnSubjectRefItemDTO.java @@ -0,0 +1,52 @@ +package cn.soul2.demo.dto; + +import cn.soul2.demo.dto.base.PageParams; +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-16 19:20 + */ + +@Data +@Accessors(chain = true) +public class QnSubjectRefItemDTO extends PageParams { + + /** + * 问题Id + */ + private String subjectId; + + /** + * 问卷id + */ + private String qnId; + + /** + * 题目标题 + */ + private String title; + + /** + * 题目内容 + */ + private String content; + + /** + * 排列序号 + */ + private Short sort; + + + /** + * 题目类型:0-单选;1-多选;2-文字 + */ + private Short type; + + /** + * 已选中 + */ + private Boolean selected; + +} diff --git a/src/main/java/cn/soul2/demo/dto/QnSubjectRefDTO.java b/src/main/java/cn/soul2/demo/dto/QnSubjectRefSaveDTO.java similarity index 75% rename from src/main/java/cn/soul2/demo/dto/QnSubjectRefDTO.java rename to src/main/java/cn/soul2/demo/dto/QnSubjectRefSaveDTO.java index f95f2ce..eae355f 100644 --- a/src/main/java/cn/soul2/demo/dto/QnSubjectRefDTO.java +++ b/src/main/java/cn/soul2/demo/dto/QnSubjectRefSaveDTO.java @@ -7,20 +7,20 @@ import java.util.Collection; /** * @author Soul2 - * @date 2024-03-13 15:21 + * @date 2024-03-16 20:30 */ @Data @Accessors(chain = true) -public class QnSubjectRefDTO { +public class QnSubjectRefSaveDTO { /** - * 问卷Id + * QnId */ private String qnId; /** - * 题目id + * 问题ids */ private Collection subjectIds; diff --git a/src/main/java/cn/soul2/demo/dto/SubjectDTO.java b/src/main/java/cn/soul2/demo/dto/SubjectDTO.java index 0444a0a..744d0b9 100644 --- a/src/main/java/cn/soul2/demo/dto/SubjectDTO.java +++ b/src/main/java/cn/soul2/demo/dto/SubjectDTO.java @@ -1,5 +1,6 @@ package cn.soul2.demo.dto; +import cn.soul2.demo.dto.base.PageParams; import lombok.Data; import lombok.experimental.Accessors; @@ -12,7 +13,7 @@ import java.util.List; @Data @Accessors(chain = true) -public class SubjectDTO { +public class SubjectDTO extends PageParams { /** * id diff --git a/src/main/java/cn/soul2/demo/entity/SubjectItemsDO.java b/src/main/java/cn/soul2/demo/entity/SubjectItemsDO.java index 2155075..c298335 100644 --- a/src/main/java/cn/soul2/demo/entity/SubjectItemsDO.java +++ b/src/main/java/cn/soul2/demo/entity/SubjectItemsDO.java @@ -15,7 +15,7 @@ import java.time.LocalDateTime; *

* * @author Soul2 - * @since 2024-03-12 10:10:24 + * @since 2024-03-15 20:03:34 */ @Getter @Setter @@ -44,10 +44,10 @@ public class SubjectItemsDO extends Model { private Short sort; /** - * 状态:0:禁用;1:启用; + * 题目id */ - @TableField("status") - private Short status; + @TableField("subject_id") + private String subjectId; /** * 更新时间 diff --git a/src/main/java/cn/soul2/demo/entity/sqlresult/RefQuestionnaireSubjectUseCountDO.java b/src/main/java/cn/soul2/demo/entity/sqlresult/RefQuestionnaireSubjectUseCountDO.java new file mode 100644 index 0000000..317344f --- /dev/null +++ b/src/main/java/cn/soul2/demo/entity/sqlresult/RefQuestionnaireSubjectUseCountDO.java @@ -0,0 +1,24 @@ +package cn.soul2.demo.entity.sqlresult; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-16 15:04 + */ + +@Data +@Accessors(chain = true) +public class RefQuestionnaireSubjectUseCountDO { + + /** + * 题目id + */ + private String subjectId; + + /** + * 被问卷使用的次数 + */ + private Integer useCount; +} diff --git a/src/main/java/cn/soul2/demo/entity/sqlresult/SubjectChooseListDO.java b/src/main/java/cn/soul2/demo/entity/sqlresult/SubjectChooseListDO.java new file mode 100644 index 0000000..db813b4 --- /dev/null +++ b/src/main/java/cn/soul2/demo/entity/sqlresult/SubjectChooseListDO.java @@ -0,0 +1,50 @@ +package cn.soul2.demo.entity.sqlresult; + +import lombok.Data; +import lombok.experimental.Accessors; + +/** + * @author Soul2 + * @date 2024-03-16 13:22 + */ + +@Data +@Accessors(chain = true) +public class SubjectChooseListDO { + + /** + * id + */ + private String id; + + /** + * 题目标题 + */ + private String title; + + /** + * 题目内容 + */ + private String content; + + /** + * 排列序号 + */ + private Short sort; + + /** + * 题目类型:0-单选;1-多选;2-文字 + */ + private Short type; + + /** + * 被问卷使用的次数 + */ + private Integer useCount; + + /** + * 已选中 + */ + private Integer selected; + +} diff --git a/src/main/java/cn/soul2/demo/mapper/QuestionnaireMapper.java b/src/main/java/cn/soul2/demo/mapper/QuestionnaireMapper.java index a02fb4d..e01c497 100644 --- a/src/main/java/cn/soul2/demo/mapper/QuestionnaireMapper.java +++ b/src/main/java/cn/soul2/demo/mapper/QuestionnaireMapper.java @@ -1,7 +1,13 @@ package cn.soul2.demo.mapper; import cn.soul2.demo.entity.QuestionnaireDO; +import cn.soul2.demo.vo.QuestionnaireVO; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; /** *

@@ -13,4 +19,15 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface QuestionnaireMapper extends BaseMapper { + /** + * 分页查询问卷及选择题目数量 + * + * @param page 页码 + * @param wrapper 查询条件 + * @return {@link IPage}<{@link QuestionnaireVO}> + */ + @Select("select a.*, IFNULL(r.has_subject_count,0) as has_subject_count from (SELECT * FROM tb_questionnaire WHERE removed=0) a left join (select qn_id, count(subject_id) as has_subject_count from tb_ref_questionnaire_subject WHERE removed=0) r on a.id=r.qn_id " + + "${ew.customSqlSegment}") + IPage page(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper); + } diff --git a/src/main/java/cn/soul2/demo/mapper/SubjectMapper.java b/src/main/java/cn/soul2/demo/mapper/SubjectMapper.java index b792bdc..5befbbe 100644 --- a/src/main/java/cn/soul2/demo/mapper/SubjectMapper.java +++ b/src/main/java/cn/soul2/demo/mapper/SubjectMapper.java @@ -1,7 +1,13 @@ package cn.soul2.demo.mapper; import cn.soul2.demo.entity.SubjectDO; +import cn.soul2.demo.entity.sqlresult.SubjectChooseListDO; +import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; /** *

@@ -13,4 +19,16 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; */ public interface SubjectMapper extends BaseMapper { + /** + * 分页查询已选题目, 用于问卷选择题目 + * + * @param page 页码 + * @param wrapper 查询条件 + * @param qnId 问卷id + * @return {@link IPage}<{@link SubjectChooseListDO}> + */ + @Select("select a.id, ifnull(r.use_count, 0) as use_count, a.content, a.sort, a.title, a.type, (CASE WHEN EXISTS (SELECT 1 FROM tb_ref_questionnaire_subject WHERE removed = 0 and qn_id = #{qnId} AND subject_id = a.id) THEN 1 ELSE 0 END) AS selected from (select * from tb_subject WHERE removed = 0) a left join (select subject_id, count(qn_id) as use_count from tb_ref_questionnaire_subject WHERE removed = 0) r on a.id=r.subject_id " + + "${ew.customSqlSegment}") + IPage useCounts(IPage page, @Param(Constants.WRAPPER) Wrapper wrapper, String qnId); + } diff --git a/src/main/java/cn/soul2/demo/repository/IRefQuestionnaireSubjectRepository.java b/src/main/java/cn/soul2/demo/repository/IRefQuestionnaireSubjectRepository.java index be5d96e..e45ef2e 100644 --- a/src/main/java/cn/soul2/demo/repository/IRefQuestionnaireSubjectRepository.java +++ b/src/main/java/cn/soul2/demo/repository/IRefQuestionnaireSubjectRepository.java @@ -1,6 +1,6 @@ package cn.soul2.demo.repository; -import cn.soul2.demo.dto.QnSubjectRefDTO; +import cn.soul2.demo.dto.QnSubjectRefSaveDTO; import cn.soul2.demo.entity.RefQuestionnaireSubjectDO; import cn.soul2.demo.entity.SubjectDO; import com.baomidou.mybatisplus.extension.service.IService; @@ -26,13 +26,7 @@ public interface IRefQuestionnaireSubjectRepository extends IService getSubjects(Collection qnIds); - /** - * 连接问卷-题目 - * - * @param dto QnId and subjectIds - * @return {@link Boolean} - */ - Boolean connectSubjects(QnSubjectRefDTO dto); + Boolean updateRefSubjects(QnSubjectRefSaveDTO dto); } diff --git a/src/main/java/cn/soul2/demo/repository/IRefSubjectItemsRepository.java b/src/main/java/cn/soul2/demo/repository/IRefSubjectItemsRepository.java index 2a875d0..638de27 100644 --- a/src/main/java/cn/soul2/demo/repository/IRefSubjectItemsRepository.java +++ b/src/main/java/cn/soul2/demo/repository/IRefSubjectItemsRepository.java @@ -26,6 +26,16 @@ public interface IRefSubjectItemsRepository extends IService */ List getSubjectItems(Collection subjectIds); + /** + * 更新连接 + * 不在新列表中的则删除,无则 + * + * @param subjectId + * @param newItemIds + * @return {@link Integer} + */ + Integer updateRef(String subjectId, Collection newItemIds); + /** * 连接题目-选项 * diff --git a/src/main/java/cn/soul2/demo/repository/ISubjectItemsRepository.java b/src/main/java/cn/soul2/demo/repository/ISubjectItemsRepository.java index ead2eab..42a6e80 100644 --- a/src/main/java/cn/soul2/demo/repository/ISubjectItemsRepository.java +++ b/src/main/java/cn/soul2/demo/repository/ISubjectItemsRepository.java @@ -3,6 +3,9 @@ package cn.soul2.demo.repository; import cn.soul2.demo.entity.SubjectItemsDO; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.Collection; +import java.util.List; + /** *

* 题选项表 服务类 @@ -13,5 +16,29 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ISubjectItemsRepository extends IService { + /** + * 根据题目id查询选项 + * + * @param subjectId 题目id + * @return {@link List}<{@link SubjectItemsDO}> + */ + List listBySubjectId(String subjectId); + + /** + * 根据题目id查询选项 + * + * @param subjectIds 题目id + * @return {@link List}<{@link SubjectItemsDO}> + */ + List listBySubjectIds(Collection subjectIds); + + /** + * 删除指定题目id下的所有选项 + * + * @param subjectIds 题目id + * @return {@link Boolean} + */ + Boolean removeBySubjectId(Collection subjectIds); + } diff --git a/src/main/java/cn/soul2/demo/repository/ISubjectRepository.java b/src/main/java/cn/soul2/demo/repository/ISubjectRepository.java index 4982123..bd80214 100644 --- a/src/main/java/cn/soul2/demo/repository/ISubjectRepository.java +++ b/src/main/java/cn/soul2/demo/repository/ISubjectRepository.java @@ -1,9 +1,16 @@ package cn.soul2.demo.repository; +import cn.soul2.demo.dto.QnSubjectRefItemDTO; import cn.soul2.demo.dto.SubjectDTO; +import cn.soul2.demo.dto.base.UpdateStatusDTO; import cn.soul2.demo.entity.SubjectDO; +import cn.soul2.demo.entity.sqlresult.SubjectChooseListDO; +import cn.soul2.demo.vo.SubjectVO; +import cn.soul2.demo.vo.base.VPage; import com.baomidou.mybatisplus.extension.service.IService; +import java.util.Collection; + /** *

* 题目表 服务类 @@ -14,6 +21,44 @@ import com.baomidou.mybatisplus.extension.service.IService; */ public interface ISubjectRepository extends IService { + /** + * 保存或更新 + * + * @param dto 入参 + * @return {@link Boolean} + */ Boolean saveOrUpdate(SubjectDTO dto); + /** + * 删除题目,同时删除选项 + * + * @param ids 题目id + * @return {@link Boolean} + */ + Boolean removeAndItems(Collection ids); + + /** + * 分页查询 + * + * @param dto 查询条件 + * @return {@link VPage}<{@link SubjectVO}> + */ + VPage page(SubjectDTO dto); + + /** + * 更新状态 + * + * @param dto 目标id和状态 + * @return {@link Boolean} + * @deprecated 问题状态无意义, 更新状态将没有任何影响 + */ + Boolean status(UpdateStatusDTO dto); + + /** + * 问卷选择题目时的视图查询 + * + * @param dto 查询条件 + * @return {@link VPage}<{@link SubjectChooseListDO}> + */ + VPage chooseList(QnSubjectRefItemDTO dto); } diff --git a/src/main/java/cn/soul2/demo/repository/impl/QuestionnaireRepositoryImpl.java b/src/main/java/cn/soul2/demo/repository/impl/QuestionnaireRepositoryImpl.java index 182ce5f..a96b0f2 100644 --- a/src/main/java/cn/soul2/demo/repository/impl/QuestionnaireRepositoryImpl.java +++ b/src/main/java/cn/soul2/demo/repository/impl/QuestionnaireRepositoryImpl.java @@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; +import javax.annotation.Resource; import java.util.stream.Collectors; /** @@ -29,6 +30,9 @@ import java.util.stream.Collectors; @Service public class QuestionnaireRepositoryImpl extends ServiceImpl implements IQuestionnaireRepository { + @Resource + private QuestionnaireMapper questionnaireMapper; + @Override public VPage page(QuestionnaireDTO dto) { LambdaQueryWrapper query = Wrappers.lambdaQuery(); @@ -41,7 +45,7 @@ public class QuestionnaireRepositoryImpl extends ServiceImpl page = PageUtils.to(super.page(PageUtils.build(dto), query)); + VPage page = PageUtils.to(questionnaireMapper.page(PageUtils.build(dto), query)); return PageUtils.to(page, page.getRows().stream().map(e -> { QuestionnaireVO vo = new QuestionnaireVO(); BeanUtils.copyProperties(e, vo); diff --git a/src/main/java/cn/soul2/demo/repository/impl/RefQuestionnaireSubjectRepositoryImpl.java b/src/main/java/cn/soul2/demo/repository/impl/RefQuestionnaireSubjectRepositoryImpl.java index 79f515b..ad8b9d2 100644 --- a/src/main/java/cn/soul2/demo/repository/impl/RefQuestionnaireSubjectRepositoryImpl.java +++ b/src/main/java/cn/soul2/demo/repository/impl/RefQuestionnaireSubjectRepositoryImpl.java @@ -1,6 +1,6 @@ package cn.soul2.demo.repository.impl; -import cn.soul2.demo.dto.QnSubjectRefDTO; +import cn.soul2.demo.dto.QnSubjectRefSaveDTO; import cn.soul2.demo.entity.RefQuestionnaireSubjectDO; import cn.soul2.demo.entity.SubjectDO; import cn.soul2.demo.mapper.RefQuestionnaireSubjectMapper; @@ -10,8 +10,11 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.util.ArrayList; import java.util.Collection; @@ -50,11 +53,39 @@ public class RefQuestionnaireSubjectRepositoryImpl extends ServiceImpl { - RefQuestionnaireSubjectDO ref = new RefQuestionnaireSubjectDO(); - ref.setSubjectId(s).setQnId(dto.getQnId()); - return ref; - }).collect(Collectors.toList())); + @Transactional + public Boolean updateRefSubjects(QnSubjectRefSaveDTO dto) { + if (StringUtils.isBlank(dto.getQnId())) { + return Boolean.FALSE; + } + // load old Ref data + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(RefQuestionnaireSubjectDO::getQnId, dto.getQnId()); + List oldRefs = super.list(query); + List oldRefSubjectIds = oldRefs.stream().map(RefQuestionnaireSubjectDO::getSubjectId).collect(Collectors.toList()); + + // Calculate the data that needs to be changed + List removeRefs = oldRefs.stream().filter(e -> !dto.getSubjectIds().contains(e.getSubjectId())).collect(Collectors.toList()); + List insertRefs = dto.getSubjectIds().stream().filter(e -> !oldRefSubjectIds.contains(e)).collect(Collectors.toList()); + boolean removed; + if (CollectionUtils.isNotEmpty(removeRefs)) { + removed = super.removeByIds(removeRefs.stream().map(RefQuestionnaireSubjectDO::getId).collect(Collectors.toList())); + } else { + removed = true; + } + if (removed && CollectionUtils.isEmpty(insertRefs)) { + return Boolean.TRUE; + } + if (removed) { + boolean saved = super.saveBatch(insertRefs.stream().map(e -> { + RefQuestionnaireSubjectDO ref = new RefQuestionnaireSubjectDO(); + return ref.setQnId(dto.getQnId()).setSubjectId(e); + }).collect(Collectors.toList())); + if (saved) { + return Boolean.TRUE; + } + } + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return Boolean.FALSE; } } diff --git a/src/main/java/cn/soul2/demo/repository/impl/RefSubjectItemsRepositoryImpl.java b/src/main/java/cn/soul2/demo/repository/impl/RefSubjectItemsRepositoryImpl.java index d2b960e..731b143 100644 --- a/src/main/java/cn/soul2/demo/repository/impl/RefSubjectItemsRepositoryImpl.java +++ b/src/main/java/cn/soul2/demo/repository/impl/RefSubjectItemsRepositoryImpl.java @@ -99,4 +99,9 @@ public class RefSubjectItemsRepositoryImpl extends ServiceImpl newItemIds) { + return null; + } } diff --git a/src/main/java/cn/soul2/demo/repository/impl/SubjectItemsRepositoryImpl.java b/src/main/java/cn/soul2/demo/repository/impl/SubjectItemsRepositoryImpl.java index bcc03fe..d367ee0 100644 --- a/src/main/java/cn/soul2/demo/repository/impl/SubjectItemsRepositoryImpl.java +++ b/src/main/java/cn/soul2/demo/repository/impl/SubjectItemsRepositoryImpl.java @@ -3,9 +3,18 @@ package cn.soul2.demo.repository.impl; import cn.soul2.demo.entity.SubjectItemsDO; import cn.soul2.demo.mapper.SubjectItemsMapper; import cn.soul2.demo.repository.ISubjectItemsRepository; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + /** *

* 题选项表 服务实现类 @@ -17,4 +26,30 @@ import org.springframework.stereotype.Service; @Service public class SubjectItemsRepositoryImpl extends ServiceImpl implements ISubjectItemsRepository { + @Override + public List listBySubjectId(String subjectId) { + if (StringUtils.isBlank(subjectId)) { + return new ArrayList<>(); + } + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(SubjectItemsDO::getSubjectId, subjectId); + return super.list(query); + } + + @Override + public List listBySubjectIds(Collection subjectIds) { + if (CollectionUtils.isEmpty(subjectIds)) { + return new ArrayList<>(); + } + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.in(SubjectItemsDO::getSubjectId, subjectIds); + return super.list(query); + } + + @Override + public Boolean removeBySubjectId(Collection subjectIds) { + LambdaUpdateWrapper update = Wrappers.lambdaUpdate(); + update.in(SubjectItemsDO::getSubjectId, subjectIds); + return super.remove(update); + } } diff --git a/src/main/java/cn/soul2/demo/repository/impl/SubjectRepositoryImpl.java b/src/main/java/cn/soul2/demo/repository/impl/SubjectRepositoryImpl.java index 2c12e81..93989bf 100644 --- a/src/main/java/cn/soul2/demo/repository/impl/SubjectRepositoryImpl.java +++ b/src/main/java/cn/soul2/demo/repository/impl/SubjectRepositoryImpl.java @@ -1,12 +1,22 @@ package cn.soul2.demo.repository.impl; +import cn.soul2.demo.dto.QnSubjectRefItemDTO; import cn.soul2.demo.dto.SubjectDTO; +import cn.soul2.demo.dto.SubjectItemDTO; +import cn.soul2.demo.dto.base.UpdateStatusDTO; import cn.soul2.demo.entity.SubjectDO; import cn.soul2.demo.entity.SubjectItemsDO; +import cn.soul2.demo.entity.sqlresult.SubjectChooseListDO; import cn.soul2.demo.mapper.SubjectMapper; -import cn.soul2.demo.repository.IRefSubjectItemsRepository; import cn.soul2.demo.repository.ISubjectItemsRepository; import cn.soul2.demo.repository.ISubjectRepository; +import cn.soul2.demo.utils.base.PageUtils; +import cn.soul2.demo.vo.SubjectVO; +import cn.soul2.demo.vo.base.VPage; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.BeanUtils; @@ -15,6 +25,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; +import javax.annotation.Resource; +import java.util.*; import java.util.stream.Collectors; /** @@ -31,33 +43,113 @@ public class SubjectRepositoryImpl extends ServiceImpl @Autowired private ISubjectItemsRepository itemsRepository; - @Autowired - private IRefSubjectItemsRepository refSubjectItemsRepository; + @Resource + private SubjectMapper subjectMapper; @Override @Transactional public Boolean saveOrUpdate(SubjectDTO dto) { SubjectDO entity = new SubjectDO(); BeanUtils.copyProperties(dto, entity); - if (StringUtils.isNotBlank(entity.getId())) { - // delete old connections when updating - refSubjectItemsRepository.disConnectItems(entity.getId(), true); + if (!super.saveOrUpdate(entity)) { + return Boolean.FALSE; } - if (super.saveOrUpdate(entity)) { - boolean itemsSaved = itemsRepository.saveBatch(dto.getItems().stream().map(e -> { - SubjectItemsDO item = new SubjectItemsDO(); - BeanUtils.copyProperties(e, item); - if (StringUtils.isNotEmpty(item.getId())) { - item.setId(item.getId()); + // If no id is passed, it is save. + if (StringUtils.isBlank(entity.getId())) { + if (CollectionUtils.isNotEmpty(dto.getItems())) { + boolean itemsSaved = itemsRepository.saveBatch(dto.getItems().stream().map(e -> { + SubjectItemsDO item = new SubjectItemsDO(); + BeanUtils.copyProperties(e, item); + item.setSubjectId(entity.getId()); + return item; + }).collect(Collectors.toList())); + if (!itemsSaved) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return Boolean.FALSE; + } + } + return Boolean.TRUE; + } else { + // otherwise update + List addOrUpdateItems = new ArrayList<>(); + List removeItems = new ArrayList<>(); + + List oldItems = itemsRepository.listBySubjectId(entity.getId()); + Map oldMap = oldItems.stream().collect(Collectors.toMap(SubjectItemsDO::getId, o -> o, (o1, o2) -> o1)); + Map dtoMap = null; + if (CollectionUtils.isNotEmpty(dto.getItems())) { + dtoMap = dto.getItems().stream().collect(Collectors.toMap(SubjectItemDTO::getItemId, o -> o, (o1, o2) -> o1)); + } else { + dtoMap = new HashMap<>(0); + } + dtoMap.forEach((k, v) -> { + if (!oldMap.containsKey(k)) { + SubjectItemsDO addItem = new SubjectItemsDO(); + BeanUtils.copyProperties(v, addItem); + addItem.setSubjectId(entity.getId()); + addOrUpdateItems.add(addItem); } - return item; - }).collect(Collectors.toList())); - if (!itemsSaved) { + }); + Map finalDtoMap = dtoMap; + oldMap.forEach((k, v) -> { + if (!finalDtoMap.containsKey(k)) { + removeItems.add(k); + } else { + SubjectItemsDO addItem = new SubjectItemsDO(); + BeanUtils.copyProperties(v, addItem); + BeanUtils.copyProperties(finalDtoMap.get(k), addItem); + addOrUpdateItems.add(addItem); + } + }); + if (CollectionUtils.isNotEmpty(removeItems) && !itemsRepository.removeByIds(removeItems)) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return Boolean.FALSE; + } else if (CollectionUtils.isNotEmpty(addOrUpdateItems) && !itemsRepository.saveOrUpdateBatch(addOrUpdateItems)) { TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return Boolean.FALSE; } return Boolean.TRUE; } - return Boolean.FALSE; } + + @Override + @Transactional + public Boolean removeAndItems(Collection ids) { + if (!super.removeByIds(ids) || !itemsRepository.removeBySubjectId(ids)) { + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return Boolean.FALSE; + } + return Boolean.TRUE; + } + + @Override + public VPage page(SubjectDTO dto) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.eq(dto.getType() != null, SubjectDO::getType, dto.getType()) + .likeRight(StringUtils.isNotBlank(dto.getTitle()), SubjectDO::getTitle, dto.getTitle()) + .orderByDesc(SubjectDO::getUpdatedTime); + VPage dovPage = PageUtils.to(super.page(PageUtils.build(dto), query)); + return PageUtils.to(dovPage, dovPage.getRows().stream().map(e -> { + SubjectVO vo = new SubjectVO(); + BeanUtils.copyProperties(e, vo); + return vo; + }).collect(Collectors.toList())); + } + + @Override + public Boolean status(UpdateStatusDTO dto) { + LambdaUpdateWrapper update = Wrappers.lambdaUpdate(); + update.set(SubjectDO::getStatus, dto.getStatus()).eq(SubjectDO::getId, dto.getId()); + return super.update(update); + } + + @Override + public VPage chooseList(QnSubjectRefItemDTO dto) { + LambdaQueryWrapper query = Wrappers.lambdaQuery(); + query.like(StringUtils.isNotBlank(dto.getTitle()), SubjectDO::getTitle, dto.getTitle()) + .eq(dto.getType() != null, SubjectDO::getType, dto.getType()) + .orderByDesc(SubjectDO::getUpdatedTime); + return PageUtils.to(subjectMapper.useCounts(PageUtils.build(dto), query, dto.getQnId())); + } + } diff --git a/src/main/java/cn/soul2/demo/utils/MybatisFastGenerator.java b/src/main/java/cn/soul2/demo/utils/MybatisFastGenerator.java index 7c5f962..69ebaba 100644 --- a/src/main/java/cn/soul2/demo/utils/MybatisFastGenerator.java +++ b/src/main/java/cn/soul2/demo/utils/MybatisFastGenerator.java @@ -27,8 +27,7 @@ public class MybatisFastGenerator { * 设置需要生成的表名 */ private static final String[] TABLE_NAMES = { - "tb_ref_questionnaire_subject", - "tb_ref_subject_items", + "tb_subject_items", }; /** * 是否为表更新 diff --git a/src/main/java/cn/soul2/demo/vo/QuestionnaireVO.java b/src/main/java/cn/soul2/demo/vo/QuestionnaireVO.java index ee3c908..5d3d4c3 100644 --- a/src/main/java/cn/soul2/demo/vo/QuestionnaireVO.java +++ b/src/main/java/cn/soul2/demo/vo/QuestionnaireVO.java @@ -39,4 +39,9 @@ public class QuestionnaireVO { */ private LocalDateTime updatedTime; + /** + * 已选择的题目数量 + */ + private Integer hasSubjectCount; + }