Bläddra i källkod

Merge branch 'refs/heads/sit' into sit-three-categories

dujian 3 månader sedan
förälder
incheckning
fc1081fc2c

+ 4 - 2
alien-second/src/main/java/shop/alien/second/util/AiUserViolationUtils.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.map.HashedMap;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.http.*;
 import org.springframework.stereotype.Component;
 import org.springframework.util.LinkedMultiValueMap;
@@ -27,13 +28,14 @@ import java.util.Map;
 @Slf4j
 @Component
 @RequiredArgsConstructor
+@RefreshScope
 public class AiUserViolationUtils {
 
     private final RestTemplate restTemplate;
     private final LifeUserMapper lifeUserMapper;
     private final LifeMessageMapper lifeMessageMapper;
 
-    @Value("${third-party-login.base-url1:http://192.168.2.250:9000/ai/user-auth-core/api/v1/auth/login}")
+    @Value("${third-party-login.base-url}")
     private String loginUrl;
 
     @Value("${third-party-user-name.base-url:UdUser}")
@@ -42,7 +44,7 @@ public class AiUserViolationUtils {
     @Value("${third-party-pass-word.base-url:123456}")
     private String passWord;
 
-    @Value("${third-party-userComplaintRecordUrl.base-url1:http://192.168.2.250:9000/ai/auto-review/api/v1/user_complaint_record/submit}")
+    @Value("${third-party-userComplaintRecordUrl.base-url}")
     private String userComplaintRecordUrl;
 
 

+ 93 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/controller/StorePlatformDiscussionController.java

@@ -0,0 +1,93 @@
+package shop.alien.storeplatform.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.storeplatform.entity.StorePlatformDiscussion;
+import shop.alien.storeplatform.service.StorePlatformDiscussionService;
+import shop.alien.storeplatform.vo.StorePlatformDiscussionReplyVo;
+import shop.alien.storeplatform.vo.StorePlatformDiscussionUserVo;
+
+import java.util.List;
+
+/**
+ * 商户平台-店铺讨论Controller
+ *
+ * @author alien
+ * @since 2025-12-30
+ */
+@Slf4j
+@Api(tags = {"商户平台-店铺问答讨论"})
+@RestController
+@RequestMapping("/platformStoreDiscussion")
+@RequiredArgsConstructor
+public class StorePlatformDiscussionController {
+
+    private final StorePlatformDiscussionService storeDiscussionService;
+
+    @ApiOperation("发布一级问答讨论 (主贴)")
+    @PostMapping("/postTopic")
+    public R<Boolean> postTopic(@RequestBody StorePlatformDiscussion discussion) {
+        log.info("StorePlatformDiscussionController.postTopic?discussion={}", discussion);
+        try {
+            boolean success = storeDiscussionService.postTopic(discussion);
+            return success ? R.success("发布成功") : R.fail("发布失败");
+        } catch (Exception e) {
+            log.error("发布讨论失败", e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    @ApiOperation("回复问答讨论")
+    @PostMapping("/postReply")
+    public R<Boolean> postReply(@RequestBody StorePlatformDiscussion discussion) {
+        log.info("StorePlatformDiscussionController.postReply?discussion={}", discussion);
+        try {
+            boolean success = storeDiscussionService.postReply(discussion);
+            return success ? R.success("回复成功") : R.fail("回复失败");
+        } catch (Exception e) {
+            log.error("回复讨论失败", e);
+            return R.fail(e.getMessage());
+        }
+    }
+
+    @ApiOperation("分页获取店铺一级问答讨论列表")
+    @GetMapping("/pageRoot")
+    public R<IPage<StorePlatformDiscussionUserVo>> pageRoot(
+            @ApiParam(value = "店铺ID", required = true) @RequestParam Integer storeId,
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
+        log.info("StorePlatformDiscussionController.pageRoot?storeId={}, pageNum={}, pageSize={}", storeId, pageNum, pageSize);
+        return R.data(storeDiscussionService.pageRootDiscussions(storeId, pageNum, pageSize));
+    }
+
+    @ApiOperation("分页获取某条一级问答讨论下的所有回复")
+    @GetMapping("/pageReplies")
+    public R<StorePlatformDiscussionReplyVo> pageReplies(
+            @ApiParam(value = "一级讨论ID (rootId)", required = true) @RequestParam Integer rootId,
+            @ApiParam(value = "页码", defaultValue = "1") @RequestParam(defaultValue = "1") Integer pageNum,
+            @ApiParam(value = "每页数量", defaultValue = "10") @RequestParam(defaultValue = "10") Integer pageSize) {
+        log.info("StorePlatformDiscussionController.pageReplies?rootId={}, pageNum={}, pageSize={}", rootId, pageNum, pageSize);
+        return R.data(storeDiscussionService.pageRepliesByRootId(rootId, pageNum, pageSize));
+    }
+
+    @ApiOperation("获取店铺问答讨论列表")
+    @GetMapping("/list")
+    public R<List<StorePlatformDiscussionUserVo>> list(@ApiParam(value = "店铺ID", required = true) @RequestParam Integer storeId) {
+        log.info("StorePlatformDiscussionController.list?storeId={}", storeId);
+        return R.data(storeDiscussionService.listByStoreId(storeId));
+    }
+
+    @ApiOperation("删除问答讨论")
+    @DeleteMapping("/delete/{id}")
+    public R<Boolean> delete(@PathVariable Integer id) {
+        log.info("StorePlatformDiscussionController.delete?id={}", id);
+        boolean success = storeDiscussionService.removeById(id);
+        return success ? R.success("删除成功") : R.fail("删除失败");
+    }
+}

+ 68 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/entity/StorePlatformDiscussion.java

@@ -0,0 +1,68 @@
+package shop.alien.storeplatform.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 店铺讨论表
+ *
+ * @author alien
+ * @since 2025-12-30
+ */
+@Data
+@TableName("store_discussion")
+@ApiModel(value = "StoreDiscussion对象", description = "店铺讨论表")
+public class StorePlatformDiscussion {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "店铺ID")
+    @TableField("store_id")
+    private Integer storeId;
+
+    @ApiModelProperty(value = "用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "讨论内容")
+    @TableField("content")
+    private String content;
+
+    @ApiModelProperty(value = "父级讨论ID (用于回复)")
+    @TableField("parent_id")
+    private Integer parentId;
+
+    @ApiModelProperty(value = "根讨论ID (一级讨论的ID)")
+    @TableField("root_id")
+    private Integer rootId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 17 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/mapper/StorePlatformDiscussionMapper.java

@@ -0,0 +1,17 @@
+package shop.alien.storeplatform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.storeplatform.entity.StorePlatformDiscussion;
+
+/**
+ * 店铺讨论表 Mapper 接口
+ *
+ * @author alien
+ * @since 2025-12-30
+ */
+@Mapper
+public interface StorePlatformDiscussionMapper extends BaseMapper<StorePlatformDiscussion> {
+
+}
+

+ 57 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/StorePlatformDiscussionService.java

@@ -0,0 +1,57 @@
+package shop.alien.storeplatform.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.storeplatform.entity.StorePlatformDiscussion;
+import shop.alien.storeplatform.vo.StorePlatformDiscussionReplyVo;
+import shop.alien.storeplatform.vo.StorePlatformDiscussionUserVo;
+
+import java.util.List;
+
+/**
+ * 店铺讨论表 服务类
+ *
+ * @author alien
+ * @since 2025-12-30
+ */
+public interface StorePlatformDiscussionService extends IService<StorePlatformDiscussion> {
+
+    /**
+     * 分页查询店铺一级讨论
+     * @param storeId 店铺ID
+     * @param pageNum 页码
+     * @param pageSize 每页数量
+     * @return 分页结果
+     */
+    IPage<StorePlatformDiscussionUserVo> pageRootDiscussions(Integer storeId, Integer pageNum, Integer pageSize);
+
+    /**
+     * 分页查询某条一级讨论下的所有回复
+     * @param rootId 一级讨论ID
+     * @param pageNum 页码
+     * @param pageSize 每页数量
+     * @return 包含主贴信息的回复分页对象
+     */
+    StorePlatformDiscussionReplyVo pageRepliesByRootId(Integer rootId, Integer pageNum, Integer pageSize);
+
+    /**
+     * 根据店铺ID查询讨论列表
+     * @param storeId 店铺ID
+     * @return 讨论列表
+     */
+    List<StorePlatformDiscussionUserVo> listByStoreId(Integer storeId);
+
+    /**
+     * 发布一级讨论 (主贴)
+     * @param discussion 讨论信息 (带 storeId, content)
+     * @return 是否成功
+     */
+    boolean postTopic(StorePlatformDiscussion discussion);
+
+    /**
+     * 回复讨论
+     * @param discussion 讨论信息 (带 parentId, content)
+     * @return 是否成功
+     */
+    boolean postReply(StorePlatformDiscussion discussion);
+}

+ 191 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/StorePlatformDiscussionServiceImpl.java

@@ -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() : "未知用户";
+                }
+        ));
+    }
+}

+ 42 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/vo/StorePlatformDiscussionReplyVo.java

@@ -0,0 +1,42 @@
+package shop.alien.storeplatform.vo;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 讨论回复分页返回对象 ()
+ */
+@Data
+@ApiModel(value = "StorePlatformDiscussionReplyVo对象", description = "讨论回复分页返回对象")
+public class StorePlatformDiscussionReplyVo {
+
+    @ApiModelProperty(value = "原问题/主贴信息")
+    private StorePlatformDiscussionUserVo topic;
+
+    @ApiModelProperty(value = "回复列表")
+    private List<StorePlatformDiscussionUserVo> replies;
+
+    @ApiModelProperty(value = "总页数")
+    private long pages;
+
+    @ApiModelProperty(value = "当前页")
+    private long current;
+
+    @ApiModelProperty(value = "总条数")
+    private long total;
+
+    public static StorePlatformDiscussionReplyVo fromPage(StorePlatformDiscussionUserVo topic, IPage<StorePlatformDiscussionUserVo> page) {
+        StorePlatformDiscussionReplyVo vo = new StorePlatformDiscussionReplyVo();
+        vo.setTopic(topic);
+        vo.setReplies(page.getRecords());
+        vo.setPages(page.getPages());
+        vo.setCurrent(page.getCurrent());
+        vo.setTotal(page.getTotal());
+        return vo;
+    }
+}
+

+ 26 - 0
alien-store-platform/src/main/java/shop/alien/storeplatform/vo/StorePlatformDiscussionUserVo.java

@@ -0,0 +1,26 @@
+package shop.alien.storeplatform.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import shop.alien.storeplatform.entity.StorePlatformDiscussion;
+
+/**
+ * 店铺讨论人员VO
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel(value = "StorePlatformDiscussionVo对象", description = "店铺讨论人员显示对象")
+public class StorePlatformDiscussionUserVo extends StorePlatformDiscussion {
+
+    @ApiModelProperty(value = "用户名称")
+    private String userName;
+
+    @ApiModelProperty(value = "用户头像")
+    private String userImage;
+    
+    @ApiModelProperty(value = "被回复人名称 (如果是回复)")
+    private String parentUserName;
+}
+

+ 147 - 0
alien-store-platform/接口文档/36-店铺讨论模块接口.md

@@ -0,0 +1,147 @@
+# 商户平台-店铺讨论模块接口文档
+
+## 模块概述
+
+本模块提供店铺讨论功能,支持分页查询一级讨论(主贴)以及一级讨论下的所有回复(仿B站评论模式)。支持逻辑删除、层级归类以及用户信息显示。
+
+---
+
+## 接口列表
+
+1. [发布一级讨论](#接口一发布一级讨论) - 用户在店铺下发起新讨论
+2. [回复讨论](#接口二回复讨论) - 用户回复已有讨论
+3. [分页获取一级讨论](#接口三分页获取一级讨论) - 分页查询店铺的主讨论列表 (带用户信息)
+4. [分页获取回复列表](#接口四分页获取回复列表) - 分页查询回复 (带主贴信息和用户信息)
+5. [获取所有讨论列表](#接口五获取所有讨论列表) - 查询店铺所有讨论 (不分页)
+6. [删除讨论](#接口六删除讨论) - 根据ID逻辑删除讨论记录
+
+---
+
+## 接口一:发布一级讨论
+
+### 接口信息
+
+- **接口名称**: 发布一级问答讨论 (主贴)
+- **接口路径**: `POST /platformStoreDiscussion/postTopic`
+- **请求方式**: POST
+- **接口描述**: 在指定店铺下发起新的讨论。系统会自动将 `rootId` 设置为生成的主键 ID。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| storeId | Integer | 是 | 店铺ID |
+| userId | Integer | 是 | 用户ID |
+| content | String | 是 | 讨论内容 |
+
+### 响应参数
+
+```json
+{
+    "code": 200,
+    "success": true,
+    "data": true,
+    "msg": "发布成功"
+}
+```
+
+---
+
+## 接口二:回复讨论
+
+### 接口信息
+
+- **接口名称**: 回复问答讨论
+- **接口路径**: `POST /platformStoreDiscussion/postReply`
+- **请求方式**: POST
+- **接口描述**: 对已有讨论进行回复。系统会根据 `parentId` 自动查询并填充 `storeId` 和 `rootId`。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| userId | Integer | 是 | 用户ID |
+| content | String | 是 | 讨论内容 |
+| parentId | Integer | 是 | 被回复的讨论 ID |
+
+### 响应参数
+
+```json
+{
+    "code": 200,
+    "success": true,
+    "data": true,
+    "msg": "回复成功"
+}
+```
+
+---
+
+## 接口三:分页获取一级讨论
+
+### 接口信息
+
+- **接口名称**: 分页获取一级问答讨论列表
+- **接口路径**: `GET /platformStoreDiscussion/pageRoot`
+- **请求方式**: GET
+
+### 响应参数 (核心部分)
+
+```json
+{
+    "code": 200,
+    "data": {
+        "records": [
+            {
+                "id": 1,
+                "content": "主贴内容",
+                "userName": "用户昵称",
+                "userImage": "用户头像URL",
+                "createdTime": "2025-12-30 14:00:00"
+            }
+        ],
+        "total": 100,
+        "size": 10,
+        "current": 1
+    }
+}
+```
+
+---
+
+## 接口四:分页获取回复列表
+
+### 接口信息
+
+- **接口名称**: 分页获取某条一级问答讨论下的所有回复
+- **接口路径**: `GET /platformStoreDiscussion/pageReplies`
+- **请求方式**: GET
+- **接口描述**: 返回结构包含原主贴信息 (`topic`) 和分页后的回复列表 (`replies`)。注意:`replies` 列表中不包含 `topic` 本身。
+
+---
+
+## 接口五:获取所有讨论列表
+
+### 接口信息
+
+- **接口名称**: 获取店铺问答讨论列表
+- **接口路径**: `GET /platformStoreDiscussion/list`
+- **请求方式**: GET
+- **接口描述**: 不分页获取店铺下所有讨论记录。
+
+---
+
+## 接口六:删除讨论
+
+### 接口信息
+
+- **接口名称**: 删除问答讨论
+- **接口路径**: `DELETE /platformStoreDiscussion/delete/{id}`
+- **请求方式**: DELETE
+- **接口描述**: 根据讨论ID逻辑删除。
+
+---
+
+**文档版本**: v1.3  
+**最后更新**: 2025-12-30  
+**维护人员**: alien

+ 170 - 0
alien-store-platform/接口文档/36-店铺问答讨论模块接口.md

@@ -0,0 +1,170 @@
+# 商户平台-店铺问答讨论模块接口文档
+
+## 模块概述
+
+本模块提供店铺讨论功能,允许用户在商户平台上针对特定店铺发表讨论、回复他人讨论,并支持讨论的列表查询和删除。类似于论坛功能,旨在增强用户与店铺之间的互动。
+
+---
+
+## 接口列表
+
+1. [发表讨论/回复](#接口一发表讨论回复) - 用户发表新讨论或回复已有讨论
+2. [获取店铺讨论列表](#接口二获取店铺讨论列表) - 查询指定店铺的所有讨论记录
+3. [删除讨论](#接口三删除讨论) - 根据ID逻辑删除讨论记录
+
+---
+
+## 接口一:发表讨论/回复
+
+### 接口信息
+
+- **接口名称**: 发表讨论/回复
+- **接口路径**: `POST /platformStoreDiscussion/post`
+- **请求方式**: POST
+- **接口描述**: 用户对店铺发表主贴讨论,或对已有讨论进行回复。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| storeId | Integer | 是 | 店铺ID |
+| userId | Integer | 是 | 用户ID |
+| content | String | 是 | 讨论内容 |
+| parentId | Integer | 否 | 父级讨论ID (发表主贴填0或不传,回复填被回复ID) |
+
+### 请求示例
+
+```json
+{
+    "storeId": 1,
+    "userId": 1001,
+    "content": "这家店的服务非常到位,强烈推荐!",
+    "parentId": 0
+}
+```
+
+### 响应参数
+
+```json
+{
+    "code": 200,
+    "success": true,
+    "data": true,
+    "msg": "发表成功"
+}
+```
+
+---
+
+## 接口二:获取店铺讨论列表
+
+### 接口信息
+
+- **接口名称**: 获取店铺讨论列表
+- **接口路径**: `GET /platformStoreDiscussion/list`
+- **请求方式**: GET
+- **接口描述**: 获取指定店铺下的所有讨论记录,按创建时间倒序排列。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| storeId | Integer | 是 | 店铺ID |
+
+### 请求示例
+
+```http
+GET /platformStoreDiscussion/list?storeId=1
+```
+
+### 响应参数
+
+```json
+{
+    "code": 200,
+    "success": true,
+    "data": [
+        {
+            "id": 1,
+            "storeId": 1,
+            "userId": 1001,
+            "content": "这家店的服务非常到位,强烈推荐!",
+            "parentId": 0,
+            "deleteFlag": 0,
+            "createdTime": "2025-12-30 14:00:00",
+            "createdUserId": 1001,
+            "updatedTime": "2025-12-30 14:00:00",
+            "updatedUserId": null
+        }
+    ],
+    "msg": "操作成功"
+}
+```
+
+---
+
+## 接口三:删除讨论
+
+### 接口信息
+
+- **接口名称**: 删除讨论
+- **接口路径**: `DELETE /platformStoreDiscussion/delete/{id}`
+- **请求方式**: DELETE
+- **接口描述**: 根据讨论ID逻辑删除该条记录。
+
+### 请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+|--------|------|------|------|
+| id | Integer | 是 | 讨论记录ID (路径参数) |
+
+### 请求示例
+
+```http
+DELETE /platformStoreDiscussion/delete/1
+```
+
+### 响应参数
+
+```json
+{
+    "code": 200,
+    "success": true,
+    "data": true,
+    "msg": "删除成功"
+}
+```
+
+---
+
+## 业务规则说明
+
+1. **父子关系**: 
+   - `parentId` 为 `0` 或 `null` 表示该记录是一条独立的讨论(主贴)。
+   - `parentId` 大于 `0` 表示该记录是对另一条讨论的回复。
+2. **删除逻辑**: 采用逻辑删除,更新 `delete_flag` 字段为 `1`。
+3. **排序规则**: 列表接口默认按 `created_time` 倒序排列,确保最新的讨论显示在最前面。
+
+---
+
+## 数据库设计 (`store_discussion`)
+
+| 字段名 | 类型 | 说明 |
+|--------|------|------|
+| id | int | 主键,自增 |
+| store_id | int | 店铺ID |
+| user_id | int | 用户ID |
+| content | text | 讨论内容 |
+| parent_id | int | 父级讨论ID,默认为0 |
+| delete_flag | tinyint | 删除标记 (0:未删除, 1:已删除) |
+| created_time | datetime | 创建时间 |
+| created_user_id | int | 创建人ID |
+| updated_time | datetime | 修改时间 |
+| updated_user_id | int | 修改人ID |
+
+---
+
+**文档版本**: v1.0  
+**最后更新**: 2025-12-30  
+**维护人员**: alien
+