|
|
@@ -0,0 +1,287 @@
|
|
|
+package com.xjrsoft.module.feedback.service.impl;
|
|
|
+
|
|
|
+import cn.dev33.satoken.stp.StpUtil;
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.github.yulichang.base.MPJBaseServiceImpl;
|
|
|
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
|
|
|
+import com.xjrsoft.common.exception.MyException;
|
|
|
+import com.xjrsoft.common.page.ConventPage;
|
|
|
+import com.xjrsoft.common.utils.VoToColumnUtil;
|
|
|
+import com.xjrsoft.module.feedback.dto.*;
|
|
|
+import com.xjrsoft.module.feedback.entity.Feedback;
|
|
|
+import com.xjrsoft.module.feedback.entity.FeedbackItem;
|
|
|
+import com.xjrsoft.module.feedback.mapper.FeedbackItemMapper;
|
|
|
+import com.xjrsoft.module.feedback.mapper.FeedbackMapper;
|
|
|
+import com.xjrsoft.module.feedback.service.IFeedbackService;
|
|
|
+import com.xjrsoft.module.feedback.vo.FeedbackPageVo;
|
|
|
+import com.xjrsoft.module.feedback.vo.HistoryPageMobileVo;
|
|
|
+import com.xjrsoft.module.feedback.vo.ItemDetailListVo;
|
|
|
+import com.xjrsoft.module.system.entity.DictionaryDetail;
|
|
|
+import com.xjrsoft.module.system.entity.File;
|
|
|
+import com.xjrsoft.module.system.service.IFileService;
|
|
|
+import com.xjrsoft.module.teacher.entity.XjrUser;
|
|
|
+import lombok.AllArgsConstructor;
|
|
|
+import org.apache.commons.collections.CollectionUtils;
|
|
|
+import org.apache.commons.lang3.ObjectUtils;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+
|
|
|
+/**
|
|
|
+* @title: 意见反馈
|
|
|
+* @Author phoenix
|
|
|
+* @Date: 2025-04-09
|
|
|
+* @Version 1.0
|
|
|
+*/
|
|
|
+@Service
|
|
|
+@AllArgsConstructor
|
|
|
+public class FeedbackServiceImpl extends MPJBaseServiceImpl<FeedbackMapper, Feedback> implements IFeedbackService {
|
|
|
+
|
|
|
+ private final FeedbackItemMapper feedbackItemMapper;
|
|
|
+
|
|
|
+ private final IFileService fileService;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<FeedbackPageVo> pageRubAndHand(FeedbackPageDto dto) {
|
|
|
+ MPJLambdaWrapper<Feedback> feedbackMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ feedbackMPJLambdaWrapper
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .select(Feedback::getId)
|
|
|
+ .select(Feedback.class,x -> VoToColumnUtil.fieldsToColumns(FeedbackPageVo.class).contains(x.getProperty()))
|
|
|
+ .leftJoin(XjrUser.class, XjrUser::getId, Feedback::getUserId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(XjrUser::getName, FeedbackPageVo::getUserIdCn)
|
|
|
+ .like(StringUtils.isNotEmpty(dto.getUserIdCn()), XjrUser::getName, dto.getUserIdCn())
|
|
|
+ )
|
|
|
+ .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Feedback::getTerminalType,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(DictionaryDetail::getName, FeedbackPageVo::getTerminalTypeCn)
|
|
|
+ )
|
|
|
+ .eq(Feedback::getHandleStatus, dto.getHandleStatus())
|
|
|
+ .eq(ObjectUtils.isNotEmpty(dto.getUserType()), Feedback::getUserType, dto.getUserType())
|
|
|
+ .eq(StringUtils.isNotEmpty(dto.getTerminalType()), Feedback::getTerminalType, dto.getTerminalType())
|
|
|
+ .orderByDesc(Feedback::getCreateDate)
|
|
|
+ ;
|
|
|
+ return this.selectJoinListPage(ConventPage.getPage(dto), FeedbackPageVo.class, feedbackMPJLambdaWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<HistoryPageMobileVo> historyPageMobile(HistoryPageMobileDto dto) {
|
|
|
+ Long loginId = StpUtil.getLoginIdAsLong();
|
|
|
+
|
|
|
+ MPJLambdaWrapper<Feedback> feedbackMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ feedbackMPJLambdaWrapper
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .select(Feedback::getId)
|
|
|
+ .select(Feedback.class,x -> VoToColumnUtil.fieldsToColumns(HistoryPageMobileVo.class).contains(x.getProperty()))
|
|
|
+ .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Feedback::getTerminalType,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(DictionaryDetail::getName, HistoryPageMobileVo::getTerminalTypeCn)
|
|
|
+ )
|
|
|
+ .eq(Feedback::getUserId, loginId)
|
|
|
+ .orderByDesc(Feedback::getHandleReadStatus)
|
|
|
+ ;
|
|
|
+ IPage<HistoryPageMobileVo> page = this.selectJoinListPage(ConventPage.getPage(dto), HistoryPageMobileVo.class, feedbackMPJLambdaWrapper);
|
|
|
+
|
|
|
+ // 处理最后一条反馈内容
|
|
|
+ List<HistoryPageMobileVo> dataList = page.getRecords();
|
|
|
+ if(CollectionUtils.isNotEmpty(dataList)){
|
|
|
+ List<String> ids = dataList.stream()
|
|
|
+ .map(HistoryPageMobileVo::getId)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if(CollectionUtils.isNotEmpty(ids)){
|
|
|
+ List<FeedbackItem> feedbackItems = feedbackItemMapper.selectList(
|
|
|
+ Wrappers.lambdaQuery(FeedbackItem.class)
|
|
|
+ .in(FeedbackItem::getFeedbackId, ids)
|
|
|
+ );
|
|
|
+
|
|
|
+ Map<Long, List<FeedbackItem>> groupByFeedbackId = feedbackItems.stream()
|
|
|
+ .collect(Collectors.groupingBy(FeedbackItem::getFeedbackId));
|
|
|
+
|
|
|
+ for (HistoryPageMobileVo vo : page.getRecords()){
|
|
|
+ List<FeedbackItem> feedbackItemList = groupByFeedbackId.get(Long.parseLong(vo.getId()));
|
|
|
+ if(CollectionUtils.isNotEmpty(feedbackItemList)){
|
|
|
+ feedbackItemList.sort(Comparator.comparing(FeedbackItem::getCreateDate).reversed());
|
|
|
+ FeedbackItem lastOne = feedbackItemList.get(0);
|
|
|
+ if(ObjectUtils.isNotEmpty(lastOne)){
|
|
|
+ vo.setFeedback(lastOne.getFeedback());
|
|
|
+ vo.setReply(lastOne.getReply());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return page;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<ItemDetailListVo> itemDetailList(ItemDetailListDto dto) {
|
|
|
+ MPJLambdaWrapper<FeedbackItem> feedbackItemMPJLambdaWrapper = new MPJLambdaWrapper<>();
|
|
|
+ feedbackItemMPJLambdaWrapper
|
|
|
+ .disableSubLogicDel()
|
|
|
+ .select(FeedbackItem::getId)
|
|
|
+ .select(FeedbackItem.class,x -> VoToColumnUtil.fieldsToColumns(ItemDetailListVo.class).contains(x.getProperty()))
|
|
|
+ .innerJoin(Feedback.class, Feedback::getId, FeedbackItem::getFeedbackId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(Feedback::getUserType, ItemDetailListVo::getUserType)
|
|
|
+ .selectAs(Feedback::getTerminalType, ItemDetailListVo::getTerminalType)
|
|
|
+ .leftJoin(DictionaryDetail.class, DictionaryDetail::getCode, Feedback::getTerminalType,
|
|
|
+ wrap -> wrap
|
|
|
+ .selectAs(DictionaryDetail::getName, ItemDetailListVo::getTerminalTypeCn)
|
|
|
+ )
|
|
|
+ )
|
|
|
+ .leftJoin(XjrUser.class, XjrUser::getId, FeedbackItem::getCreateUserId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(XjrUser::getName, ItemDetailListVo::getCreateUserIdCn)
|
|
|
+ )
|
|
|
+ .leftJoin(XjrUser.class, XjrUser::getId, FeedbackItem::getReplyUserId,
|
|
|
+ wrapper -> wrapper
|
|
|
+ .selectAs(XjrUser::getName, ItemDetailListVo::getReplyUserIdCn)
|
|
|
+ )
|
|
|
+ .eq(FeedbackItem::getFeedbackId, dto.getFeedbackId())
|
|
|
+ ;
|
|
|
+ List<ItemDetailListVo> itemDetailListVos = feedbackItemMapper.selectJoinList(ItemDetailListVo.class, feedbackItemMPJLambdaWrapper);
|
|
|
+
|
|
|
+ for (ItemDetailListVo vo : itemDetailListVos){
|
|
|
+ if(ObjectUtils.isNotEmpty(vo.getFeedbackFileId())){
|
|
|
+ List<File> feedbackFile = fileService.list(Wrappers.<File>query().lambda().eq(File::getFolderId, vo.getFeedbackFileId()));
|
|
|
+ vo.setFeedbackFiles(feedbackFile);
|
|
|
+ }
|
|
|
+ if(ObjectUtils.isNotEmpty(vo.getReplyFileId())){
|
|
|
+ List<File> replyFile = fileService.list(Wrappers.<File>query().lambda().eq(File::getFolderId, vo.getReplyFileId()));
|
|
|
+ vo.setFeedbackFiles(replyFile);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return itemDetailListVos;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean addFeedbackItem(AddFeedbackItemDto dto) {
|
|
|
+ LocalDateTime nowLocalDateTime = LocalDateTime.now();
|
|
|
+ Long loginId = StpUtil.getLoginIdAsLong();
|
|
|
+
|
|
|
+ // 如果没有传入了意见反馈主键id表示为新增反馈,应该添加主表记录
|
|
|
+ if(ObjectUtils.isEmpty(dto.getFeedbackId())){
|
|
|
+ Feedback feedback = new Feedback();
|
|
|
+ feedback.setCreateDate(nowLocalDateTime);
|
|
|
+ feedback.setCreateUserId(loginId);
|
|
|
+ feedback.setUserId(loginId);
|
|
|
+
|
|
|
+ // 处理用户类别
|
|
|
+ if(StpUtil.hasRole("TEACHER")){
|
|
|
+ feedback.setUserType(1);
|
|
|
+ } else if(StpUtil.hasRole("STUDENT")){
|
|
|
+ feedback.setUserType(2);
|
|
|
+ } else if(StpUtil.hasRole("PARENT")){
|
|
|
+ feedback.setUserType(3);
|
|
|
+ } else {
|
|
|
+ feedback.setUserType(4);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ObjectUtils.isNotEmpty(dto.getTerminalType())){
|
|
|
+ feedback.setTerminalType(dto.getTerminalType());
|
|
|
+ } else {
|
|
|
+ throw new MyException("请选择终端类型");
|
|
|
+ }
|
|
|
+
|
|
|
+ feedback.setFeedbackTime(nowLocalDateTime);
|
|
|
+ feedback.setHandleStatus(0);
|
|
|
+ feedback.setHandleReadStatus(0);
|
|
|
+
|
|
|
+ this.save(feedback);
|
|
|
+
|
|
|
+ dto.setFeedbackId(feedback.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ FeedbackItem feedbackItem = BeanUtil.toBean(dto, FeedbackItem.class);
|
|
|
+ feedbackItem.setCreateDate(nowLocalDateTime);
|
|
|
+ feedbackItem.setCreateUserId(loginId);
|
|
|
+ feedbackItemMapper.insert(feedbackItem);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean replyFeedbackItem(ReplyFeedbackItemDto dto) {
|
|
|
+ FeedbackItem old = feedbackItemMapper.selectById(dto.getId());
|
|
|
+
|
|
|
+ if(ObjectUtils.isEmpty(old)){
|
|
|
+ throw new MyException("当前反馈已被修改,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime nowLocalDateTime = LocalDateTime.now();
|
|
|
+ Long loginId = StpUtil.getLoginIdAsLong();
|
|
|
+
|
|
|
+ FeedbackItem feedbackItem = BeanUtil.toBean(dto, FeedbackItem.class);
|
|
|
+ feedbackItem.setModifyDate(nowLocalDateTime);
|
|
|
+ feedbackItem.setModifyUserId(loginId);
|
|
|
+
|
|
|
+ feedbackItem.setReplyStatus(1);
|
|
|
+ feedbackItem.setReplyUserId(loginId);
|
|
|
+ feedbackItem.setReplyTime(nowLocalDateTime);
|
|
|
+ feedbackItem.setReplyReadStatus(0);
|
|
|
+
|
|
|
+ feedbackItemMapper.insert(feedbackItem);
|
|
|
+
|
|
|
+ // 处理主反馈的状态
|
|
|
+ Feedback updateFeedback = new Feedback();
|
|
|
+ updateFeedback.setId(old.getFeedbackId());
|
|
|
+ updateFeedback.setModifyDate(nowLocalDateTime);
|
|
|
+ updateFeedback.setModifyUserId(loginId);
|
|
|
+
|
|
|
+ // 查询当前主反馈是否还有没有回复的
|
|
|
+ LambdaQueryWrapper<FeedbackItem> replyLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ replyLambdaQueryWrapper
|
|
|
+ .eq(FeedbackItem::getFeedbackId, old.getFeedbackId())
|
|
|
+ .eq(FeedbackItem::getReplyStatus, 0)
|
|
|
+ ;
|
|
|
+ List<FeedbackItem> replyLFeedbackItems = feedbackItemMapper.selectList(replyLambdaQueryWrapper);
|
|
|
+ if(CollectionUtils.isEmpty(replyLFeedbackItems)){
|
|
|
+ updateFeedback.setHandleReadStatus(1);
|
|
|
+ updateFeedback.setHandleTime(nowLocalDateTime);
|
|
|
+ }
|
|
|
+
|
|
|
+ updateFeedback.setHandleReadStatus(0);
|
|
|
+
|
|
|
+ this.updateById(updateFeedback);
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public Boolean readFeedbackItem(ReadFeedbackItemDto dto) {
|
|
|
+ Feedback old = this.getById(dto.getId());
|
|
|
+
|
|
|
+ if(ObjectUtils.isEmpty(old)){
|
|
|
+ throw new MyException("当前反馈已被修改,请刷新重试");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 将所有已经处理反馈项阅读
|
|
|
+ LambdaUpdateWrapper<FeedbackItem> feedbackItemLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ feedbackItemLambdaUpdateWrapper
|
|
|
+ .set(FeedbackItem::getReplyReadStatus, 1)
|
|
|
+ .eq(FeedbackItem::getFeedbackId, dto.getId())
|
|
|
+ .eq(FeedbackItem::getReplyStatus, 1)
|
|
|
+ ;
|
|
|
+ feedbackItemMapper.update(new FeedbackItem(), feedbackItemLambdaUpdateWrapper);
|
|
|
+
|
|
|
+ this.updateById(new Feedback(){{
|
|
|
+ setId(dto.getId());
|
|
|
+ setHandleReadStatus(1);
|
|
|
+ }});
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|