Commit 9ee4fd91 by Shucai Chen

智能客服分析界面开发

parent 2a8229c8
......@@ -88,6 +88,8 @@ public interface ErrorCodeConstants {
ErrorCode FASTGPT_REF_ERROR = new ErrorCode(1_022_009_005, "未找到知识库引用");
ErrorCode FASTGPT_DETAIL_ERROR = new ErrorCode(1_022_009_005, "未找到知识库详情");
ErrorCode FASTGPT_CONFIG_ERROR = new ErrorCode(1_022_009_006, "FastGPT 知识库配置错误,未找到对应的知识库");
ErrorCode FASTGPT_UPLOAD_FAILED = new ErrorCode(1_022_009_007, "上传至 FastGPT 知识库失败");
ErrorCode AGENT_POLICY_NOTIFY_NOT_EXISTS = new ErrorCode(1_043_001_001, "操作失败,找不到该记录");
}
......@@ -144,4 +144,27 @@ public class AiChatAnalysisController {
return success(true);
}
@PostMapping("/upload-to-fastgpt")
@Operation(summary = "上传对话总结至 FastGPT 测试知识库")
public CommonResult<Boolean> uploadToFastGpt(
@Valid @RequestBody AiChatSummaryUploadReqVO reqVO) {
chatAnalysisService.uploadToFastGpt(reqVO);
return success(true);
}
@PostMapping("/upload-to-production-fastgpt")
@Operation(summary = "上传对话总结至 FastGPT 正式知识库(测试通过后调用)")
public CommonResult<Boolean> uploadToProductionFastGpt(
@Valid @RequestBody AiChatSummaryUploadReqVO reqVO) {
chatAnalysisService.uploadToProductionFastGpt(reqVO);
return success(true);
}
@PostMapping("/test-fastgpt")
@Operation(summary = "测试 FastGPT 知识库连接")
public CommonResult<String> testFastGpt(@Valid @RequestBody AiChatTestFastGptReqVO reqVO) {
String result = chatAnalysisService.testFastGpt(reqVO.getQuestion(), reqVO.getCategory());
return success(result);
}
}
......@@ -4,6 +4,8 @@ import com.fhs.core.trans.vo.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 对话分析记录 Response VO")
@Data
public class AiChatSummaryRespVO implements VO {
......@@ -21,4 +23,16 @@ public class AiChatSummaryRespVO implements VO {
@Schema(description = "状态", example = "0")
private Integer status;
@Schema(description = "分析时间")
private LocalDateTime summaryTime;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "修改时间(测试通过时间)")
private LocalDateTime updateTime;
@Schema(description = "处理人昵称")
private String modifierName;
}
package cn.iocoder.yudao.module.ai.controller.admin.chat.vo.analysis;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@Schema(description = "管理后台 - 对话分析总结上传至 FastGPT 知识库 Request VO")
@Data
public class AiChatSummaryUploadReqVO {
@Schema(description = "总结记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
@NotNull(message = "总结记录编号不能为空")
private Long id;
@Schema(description = "知识库标题(用户问题)", requiredMode = Schema.RequiredMode.REQUIRED, example = "公租房申请条件是什么")
@NotBlank(message = "知识库标题不能为空")
private String kbTitle;
@Schema(description = "知识库正文内容(AI 回答)", requiredMode = Schema.RequiredMode.REQUIRED, example = "公租房申请需要满足以下条件...")
@NotBlank(message = "知识库正文内容不能为空")
private String kbContent;
@Schema(description = "分类(公租房/长租房)", requiredMode = Schema.RequiredMode.REQUIRED, example = "公租房")
@NotBlank(message = "分类不能为空")
private String category;
}
......@@ -52,4 +52,9 @@ public class AiChatSummaryDO extends BaseDO {
private Integer status;
/**
* 处理人昵称(测试通过时的操作人)
*/
private String modifierName;
}
......@@ -94,7 +94,7 @@ public interface AiKnowledgeDocumentMapper extends BaseMapperX<AiKnowledgeDocume
.in(AiKnowledgeDocumentDO::getId, ids));
}
@Select("SELECT COALESCE(SUM(content_length), 0) FROM ai_knowledge_document WHERE creator = #{userId} AND is_dir = 0 AND knowledge_id = 6 AND deleted = 0")
@Select("SELECT COALESCE(SUM(content_length), 0) FROM ai_knowledge_document WHERE creator = #{userId} AND is_dir = 0 AND deleted = 0")
Long selectCountKBSize(Long userId);
default List<AiKnowledgeDocumentDO> selectListByParentId(Long id) {
......
......@@ -34,4 +34,27 @@ public interface AiChatAnalysisService {
PageResult<AiChatSummaryDO> getChatSummaryPage(AiChatSummaryPageReqVO pageReqVO);
void updateSummaryStatus(AiSummaryUpdateStatusReqVO reqVO);
/**
* 上传总结至 FastGPT 测试知识库
*
* @param reqVO 上传请求
*/
void uploadToFastGpt(AiChatSummaryUploadReqVO reqVO);
/**
* 上传总结至 FastGPT 正式知识库(测试通过后调用)
*
* @param reqVO 上传请求
*/
void uploadToProductionFastGpt(AiChatSummaryUploadReqVO reqVO);
/**
* 测试 FastGPT 知识库连接
*
* @param question 测试问题
* @param category 分类(公租房/长租房)
* @return FastGPT 的回复内容
*/
String testFastGpt(String question, String category);
}
......@@ -476,7 +476,7 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
if(userId == null){
throw exception(USER_NOT_EXISTS);
}
AiKnowledgeDO aiKnowledgeDO = knowledgeService.getKnowledge(pageReqVO.getKnowledgeId());
AiKnowledgeDO aiKnowledgeDO = knowledgeService.validateKnowledgeExists(pageReqVO.getKnowledgeId());
String permission = KnowledgePermissionUtils.checkSeeKBPermission(aiKnowledgeDO.getEmbeddingModel(), userId);
PageResult<AiKnowledgeDocumentDO> pageResult;
......@@ -541,7 +541,7 @@ public class AiKnowledgeDocumentServiceImpl implements AiKnowledgeDocumentServic
if(userId == null){
throw exception(USER_NOT_EXISTS);
}
AiKnowledgeDO aiKnowledgeDO = knowledgeService.getKnowledge(pageReqVO.getKnowledgeId());
AiKnowledgeDO aiKnowledgeDO = knowledgeService.validateKnowledgeExists(pageReqVO.getKnowledgeId());
PageResult<AiKnowledgeDocumentDO> pageResult;
......
package cn.iocoder.yudao.server;
import org.springframework.ai.autoconfigure.transformers.TransformersEmbeddingModelAutoConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
......@@ -13,13 +14,16 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* @author 芋道源码
*/
@SuppressWarnings("SpringComponentScan") // 忽略 IDEA 无法识别 ${yudao.info.base-package}
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"})
@SpringBootApplication(
scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"},
exclude = {TransformersEmbeddingModelAutoConfiguration.class}
)
public class YudaoServerApplication {
public static void main(String[] args) {
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
// 如果你碰到启动的问题,请认真阅读 https://doc.iocoder.cn/quick-start/ 文章
System.out.println("====== 真正有效的密文 ======");
System.out.println(new org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder().encode("admin123"));
System.out.println("===========================");
SpringApplication.run(YudaoServerApplication.class, args);
// new SpringApplicationBuilder(YudaoServerApplication.class)
......
......@@ -104,7 +104,109 @@ const include = [
'element-plus/es/components/collapse/style/css',
'element-plus/es/components/collapse-item/style/css',
'element-plus/es/components/button-group/style/css',
'element-plus/es/components/text/style/css'
'element-plus/es/components/text/style/css',
'element-plus/es/components/input-tag/style/css',
'element-plus/es/components/transfer/style/css',
'element-plus/es/components/calendar/style/css',
'element-plus/es/components/tabs/style/css',
'element-plus/es/components/tab-pane/style/css',
'element-plus/es/components/result/style/css',
'element-plus/es/components/steps/style/css',
'element-plus/es/components/step/style/css',
'element-plus/es/components/divider/style/css',
'element-plus/es/components/empty/style/css',
'element-plus/es/components/infinite-scroll/style/css',
'element-plus/es/components/page-header/style/css',
'element-plus/es/components/timeline/style/css',
'element-plus/es/components/timeline-item/style/css',
'element-plus/es/components/alert/style/css',
'element-plus/es/components/badge/style/css',
'element-plus/es/components/progress/style/css',
'element-plus/es/components/skeleton/style/css',
'element-plus/es/components/spinner/style/css',
'element-plus/es/components/statistic/style/css',
'element-plus/es/components/avatar-group/style/css',
'element-plus/es/components/date-picker/style/css',
'element-plus/es/components/time-picker/style/css',
'element-plus/es/components/autocomplete/style/css',
'element-plus/es/components/cascader/style/css',
'element-plus/es/components/checkbox/style/css',
'element-plus/es/components/checkbox-group/style/css',
'element-plus/es/components/checkbox-button/style/css',
'element-plus/es/components/color-picker/style/css',
'element-plus/es/components/input/style/css',
'element-plus/es/components/input-number/style/css',
'element-plus/es/components/radio/style/css',
'element-plus/es/components/radio-group/style/css',
'element-plus/es/components/radio-button/style/css',
'element-plus/es/components/rate/style/css',
'element-plus/es/components/select/style/css',
'element-plus/es/components/select-v2/style/css',
'element-plus/es/components/option/style/css',
'element-plus/es/components/option-group/style/css',
'element-plus/es/components/switch/style/css',
'element-plus/es/components/time-select/style/css',
'element-plus/es/components/tree-select/style/css',
'element-plus/es/components/upload/style/css',
'element-plus/es/components/form/style/css',
'element-plus/es/components/form-item/style/css',
'element-plus/es/components/dialog/style/css',
'element-plus/es/components/drawer/style/css',
'element-plus/es/components/message-box/style/css',
'element-plus/es/components/loading/style/css',
'element-plus/es/components/message/style/css',
'element-plus/es/components/notification/style/css',
'element-plus/es/components/breadcrumb/style/css',
'element-plus/es/components/breadcrumb-item/style/css',
'element-plus/es/components/page-header/style/css',
'element-plus/es/components/tabs/style/css',
'element-plus/es/components/tab-pane/style/css',
'element-plus/es/components/tag/style/css',
'element-plus/es/components/tooltip/style/css',
'element-plus/es/components/pagination/style/css',
'element-plus/es/components/table/style/css',
'element-plus/es/components/table-column/style/css',
'element-plus/es/components/table-v2/style/css',
'element-plus/es/components/card/style/css',
'element-plus/es/components/collapse/style/css',
'element-plus/es/components/collapse-item/style/css',
'element-plus/es/components/divider/style/css',
'element-plus/es/components/empty/style/css',
'element-plus/es/components/result/style/css',
'element-plus/es/components/space/style/css',
'element-plus/es/components/steps/style/css',
'element-plus/es/components/step/style/css',
'element-plus/es/components/timeline/style/css',
'element-plus/es/components/timeline-item/style/css',
'element-plus/es/components/transfer/style/css',
'element-plus/es/components/calendar/style/css',
'element-plus/es/components/affix/style/css',
'element-plus/es/components/backtop/style/css',
'element-plus/es/components/infinite-scroll/style/css',
'element-plus/es/components/scrollbar/style/css',
'element-plus/es/components/skeleton/style/css',
'element-plus/es/components/avatar/style/css',
'element-plus/es/components/avatar-group/style/css',
'element-plus/es/components/badge/style/css',
'element-plus/es/components/progress/style/css',
'element-plus/es/components/spinner/style/css',
'element-plus/es/components/statistic/style/css',
'element-plus/es/components/button/style/css',
'element-plus/es/components/button-group/style/css',
'element-plus/es/components/dropdown/style/css',
'element-plus/es/components/dropdown-menu/style/css',
'element-plus/es/components/dropdown-item/style/css',
'element-plus/es/components/menu/style/css',
'element-plus/es/components/sub-menu/style/css',
'element-plus/es/components/menu-item/style/css',
'element-plus/es/components/tree/style/css',
'element-plus/es/components/image/style/css',
'element-plus/es/components/image-viewer/style/css',
'element-plus/es/components/link/style/css',
'element-plus/es/components/descriptions/style/css',
'element-plus/es/components/descriptions-item/style/css',
'element-plus/es/components/collapse-transition/style/css',
'element-plus/es/components/slider/style/css'
]
const exclude = ['@iconify/json']
......
......@@ -9,11 +9,11 @@
"dev": "vite --mode env.local",
"dev-server": "vite --mode dev",
"ts:check": "vue-tsc --noEmit",
"build:local": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build",
"build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev",
"build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test",
"build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage",
"build:prod": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode prod",
"build:local": "node node_modules/vite/bin/vite.js build",
"build:dev": "node node_modules/vite/bin/vite.js build --mode dev",
"build:test": "node node_modules/vite/bin/vite.js build --mode test",
"build:stage": "node node_modules/vite/bin/vite.js build --mode stage",
"build:prod": "node node_modules/vite/bin/vite.js build --mode prod",
"serve:dev": "vite preview --mode dev",
"serve:prod": "vite preview --mode prod",
"preview": "pnpm build:local && vite preview",
......@@ -47,7 +47,7 @@
"driver.js": "^1.3.1",
"echarts": "^5.5.0",
"echarts-wordcloud": "^2.1.0",
"element-plus": "2.8.0",
"element-plus": "2.14.2",
"fast-xml-parser": "^4.3.2",
"highlight.js": "^11.9.0",
"jsencrypt": "^3.3.2",
......@@ -124,7 +124,7 @@
"unplugin-auto-import": "^0.16.7",
"unplugin-element-plus": "^0.8.0",
"unplugin-vue-components": "^0.25.2",
"vite": "5.1.4",
"vite": "4.5.0",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-ejs": "^1.7.0",
"vite-plugin-eslint": "^1.8.1",
......
......@@ -73,4 +73,35 @@ export const ChatAnalysisApi = {
data
})
},
// 上传至 FastGPT 测试知识库
uploadToFastGpt: async (data: {
id: number
kbTitle: string
kbContent: string
category: string
}) => {
return await request.post({
url: `/ai/chat/analysis/upload-to-fastgpt`,
data
})
},
// 上传至 FastGPT 正式知识库(测试通过后调用)
uploadToProductionFastGpt: async (data: {
id: number
kbTitle: string
kbContent: string
category: string
}) => {
return await request.post({
url: `/ai/chat/analysis/upload-to-production-fastgpt`,
data
})
},
// 测试 FastGPT 知识库连接
testFastGpt: async (data: { question: string; category: string }) => {
return await request.post({
url: `/ai/chat/analysis/test-fastgpt`,
data
})
},
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment