|
|
@@ -0,0 +1,191 @@
|
|
|
+package shop.alien.storeplatform.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import shop.alien.entity.store.LifeUser;
|
|
|
+import shop.alien.mapper.LifeUserMapper;
|
|
|
+import shop.alien.storeplatform.entity.StorePlatformDiscussion;
|
|
|
+import shop.alien.storeplatform.mapper.StorePlatformDiscussionMapper;
|
|
|
+import shop.alien.storeplatform.service.StorePlatformDiscussionService;
|
|
|
+import shop.alien.storeplatform.vo.StorePlatformDiscussionReplyVo;
|
|
|
+import shop.alien.storeplatform.vo.StorePlatformDiscussionUserVo;
|
|
|
+
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 店铺问题讨论服务实现类
|
|
|
+ *
|
|
|
+ * @author alien
|
|
|
+ * @since 2025-12-30
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class StorePlatformDiscussionServiceImpl extends ServiceImpl<StorePlatformDiscussionMapper, StorePlatformDiscussion> implements StorePlatformDiscussionService {
|
|
|
+
|
|
|
+ private final LifeUserMapper lifeUserMapper;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<StorePlatformDiscussionUserVo> pageRootDiscussions(Integer storeId, Integer pageNum, Integer pageSize) {
|
|
|
+ Page<StorePlatformDiscussion> page = new Page<>(pageNum, pageSize);
|
|
|
+ IPage<StorePlatformDiscussion> discussionPage = this.page(page, new LambdaQueryWrapper<StorePlatformDiscussion>()
|
|
|
+ .eq(StorePlatformDiscussion::getStoreId, storeId)
|
|
|
+ .eq(StorePlatformDiscussion::getParentId, 0)
|
|
|
+ .orderByDesc(StorePlatformDiscussion::getCreatedTime));
|
|
|
+
|
|
|
+ return discussionPage.convert(this::convertToVoWithUserInfo);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public StorePlatformDiscussionReplyVo pageRepliesByRootId(Integer rootId, Integer pageNum, Integer pageSize) {
|
|
|
+ // 1. 获取主贴信息
|
|
|
+ StorePlatformDiscussion root = this.getById(rootId);
|
|
|
+ if (root == null) {
|
|
|
+ throw new RuntimeException("主贴讨论不存在");
|
|
|
+ }
|
|
|
+ StorePlatformDiscussionUserVo topicVo = convertToVoWithUserInfo(root);
|
|
|
+
|
|
|
+ // 2. 分页获取回复
|
|
|
+ Page<StorePlatformDiscussion> page = new Page<>(pageNum, pageSize);
|
|
|
+ IPage<StorePlatformDiscussion> replyPage = this.page(page, new LambdaQueryWrapper<StorePlatformDiscussion>()
|
|
|
+ .eq(StorePlatformDiscussion::getRootId, rootId)
|
|
|
+ .ne(StorePlatformDiscussion::getId, rootId) // 排除主贴本身
|
|
|
+ .orderByAsc(StorePlatformDiscussion::getCreatedTime));
|
|
|
+
|
|
|
+ // 3. 转换为VO并补充用户信息
|
|
|
+ IPage<StorePlatformDiscussionUserVo> voPage = replyPage.convert(this::convertToVo);
|
|
|
+ fillUserInfoBatch(voPage.getRecords());
|
|
|
+
|
|
|
+ return StorePlatformDiscussionReplyVo.fromPage(topicVo, voPage);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<StorePlatformDiscussionUserVo> listByStoreId(Integer storeId) {
|
|
|
+ List<StorePlatformDiscussion> list = this.list(new LambdaQueryWrapper<StorePlatformDiscussion>()
|
|
|
+ .eq(StorePlatformDiscussion::getStoreId, storeId)
|
|
|
+ .orderByDesc(StorePlatformDiscussion::getCreatedTime));
|
|
|
+
|
|
|
+ List<StorePlatformDiscussionUserVo> voList = list.stream().map(this::convertToVo).collect(Collectors.toList());
|
|
|
+ fillUserInfoBatch(voList);
|
|
|
+ return voList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean postTopic(StorePlatformDiscussion discussion) {
|
|
|
+ discussion.setParentId(0);
|
|
|
+ discussion.setRootId(0);
|
|
|
+ boolean saved = this.save(discussion);
|
|
|
+ if (saved) {
|
|
|
+ // 一级讨论的 rootId 设置为它自己的 ID
|
|
|
+ discussion.setRootId(discussion.getId());
|
|
|
+ this.updateById(discussion);
|
|
|
+ }
|
|
|
+ return saved;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ @Transactional(rollbackFor = Exception.class)
|
|
|
+ public boolean postReply(StorePlatformDiscussion discussion) {
|
|
|
+ if (discussion.getParentId() == null || discussion.getParentId() == 0) {
|
|
|
+ throw new RuntimeException("回复必须指定父级讨论 ID");
|
|
|
+ }
|
|
|
+
|
|
|
+ StorePlatformDiscussion parent = this.getById(discussion.getParentId());
|
|
|
+ if (parent == null) {
|
|
|
+ throw new RuntimeException("父级讨论不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从父级继承 storeId 和 rootId
|
|
|
+ discussion.setStoreId(parent.getStoreId());
|
|
|
+ if (parent.getParentId() == 0) {
|
|
|
+ // 如果父级是根讨论,那么 rootId 就是父级的 id
|
|
|
+ discussion.setRootId(parent.getId());
|
|
|
+ } else {
|
|
|
+ // 如果父级本身也是回复,那么 rootId 沿用父级的 rootId
|
|
|
+ discussion.setRootId(parent.getRootId());
|
|
|
+ }
|
|
|
+
|
|
|
+ return this.save(discussion);
|
|
|
+ }
|
|
|
+
|
|
|
+ private StorePlatformDiscussionUserVo convertToVo(StorePlatformDiscussion discussion) {
|
|
|
+ if (discussion == null) return null;
|
|
|
+ StorePlatformDiscussionUserVo vo = new StorePlatformDiscussionUserVo();
|
|
|
+ BeanUtils.copyProperties(discussion, vo);
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private StorePlatformDiscussionUserVo convertToVoWithUserInfo(StorePlatformDiscussion discussion) {
|
|
|
+ StorePlatformDiscussionUserVo vo = convertToVo(discussion);
|
|
|
+ if (vo != null) {
|
|
|
+ List<StorePlatformDiscussionUserVo> list = new ArrayList<>();
|
|
|
+ list.add(vo);
|
|
|
+ fillUserInfoBatch(list);
|
|
|
+ }
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 批量填充用户信息
|
|
|
+ */
|
|
|
+ private void fillUserInfoBatch(List<StorePlatformDiscussionUserVo> voList) {
|
|
|
+ if (CollectionUtils.isEmpty(voList)) return;
|
|
|
+
|
|
|
+ // 提取所有用户ID和父级ID对应的人
|
|
|
+ Set<Integer> userIds = voList.stream().map(StorePlatformDiscussionUserVo::getUserId).collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 提取所有父级讨论,用于获取回复对象的名称
|
|
|
+ Set<Integer> parentIds = voList.stream()
|
|
|
+ .map(StorePlatformDiscussionUserVo::getParentId)
|
|
|
+ .filter(id -> id != null && id != 0)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 获取评论人信息
|
|
|
+ Map<Integer, LifeUser> userMap = getUserMap(userIds);
|
|
|
+
|
|
|
+ // 获取回复对象信息 (如果是回复,需要知道在回复谁)
|
|
|
+ Map<Integer, String> parentUserNameMap = getParentUserNameMap(parentIds);
|
|
|
+
|
|
|
+ voList.forEach(vo -> {
|
|
|
+ LifeUser user = userMap.get(vo.getUserId());
|
|
|
+ if (user != null) {
|
|
|
+ vo.setUserName(user.getUserName());
|
|
|
+ vo.setUserImage(user.getUserImage());
|
|
|
+ }
|
|
|
+ if (vo.getParentId() != null && vo.getParentId() != 0) {
|
|
|
+ vo.setParentUserName(parentUserNameMap.get(vo.getParentId()));
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<Integer, LifeUser> getUserMap(Set<Integer> userIds) {
|
|
|
+ if (CollectionUtils.isEmpty(userIds)) return Collections.emptyMap();
|
|
|
+ List<LifeUser> users = lifeUserMapper.selectBatchIds(userIds);
|
|
|
+ return users.stream().collect(Collectors.toMap(LifeUser::getId, u -> u));
|
|
|
+ }
|
|
|
+
|
|
|
+ private Map<Integer, String> getParentUserNameMap(Set<Integer> parentIds) {
|
|
|
+ if (CollectionUtils.isEmpty(parentIds)) return Collections.emptyMap();
|
|
|
+ List<StorePlatformDiscussion> parents = this.baseMapper.selectBatchIds(parentIds);
|
|
|
+ if (CollectionUtils.isEmpty(parents)) return Collections.emptyMap();
|
|
|
+
|
|
|
+ Set<Integer> parentUserIds = parents.stream().map(StorePlatformDiscussion::getUserId).collect(Collectors.toSet());
|
|
|
+ Map<Integer, LifeUser> userMap = getUserMap(parentUserIds);
|
|
|
+
|
|
|
+ return parents.stream().collect(Collectors.toMap(
|
|
|
+ StorePlatformDiscussion::getId,
|
|
|
+ p -> {
|
|
|
+ LifeUser u = userMap.get(p.getUserId());
|
|
|
+ return u != null ? u.getUserName() : "未知用户";
|
|
|
+ }
|
|
|
+ ));
|
|
|
+ }
|
|
|
+}
|