Administrator
2025-08-13 2be073dedb043f63700484fab18e4a0ffe1d5e09
feat(ai): 添加对话记录分页查询功能

- 新增 ApiMemberTalkItemPageDto 和 ApiMemberTalkItemVo 类用于分页查询参数和结果
- 在 AiMemberTalkItemMapper 中添加 getPageListByQuery 方法实现分页查询
- 在 AiMemberTalkItemService 和 AiMemberTalkService 中添加 historyPage 方法处理分页查询请求
- 在 ApiMemberTalkController 中添加 historyPage接口
- 修改 AiMemberTalkVo 中的 report 字段类型从 Report 改为 String
-移除 Report 类中的 radarData 字段
9 files modified
2 files added
172 ■■■■■ changed files
src/main/java/cc/mrbird/febs/ai/controller/memberTalk/ApiMemberTalkController.java 14 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java 5 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/req/memberTalk/ApiMemberTalkItemPageDto.java 34 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/ai/Report.java 8 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/memberTalk/ApiMemberTalkItemVo.java 43 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/res/memberTalk/ApiMemberTalkVo.java 2 ●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java 26 ●●●● patch | view | raw | blame | history
src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml 20 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/ai/controller/memberTalk/ApiMemberTalkController.java
@@ -2,6 +2,8 @@
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkAnswerDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkItemVo;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkVo;
import cc.mrbird.febs.ai.service.AiMemberTalkService;
import cc.mrbird.febs.common.entity.FebsResponse;
@@ -15,7 +17,9 @@
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
/**
 * @author Administrator
@@ -52,6 +56,16 @@
        return aiMemberTalkService.answer(dto);
    }
    @ApiOperation(value = "对话记录分页查询", notes = "对话记录分页查询")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = ApiMemberTalkItemVo.class)
    })
    @PostMapping(value = "/historyPage")
    public FebsResponse historyPage(@RequestBody @Validated ApiMemberTalkItemPageDto dto) {
        return aiMemberTalkService.historyPage(dto);
    }
    @PostMapping("/start-stream")
    @ApiOperation("开始AI对话(流式)")
    @ApiResponses({
src/main/java/cc/mrbird/febs/ai/mapper/AiMemberTalkItemMapper.java
@@ -1,7 +1,11 @@
package cc.mrbird.febs.ai.mapper;
import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkItemVo;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
 * AI用户对话训练记录子表 Mapper接口
@@ -11,4 +15,5 @@
 */
public interface AiMemberTalkItemMapper extends BaseMapper<AiMemberTalkItem> {
    Page<ApiMemberTalkItemVo> getPageListByQuery(Page<ApiMemberTalkItemVo> page, ApiMemberTalkItemPageDto dto);
}
src/main/java/cc/mrbird/febs/ai/req/memberTalk/ApiMemberTalkItemPageDto.java
New file
@@ -0,0 +1,34 @@
package cc.mrbird.febs.ai.req.memberTalk;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiMemberTalkDto", description = "参数")
public class ApiMemberTalkItemPageDto {
    @NotNull(message = "页码不能为空")
    @ApiModelProperty(value = "页码", example = "1")
    private Integer pageNow;
    @NotNull(message = "每页数量不能为空")
    @ApiModelProperty(value = "每页数量", example = "10")
    private Integer pageSize;
    @NotNull(message = "会话ID不能为空")
    @ApiModelProperty(value = "会话ID", example = "1")
    private String memberTalkId;
    @ApiModelProperty(value = "消息ID")
    private String memberTalkItemId;
    @ApiModelProperty(hidden = true)
    private String memberUuid;
}
src/main/java/cc/mrbird/febs/ai/res/ai/Report.java
@@ -15,10 +15,10 @@
public class Report {
    @ApiModelProperty(value = "雷达图表数据")
    @JsonProperty("radar_data")
    private RadarData radarData;
//
//    @ApiModelProperty(value = "雷达图表数据")
//    @JsonProperty("radar_data")
//    private RadarData radarData;
    @ApiModelProperty(value = "雷达图表数据集合")
    @JsonProperty("radar_data_items")
src/main/java/cc/mrbird/febs/ai/res/memberTalk/ApiMemberTalkItemVo.java
New file
@@ -0,0 +1,43 @@
package cc.mrbird.febs.ai.res.memberTalk;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
 * @author Administrator
 */
@Data
@ApiModel(value = "ApiMemberTalkItemVo", description = "参数")
public class ApiMemberTalkItemVo {
    /**
     * 用户对话ID (UUID)
     */
    @ApiModelProperty(value = "会话ID")
    private String memberTalkId;
    /**
     * 用户消息ID (UUID)
     */
    @ApiModelProperty(value = "消息ID")
    private String memberTalkItemId;
    /**
     * 类型 1-AI提问 2-用户回答 3-AI分析结果
     */
    @ApiModelProperty(value = "类型 1-AI提问 2-用户回答 3-AI分析结果")
    private Integer type;
    /**
     * 内容
     */
    @ApiModelProperty(value = "内容(文本格式)")
    private String context;
}
src/main/java/cc/mrbird/febs/ai/res/memberTalk/ApiMemberTalkVo.java
@@ -34,6 +34,6 @@
    private String context;
    @ApiModelProperty(value = "内容亮点、建议、参考答案、核心知识点雷达图表数据(数据对象)")
    private Report report;
    private String report;
}
src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkItemService.java
@@ -1,6 +1,8 @@
package cc.mrbird.febs.ai.service;
import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.common.entity.FebsResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
@@ -19,4 +21,6 @@
    void add(String memberUuid, String id, int type, String resContext, Date createdTime);
    AiMemberTalkItem getByQuery(LambdaQueryWrapper<AiMemberTalkItem> memberTalkItemQuery);
    FebsResponse historyPage(ApiMemberTalkItemPageDto dto);
}
src/main/java/cc/mrbird/febs/ai/service/AiMemberTalkService.java
@@ -3,6 +3,7 @@
import cc.mrbird.febs.ai.entity.AiMemberTalk;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkAnswerDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.ai.res.ai.AiResponse;
import cc.mrbird.febs.common.entity.FebsResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -33,4 +34,6 @@
    FebsResponse answer(ApiMemberTalkAnswerDto dto);
    AiMemberTalk add(String memberUuid, String productId, Date nowTime);
    FebsResponse historyPage(ApiMemberTalkItemPageDto dto);
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkItemServiceImpl.java
@@ -2,9 +2,14 @@
import cc.mrbird.febs.ai.entity.AiMemberTalkItem;
import cc.mrbird.febs.ai.mapper.AiMemberTalkItemMapper;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkItemVo;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import cc.mrbird.febs.ai.service.AiMemberTalkItemService;
import cc.mrbird.febs.ai.utils.UUID;
import cc.mrbird.febs.common.entity.FebsResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -44,4 +49,12 @@
    public AiMemberTalkItem getByQuery(LambdaQueryWrapper<AiMemberTalkItem> memberTalkItemQuery) {
        return aiMemberTalkItemMapper.selectOne(memberTalkItemQuery);
    }
    @Override
    public FebsResponse historyPage(ApiMemberTalkItemPageDto dto) {
        // 创建分页对象,传入当前页和每页大小
        Page<ApiMemberTalkItemVo> page = new Page<>(dto.getPageNow(), dto.getPageSize());
        Page<ApiMemberTalkItemVo> pageListByQuery = aiMemberTalkItemMapper.getPageListByQuery(page, dto);
        return new FebsResponse().success().data(pageListByQuery);
    }
}
src/main/java/cc/mrbird/febs/ai/service/impl/AiMemberTalkServiceImpl.java
@@ -7,8 +7,11 @@
import cc.mrbird.febs.ai.req.ai.AiRequest;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkAnswerDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkDto;
import cc.mrbird.febs.ai.req.memberTalk.ApiMemberTalkItemPageDto;
import cc.mrbird.febs.ai.res.ai.AiResponse;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkItemVo;
import cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkVo;
import cc.mrbird.febs.ai.res.product.ApiProductVo;
import cc.mrbird.febs.ai.service.AiMemberTalkItemService;
import cc.mrbird.febs.ai.service.AiMemberTalkService;
import cc.mrbird.febs.ai.service.AiProductRoleLinkService;
@@ -19,8 +22,10 @@
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -86,8 +91,6 @@
        apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId());
        apiMemberTalkVo.setType(1);
        apiMemberTalkVo.setContext(aiResponse.getResContext());
        apiMemberTalkVo.setReport(aiResponse.getReport());
        return new FebsResponse().success().data(apiMemberTalkVo);
    }
@@ -207,11 +210,13 @@
        String format = StrUtil.format(ANSWER_FORMAT, aiMemberTalkItem.getContext(), reqContext);
        log.info("format:{}",format);
        AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), format);
//        AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), reqContext);
//        AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), format);
        AiResponse aiResponse = aiService.start(aiProductRoleLink.getProductRoleId(), reqContext);
        String context = null;
        if(aiResponse.getCode().equals("200")){
            Date nowTime = new Date();
            aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),3,aiResponse.getResContext(),nowTime);
            context = String.valueOf(JSONUtil.parse(aiResponse.getReport()));
            aiMemberTalkItemService.add(memberUuid,aiMemberTalk.getId(),3, context,nowTime);
            this.updateTimeUpdate(nowTime,aiMemberTalk.getId());
        }else{
            throw new FebsException(aiResponse.getDescription());
@@ -219,8 +224,7 @@
        ApiMemberTalkVo apiMemberTalkVo = new ApiMemberTalkVo();
        apiMemberTalkVo.setMemberTalkId(aiMemberTalk.getId());
        apiMemberTalkVo.setType(3);
        apiMemberTalkVo.setContext(aiResponse.getResContext());
        apiMemberTalkVo.setReport(aiResponse.getReport());
        apiMemberTalkVo.setContext(context);
        return new FebsResponse().success().data(apiMemberTalkVo);
    }
    @Override
@@ -233,4 +237,12 @@
        aiMemberTalkMapper.insert(aiMemberTalk);
        return aiMemberTalk;
    }
    @Override
    public FebsResponse historyPage(ApiMemberTalkItemPageDto dto) {
        String memberUuid = LoginUserUtil.getLoginUser().getMemberUuid();
        dto.setMemberUuid(memberUuid);
        return aiMemberTalkItemService.historyPage(dto);
    }
}
src/main/resources/mapper/modules/AiMemberTalkItemMapper.xml
@@ -1,4 +1,24 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cc.mrbird.febs.ai.mapper.AiMemberTalkItemMapper">
    <select id="getPageListByQuery" resultType="cc.mrbird.febs.ai.res.memberTalk.ApiMemberTalkItemVo">
        select
        a.ID as memberTalkItemId,
        a.member_talk_id as memberTalkId,
        a.type as type,
        a.context as context
        from ai_member_talk_item a
        <where>
            and a.member_id = #{record.memberUuid}
            and a.member_talk_id = #{record.memberTalkId}
            <if test="record != null">
                <if test="record.memberTalkItemId != null">
                    and a.id &lt; #{record.memberTalkItemId}
                </if>
            </if>
        </where>
        order by a.CREATED_TIME desc
    </select>
</mapper>