Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
KnowledgePlanet
road-map
xfg-frame-mvc
提交
dea18221
xfg-frame-mvc
项目概览
KnowledgePlanet
/
road-map
/
xfg-frame-mvc
通知
561
Star
28
Fork
25
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
xfg-frame-mvc
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
dea18221
编写于
10月 20, 2025
作者:
L
Linnea Lin
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 集成RagFlow AI助手功能
- 配置Retrofit客户端支持动态URL和认证拦截器 - 新增创建聊天和会话的API接口定义 - 实现从配置文件加载提示词模板的功能 - 添加不同类型提示词配置,并补充接口
上级
4194d522
变更
6
显示空白变更内容
内联
并排
Showing
6 changed file
with
183 addition
and
27 deletion
+183
-27
src/main/java/cn/bugstack/xfg/frame/config/Retrofit2Config.java
...in/java/cn/bugstack/xfg/frame/config/Retrofit2Config.java
+37
-21
src/main/java/cn/bugstack/xfg/frame/controller/UserController.java
...java/cn/bugstack/xfg/frame/controller/UserController.java
+44
-2
src/main/java/cn/bugstack/xfg/frame/service/IKnowledgeCenterService.java
...n/bugstack/xfg/frame/service/IKnowledgeCenterService.java
+28
-2
src/main/java/cn/bugstack/xfg/frame/service/IPromptService.java
...in/java/cn/bugstack/xfg/frame/service/IPromptService.java
+32
-0
src/main/resources/application.yml
src/main/resources/application.yml
+21
-1
target/classes/application.yml
target/classes/application.yml
+21
-1
未找到文件。
src/main/java/cn/bugstack/xfg/frame/config/Retrofit2Config.java
浏览文件 @
dea18221
...
...
@@ -3,46 +3,62 @@ package cn.bugstack.xfg.frame.config;
import
cn.bugstack.xfg.frame.service.IKnowledgeCenterService
;
import
lombok.extern.slf4j.Slf4j
;
import
okhttp3.OkHttpClient
;
import
okhttp3.Request
;
import
okhttp3.logging.HttpLoggingInterceptor
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
retrofit2.Retrofit
;
import
retrofit2.converter.jackson.JacksonConverterFactory
;
import
javax.annotation.Resource
;
import
java.util.concurrent.TimeUnit
;
@Slf4j
@Configuration
public
class
Retrofit2Config
{
private
static
final
String
BASE_URL
=
"https://demo.ragflow.io/"
;
@Resource
private
RagflowProperties
ragflowProperties
;
@Resource
private
AuthInterceptor
authInterceptor
;
@Bean
public
Retrofit
retrofit
()
{
// 创建日志拦截器
HttpLoggingInterceptor
loggingInterceptor
=
new
HttpLoggingInterceptor
(
new
HttpLoggingInterceptor
.
Logger
()
{
@Override
public
void
log
(
String
message
)
{
// 使用 SLF4J 记录日志,便于与 Spring Boot 日志系统集成
log
.
info
(
"Retrofit: {}"
,
message
);
return
new
Retrofit
.
Builder
()
.
baseUrl
(
ragflowProperties
.
getApi
().
getBaseUrl
())
.
client
(
createOkHttpClient
())
.
addConverterFactory
(
JacksonConverterFactory
.
create
()).
build
(
);
}
});
// 设置日志级别
private
OkHttpClient
createOkHttpClient
()
{
// 创建日志拦截器
HttpLoggingInterceptor
loggingInterceptor
=
new
HttpLoggingInterceptor
();
loggingInterceptor
.
setLevel
(
HttpLoggingInterceptor
.
Level
.
BODY
);
// 创建 OkHttpClient 并添加拦截器
OkHttpClient
okHttpClient
=
new
OkHttpClient
.
Builder
()
.
addInterceptor
(
loggingInterceptor
)
.
connectTimeout
(
30
,
TimeUnit
.
SECONDS
)
.
readTimeout
(
30
,
TimeUnit
.
SECONDS
)
.
writeTimeout
(
30
,
TimeUnit
.
SECONDS
)
// 创建请求头拦截器
okhttp3
.
Interceptor
headerInterceptor
=
chain
->
{
okhttp3
.
Request
originalRequest
=
chain
.
request
();
// 添加公共请求头
okhttp3
.
Request
newRequest
=
originalRequest
.
newBuilder
()
.
addHeader
(
"Content-Type"
,
"application/json"
)
.
addHeader
(
"Authorization"
,
"Bearer ragflow-IzZjQ5Y2ZhYWNkZjExZjA5MTA4MDI0Mm"
)
// 认证token
.
build
();
return
new
Retrofit
.
Builder
()
.
baseUrl
(
BASE_URL
)
.
client
(
okHttpClient
)
.
addConverterFactory
(
JacksonConverterFactory
.
create
()).
build
();
return
chain
.
proceed
(
newRequest
);
};
return
new
OkHttpClient
.
Builder
()
.
connectTimeout
(
30
,
TimeUnit
.
SECONDS
)
// 连接超时
.
readTimeout
(
30
,
TimeUnit
.
SECONDS
)
// 读取超时
.
writeTimeout
(
30
,
TimeUnit
.
SECONDS
)
// 写入超时
.
addInterceptor
(
headerInterceptor
)
// 添加请求头拦截器
.
addInterceptor
(
loggingInterceptor
)
// 添加日志拦截器
.
build
();
}
@Bean
...
...
src/main/java/cn/bugstack/xfg/frame/controller/UserController.java
浏览文件 @
dea18221
package
cn.bugstack.xfg.frame.controller
;
import
cn.bugstack.xfg.frame.common.AssistantType
;
import
cn.bugstack.xfg.frame.common.Result
;
import
cn.bugstack.xfg.frame.domain.req.CreateChatReq
;
import
cn.bugstack.xfg.frame.domain.req.CreateSessionReq
;
import
cn.bugstack.xfg.frame.domain.req.KeySensorCompletionReq
;
import
cn.bugstack.xfg.frame.domain.res.ChatIdRes
;
import
cn.bugstack.xfg.frame.domain.res.CompletionRes
;
import
cn.bugstack.xfg.frame.domain.res.SessionRes
;
import
cn.bugstack.xfg.frame.domain.res.UserRes
;
import
cn.bugstack.xfg.frame.domain.vo.UserVO
;
import
cn.bugstack.xfg.frame.service.IKnowledgeCenterService
;
import
cn.bugstack.xfg.frame.service.IPromptService
;
import
cn.bugstack.xfg.frame.service.IUserService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.web.bind.annotation.RequestMapping
;
...
...
@@ -44,13 +50,49 @@ public class UserController {
@RequestMapping
(
"/queryAI"
)
public
String
queryAI
()
throws
IOException
{
// todo 构建ai (提示词)
// 根据这里的key 拿到提示词位置
AssistantType
generalAssistant
=
AssistantType
.
fromConfigKey
(
"general"
);
// 获取这个type 对应的提示词
String
sysPrompt
=
IPromptService
.
loadPromptFromFile
(
generalAssistant
);
// 3. 构建 PromptConfig
CreateChatReq
.
PromptConfig
promptConfig
=
CreateChatReq
.
PromptConfig
.
builder
()
.
prompt
(
sysPrompt
)
.
build
();
// 5. 构建创建聊天请求
CreateChatReq
createChatReq
=
CreateChatReq
.
builder
()
.
name
(
generalAssistant
.
getDescription
()
+
" - "
+
System
.
currentTimeMillis
())
.
promptConfig
(
promptConfig
)
.
build
();
Call
<
ChatIdRes
>
chat
=
knowledgeCenterService
.
createChat
(
createChatReq
);
ChatIdRes
chatIdRes
=
chat
.
execute
().
body
();
log
.
info
(
"chatIdRes: {}"
,
chatIdRes
);
// ========================
log
.
info
(
"开始创建session"
);
CreateSessionReq
newSession
=
CreateSessionReq
.
builder
().
name
(
"new session"
).
build
();
Call
<
SessionRes
>
session
=
knowledgeCenterService
.
createSession
(
chatIdRes
.
getId
(),
newSession
);
SessionRes
sessionRes
=
session
.
execute
().
body
();
log
.
info
(
"sessionRes: {}"
,
sessionRes
);
log
.
info
(
"sessionId: {}"
,
sessionRes
.
getData
().
getId
());
log
.
info
(
"=======》成功拿到session"
);
// todo 根据上一步拿到的aichat id 创建一个session
// 构建请求参数
KeySensorCompletionReq
.
KeySensorCompletionReqBuilder
reqBuilder
=
KeySensorCompletionReq
.
builder
()
.
question
(
"
请给我一个5个字
"
)
.
question
(
"
hello
"
)
.
style
(
"normal"
);
Call
<
CompletionRes
>
call
=
knowledgeCenterService
.
getCompletions
(
"Bearer ragflow-djN2QwZjc0YTNlNzExZjBiYjBlNDIwMT"
,
reqBuilder
.
build
(),
"56a8f80aa85911f08a8a42010a8e0005"
);
Call
<
CompletionRes
>
call
=
knowledgeCenterService
.
getCompletions
(
reqBuilder
.
build
(),
sessionRes
.
getData
().
getId
()
);
CompletionRes
completionRes
=
call
.
execute
().
body
();
log
.
info
(
"completionRes: {}"
,
completionRes
);
return
"test"
;
...
...
src/main/java/cn/bugstack/xfg/frame/service/IKnowledgeCenterService.java
浏览文件 @
dea18221
package
cn.bugstack.xfg.frame.service
;
import
cn.bugstack.xfg.frame.domain.req.CreateChatReq
;
import
cn.bugstack.xfg.frame.domain.req.CreateSessionReq
;
import
cn.bugstack.xfg.frame.domain.req.KeySensorCompletionReq
;
import
cn.bugstack.xfg.frame.domain.res.ChatIdRes
;
import
cn.bugstack.xfg.frame.domain.res.CompletionRes
;
import
cn.bugstack.xfg.frame.domain.res.SessionRes
;
import
retrofit2.Call
;
import
retrofit2.http.*
;
public
interface
IKnowledgeCenterService
{
/**
* 创建聊天助手
*
* @param req 创建聊天请求参数
* @return 聊天 ID 响应
*/
@POST
(
"api/v1/chats"
)
Call
<
ChatIdRes
>
createChat
(
@Body
CreateChatReq
req
);
/**
* 创建会话
*
* @param chatId 聊天助手 ID
* @param req 创建会话请求参数
* @return 会话响应
*/
@POST
(
"api/v1/chats/{chat_id}/sessions"
)
Call
<
SessionRes
>
createSession
(
@Path
(
"chat_id"
)
String
chatId
,
@Body
CreateSessionReq
req
);
/**
* 对接 completion 接口
*
* @param authorization 认证头信息
* @param req 请求参数对象
* @param chat_id 聊天 ID
* @return 响应结果
*/
@POST
(
"api/v1/chats/{chat_id}/completions"
)
Call
<
CompletionRes
>
getCompletions
(
@Header
(
"Authorization"
)
String
authorization
,
@Body
KeySensorCompletionReq
req
,
@Path
(
"chat_id"
)
String
chat_id
);
...
...
src/main/java/cn/bugstack/xfg/frame/service/IPromptService.java
浏览文件 @
dea18221
package
cn.bugstack.xfg.frame.service
;
import
cn.bugstack.xfg.frame.common.AssistantType
;
import
cn.bugstack.xfg.frame.config.RagflowProperties
;
import
cn.bugstack.xfg.frame.domain.req.KSReq
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.util.StreamUtils
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.nio.charset.StandardCharsets
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -13,6 +21,7 @@ import java.util.stream.Collectors;
* @Description xx类
* @Date 2025/10/18
*/
@Slf4j
public
class
IPromptService
{
private
String
buildBatchPrompt
(
List
<
KSReq
>
ksReqs
){
StringBuilder
batchPrompt
=
new
StringBuilder
();
...
...
@@ -66,4 +75,27 @@ public class IPromptService {
,
otherContextIdStr
);
}
/**
* 从文件加载 prompt 内容
* @param assistantType 助手类型
* @return prompt 内容
*/
public
static
String
loadPromptFromFile
(
AssistantType
assistantType
)
{
try
{
String
promptFilePath
=
assistantType
.
getPromptFilePath
();
ClassPathResource
resource
=
new
ClassPathResource
(
promptFilePath
);
try
(
InputStream
inputStream
=
resource
.
getInputStream
())
{
String
content
=
StreamUtils
.
copyToString
(
inputStream
,
StandardCharsets
.
UTF_8
);
log
.
info
(
"成功加载 {} 助手的 prompt 模板,文件路径: {}"
,
assistantType
.
getDescription
(),
promptFilePath
);
return
content
;
}
}
catch
(
IOException
e
)
{
log
.
error
(
"加载 {} 助手的 prompt 模板失败: {}"
,
assistantType
.
getDescription
(),
e
.
getMessage
());
throw
new
RuntimeException
(
"加载 prompt 模板失败"
,
e
);
}
}
}
src/main/resources/application.yml
浏览文件 @
dea18221
...
...
@@ -11,3 +11,23 @@ spring:
mybatis
:
mapper-locations
:
classpath:/mybatis/mapper/*.xml
config-location
:
classpath:/mybatis/config/mybatis-config.xml
# RagFlow 配置
ragflow
:
api
:
base-url
:
http://47.107.166.69/
api-key
:
ragflow-IzZjQ5Y2ZhYWNkZjExZjA5MTA4MDI0Mm
prompts
:
general
:
file
:
prompts/general-assistant.txt
opener
:
"
Hi!
I'm
your
general
assistant.
What
can
I
help
you
with
today?"
empty-response
:
"
Sorry!
No
relevant
content
was
found
in
the
knowledge
base!"
technical
:
file
:
prompts/technical-assistant.txt
opener
:
"
Hello!
I'm
your
technical
assistant.
What
technical
question
can
I
help
you
solve?"
empty-response
:
"
Sorry!
No
relevant
technical
information
was
found
in
the
knowledge
base!"
customer-service
:
file
:
prompts/customer-service.txt
opener
:
"
Hello!
Welcome
to
our
customer
service.
How
may
I
assist
you
today?"
empty-response
:
"
Sorry!
I
couldn't
find
relevant
information
to
help
with
your
inquiry.
Please
contact
our
support
team
for
further
assistance."
\ No newline at end of file
target/classes/application.yml
浏览文件 @
dea18221
...
...
@@ -11,3 +11,23 @@ spring:
mybatis
:
mapper-locations
:
classpath:/mybatis/mapper/*.xml
config-location
:
classpath:/mybatis/config/mybatis-config.xml
# RagFlow 配置
ragflow
:
api
:
base-url
:
http://47.107.166.69/
api-key
:
ragflow-IzZjQ5Y2ZhYWNkZjExZjA5MTA4MDI0Mm
prompts
:
general
:
file
:
prompts/general-assistant.txt
opener
:
"
Hi!
I'm
your
general
assistant.
What
can
I
help
you
with
today?"
empty-response
:
"
Sorry!
No
relevant
content
was
found
in
the
knowledge
base!"
technical
:
file
:
prompts/technical-assistant.txt
opener
:
"
Hello!
I'm
your
technical
assistant.
What
technical
question
can
I
help
you
solve?"
empty-response
:
"
Sorry!
No
relevant
technical
information
was
found
in
the
knowledge
base!"
customer-service
:
file
:
prompts/customer-service.txt
opener
:
"
Hello!
Welcome
to
our
customer
service.
How
may
I
assist
you
today?"
empty-response
:
"
Sorry!
I
couldn't
find
relevant
information
to
help
with
your
inquiry.
Please
contact
our
support
team
for
further
assistance."
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录