首页增加统计项,日志管理增加存入知识库功能,按钮管理增加字段code,日志管理增加提问方式字段
正在显示
10 个修改的文件
包含
264 行增加
和
8 行删除
| 1 | package org.jeecg.modules.airag.app.controller; | 1 | package org.jeecg.modules.airag.app.controller; |
| 2 | 2 | ||
| 3 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 4 | import com.baomidou.mybatisplus.core.metadata.IPage; | 5 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| @@ -14,9 +15,13 @@ import org.jeecg.common.aspect.annotation.AutoLog; | @@ -14,9 +15,13 @@ import org.jeecg.common.aspect.annotation.AutoLog; | ||
| 14 | import org.jeecg.common.system.base.controller.JeecgController; | 15 | import org.jeecg.common.system.base.controller.JeecgController; |
| 15 | import org.jeecg.common.system.query.QueryGenerator; | 16 | import org.jeecg.common.system.query.QueryGenerator; |
| 16 | import org.jeecg.modules.airag.app.config.DataSourceConfig; | 17 | import org.jeecg.modules.airag.app.config.DataSourceConfig; |
| 18 | +import org.jeecg.modules.airag.app.entity.AiragButton; | ||
| 17 | import org.jeecg.modules.airag.app.entity.AiragLog; | 19 | import org.jeecg.modules.airag.app.entity.AiragLog; |
| 20 | +import org.jeecg.modules.airag.app.entity.Embeddings; | ||
| 18 | import org.jeecg.modules.airag.app.entity.QuestionEmbedding; | 21 | import org.jeecg.modules.airag.app.entity.QuestionEmbedding; |
| 22 | +import org.jeecg.modules.airag.app.mapper.AiragButtonMapper; | ||
| 19 | import org.jeecg.modules.airag.app.service.IAiragLogService; | 23 | import org.jeecg.modules.airag.app.service.IAiragLogService; |
| 24 | +import org.jeecg.modules.airag.app.service.IEmbeddingsService; | ||
| 20 | import org.jeecg.modules.airag.app.service.IQuestionEmbeddingService; | 25 | import org.jeecg.modules.airag.app.service.IQuestionEmbeddingService; |
| 21 | import org.jeecg.modules.airag.llm.entity.AiragKnowledge; | 26 | import org.jeecg.modules.airag.llm.entity.AiragKnowledge; |
| 22 | import org.jeecg.modules.airag.llm.entity.AiragModel; | 27 | import org.jeecg.modules.airag.llm.entity.AiragModel; |
| @@ -58,6 +63,11 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | @@ -58,6 +63,11 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | ||
| 58 | @Autowired | 63 | @Autowired |
| 59 | private IAiragKnowledgeService airagKnowledgeService; | 64 | private IAiragKnowledgeService airagKnowledgeService; |
| 60 | 65 | ||
| 66 | + @Autowired | ||
| 67 | + private IEmbeddingsService embeddingsService; | ||
| 68 | + | ||
| 69 | + @Autowired | ||
| 70 | + private AiragButtonMapper airagButtonMapper; | ||
| 61 | /** | 71 | /** |
| 62 | * 分页列表查询 | 72 | * 分页列表查询 |
| 63 | * | 73 | * |
| @@ -92,10 +102,55 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | @@ -92,10 +102,55 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | ||
| 92 | for(AiragModel airagModel : list){ | 102 | for(AiragModel airagModel : list){ |
| 93 | nameMap.put(airagModel.getId(), airagModel.getName()); | 103 | nameMap.put(airagModel.getId(), airagModel.getName()); |
| 94 | } | 104 | } |
| 105 | + | ||
| 106 | + | ||
| 107 | + // 收集所有需要查询的按钮名称 | ||
| 108 | + Set<String> buttonNames = new HashSet<>(); | ||
| 95 | for (AiragLog log : pageList.getRecords()) { | 109 | for (AiragLog log : pageList.getRecords()) { |
| 96 | - String modelId = log.getModelId(); // 获取当前日志的 model_id | ||
| 97 | - log.setName(nameMap.get(modelId)); // 从 nameMap 中匹配 name | 110 | + String modelId = log.getModelId(); |
| 111 | + log.setName(nameMap.get(modelId)); | ||
| 112 | + | ||
| 113 | + // 收集快捷按钮提问的问题内容 | ||
| 114 | + if (log.getCodeType() == 1 && StringUtils.isNotBlank(log.getQuestion())) { | ||
| 115 | + buttonNames.add(log.getQuestion()); | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + // 批量查询按钮code | ||
| 120 | + Map<String, String> buttonCodeMap = new HashMap<>(); | ||
| 121 | + if (!buttonNames.isEmpty()) { | ||
| 122 | + LambdaQueryWrapper<AiragButton> buttonWrapper = new LambdaQueryWrapper<>(); | ||
| 123 | + buttonWrapper.in(AiragButton::getButtonName, buttonNames); | ||
| 124 | + List<AiragButton> buttons = airagButtonMapper.selectList(buttonWrapper); | ||
| 125 | + | ||
| 126 | + for (AiragButton button : buttons) { | ||
| 127 | + buttonCodeMap.put(button.getButtonName(), button.getCode()); | ||
| 128 | + } | ||
| 98 | } | 129 | } |
| 130 | + | ||
| 131 | + // 设置按钮code | ||
| 132 | + for (AiragLog log : pageList.getRecords()) { | ||
| 133 | + if (log.getCodeType() == 0) { | ||
| 134 | + // 输入框提问,按钮code为空 | ||
| 135 | + log.setCode(null); | ||
| 136 | + } else if (log.getCodeType() == 1) { | ||
| 137 | + // 快捷按钮提问 | ||
| 138 | + if (StringUtils.isNotBlank(log.getQuestion())) { | ||
| 139 | + String code = buttonCodeMap.get(log.getQuestion()); | ||
| 140 | + if (StringUtils.isNotBlank(code)) { | ||
| 141 | + log.setCode(code); | ||
| 142 | + airagLogService.updateById(log); | ||
| 143 | + } else { | ||
| 144 | + // 未找到匹配按钮 | ||
| 145 | + log.setCode("INPUT_QUESTION"); | ||
| 146 | + } | ||
| 147 | + } else { | ||
| 148 | + log.setCode(null); | ||
| 149 | + } | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + | ||
| 99 | return Result.OK(pageList); | 154 | return Result.OK(pageList); |
| 100 | } | 155 | } |
| 101 | 156 | ||
| @@ -156,7 +211,7 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | @@ -156,7 +211,7 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | ||
| 156 | 211 | ||
| 157 | 212 | ||
| 158 | /** | 213 | /** |
| 159 | - * 添加到知识库 | 214 | + * 添加到问题库 |
| 160 | * | 215 | * |
| 161 | * @param airagLog | 216 | * @param airagLog |
| 162 | * @return | 217 | * @return |
| @@ -182,6 +237,34 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | @@ -182,6 +237,34 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | ||
| 182 | return Result.OK("存入问题库成功!"); | 237 | return Result.OK("存入问题库成功!"); |
| 183 | } | 238 | } |
| 184 | 239 | ||
| 240 | + | ||
| 241 | + /** | ||
| 242 | + * 添加到知识库 | ||
| 243 | + * | ||
| 244 | + * @param airagLog | ||
| 245 | + * @return | ||
| 246 | + */ | ||
| 247 | + @AutoLog(value = "日志管理-存入知识库") | ||
| 248 | + @Operation(summary = "日志管理-存入知识库") | ||
| 249 | + @RequiresPermissions("airaglog:airag_log:saveToEmbeddingLibrary") | ||
| 250 | + @PostMapping(value = "/saveToEmbeddingLibrary") | ||
| 251 | + public Result<String> saveToEmbeddingLibrary(@RequestBody AiragLog airagLog) { | ||
| 252 | + Embeddings embeddings = new Embeddings(); | ||
| 253 | + embeddings.setText(airagLog.getAnswer()); | ||
| 254 | + int embdeddingCount = embeddingsService.findEmbeddingCount(embeddings); | ||
| 255 | + if(embdeddingCount > 0){ | ||
| 256 | + return Result.error("重复回答不能存入"); | ||
| 257 | + } | ||
| 258 | + | ||
| 259 | + airagLog.setIfSaveKnowledge(1); | ||
| 260 | + try { | ||
| 261 | + airagLogService.saveToEmbeddingLibrary(airagLog); | ||
| 262 | + }catch (Exception e){ | ||
| 263 | + e.printStackTrace(); | ||
| 264 | + } | ||
| 265 | + return Result.OK("存入知识库成功!"); | ||
| 266 | + } | ||
| 267 | + | ||
| 185 | /** | 268 | /** |
| 186 | * 编辑 | 269 | * 编辑 |
| 187 | * | 270 | * |
| @@ -269,4 +352,13 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | @@ -269,4 +352,13 @@ public class AiragLogController extends JeecgController<AiragLog, IAiragLogServi | ||
| 269 | return super.importExcel(request, response, AiragLog.class); | 352 | return super.importExcel(request, response, AiragLog.class); |
| 270 | } | 353 | } |
| 271 | 354 | ||
| 355 | + | ||
| 356 | + | ||
| 357 | + @AutoLog(value = "日志管理-获取统计信息") | ||
| 358 | + @Operation(summary="日志管理-获取统计信息") | ||
| 359 | + @GetMapping(value = "/getStatistics") | ||
| 360 | + public Result<Map<String, Object>> getStatistics() { | ||
| 361 | + Map<String, Object> result = airagLogService.getStatistics(); | ||
| 362 | + return Result.OK(result); | ||
| 363 | + } | ||
| 272 | } | 364 | } |
| 1 | package org.jeecg.modules.airag.app.entity; | 1 | package org.jeecg.modules.airag.app.entity; |
| 2 | 2 | ||
| 3 | import com.baomidou.mybatisplus.annotation.IdType; | 3 | import com.baomidou.mybatisplus.annotation.IdType; |
| 4 | +import com.baomidou.mybatisplus.annotation.TableField; | ||
| 4 | import com.baomidou.mybatisplus.annotation.TableId; | 5 | import com.baomidou.mybatisplus.annotation.TableId; |
| 5 | import com.baomidou.mybatisplus.annotation.TableName; | 6 | import com.baomidou.mybatisplus.annotation.TableName; |
| 6 | import com.fasterxml.jackson.annotation.JsonFormat; | 7 | import com.fasterxml.jackson.annotation.JsonFormat; |
| @@ -64,4 +65,11 @@ public class AiragButton implements Serializable { | @@ -64,4 +65,11 @@ public class AiragButton implements Serializable { | ||
| 64 | @Excel(name = "按钮值", width = 15) | 65 | @Excel(name = "按钮值", width = 15) |
| 65 | @Schema(description = "按钮值") | 66 | @Schema(description = "按钮值") |
| 66 | private String buttonValues; | 67 | private String buttonValues; |
| 68 | + | ||
| 69 | + /** | ||
| 70 | + * 按钮code | ||
| 71 | + */ | ||
| 72 | + @Excel(name = "按钮code", width = 15) | ||
| 73 | + @TableField(value = "code") | ||
| 74 | + private String code; | ||
| 67 | } | 75 | } |
| @@ -85,12 +85,32 @@ public class AiragLog implements Serializable { | @@ -85,12 +85,32 @@ public class AiragLog implements Serializable { | ||
| 85 | @Schema(description = "回答方式:1:问题库回答 2:模型回答 3:未命中") | 85 | @Schema(description = "回答方式:1:问题库回答 2:模型回答 3:未命中") |
| 86 | private int answerType; | 86 | private int answerType; |
| 87 | /** | 87 | /** |
| 88 | - * 回答方式 | 88 | + * 提问方式 |
| 89 | + */ | ||
| 90 | + @Excel(name = "提问方式", width = 15) | ||
| 91 | + @TableField("code_type") | ||
| 92 | + @Schema(description = "提问方式:0:输入框提问 ,1:快捷按钮提问") | ||
| 93 | + private int codeType; | ||
| 94 | + /** | ||
| 95 | + * 按钮code | ||
| 96 | + */ | ||
| 97 | + @Excel(name = "按钮code", width = 15) | ||
| 98 | + @TableField(value = "code") | ||
| 99 | + private String code; | ||
| 100 | + /** | ||
| 101 | + * 存入问题库 | ||
| 89 | */ | 102 | */ |
| 90 | @Excel(name = "是否存入问题库", width = 15) | 103 | @Excel(name = "是否存入问题库", width = 15) |
| 91 | @TableField("is_storage") | 104 | @TableField("is_storage") |
| 92 | @Schema(description = "是否存入问题库 0:否 1:是") | 105 | @Schema(description = "是否存入问题库 0:否 1:是") |
| 93 | private int isStorage; | 106 | private int isStorage; |
| 107 | + /** | ||
| 108 | + * 存入知识库 | ||
| 109 | + */ | ||
| 110 | + @Excel(name = "是否存入知识库", width = 15) | ||
| 111 | + @TableField("if_save_knowledge") | ||
| 112 | + @Schema(description = "是否存入知识库 0:否 1:是") | ||
| 113 | + private int ifSaveKnowledge; | ||
| 94 | 114 | ||
| 95 | // 新增:临时字段(非数据库字段) | 115 | // 新增:临时字段(非数据库字段) |
| 96 | @TableField(exist = false) // MyBatis-Plus 标记该字段不存在于数据库表中 | 116 | @TableField(exist = false) // MyBatis-Plus 标记该字段不存在于数据库表中 |
| @@ -7,6 +7,7 @@ import io.lettuce.core.dynamic.annotation.Param; | @@ -7,6 +7,7 @@ import io.lettuce.core.dynamic.annotation.Param; | ||
| 7 | import org.jeecg.modules.airag.app.entity.AiragLog; | 7 | import org.jeecg.modules.airag.app.entity.AiragLog; |
| 8 | 8 | ||
| 9 | import java.util.List; | 9 | import java.util.List; |
| 10 | +import java.util.Map; | ||
| 10 | 11 | ||
| 11 | /** | 12 | /** |
| 12 | * @Description: 日志管理 | 13 | * @Description: 日志管理 |
| @@ -21,4 +22,9 @@ public interface AiragLogMapper extends BaseMapper<AiragLog> { | @@ -21,4 +22,9 @@ public interface AiragLogMapper extends BaseMapper<AiragLog> { | ||
| 21 | 22 | ||
| 22 | int updataIsStorage(@Param("param1") int isStorage, @Param("param2") String id); | 23 | int updataIsStorage(@Param("param1") int isStorage, @Param("param2") String id); |
| 23 | 24 | ||
| 25 | + int updataIfSaveKnowledge(@Param("param1") int ifSaveKnowledge, @Param("param2") String id); | ||
| 26 | + | ||
| 27 | + List<Map<String, Object>> getButtonRankList(); | ||
| 28 | + | ||
| 29 | + List<Map<String, Object>> getMonthlyCount(); | ||
| 24 | } | 30 | } |
| @@ -279,7 +279,6 @@ public class QuestionEmbeddingMapper { | @@ -279,7 +279,6 @@ public class QuestionEmbeddingMapper { | ||
| 279 | // 2. 获取问题的嵌入向量 | 279 | // 2. 获取问题的嵌入向量 |
| 280 | Response<Embedding> embeddingResponse = aiModelUtils.getEmbedding(embedId, question); | 280 | Response<Embedding> embeddingResponse = aiModelUtils.getEmbedding(embedId, question); |
| 281 | float[] queryVector = embeddingResponse.content().vector(); | 281 | float[] queryVector = embeddingResponse.content().vector(); |
| 282 | - | ||
| 283 | // 3. 计算最大允许距离(1 - 相似度阈值) | 282 | // 3. 计算最大允许距离(1 - 相似度阈值) |
| 284 | double maxDistance = 1 - minSimilarity; | 283 | double maxDistance = 1 - minSimilarity; |
| 285 | 284 |
| @@ -12,7 +12,8 @@ | @@ -12,7 +12,8 @@ | ||
| 12 | select | 12 | select |
| 13 | id, create_by, create_time, | 13 | id, create_by, create_time, |
| 14 | update_by, update_time, question, | 14 | update_by, update_time, question, |
| 15 | - answer, model_id, answer_type, is_storage | 15 | + answer, model_id, answer_type, is_storage, if_save_knowledge, |
| 16 | + code_type, code | ||
| 16 | from airag_log | 17 | from airag_log |
| 17 | where 1=1 | 18 | where 1=1 |
| 18 | <if test="param1.isStorage != null and param1.isStorage != -1"> | 19 | <if test="param1.isStorage != null and param1.isStorage != -1"> |
| @@ -38,4 +39,31 @@ | @@ -38,4 +39,31 @@ | ||
| 38 | set is_storage = #{isStorage} | 39 | set is_storage = #{isStorage} |
| 39 | where id = #{id} | 40 | where id = #{id} |
| 40 | </update> | 41 | </update> |
| 42 | + | ||
| 43 | + <update id="updataIfSaveKnowledge"> | ||
| 44 | + update airag_log | ||
| 45 | + set if_save_knowledge = #{ifSaveKnowledge} | ||
| 46 | + where id = #{id} | ||
| 47 | + </update> | ||
| 48 | + | ||
| 49 | + | ||
| 50 | + <select id="getMonthlyCount" resultType="java.util.Map"> | ||
| 51 | + SELECT | ||
| 52 | + DATE_FORMAT(create_time, '%Y-%m') AS month, | ||
| 53 | + COUNT(*) AS count | ||
| 54 | + FROM airag_log | ||
| 55 | + WHERE create_time >= DATE_SUB(CURDATE(), INTERVAL 12 MONTH) | ||
| 56 | + GROUP BY DATE_FORMAT(create_time, '%Y-%m') | ||
| 57 | + ORDER BY month ASC | ||
| 58 | + </select> | ||
| 59 | + | ||
| 60 | + <select id="getButtonRankList" resultType="java.util.Map"> | ||
| 61 | + SELECT | ||
| 62 | + question, COUNT(*) as count | ||
| 63 | + FROM airag_log | ||
| 64 | + WHERE code IS NOT NULL AND code != '' | ||
| 65 | + GROUP BY question | ||
| 66 | + ORDER BY count DESC | ||
| 67 | + LIMIT 7 | ||
| 68 | + </select> | ||
| 41 | </mapper> | 69 | </mapper> |
| @@ -9,6 +9,7 @@ import org.apache.poi.ss.formula.functions.T; | @@ -9,6 +9,7 @@ import org.apache.poi.ss.formula.functions.T; | ||
| 9 | import org.jeecg.modules.airag.app.entity.AiragLog; | 9 | import org.jeecg.modules.airag.app.entity.AiragLog; |
| 10 | 10 | ||
| 11 | import java.util.List; | 11 | import java.util.List; |
| 12 | +import java.util.Map; | ||
| 12 | 13 | ||
| 13 | /** | 14 | /** |
| 14 | * @Description: 日志管理 | 15 | * @Description: 日志管理 |
| @@ -20,9 +21,13 @@ public interface IAiragLogService extends IService<AiragLog> { | @@ -20,9 +21,13 @@ public interface IAiragLogService extends IService<AiragLog> { | ||
| 20 | // List<AiragLog> getLogListWithModelName(); | 21 | // List<AiragLog> getLogListWithModelName(); |
| 21 | void saveToQuestionLibrary(AiragLog log) throws JsonProcessingException; | 22 | void saveToQuestionLibrary(AiragLog log) throws JsonProcessingException; |
| 22 | 23 | ||
| 24 | + void saveToEmbeddingLibrary(AiragLog log) throws JsonProcessingException; | ||
| 25 | + | ||
| 23 | IPage<AiragLog> list1(AiragLog airagLog,Page<AiragLog> page); | 26 | IPage<AiragLog> list1(AiragLog airagLog,Page<AiragLog> page); |
| 24 | 27 | ||
| 25 | IPage<AiragLog> pageList(AiragLog airagLog, Page<AiragLog> page); | 28 | IPage<AiragLog> pageList(AiragLog airagLog, Page<AiragLog> page); |
| 26 | 29 | ||
| 30 | + Map<String, Object> getStatistics(); | ||
| 31 | + | ||
| 27 | // List<T> list(Page<AiragLog> page, QueryWrapper<AiragLog> queryWrapper); | 32 | // List<T> list(Page<AiragLog> page, QueryWrapper<AiragLog> queryWrapper); |
| 28 | } | 33 | } |
| @@ -4,6 +4,7 @@ package org.jeecg.modules.airag.app.service; | @@ -4,6 +4,7 @@ package org.jeecg.modules.airag.app.service; | ||
| 4 | 4 | ||
| 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 6 | import org.jeecg.modules.airag.app.entity.Embeddings; | 6 | import org.jeecg.modules.airag.app.entity.Embeddings; |
| 7 | +import org.jeecg.modules.airag.app.entity.QuestionEmbedding; | ||
| 7 | 8 | ||
| 8 | import java.util.ArrayList; | 9 | import java.util.ArrayList; |
| 9 | import java.util.List; | 10 | import java.util.List; |
| @@ -22,4 +23,6 @@ public interface IEmbeddingsService { | @@ -22,4 +23,6 @@ public interface IEmbeddingsService { | ||
| 22 | int update(Embeddings record); | 23 | int update(Embeddings record); |
| 23 | Embeddings findById(String id); | 24 | Embeddings findById(String id); |
| 24 | int removeByIds(List<String> ids); | 25 | int removeByIds(List<String> ids); |
| 26 | + | ||
| 27 | + Integer findEmbeddingCount(Embeddings embeddings); | ||
| 25 | } | 28 | } |
| 1 | package org.jeecg.modules.airag.app.service.impl; | 1 | package org.jeecg.modules.airag.app.service.impl; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.generator.SnowflakeGenerator; | 3 | import cn.hutool.core.lang.generator.SnowflakeGenerator; |
| 4 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 4 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | 5 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
| 5 | import com.baomidou.mybatisplus.core.metadata.IPage; | 6 | import com.baomidou.mybatisplus.core.metadata.IPage; |
| 6 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 7 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| @@ -9,11 +10,13 @@ import com.fasterxml.jackson.core.JsonProcessingException; | @@ -9,11 +10,13 @@ import com.fasterxml.jackson.core.JsonProcessingException; | ||
| 9 | import com.fasterxml.jackson.databind.ObjectMapper; | 10 | import com.fasterxml.jackson.databind.ObjectMapper; |
| 10 | import com.fasterxml.jackson.databind.util.ObjectBuffer; | 11 | import com.fasterxml.jackson.databind.util.ObjectBuffer; |
| 11 | import io.minio.messages.Metadata; | 12 | import io.minio.messages.Metadata; |
| 13 | +import org.apache.commons.lang3.StringUtils; | ||
| 12 | import org.apache.poi.ss.formula.functions.T; | 14 | import org.apache.poi.ss.formula.functions.T; |
| 15 | +import org.jeecg.modules.airag.app.entity.AiragButton; | ||
| 13 | import org.jeecg.modules.airag.app.entity.AiragLog; | 16 | import org.jeecg.modules.airag.app.entity.AiragLog; |
| 17 | +import org.jeecg.modules.airag.app.entity.Embeddings; | ||
| 14 | import org.jeecg.modules.airag.app.entity.QuestionEmbedding; | 18 | import org.jeecg.modules.airag.app.entity.QuestionEmbedding; |
| 15 | -import org.jeecg.modules.airag.app.mapper.AiragLogMapper; | ||
| 16 | -import org.jeecg.modules.airag.app.mapper.QuestionEmbeddingMapper; | 19 | +import org.jeecg.modules.airag.app.mapper.*; |
| 17 | import org.jeecg.modules.airag.app.service.IAiragLogService; | 20 | import org.jeecg.modules.airag.app.service.IAiragLogService; |
| 18 | import org.springframework.beans.factory.annotation.Autowired; | 21 | import org.springframework.beans.factory.annotation.Autowired; |
| 19 | import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; | 22 | import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; |
| @@ -36,6 +39,12 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | @@ -36,6 +39,12 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | ||
| 36 | private QuestionEmbeddingMapper questionEmbeddingMapper; | 39 | private QuestionEmbeddingMapper questionEmbeddingMapper; |
| 37 | 40 | ||
| 38 | @Autowired | 41 | @Autowired |
| 42 | + private AiragButtonMapper airagButtonMapper; | ||
| 43 | + | ||
| 44 | + @Autowired | ||
| 45 | + private PgVectorMapper pgVectorMapper; | ||
| 46 | + | ||
| 47 | + @Autowired | ||
| 39 | private AiragLogMapper airagLogMapper; | 48 | private AiragLogMapper airagLogMapper; |
| 40 | 49 | ||
| 41 | 50 | ||
| @@ -60,7 +69,24 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | @@ -60,7 +69,24 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | ||
| 60 | questionEmbedding.setMetadata(metadataJson); | 69 | questionEmbedding.setMetadata(metadataJson); |
| 61 | questionEmbeddingMapper.insert(questionEmbedding); | 70 | questionEmbeddingMapper.insert(questionEmbedding); |
| 62 | airagLogMapper.updataIsStorage(log.getIsStorage(),log.getId()); | 71 | airagLogMapper.updataIsStorage(log.getIsStorage(),log.getId()); |
| 72 | + System.out.println("1"); | ||
| 73 | + } | ||
| 63 | 74 | ||
| 75 | + @Override | ||
| 76 | + public void saveToEmbeddingLibrary(AiragLog log) throws JsonProcessingException { | ||
| 77 | + // 这里实现将问题和回答存入问题库数据表的逻辑 | ||
| 78 | + // 假设问题库数据表的实体类为 QuestionLibrary,Mapper 接口为 QuestionLibraryMapper | ||
| 79 | + Embeddings embeddings = new Embeddings(); | ||
| 80 | + embeddings.setText(log.getAnswer()); | ||
| 81 | + embeddings.setKnowledgeId(log.getKnowledgeId()); | ||
| 82 | + Map<String, Object> metadata = new LinkedHashMap<>(); | ||
| 83 | + metadata.put("title", ""); | ||
| 84 | + metadata.put("docName", ""); | ||
| 85 | + metadata.put("knowledgeId", embeddings.getKnowledgeId()); | ||
| 86 | + metadata.put("storedFileName", ""); // 自动生成唯一文档ID | ||
| 87 | + embeddings.setMetadata(metadata); | ||
| 88 | + pgVectorMapper.insert(embeddings); | ||
| 89 | + airagLogMapper.updataIfSaveKnowledge(log.getIfSaveKnowledge(),log.getId()); | ||
| 64 | } | 90 | } |
| 65 | 91 | ||
| 66 | @Override | 92 | @Override |
| @@ -73,6 +99,69 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | @@ -73,6 +99,69 @@ public class AiragLogServiceImpl extends ServiceImpl<AiragLogMapper, AiragLog> i | ||
| 73 | return airagLogMapper.pageList(airagLog,page); | 99 | return airagLogMapper.pageList(airagLog,page); |
| 74 | } | 100 | } |
| 75 | 101 | ||
| 102 | + | ||
| 103 | + @Override | ||
| 104 | + public Map<String, Object> getStatistics() { | ||
| 105 | + Map<String, Object> result = new HashMap<>(); | ||
| 106 | + | ||
| 107 | + // 1. 获取今日问答次数 | ||
| 108 | + QueryWrapper<AiragLog> todayWrapper = new QueryWrapper<>(); | ||
| 109 | + todayWrapper.apply("DATE(create_time) = CURDATE()"); | ||
| 110 | + long todayCount = this.count(todayWrapper); | ||
| 111 | + | ||
| 112 | + // 2. 获取昨日问答次数 | ||
| 113 | + QueryWrapper<AiragLog> yesterdayWrapper = new QueryWrapper<>(); | ||
| 114 | + yesterdayWrapper.apply("DATE(create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)"); | ||
| 115 | + long yesterdayCount = this.count(yesterdayWrapper); | ||
| 116 | + | ||
| 117 | + // 3. 计算日增长率 | ||
| 118 | + double growthRate = 0.0; | ||
| 119 | + if (yesterdayCount > 0) { | ||
| 120 | + growthRate = ((double)(todayCount - yesterdayCount) / yesterdayCount) * 100; | ||
| 121 | + } else if (todayCount > 0) { | ||
| 122 | + // 昨天为0,今天有数据,则增长率为100% | ||
| 123 | + growthRate = 100.0; | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + // 4. 获取拒绝回答次数 | ||
| 127 | + QueryWrapper<AiragLog> rejectedWrapper = new QueryWrapper<>(); | ||
| 128 | + rejectedWrapper.eq("answer_type", 3); // 假设3表示拒绝回答 | ||
| 129 | + long rejectedCount = this.count(rejectedWrapper); | ||
| 130 | + | ||
| 131 | + // 5. 获取累计问答次数 | ||
| 132 | + long totalCount = this.count(); | ||
| 133 | + | ||
| 134 | + // 6. 计算平均问答次数(基于有记录的天数) | ||
| 135 | + QueryWrapper<AiragLog> distinctDaysWrapper = new QueryWrapper<>(); | ||
| 136 | + distinctDaysWrapper.select("DISTINCT DATE(create_time)"); | ||
| 137 | + long distinctDays = this.count(distinctDaysWrapper); | ||
| 138 | + | ||
| 139 | + double averageCount = 0.0; | ||
| 140 | + if (distinctDays > 0) { | ||
| 141 | + averageCount = (double) totalCount / distinctDays; | ||
| 142 | + // 保留两位小数 | ||
| 143 | + averageCount = Math.round(averageCount * 100.0) / 100.0; | ||
| 144 | + } | ||
| 145 | + | ||
| 146 | + // 7.获取按钮问题和按钮code次数,只获取有按钮code的问题(log.question) | ||
| 147 | + List<Map<String, Object>> buttonStats = airagLogMapper.getButtonRankList(); | ||
| 148 | + | ||
| 149 | + // 8. 获取最近12个月的月度数据 | ||
| 150 | + List<Map<String, Object>> monthlyData = airagLogMapper.getMonthlyCount(); | ||
| 151 | + | ||
| 152 | + // 9. 添加前一天数据 | ||
| 153 | + result.put("yesterdayCount", yesterdayCount); | ||
| 154 | + result.put("growthRate", Math.round(growthRate * 100.0) / 100.0); // 保留两位小数 | ||
| 155 | + result.put("todayCount", todayCount); | ||
| 156 | + result.put("rejectedCount", rejectedCount); | ||
| 157 | + result.put("totalCount", totalCount); | ||
| 158 | + result.put("averageCount", averageCount); | ||
| 159 | + result.put("buttonStats", buttonStats); | ||
| 160 | + result.put("monthlyData", monthlyData); | ||
| 161 | + | ||
| 162 | + return result; | ||
| 163 | + } | ||
| 164 | + | ||
| 76 | /* @Override | 165 | /* @Override |
| 77 | public List<T> list(Page<AiragLog> page, QueryWrapper<AiragLog> queryWrapper) { | 166 | public List<T> list(Page<AiragLog> page, QueryWrapper<AiragLog> queryWrapper) { |
| 78 | 167 |
| @@ -2,6 +2,7 @@ package org.jeecg.modules.airag.app.service.impl; | @@ -2,6 +2,7 @@ package org.jeecg.modules.airag.app.service.impl; | ||
| 2 | 2 | ||
| 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | 3 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| 4 | import org.jeecg.modules.airag.app.entity.Embeddings; | 4 | import org.jeecg.modules.airag.app.entity.Embeddings; |
| 5 | +import org.jeecg.modules.airag.app.entity.QuestionEmbedding; | ||
| 5 | import org.jeecg.modules.airag.app.mapper.PgVectorMapper; | 6 | import org.jeecg.modules.airag.app.mapper.PgVectorMapper; |
| 6 | import org.jeecg.modules.airag.app.service.IEmbeddingsService; | 7 | import org.jeecg.modules.airag.app.service.IEmbeddingsService; |
| 7 | import org.springframework.beans.factory.annotation.Autowired; | 8 | import org.springframework.beans.factory.annotation.Autowired; |
| @@ -25,6 +26,11 @@ public class IEmbeddingsServiceImpl implements IEmbeddingsService { | @@ -25,6 +26,11 @@ public class IEmbeddingsServiceImpl implements IEmbeddingsService { | ||
| 25 | return pgVectorMapper.findAll(embeddings,pageNo,pageSize); | 26 | return pgVectorMapper.findAll(embeddings,pageNo,pageSize); |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 29 | + @Override | ||
| 30 | + public Integer findEmbeddingCount(Embeddings embeddings) { | ||
| 31 | + return pgVectorMapper.findEmbeddingCount(embeddings); | ||
| 32 | + } | ||
| 33 | + | ||
| 28 | public int deleteById(String id) { | 34 | public int deleteById(String id) { |
| 29 | return pgVectorMapper.deleteById(id); | 35 | return pgVectorMapper.deleteById(id); |
| 30 | } | 36 | } |
-
请 注册 或 登录 后发表评论