Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
elleai
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tech
E
ellehuis-group
backend
elleai
Commits
012c8d80
Commit
012c8d80
authored
Oct 30, 2024
by
陈立彬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AI问答改为流式响应
parent
fdb9dd91
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
36 deletions
+76
-36
pom.xml
pom.xml
+4
-1
AppChatCompletionService.java
.../elleai/application/service/AppChatCompletionService.java
+61
-29
ChatCompletionMobileController.java
...leai/controller/front/ChatCompletionMobileController.java
+11
-6
No files found.
pom.xml
View file @
012c8d80
...
...
@@ -192,7 +192,10 @@
<artifactId>
activation
</artifactId>
<version>
1.1.1
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
<artifactId>
spring-boot-starter-webflux
</artifactId>
</dependency>
</dependencies>
<build>
...
...
src/main/java/cn/breeze/elleai/application/service/AppChatCompletionService.java
View file @
012c8d80
...
...
@@ -2,35 +2,38 @@ package cn.breeze.elleai.application.service;
import
cn.breeze.elleai.application.dto.PageResult
;
import
cn.breeze.elleai.application.dto.inner.AiChatComplateResultDto
;
import
cn.breeze.elleai.application.dto.inner.AiSingleEvaluateResultDto
;
import
cn.breeze.elleai.application.dto.request.*
;
import
cn.breeze.elleai.application.dto.response.*
;
import
cn.breeze.elleai.domain.sparring.model.request.QaAssistantRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.request.QaAssistantSaveModel
;
import
cn.breeze.elleai.domain.sparring.model.request.UserChatCompletionSaveModel
;
import
cn.breeze.elleai.domain.sparring.model.request.UserQaRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.response.*
;
import
cn.breeze.elleai.domain.sparring.model.response.KbTagResponseModel
;
import
cn.breeze.elleai.domain.sparring.model.response.QaAssistantResponseModel
;
import
cn.breeze.elleai.domain.sparring.model.response.UserChatCompletionHistoryResponseModel
;
import
cn.breeze.elleai.domain.sparring.model.response.UserChatCompletionResponseModel
;
import
cn.breeze.elleai.domain.sparring.service.ChatCompletionService
;
import
cn.breeze.elleai.domain.sparring.service.KbService
;
import
cn.breeze.elleai.domain.sparring.service.KbTagService
;
import
cn.breeze.elleai.util.UserPrincipal
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.
lang.UUID
;
import
cn.hutool.core.
util.ObjectUtil
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mybatisflex.core.paginate.Page
;
import
jakarta.annotation.PostConstruct
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
import
org.springframework.http.*
;
import
org.springframework.http.codec.ServerSentEvent
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.reactive.function.client.WebClient
;
import
reactor.core.publisher.Flux
;
import
java.util.*
;
import
java.util.concurrent.TimeUnit
;
import
java.util.stream.Collectors
;
...
...
@@ -56,6 +59,17 @@ public class AppChatCompletionService {
private
final
KbTagService
kbTagService
;
private
WebClient
webClient
;
@PostConstruct
public
void
init
()
{
webClient
=
WebClient
.
builder
().
baseUrl
(
difyBase
)
.
defaultHeader
(
HttpHeaders
.
CONTENT_TYPE
,
MediaType
.
APPLICATION_JSON_VALUE
)
.
defaultHeader
(
HttpHeaders
.
AUTHORIZATION
,
"Bearer "
+
apiKey
)
.
defaultHeader
(
HttpHeaders
.
CACHE_CONTROL
,
"no-cache"
)
.
build
();
}
/************************************************** AI助手 **************************************************/
...
...
@@ -315,9 +329,7 @@ public class AppChatCompletionService {
* @param request
* @return
*/
public
UserAskResultMobileDto
userAsk
(
UserPrincipal
userPrincipal
,
UserQaMobileRequestDto
request
)
{
UserAskResultMobileDto
result
=
new
UserAskResultMobileDto
();
public
Flux
<
ServerSentEvent
<
UserAskResultMobileDto
>>
userAsk
(
UserPrincipal
userPrincipal
,
UserQaMobileRequestDto
request
)
{
// 获取会话详情
UserQaRequestModel
requestModel
=
new
UserQaRequestModel
();
requestModel
.
setChatCompletionId
(
request
.
getChatCompletionId
());
...
...
@@ -347,29 +359,49 @@ public class AppChatCompletionService {
// 保存问答详情
chatCompletionService
.
saveUserQaRecord
(
recordId
,
0
,
request
.
getContent
(),
request
.
getAssistantId
());
// 问一下AI
AiChatComplateResultDto
complateResultDto
=
ask4Knowledge
(
sessionId
,
userPrincipal
.
getUserId
(),
request
.
getContent
(),
request
.
getAssistantId
());
if
(
Objects
.
nonNull
(
complateResultDto
))
{
String
replyContent
=
complateResultDto
.
getContent
();
// 更新DIFY会话ID
if
(
StrUtil
.
isEmpty
(
sessionId
))
{
UserChatCompletionSaveModel
updateModel
=
new
UserChatCompletionSaveModel
();
updateModel
.
setId
(
recordId
);
updateModel
.
setSessionId
(
sessionId
);
chatCompletionService
.
saveUserQaSession
(
updateModel
);
}
// 保存AI问答详情
chatCompletionService
.
saveUserQaRecord
(
recordId
,
1
,
replyContent
,
request
.
getAssistantId
());
Map
<
String
,
String
>
inputs
=
new
HashMap
<>();
inputs
.
put
(
"assistant_id"
,
Objects
.
nonNull
(
request
.
getAssistantId
())
?
String
.
valueOf
(
request
.
getAssistantId
())
:
""
);
JSONObject
param
=
new
JSONObject
();
param
.
put
(
"query"
,
request
.
getContent
());
param
.
put
(
"inputs"
,
inputs
);
param
.
put
(
"response_mode"
,
"streaming"
);
param
.
put
(
"conversation_id"
,
sessionId
);
param
.
put
(
"user"
,
userPrincipal
.
getUserId
());
final
StringBuffer
buffer
=
new
StringBuffer
();
final
String
[]
difySessionId
=
{
""
};
String
finalSessionId
=
sessionId
;
return
webClient
.
post
().
uri
(
"/chat-messages"
).
accept
(
MediaType
.
TEXT_EVENT_STREAM
).
bodyValue
(
param
.
toJSONString
()).
exchangeToFlux
(
r
->
r
.
bodyToFlux
(
String
.
class
))
.
mapNotNull
(
v
->
{
JSONObject
json
=
JSONObject
.
parseObject
(
v
);
String
answer
=
json
.
getString
(
"answer"
);
if
(
ObjectUtil
.
isNotNull
(
answer
))
{
buffer
.
append
(
answer
);
}
if
(
ObjectUtil
.
isEmpty
(
difySessionId
[
0
])
&&
ObjectUtil
.
isNotEmpty
(
json
.
getString
(
"conversation_id"
)))
{
difySessionId
[
0
]
=
json
.
getString
(
"conversation_id"
);
}
result
.
setChatCompletionId
(
recordId
);
result
.
setReplyContent
(
replyContent
);
}
return
result
;
UserAskResultMobileDto
result
=
new
UserAskResultMobileDto
();
result
.
setReplyContent
(
buffer
.
toString
());
result
.
setChatCompletionId
(
recordId
);
return
result
;
}).
doOnComplete
(
()
->
{
String
replyContent
=
buffer
.
toString
();
// 更新DIFY会话ID
if
(
StrUtil
.
isEmpty
(
finalSessionId
))
{
UserChatCompletionSaveModel
updateModel
=
new
UserChatCompletionSaveModel
();
updateModel
.
setId
(
recordId
);
updateModel
.
setSessionId
(
difySessionId
[
0
]);
chatCompletionService
.
saveUserQaSession
(
updateModel
);
}
// 保存AI问答详情
chatCompletionService
.
saveUserQaRecord
(
recordId
,
1
,
replyContent
,
request
.
getAssistantId
());
}
).
map
(
v
->
ServerSentEvent
.
builder
(
v
).
build
());
}
/**
* 新会话
* @return
...
...
src/main/java/cn/breeze/elleai/controller/front/ChatCompletionMobileController.java
View file @
012c8d80
...
...
@@ -3,19 +3,25 @@ package cn.breeze.elleai.controller.front;
import
cn.breeze.elleai.application.dto.ApiResponse
;
import
cn.breeze.elleai.application.dto.PageResult
;
import
cn.breeze.elleai.application.dto.request.*
;
import
cn.breeze.elleai.application.dto.inner.AiChatComplateResultDto
;
import
cn.breeze.elleai.application.dto.request.QaAssistantRequestDto
;
import
cn.breeze.elleai.application.dto.request.SwitchAssistantMobileRequestDto
;
import
cn.breeze.elleai.application.dto.request.UserQaHistoryRequestDto
;
import
cn.breeze.elleai.application.dto.request.UserQaMobileRequestDto
;
import
cn.breeze.elleai.application.dto.response.*
;
import
cn.breeze.elleai.application.service.AppChatCompletionService
;
import
cn.breeze.elleai.application.service.AppCommonService
;
import
cn.breeze.elleai.config.QueryParam
;
import
cn.breeze.elleai.util.UserPrincipal
;
import
com.alibaba.fastjson.JSON
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.Parameter
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.codec.ServerSentEvent
;
import
org.springframework.web.bind.annotation.*
;
import
reactor.core.publisher.Flux
;
@RestController
@RequestMapping
(
value
=
"/front/chat"
)
...
...
@@ -51,11 +57,10 @@ public class ChatCompletionMobileController {
@Operation
(
summary
=
"用户提问"
)
@PostMapping
(
"/ask"
)
public
ApiResponse
<
UserAskResultMobileDto
>
ask
(
@Parameter
(
hidden
=
true
)
UserPrincipal
userPrincipal
,
@RequestBody
UserQaMobileRequestDto
request
)
{
public
Flux
<
ServerSentEvent
<
UserAskResultMobileDto
>>
ask
(
@Parameter
(
hidden
=
true
)
UserPrincipal
userPrincipal
,
@RequestBody
UserQaMobileRequestDto
request
)
{
request
.
setContent
(
commonService
.
sentenceWordCorrect
(
request
.
getContent
()));
UserAskResultMobileDto
result
=
chatCompletionService
.
userAsk
(
userPrincipal
,
request
);
return
ApiResponse
.
ok
(
result
);
return
chatCompletionService
.
userAsk
(
userPrincipal
,
request
);
}
@Operation
(
summary
=
"切换助手"
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment