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
ee350b41
Commit
ee350b41
authored
Oct 18, 2024
by
陈立彬
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
AI对练、AI问答扩展
parent
c5c894d5
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
846 additions
and
122 deletions
+846
-122
AiSingleEvaluateResultDto.java
...leai/application/dto/inner/AiSingleEvaluateResultDto.java
+22
-0
ExamineBusinessCacheDto.java
...elleai/application/dto/inner/ExamineBusinessCacheDto.java
+49
-0
AiPlatformExtensionService.java
...lleai/application/service/AiPlatformExtensionService.java
+120
-0
AppChatCompletionService.java
.../elleai/application/service/AppChatCompletionService.java
+63
-14
AppExamineService.java
.../breeze/elleai/application/service/AppExamineService.java
+273
-75
CorsConfig.java
src/main/java/cn/breeze/elleai/config/CorsConfig.java
+1
-1
Knife4jConfiguration.java
...in/java/cn/breeze/elleai/config/Knife4jConfiguration.java
+1
-1
Swagger2Config.java
src/main/java/cn/breeze/elleai/config/Swagger2Config.java
+1
-1
AiPlatformExtensionController.java
...i/controller/extension/AiPlatformExtensionController.java
+29
-0
ChatCompletionMobileController.java
...leai/controller/front/ChatCompletionMobileController.java
+11
-0
ExamineMobileController.java
...eeze/elleai/controller/front/ExamineMobileController.java
+3
-1
ExamineRecordDetailSaveModel.java
.../sparring/model/request/ExamineRecordDetailSaveModel.java
+47
-0
ExamineRecordSaveModel.java
...domain/sparring/model/request/ExamineRecordSaveModel.java
+79
-0
UserChatCompletionSaveModel.java
...n/sparring/model/request/UserChatCompletionSaveModel.java
+55
-0
ExamineRecordResponseModel.java
...n/sparring/model/response/ExamineRecordResponseModel.java
+5
-0
ChatCompletionService.java
...elleai/domain/sparring/service/ChatCompletionService.java
+5
-6
ChatCompletionServiceImpl.java
...ai/domain/sparring/service/ChatCompletionServiceImpl.java
+17
-9
ExamineService.java
...breeze/elleai/domain/sparring/service/ExamineService.java
+7
-1
ExamineServiceImpl.java
...ze/elleai/domain/sparring/service/ExamineServiceImpl.java
+34
-7
UserExamineRecordEntity.java
...n/breeze/elleai/infra/entity/UserExamineRecordEntity.java
+5
-0
UserExamineRecordTableDef.java
.../elleai/infra/entity/table/UserExamineRecordTableDef.java
+7
-1
application.yml
src/main/resources/application.yml
+2
-2
application.yml
target/classes/application.yml
+10
-3
No files found.
src/main/java/cn/breeze/elleai/application/dto/inner/AiSingleEvaluateResultDto.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
application
.
dto
.
inner
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.io.Serializable
;
/**
* AI单题点评结果
*/
@Data
public
class
AiSingleEvaluateResultDto
implements
Serializable
{
@Schema
(
description
=
"评分"
)
private
Float
score
;
@Schema
(
description
=
"评价"
)
private
String
evaluation
;
@Schema
(
description
=
"DIFY会话ID"
)
private
String
difySessionId
;;
}
src/main/java/cn/breeze/elleai/application/dto/inner/ExamineBusinessCacheDto.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
application
.
dto
.
inner
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.Data
;
import
java.io.Serializable
;
/**
* 考试流水缓存
*/
@Data
public
class
ExamineBusinessCacheDto
implements
Serializable
{
/**
* 考试ID
*/
@Schema
(
description
=
"考试ID"
)
private
Integer
examineId
;
/**
* 对练模式(0练习 1对练)
*/
@Schema
(
description
=
"对练模式(0练习 1对练)"
)
private
Integer
examineMode
;
/**
* 用户ID
*/
@Schema
(
description
=
"用户ID"
)
private
String
userId
;
/**
* 考试记录ID
*/
@Schema
(
description
=
"考试记录ID"
)
private
Integer
recordId
;
/**
* 当前题目ID
*/
@Schema
(
description
=
"当前题目ID"
)
private
Integer
currentQuestionId
;
/**
* 是否有下一题
*/
@Schema
(
description
=
"是否有下一题"
)
private
boolean
hasNext
;
}
src/main/java/cn/breeze/elleai/application/service/AiPlatformExtensionService.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
application
.
service
;
import
cn.breeze.elleai.application.dto.inner.AiSingleEvaluateResultDto
;
import
com.alibaba.fastjson2.JSONObject
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.http.*
;
import
org.springframework.scheduling.annotation.Async
;
import
org.springframework.stereotype.Component
;
import
org.springframework.web.client.RestTemplate
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
/**
* AI平台扩展服务
*/
@Slf4j
@Component
@RequiredArgsConstructor
public
class
AiPlatformExtensionService
{
@Value
(
"${dify.api_base}"
)
private
String
difyBase
;
@Value
(
"${dify.api_key}"
)
private
String
apiKey
;
private
final
RestTemplate
restTemplate
=
new
RestTemplate
();
/**
* 单题评分+点评
* @param sessionId
* @param userId
* @param question
* @param answer
* @param userAnswer
*/
public
AiSingleEvaluateResultDto
run4SingleEvaluate
(
String
sessionId
,
String
userId
,
String
question
,
String
answer
,
String
userAnswer
)
{
Map
<
String
,
String
>
inputs
=
new
HashMap
<>();
inputs
.
put
(
"scene"
,
"single_evaluate"
);
inputs
.
put
(
"question"
,
question
);
inputs
.
put
(
"answer"
,
answer
);
JSONObject
param
=
new
JSONObject
();
param
.
put
(
"query"
,
userAnswer
);
param
.
put
(
"inputs"
,
inputs
);
param
.
put
(
"response_mode"
,
"blocking"
);
param
.
put
(
"conversation_id"
,
""
);
param
.
put
(
"user"
,
userId
);
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
headers
.
setBearerAuth
(
apiKey
);
log
.
info
(
"异步请求参数1,sessionId = {}"
,
sessionId
);
log
.
info
(
"异步请求参数2,req = {}"
,
JSONObject
.
toJSONString
(
param
));
HttpEntity
<
String
>
postEntity
=
new
HttpEntity
<>(
param
.
toJSONString
(),
headers
);
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
difyBase
+
"/chat-messages"
,
postEntity
,
String
.
class
);
String
body
=
response
.
getBody
();
log
.
info
(
"执行结果:{}"
,
body
);
if
(
Objects
.
equals
(
response
.
getStatusCode
(),
HttpStatus
.
OK
))
{
JSONObject
bodyObject
=
JSONObject
.
parseObject
(
body
);
String
conversationId
=
bodyObject
.
getString
(
"conversation_id"
);
JSONObject
answerObject
=
JSONObject
.
parseObject
(
bodyObject
.
getString
(
"answer"
));
Float
score
=
answerObject
.
getFloat
(
"score"
);
String
evaluation
=
answerObject
.
getString
(
"evaluation"
);
AiSingleEvaluateResultDto
result
=
new
AiSingleEvaluateResultDto
();
result
.
setEvaluation
(
evaluation
);
result
.
setScore
(
score
);
result
.
setDifySessionId
(
conversationId
);
return
result
;
}
return
null
;
}
/**
* 考试总点评
* @param sessionId
* @param userId
* @param avgScore
* @param qaResultList
*/
public
String
run4TotalEvaluate
(
String
sessionId
,
String
userId
,
Float
avgScore
,
List
qaResultList
)
{
Map
<
String
,
Object
>
inputs
=
new
HashMap
<>();
inputs
.
put
(
"scene"
,
"total_evaluate"
);
inputs
.
put
(
"avg_score"
,
avgScore
);
inputs
.
put
(
"qa_result_list"
,
qaResultList
);
JSONObject
param
=
new
JSONObject
();
param
.
put
(
"query"
,
"Not_Null"
);
param
.
put
(
"inputs"
,
inputs
);
param
.
put
(
"response_mode"
,
"blocking"
);
param
.
put
(
"conversation_id"
,
""
);
param
.
put
(
"user"
,
userId
);
HttpHeaders
headers
=
new
HttpHeaders
();
headers
.
setContentType
(
MediaType
.
APPLICATION_JSON
);
headers
.
setBearerAuth
(
apiKey
);
log
.
info
(
"异步请求参数1,sessionId = {}"
,
sessionId
);
log
.
info
(
"异步请求参数2,req = {}"
,
JSONObject
.
toJSONString
(
param
));
HttpEntity
<
String
>
postEntity
=
new
HttpEntity
<>(
param
.
toJSONString
(),
headers
);
ResponseEntity
<
String
>
response
=
restTemplate
.
postForEntity
(
difyBase
+
"/chat-messages"
,
postEntity
,
String
.
class
);
String
body
=
response
.
getBody
();
log
.
info
(
"执行结果:{}"
,
body
);
if
(
Objects
.
equals
(
response
.
getStatusCode
(),
HttpStatus
.
OK
))
{
JSONObject
bodyObject
=
JSONObject
.
parseObject
(
body
);
String
conversationId
=
bodyObject
.
getString
(
"conversation_id"
);
JSONObject
answerObject
=
JSONObject
.
parseObject
(
bodyObject
.
getString
(
"answer"
));
String
evaluation
=
answerObject
.
getString
(
"evaluation"
);
return
evaluation
;
}
return
null
;
}
}
src/main/java/cn/breeze/elleai/application/service/AppChatCompletionService.java
View file @
ee350b41
...
...
@@ -5,7 +5,7 @@ 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.User
QaHistoryRequest
Model
;
import
cn.breeze.elleai.domain.sparring.model.request.User
ChatCompletionSave
Model
;
import
cn.breeze.elleai.domain.sparring.model.request.UserQaRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.response.QaAssistantResponseModel
;
import
cn.breeze.elleai.domain.sparring.model.response.UserChatCompletionHistoryResponseModel
;
...
...
@@ -14,6 +14,7 @@ import cn.breeze.elleai.domain.sparring.service.ChatCompletionService;
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.StrUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mybatisflex.core.paginate.Page
;
...
...
@@ -259,29 +260,77 @@ public class AppChatCompletionService {
}
/**
* AI问答会话分页查询
* 移动端历史会话明细
* @param userPrincipal
* @param chatCompletionId
* @param pageNo
* @param pageSize
* @return
*/
public
PageResult
<
UserChatCompletionHistoryMobileDto
>
userQaHistoryMobilePaginQuery
(
UserPrincipal
userPrincipal
,
Integer
chatCompletionId
,
Integer
pageNo
,
Integer
pageSize
)
{
pageNo
=
Objects
.
isNull
(
pageNo
)
?
1
:
pageNo
;
pageSize
=
Objects
.
isNull
(
pageSize
)
?
10
:
pageSize
;
UserQaRequestDto
req
=
new
UserQaRequestDto
();
req
.
setUserId
(
userPrincipal
.
getUserId
());
Page
<
UserChatCompletionHistoryResponseModel
>
historyDetailPageResult
=
chatCompletionService
.
userQaHistoryDetailPaginQuery
(
chatCompletionId
,
pageNo
,
pageSize
);
PageResult
<
UserChatCompletionHistoryMobileDto
>
pageResult
=
PageResult
.
of
(
pageNo
,
pageSize
,
(
int
)
historyDetailPageResult
.
getTotalRow
(),
null
);
if
(
Objects
.
nonNull
(
historyDetailPageResult
)
&&
CollectionUtil
.
isNotEmpty
(
historyDetailPageResult
.
getRecords
()))
{
List
<
UserChatCompletionHistoryMobileDto
>
items
=
historyDetailPageResult
.
getRecords
().
stream
().
map
(
v
->
{
UserChatCompletionHistoryMobileDto
dto
=
BeanUtil
.
copyProperties
(
v
,
UserChatCompletionHistoryMobileDto
.
class
);
return
dto
;
}).
collect
(
Collectors
.
toList
());
pageResult
.
setItems
(
items
);
}
return
pageResult
;
}
/**
* 用户提问
* @param request
* @return
*/
public
UserAskResultMobileDto
userAsk
(
UserPrincipal
userPrincipal
,
UserQaMobileRequestDto
request
)
{
//TODO 生成sessionId
UserAskResultMobileDto
result
=
new
UserAskResultMobileDto
();
result
.
setChatCompletionId
(
1
);
result
.
setReplyContent
(
"moke ai reply."
);
// 更新问答记录
// Integer recordId = chatCompletionService.saveUserQaSession(request.getUserId(), request.getSessionId());
//
// // 保存问答详情
// String content = request.getContent();
// chatCompletionService.saveUserQaRecord(recordId, 0, content);
//
// return ask4Knowledge(request.getSessionId(), request.getUserId(), content);
// 更新会话信息
UserChatCompletionSaveModel
saveModel
=
new
UserChatCompletionSaveModel
();
saveModel
.
setUserId
(
userPrincipal
.
getUserId
());
saveModel
.
setUserName
(
userPrincipal
.
getUserName
());
saveModel
.
setId
(
request
.
getChatCompletionId
());
saveModel
.
setLastQuestion
(
request
.
getContent
());
saveModel
.
setShopId
(
userPrincipal
.
getShopId
());
saveModel
.
setShopName
(
userPrincipal
.
getShopName
());
// 首次提问
if
(
Objects
.
isNull
(
request
.
getChatCompletionId
()))
{
saveModel
.
setCreateTime
(
new
Date
());
saveModel
.
setFirstQuestion
(
request
.
getContent
());
saveModel
.
setSessionId
(
UUID
.
randomUUID
().
toString
());
}
Integer
recordId
=
chatCompletionService
.
saveUserQaSession
(
saveModel
);
// 保存问答详情
chatCompletionService
.
saveUserQaRecord
(
recordId
,
0
,
request
.
getContent
());
// 问一下AI
String
replyContent
=
ask4Knowledge
(
saveModel
.
getSessionId
(),
saveModel
.
getUserId
(),
request
.
getContent
());
// 保存AI问答详情
chatCompletionService
.
saveUserQaRecord
(
recordId
,
1
,
replyContent
);
result
.
setChatCompletionId
(
recordId
);
result
.
setReplyContent
(
replyContent
);
return
result
;
}
public
String
ask4Knowledge
(
String
sessionId
,
String
userId
,
String
question
)
{
if
(
true
)
{
return
"moke ai reply."
;
}
...
...
src/main/java/cn/breeze/elleai/application/service/AppExamineService.java
View file @
ee350b41
...
...
@@ -2,19 +2,24 @@ package cn.breeze.elleai.application.service;
import
cn.breeze.elleai.application.dto.ApiResponse
;
import
cn.breeze.elleai.application.dto.PageResult
;
import
cn.breeze.elleai.application.dto.inner.AiSingleEvaluateResultDto
;
import
cn.breeze.elleai.application.dto.inner.ExamineBusinessCacheDto
;
import
cn.breeze.elleai.application.dto.request.*
;
import
cn.breeze.elleai.application.dto.response.*
;
import
cn.breeze.elleai.domain.sparring.model.request.*
;
import
cn.breeze.elleai.domain.sparring.model.response.*
;
import
cn.breeze.elleai.domain.sparring.service.ExamineService
;
import
cn.breeze.elleai.exception.InternalException
;
import
cn.breeze.elleai.util.UserPrincipal
;
import
cn.hutool.core.bean.BeanUtil
;
import
cn.hutool.core.collection.CollectionUtil
;
import
cn.hutool.core.lang.Assert
;
import
cn.hutool.core.lang.UUID
;
import
cn.hutool.core.util.StrUtil
;
import
com.alibaba.fastjson.JSONObject
;
import
com.mybatisflex.core.paginate.Page
;
import
io.micrometer.common.util.StringUtils
;
import
io.swagger.v3.oas.annotations.media.Schema
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.data.redis.core.StringRedisTemplate
;
...
...
@@ -28,6 +33,7 @@ import java.util.*;
import
java.util.concurrent.TimeUnit
;
import
java.util.function.Function
;
import
java.util.stream.Collectors
;
import
java.util.stream.IntStream
;
import
static
java
.
util
.
stream
.
Collectors
.
toMap
;
...
...
@@ -40,21 +46,17 @@ import static java.util.stream.Collectors.toMap;
@RequiredArgsConstructor
public
class
AppExamineService
{
private
static
String
EXAM_
REDIS_QUESTION_KEY
=
"EXAM_MASTER_QUESTION:%s:%s"
;
private
static
String
EXAM_
BUSINESS_REDIS_KEY
=
"examine:business:%s"
;
// 考试流水缓存信息(businessNo)
private
static
String
EXAM_
REDIS_SESSION_KEY
=
"EXAM_MASTER_SESSION:%d:%d:%s"
;
private
static
String
EXAM_
AI_TASK_REDIS_KEY
=
"examine:ai_task:%s"
;
// 考试AI点评任务执行状态(businessNo)
private
static
String
EXAM_REDIS_CAS_KEY
=
"EXAM_MASTER_CURRENT_AI_SCORE:%d:%s"
;
private
static
String
USER_SESSION_CONTEXT_KEY
=
"USER_SESSION_CONTEXT:%d:%s:%s"
;
private
static
String
USER_SESSION_CONTEXT_COUNT
=
"USER_SESSION_CONTEXT_COUNT"
;
private
final
ExamineService
examineService
;
private
final
StringRedisTemplate
redisTemplate
;
private
final
AiPlatformExtensionService
extensionService
;
/************************************************** 场景分类 **************************************************/
...
...
@@ -394,14 +396,14 @@ public class AppExamineService {
/**
* QA列表查询
* @param
request
* @param
examineId
* @return
*/
public
List
<
ExamineQaDto
>
examineQaList
(
ExamineQaRequestModel
request
)
{
public
List
<
ExamineQaDto
>
examineQaList
(
Integer
examineId
)
{
List
<
ExamineQaDto
>
resultList
=
new
ArrayList
<>();
List
<
ExamineQaResponseModel
>
modelList
=
examineService
.
examineQaList
(
request
);
List
<
ExamineQaResponseModel
>
modelList
=
examineService
.
examineQaList
(
examineId
);
if
(
CollectionUtil
.
isNotEmpty
(
modelList
))
{
resultList
=
modelList
.
stream
().
map
(
v
->
{
...
...
@@ -473,7 +475,7 @@ public class AppExamineService {
examTotalCount
=
recordList
.
size
();
practiceCount
=
examTotalCount
-
examTotalCount
;
maxOverallScore
=
recordList
.
stream
().
mapToDouble
(
ExamineRecordResponseModel:
:
getOverallScore
).
max
().
getAsDouble
();
maxOverallScore
=
recordList
.
stream
().
filter
(
v
->
Objects
.
nonNull
(
v
.
getOverallScore
())).
mapToDouble
(
ExamineRecordResponseModel:
:
getOverallScore
).
max
().
getAsDouble
();
}
result
.
setExamCount
(
examCount
);
result
.
setPracticeCount
(
practiceCount
);
...
...
@@ -995,92 +997,288 @@ public class AppExamineService {
/************************************************** 移动端对练 **************************************************/
public
ExamineQaDifyDto
getCurrentQuestion
(
Integer
examineId
,
String
sessionId
,
String
userId
)
{
ExamineQaDifyDto
result
=
new
ExamineQaDifyDto
();
/**
* 开始考试,并返回考试流水号&第一道题目
* @param userPrincipal
* @param request
* @return
*/
public
ExamineStartResultDto
startExamine
(
UserPrincipal
userPrincipal
,
StartExamineMobileRequestDto
request
)
{
String
userId
=
userPrincipal
.
getUserId
();
String
redisKey
=
String
.
format
(
EXAM_REDIS_QUESTION_KEY
,
sessionId
,
userId
);
Integer
examineId
=
request
.
getExamineId
();
Integer
examineMode
=
request
.
getExamineMode
();
String
businessNo
=
UUID
.
randomUUID
().
toString
();
String
currentQuestion
=
redisTemplate
.
opsForValue
().
get
(
redisKey
);
ExamineStartResultDto
result
=
new
ExamineStartResultDto
();
result
.
setBusinessNo
(
businessNo
);
log
.
info
(
"获取当前出题,rediskey = {}, value = {}"
,
redisKey
,
currentQuestion
);
if
(
StringUtils
.
isNotEmpty
(
currentQuestion
))
{
// 获取缓存考试会话信息
String
examBusinessKey
=
String
.
format
(
EXAM_BUSINESS_REDIS_KEY
,
businessNo
);
ExamineBusinessCacheDto
businessCache
=
getExamBusinessCache
(
businessNo
);
if
(
Objects
.
isNull
(
businessCache
))
{
ExamineQaResponseModel
model
=
examineService
.
examineQaDetail
(
Integer
.
valueOf
(
currentQuestion
));
if
(
Objects
.
nonNull
(
model
))
{
ExamineSceneCategoryResponseModel
category
=
examineService
.
sceneCategoryDetail
(
model
.
getCategoryId
());
businessCache
=
new
ExamineBusinessCacheDto
();
businessCache
.
setExamineId
(
examineId
);
businessCache
.
setExamineMode
(
examineMode
);
businessCache
.
setUserId
(
userId
);
}
// 当前出题
Integer
currentQuestionId
=
businessCache
.
getCurrentQuestionId
();
if
(
Objects
.
isNull
(
currentQuestionId
))
{
List
<
ExamineQaResponseModel
>
examineQaList
=
examineService
.
examineQaList
(
examineId
);
if
(
CollectionUtil
.
isNotEmpty
(
examineQaList
))
{
ExamineQaResponseModel
model
=
examineQaList
.
get
(
0
);
currentQuestionId
=
model
.
getId
();
result
.
setQuestionId
(
currentQuestionId
);
result
.
setQuestion
(
model
.
getQuestion
());
result
.
setAnswer
(
model
.
getAnswer
());
result
.
setProject
(
category
.
getName
());
result
.
setCode
(
category
.
getName
());
result
.
setQuestionId
(
model
.
getId
());
result
.
setNext
(
true
);
// 保存题目信息?
result
.
setNext
(
examineQaList
.
size
()
>
1
?
true
:
false
);
businessCache
.
setCurrentQuestionId
(
currentQuestionId
);
businessCache
.
setHasNext
(
result
.
isNext
());
}
}
// 缓存
redisTemplate
.
opsForValue
().
set
(
examBusinessKey
,
JSONObject
.
toJSONString
(
businessCache
),
1
,
TimeUnit
.
DAYS
);
return
result
;
}
/**
*
开始考试,获取出
题
* @param
examineId
* @param
userId
* @param
examineMode
*
获取下一
题
* @param
userPrincipal
* @param
examineId 对练ID
* @param
businessNo 考试流水号
* @return
*/
public
ExamineStartResultDto
startExamine
(
UserPrincipal
userPrincipal
,
StartExamineMobileRequestDto
request
)
{
public
ExamineStartResultDto
getNextQuestion
(
UserPrincipal
userPrincipal
,
Integer
examineId
,
String
businessNo
)
{
String
userId
=
userPrincipal
.
getUserId
();
ExamineStartResultDto
result
=
new
ExamineStartResultDto
();
result
.
setBusinessNo
(
businessNo
);
// 获取缓存考试会话信息
String
examBusinessKey
=
String
.
format
(
EXAM_BUSINESS_REDIS_KEY
,
businessNo
);
ExamineBusinessCacheDto
businessCache
=
getExamBusinessCache
(
businessNo
);
if
(
Objects
.
isNull
(
businessCache
))
{
throw
new
InternalException
(-
1
,
"获取不到考试流水信息"
);
}
// 当前出题
Integer
currentQuestionId
=
businessCache
.
getCurrentQuestionId
();
if
(
Objects
.
isNull
(
currentQuestionId
))
{
throw
new
InternalException
(-
1
,
"获取上一题信息失败"
);
}
// 获取下一题
ExamineQaResponseModel
nextQa
=
null
;
boolean
hasNext
=
false
;
List
<
ExamineQaResponseModel
>
examineQaList
=
examineService
.
examineQaList
(
examineId
);
if
(
CollectionUtil
.
isNotEmpty
(
examineQaList
))
{
OptionalInt
indexOpt
=
IntStream
.
range
(
0
,
examineQaList
.
size
())
.
filter
(
i
->
examineQaList
.
get
(
i
).
getId
()
==
currentQuestionId
)
.
findFirst
();
if
(
indexOpt
.
isPresent
())
{
int
index
=
indexOpt
.
getAsInt
();
nextQa
=
index
+
1
<
examineQaList
.
size
()
?
examineQaList
.
get
(
index
+
1
)
:
null
;
int
remainingNum
=
examineQaList
.
size
()
-
index
-
1
;
hasNext
=
remainingNum
>
1
?
true
:
false
;
}
}
if
(
Objects
.
nonNull
(
nextQa
))
{
// 返回结果
result
.
setNext
(
hasNext
);
result
.
setQuestion
(
nextQa
.
getQuestion
());
result
.
setAnswer
(
nextQa
.
getAnswer
());
result
.
setQuestionId
(
nextQa
.
getId
());
// 缓存
businessCache
.
setCurrentQuestionId
(
nextQa
.
getId
());
businessCache
.
setHasNext
(
hasNext
);
redisTemplate
.
opsForValue
().
set
(
examBusinessKey
,
JSONObject
.
toJSONString
(
businessCache
),
1
,
TimeUnit
.
DAYS
);
return
result
;
}
else
{
throw
new
InternalException
(-
1
,
"获取下一题信息有误"
);
}
}
/**
* 考试答题
* @param userPrincipal
* @param request
*/
public
void
submitAnswer
(
UserPrincipal
userPrincipal
,
SubmitAnswerMobileRequestDto
request
)
{
String
userId
=
userPrincipal
.
getUserId
();
Integer
examineId
=
request
.
getExamineId
();
String
answer
=
request
.
getAnswer
();
Integer
questionId
=
request
.
getQuestionId
();
String
businessNo
=
request
.
getBusinessNo
();
ExamineStartResultDto
result
=
new
ExamineStartResultDto
();
result
.
setBusinessNo
(
businessNo
);
// 获取缓存考试会话信息
String
examBusinessKey
=
String
.
format
(
EXAM_BUSINESS_REDIS_KEY
,
businessNo
);
ExamineBusinessCacheDto
businessCache
=
getExamBusinessCache
(
businessNo
);
if
(
Objects
.
isNull
(
businessCache
))
{
throw
new
InternalException
(-
1
,
"获取不到对练信息"
);
}
// 获取题目信息
ExamineQaDto
examineQaDto
=
qaDetail
(
questionId
);
// 获取数据库考试信息
Integer
recordId
=
null
;
ExamineRecordResponseModel
examineRecord
=
examineService
.
examineRecordDetail
(
businessNo
);
if
(
Objects
.
isNull
(
examineRecord
))
{
// 第一次答题,保存考试信息
ExamineRecordSaveModel
saveModel
=
new
ExamineRecordSaveModel
();
saveModel
.
setUserId
(
userId
);
saveModel
.
setUserName
(
userPrincipal
.
getUserName
());
saveModel
.
setShopId
(
userPrincipal
.
getShopId
());
saveModel
.
setShopName
(
userPrincipal
.
getShopName
());
saveModel
.
setAnsweredNum
(
1
);
saveModel
.
setExamineId
(
examineId
);
saveModel
.
setExamineMode
(
businessCache
.
getExamineMode
());
saveModel
.
setBusinessNo
(
businessNo
);
examineService
.
saveExamineRecord
(
saveModel
);
recordId
=
saveModel
.
getId
();
}
else
{
recordId
=
examineRecord
.
getId
();
// 更新答题数量
ExamineRecordSaveModel
saveModel
=
new
ExamineRecordSaveModel
();
saveModel
.
setId
(
recordId
);
saveModel
.
setAnsweredNum
(
examineRecord
.
getAnsweredNum
()
+
1
);
examineService
.
saveExamineRecord
(
saveModel
);
}
// 保存单题答题信息
ExamineRecordDetailSaveModel
detailSaveModel
=
new
ExamineRecordDetailSaveModel
();
detailSaveModel
.
setRecordId
(
recordId
);
detailSaveModel
.
setQaId
(
questionId
);
detailSaveModel
.
setCreateTime
(
new
Date
());
detailSaveModel
.
setAnswer
(
answer
);
// AI 点评
AiSingleEvaluateResultDto
evaluateResultDto
=
extensionService
.
run4SingleEvaluate
(
businessNo
,
userId
,
examineQaDto
.
getQuestion
(),
examineQaDto
.
getAnswer
(),
answer
);
if
(
Objects
.
nonNull
(
evaluateResultDto
))
{
detailSaveModel
.
setScore
(
evaluateResultDto
.
getScore
());
detailSaveModel
.
setEvaluation
(
evaluateResultDto
.
getEvaluation
());
}
examineService
.
saveExamineRecordDetail
(
detailSaveModel
);
// 更新缓存
businessCache
.
setRecordId
(
recordId
);
redisTemplate
.
opsForValue
().
set
(
examBusinessKey
,
JSONObject
.
toJSONString
(
businessCache
),
1
,
TimeUnit
.
DAYS
);
// 最后一题答题,执行AI总点评
if
(!
businessCache
.
isHasNext
())
{
// 获取答题结果
ExamineDetailRecordRequestModel
requestModel
=
new
ExamineDetailRecordRequestModel
();
requestModel
.
setRecordId
(
recordId
);
List
<
ExamineDetailRecordResponseModel
>
detailRecordList
=
examineService
.
examineDetailRecordList
(
requestModel
);
if
(
CollectionUtil
.
isNotEmpty
(
detailRecordList
))
{
// 计算综合评分
double
totalScore
=
detailRecordList
.
stream
().
filter
(
v
->
Objects
.
nonNull
(
v
.
getScore
())).
mapToDouble
(
ExamineDetailRecordResponseModel:
:
getScore
).
sum
();
Double
avgScore
=
totalScore
/
detailRecordList
.
size
();
// 执行综合点评
String
overallEvaluation
=
extensionService
.
run4TotalEvaluate
(
businessNo
,
userId
,
null
,
null
);
// 更新答题数量
ExamineRecordSaveModel
saveModel
=
new
ExamineRecordSaveModel
();
saveModel
.
setId
(
recordId
);
saveModel
.
setOverallEvaluation
(
overallEvaluation
);
saveModel
.
setOverallScore
(
avgScore
.
floatValue
());
examineService
.
saveExamineRecord
(
saveModel
);
}
}
}
result
.
setBusinessNo
(
UUID
.
randomUUID
().
toString
());
result
.
setQuestionId
(
1
);
result
.
setQuestion
(
"请问毛巾都是干净的嘛?"
);
result
.
setAnswer
(
"是的"
);
result
.
setNext
(
true
);
// // 获取缓存考试会话信息
// String examSessionKey = String.format(EXAM_REDIS_SESSION_KEY, examineId, examineMode, userId);
// String sessionId = redisTemplate.opsForValue().get(examSessionKey);
// if(StrUtil.isEmptyIfStr(sessionId)) {
// // 生成sessionId
// sessionId = UUID.randomUUID().toString();
// redisTemplate.opsForValue().set(examSessionKey, sessionId, 1, TimeUnit.DAYS);
// }
//
// // 获取缓存考题信息
// String questionKey = String.format(EXAM_REDIS_QUESTION_KEY, examineId, examineMode, userId, sessionId);
//
//
// ExamineQaRequestModel req = null;
// examineService.examineQaList(req);
// // 根据分类获取考题
// ExamineResponseModel model = examineService.examineDetail(examineId);
// if(Objects.nonNull(model)) {
// Long maxQuestionId = qaRecordMapper.selectSessionMaxQuestionId(tenant, sessionId, userId);
// maxQuestionId = Objects.nonNull(maxQuestionId) ? maxQuestionId : 0;
// ElehKnowledgeDo knowledgeDo = knowledgeMapper.selectQuestion(tenant, tagDo.getId(), maxQuestionId);
// if(Objects.nonNull(knowledgeDo)) {
// result.setQuestion(knowledgeDo.getQuestion());
// result.setAnswer(knowledgeDo.getAnswer());
// result.setProject(tagDo.getName());
// result.setCode(tagDo.getCode());
// result.setQuestionId(knowledgeDo.getId());
// result.setNext(true);
//
// // 存储当前会话考试信息
// String redisKey = String.format(EXAM_REDIS_QUESTION_KEY, tenant, sessionId, userId);
// redisTemplate.opsForValue().set(redisKey, result.getQuestionId()+"", 10, TimeUnit.MINUTES);
//
// log.info("出题结果:result = {}, rediskey = {}", JSONObject.toJSONString(result), redisKey);
// }
// }
/**
* 获取下一题
* @param userPrincipal
* @param examineId 对练ID
* @param businessNo 考试流水号
* @return
*/
public
ExamineFinalResultDto
getExamineFinalResult
(
UserPrincipal
userPrincipal
,
Integer
examineId
,
String
businessNo
)
{
String
userId
=
userPrincipal
.
getUserId
();
ExamineFinalResultDto
result
=
new
ExamineFinalResultDto
();
// 获取缓存考试会话信息
String
examBusinessKey
=
String
.
format
(
EXAM_BUSINESS_REDIS_KEY
,
businessNo
);
ExamineBusinessCacheDto
businessCache
=
getExamBusinessCache
(
businessNo
);
if
(
Objects
.
isNull
(
businessCache
))
{
throw
new
InternalException
(-
1
,
"获取不到考试流水信息"
);
}
// 当前出题
Integer
currentQuestionId
=
businessCache
.
getCurrentQuestionId
();
if
(
Objects
.
isNull
(
currentQuestionId
))
{
throw
new
InternalException
(-
1
,
"获取上一题信息失败"
);
}
// 获取下一题
ExamineQaResponseModel
nextQa
=
null
;
boolean
hasNext
=
false
;
List
<
ExamineQaResponseModel
>
examineQaList
=
examineService
.
examineQaList
(
examineId
);
if
(
CollectionUtil
.
isNotEmpty
(
examineQaList
))
{
OptionalInt
indexOpt
=
IntStream
.
range
(
0
,
examineQaList
.
size
())
.
filter
(
i
->
examineQaList
.
get
(
i
).
getId
()
==
currentQuestionId
)
.
findFirst
();
if
(
indexOpt
.
isPresent
())
{
int
index
=
indexOpt
.
getAsInt
();
nextQa
=
index
+
1
<
examineQaList
.
size
()
?
examineQaList
.
get
(
index
+
1
)
:
null
;
int
remainingNum
=
examineQaList
.
size
()
-
index
-
1
;
hasNext
=
remainingNum
>
1
?
true
:
false
;
}
}
if
(
Objects
.
nonNull
(
nextQa
))
{
// 返回结果
// result.setNext(hasNext);
// result.setQuestion(nextQa.getQuestion());
// result.setAnswer(nextQa.getAnswer());
// result.setQuestionId(nextQa.getId());
// 缓存
businessCache
.
setCurrentQuestionId
(
nextQa
.
getId
());
businessCache
.
setHasNext
(
hasNext
);
redisTemplate
.
opsForValue
().
set
(
examBusinessKey
,
JSONObject
.
toJSONString
(
businessCache
),
1
,
TimeUnit
.
DAYS
);
return
result
;
}
else
{
throw
new
InternalException
(-
1
,
"获取下一题信息有误"
);
}
}
/**
* 获取考试流水缓存信息
* @param businessNo
* @return
*/
private
ExamineBusinessCacheDto
getExamBusinessCache
(
String
businessNo
)
{
// 获取缓存考试会话信息
String
examBusinessKey
=
String
.
format
(
EXAM_BUSINESS_REDIS_KEY
,
businessNo
);
String
examBusinessCache
=
redisTemplate
.
opsForValue
().
get
(
examBusinessKey
);
if
(
StrUtil
.
isNotEmpty
(
examBusinessCache
))
{
return
JSONObject
.
parseObject
(
examBusinessCache
,
ExamineBusinessCacheDto
.
class
);
}
return
null
;
}
}
src/main/java/cn/breeze/elleai/CorsConfig.java
→
src/main/java/cn/breeze/elleai/
config/
CorsConfig.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
;
package
cn
.
breeze
.
elleai
.
config
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
...
...
src/main/java/cn/breeze/elleai/Knife4jConfiguration.java
→
src/main/java/cn/breeze/elleai/
config/
Knife4jConfiguration.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
;
package
cn
.
breeze
.
elleai
.
config
;
import
com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j
;
import
org.springframework.context.annotation.Bean
;
...
...
src/main/java/cn/breeze/elleai/Swagger2Config.java
→
src/main/java/cn/breeze/elleai/
config/
Swagger2Config.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
;
package
cn
.
breeze
.
elleai
.
config
;
import
io.swagger.v3.oas.models.Components
;
import
io.swagger.v3.oas.models.OpenAPI
;
...
...
src/main/java/cn/breeze/elleai/controller/extension/AiPlatformExtensionController.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
controller
.
extension
;
import
cn.breeze.elleai.application.dto.ApiResponse
;
import
cn.breeze.elleai.application.dto.response.AppRoleDto
;
import
cn.breeze.elleai.application.service.AiPlatformExtensionService
;
import
io.swagger.v3.oas.annotations.Operation
;
import
io.swagger.v3.oas.annotations.tags.Tag
;
import
lombok.RequiredArgsConstructor
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.util.List
;
import
java.util.UUID
;
/**
* @author yangyw
*/
...
...
@@ -14,7 +22,28 @@ import org.springframework.web.bind.annotation.RestController;
@RequiredArgsConstructor
public
class
AiPlatformExtensionController
{
private
final
AiPlatformExtensionService
extensionService
;
@Operation
(
summary
=
"单题点评"
)
@GetMapping
(
"/single_evaluate"
)
public
ApiResponse
<
String
>
singleEvaluate
()
{
String
userId
=
UUID
.
randomUUID
().
toString
();
String
sessionId
=
UUID
.
randomUUID
().
toString
();
String
question
=
"问题"
;
String
answer
=
"答案"
;
String
userAnswer
=
"用户答案"
;
extensionService
.
run4SingleEvaluate
(
userId
,
sessionId
,
question
,
answer
,
userAnswer
);
return
ApiResponse
.
ok
(
"SUCCESS"
);
}
@Operation
(
summary
=
"单题点评"
)
@GetMapping
(
"/total_evaluate"
)
public
ApiResponse
<
String
>
totalEvaluate
()
{
String
userId
=
UUID
.
randomUUID
().
toString
();
String
sessionId
=
UUID
.
randomUUID
().
toString
();
extensionService
.
run4TotalEvaluate
(
sessionId
,
userId
,
null
,
null
);
return
ApiResponse
.
ok
(
"SUCCESS"
);
}
}
src/main/java/cn/breeze/elleai/controller/front/ChatCompletionMobileController.java
View file @
ee350b41
...
...
@@ -73,4 +73,15 @@ public class ChatCompletionMobileController {
result
.
setChatCompletionId
(
1
);
return
ApiResponse
.
ok
(
result
);
}
@Operation
(
summary
=
"历史对话详情"
)
@GetMapping
(
"/history/detail"
)
public
ApiResponse
<
PageResult
<
UserChatCompletionHistoryMobileDto
>>
historyDetail
(
@Parameter
(
hidden
=
true
)
UserPrincipal
userPrincipal
,
@Schema
(
description
=
"历史会话ID"
)
@RequestParam
(
"chat_completion_id"
)
Integer
chatCompletionId
,
@Schema
(
description
=
"页码"
)
@RequestParam
(
"page_no"
)
Integer
pageNo
,
@Schema
(
description
=
"分页数量"
)
@RequestParam
(
"page_size"
)
Integer
pageSize
)
{
PageResult
<
UserChatCompletionHistoryMobileDto
>
pageResult
=
chatCompletionService
.
userQaHistoryMobilePaginQuery
(
userPrincipal
,
chatCompletionId
,
pageNo
,
pageSize
);
return
ApiResponse
.
ok
(
pageResult
);
}
}
src/main/java/cn/breeze/elleai/controller/front/ExamineMobileController.java
View file @
ee350b41
...
...
@@ -85,6 +85,7 @@ public class ExamineMobileController {
@PostMapping
(
value
=
"submit_answer"
)
public
ApiResponse
<
String
>
submitAnswer
(
@Parameter
(
hidden
=
true
)
UserPrincipal
userPrincipal
,
@RequestBody
SubmitAnswerMobileRequestDto
request
)
{
examineService
.
submitAnswer
(
userPrincipal
,
request
);
return
ApiResponse
.
ok
(
"SUCCESS"
);
}
...
...
@@ -95,7 +96,7 @@ public class ExamineMobileController {
@Schema
(
description
=
"对练ID"
)
@RequestParam
(
"examine_id"
)
Integer
examineId
,
@Schema
(
description
=
"考试流水号"
)
@RequestParam
(
"business_no"
)
String
businessNo
)
{
ExamineStartResultDto
result
=
new
ExamineStartResultDto
(
);
ExamineStartResultDto
result
=
examineService
.
getNextQuestion
(
userPrincipal
,
examineId
,
businessNo
);
return
ApiResponse
.
ok
(
result
);
}
...
...
@@ -107,6 +108,7 @@ public class ExamineMobileController {
@Operation
(
summary
=
"完成考试(触发最终结果更新)"
)
@PostMapping
(
value
=
"/complete_examine"
)
public
ApiResponse
<
String
>
updateExamResult
(
@RequestBody
ExamineUpdateResultDto
request
)
{
return
ApiResponse
.
ok
(
"SUCCESS"
);
}
...
...
src/main/java/cn/breeze/elleai/domain/sparring/model/request/ExamineRecordDetailSaveModel.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
domain
.
sparring
.
model
.
request
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.Date
;
@Data
public
class
ExamineRecordDetailSaveModel
implements
Serializable
{
private
Integer
id
;
/**
* 对练记录ID
*/
private
Integer
recordId
;
/**
* 题目ID
*/
private
Integer
qaId
;
/**
* 评分
*/
private
Float
score
;
/**
* 评价
*/
private
String
evaluation
;
/**
* 员工回答
*/
private
String
answer
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
}
src/main/java/cn/breeze/elleai/domain/sparring/model/request/ExamineRecordSaveModel.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
domain
.
sparring
.
model
.
request
;
import
com.mybatisflex.annotation.Id
;
import
com.mybatisflex.annotation.KeyType
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.Date
;
@Data
public
class
ExamineRecordSaveModel
implements
Serializable
{
private
Integer
id
;
/**
* 用户ID
*/
private
String
userId
;
/**
* 用户名称
*/
private
String
userName
;
/**
* 考试流水号
*/
private
String
businessNo
;
/**
* 所属门店ID
*/
private
String
shopId
;
/**
* 所属门店名称
*/
private
String
shopName
;
/**
* 会话ID
*/
private
String
sessionId
;
/**
* 对练ID
*/
private
Integer
examineId
;
/**
* 对练模式(0练习 1对练)
*/
private
Integer
examineMode
;
/**
* 已答题数量
*/
private
Integer
answeredNum
;
/**
* 综合评分
*/
private
Float
overallScore
;
/**
* 综合评价
*/
private
String
overallEvaluation
;
/**
* 创建时间
*/
private
Date
createTime
;
/**
* 更新时间
*/
private
Date
updateTime
;
}
src/main/java/cn/breeze/elleai/domain/sparring/model/request/UserChatCompletionSaveModel.java
0 → 100644
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
domain
.
sparring
.
model
.
request
;
import
com.mybatisflex.annotation.Id
;
import
com.mybatisflex.annotation.KeyType
;
import
lombok.Data
;
import
java.io.Serializable
;
import
java.util.Date
;
@Data
public
class
UserChatCompletionSaveModel
implements
Serializable
{
private
Integer
id
;
/**
* 用户ID
*/
private
String
userId
;
/**
* 用户名称
*/
private
String
userName
;
/**
* 所属门店ID
*/
private
String
shopId
;
/**
* 所属门店名称
*/
private
String
shopName
;
/**
* 会话ID
*/
private
String
sessionId
;
/**
* 首次提问时间
*/
private
String
firstQuestion
;
/**
* 最后一次提问
*/
private
String
lastQuestion
;
/**
* 创建时间
*/
private
Date
createTime
;
}
src/main/java/cn/breeze/elleai/domain/sparring/model/response/ExamineRecordResponseModel.java
View file @
ee350b41
...
...
@@ -24,6 +24,11 @@ public class ExamineRecordResponseModel implements Serializable {
*/
private
String
userName
;
/**
* 考试流水号
*/
private
String
businessNo
;
/**
* 所属门店ID
*/
...
...
src/main/java/cn/breeze/elleai/domain/sparring/service/ChatCompletionService.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
domain
.
sparring
.
service
;
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.UserQaHistoryRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.request.UserQaRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.request.*
;
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
;
...
...
@@ -20,11 +17,13 @@ public interface ChatCompletionService {
List
<
UserChatCompletionResponseModel
>
userQaList
(
UserQaRequestModel
request
);
List
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetail
(
Integer
sessionId
);
List
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetail
(
Integer
chatCompletionId
);
Page
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetailPaginQuery
(
Integer
chatCompletionId
,
Integer
pageNo
,
Integer
pageSize
);
UserChatCompletionResponseModel
userQaDetail
(
UserQaRequestModel
request
);
Integer
saveUserQaSession
(
String
userId
,
String
sessionId
);
Integer
saveUserQaSession
(
UserChatCompletionSaveModel
dto
);
void
saveUserQaRecord
(
Integer
chatCompletionId
,
Integer
type
,
String
content
);
...
...
src/main/java/cn/breeze/elleai/domain/sparring/service/ChatCompletionServiceImpl.java
View file @
ee350b41
package
cn
.
breeze
.
elleai
.
domain
.
sparring
.
service
;
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.UserQaHistoryRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.request.UserQaRequestModel
;
import
cn.breeze.elleai.domain.sparring.model.request.*
;
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
;
...
...
@@ -91,14 +88,26 @@ public class ChatCompletionServiceImpl implements ChatCompletionService{
}
@Override
public
List
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetail
(
Integer
sess
ionId
)
{
public
List
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetail
(
Integer
chatComplet
ionId
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
();
queryWrapper
.
where
(
USER_CHAT_COMPLETION_HISTORY_ENTITY
.
CHAT_COMPLETION_ID
.
eq
(
sess
ionId
));
queryWrapper
.
where
(
USER_CHAT_COMPLETION_HISTORY_ENTITY
.
CHAT_COMPLETION_ID
.
eq
(
chatComplet
ionId
));
queryWrapper
.
orderBy
(
USER_CHAT_COMPLETION_HISTORY_ENTITY
.
CREATE_TIME
,
true
);
return
chatCompletionHistoryMapper
.
selectListByQueryAs
(
queryWrapper
,
UserChatCompletionHistoryResponseModel
.
class
);
}
@Override
public
Page
<
UserChatCompletionHistoryResponseModel
>
userQaHistoryDetailPaginQuery
(
Integer
chatCompletionId
,
Integer
pageNo
,
Integer
pageSize
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
();
queryWrapper
.
where
(
USER_CHAT_COMPLETION_HISTORY_ENTITY
.
CHAT_COMPLETION_ID
.
eq
(
chatCompletionId
));
queryWrapper
.
orderBy
(
USER_CHAT_COMPLETION_HISTORY_ENTITY
.
CREATE_TIME
,
true
);
Page
<
UserChatCompletionHistoryResponseModel
>
page
=
chatCompletionHistoryMapper
.
paginateAs
(
pageNo
,
pageSize
,
queryWrapper
,
UserChatCompletionHistoryResponseModel
.
class
);
return
page
;
}
@Override
public
UserChatCompletionResponseModel
userQaDetail
(
UserQaRequestModel
request
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
();
...
...
@@ -109,10 +118,9 @@ public class ChatCompletionServiceImpl implements ChatCompletionService{
}
@Override
public
Integer
saveUserQaSession
(
String
userId
,
String
sessionId
)
{
public
Integer
saveUserQaSession
(
UserChatCompletionSaveModel
dto
)
{
UserChatCompletionEntity
entity
=
new
UserChatCompletionEntity
();
entity
.
setUserId
(
userId
);
entity
.
setSessionId
(
sessionId
);
BeanUtil
.
copyProperties
(
dto
,
entity
);
entity
.
setUpdateTime
(
new
Date
());
chatCompletionMapper
.
insertOrUpdateSelective
(
entity
);
return
entity
.
getId
();
...
...
src/main/java/cn/breeze/elleai/domain/sparring/service/ExamineService.java
View file @
ee350b41
...
...
@@ -49,7 +49,7 @@ public interface ExamineService {
*/
Page
<
ExamineQaResponseModel
>
examineQaPaginQuery
(
ExamineQaRequestModel
request
);
List
<
ExamineQaResponseModel
>
examineQaList
(
ExamineQaRequestModel
request
);
List
<
ExamineQaResponseModel
>
examineQaList
(
Integer
examineId
);
List
<
ExamineQaResponseModel
>
examineQaList
(
List
<
Integer
>
qaIds
);
...
...
@@ -94,6 +94,12 @@ public interface ExamineService {
ExamineRecordResponseModel
examineRecordDetail
(
Integer
id
);
ExamineRecordResponseModel
examineRecordDetail
(
String
businessNo
);
void
saveExamineRecord
(
ExamineRecordSaveModel
dto
);
void
saveExamineRecordDetail
(
ExamineRecordDetailSaveModel
dto
);
/***************************************** 资料库分类 *****************************************/
Page
<
WikiCategoryResponseModel
>
wikiCategoryPaginQuery
(
WikiCategoryRequestModel
request
);
...
...
src/main/java/cn/breeze/elleai/domain/sparring/service/ExamineServiceImpl.java
View file @
ee350b41
...
...
@@ -213,13 +213,16 @@ public class ExamineServiceImpl implements ExamineService {
}
@Override
public
List
<
ExamineQaResponseModel
>
examineQaList
(
ExamineQaRequestModel
request
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
()
.
where
(
EXAMINE_QA_ENTITY
.
DELETED
.
eq
(
0
));
if
(
StrUtil
.
isNotEmpty
(
request
.
getName
()))
{
queryWrapper
.
where
(
EXAMINE_QA_ENTITY
.
QUESTION
.
like
(
"%"
+
request
.
getName
()+
"%"
));
}
public
List
<
ExamineQaResponseModel
>
examineQaList
(
Integer
examineId
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
();
queryWrapper
.
select
(
EXAMINE_QA_ENTITY
.
ALL_COLUMNS
).
from
(
EXAMINE_QA_ENTITY
);
queryWrapper
.
leftJoin
(
EXAMINE_QA_XREF_ENTITY
).
on
(
EXAMINE_QA_ENTITY
.
ID
.
eq
(
EXAMINE_QA_XREF_ENTITY
.
QA_ID
))
.
and
(
EXAMINE_QA_XREF_ENTITY
.
DELETED
.
eq
(
0
));
queryWrapper
.
where
(
EXAMINE_QA_ENTITY
.
DELETED
.
eq
(
0
));
queryWrapper
.
where
(
EXAMINE_QA_XREF_ENTITY
.
EXAMINE_ID
.
eq
(
examineId
));
queryWrapper
.
orderBy
(
EXAMINE_QA_XREF_ENTITY
.
CREATE_TIME
,
false
);
System
.
out
.
println
(
queryWrapper
.
toSQL
());
return
qaMapper
.
selectListByQueryAs
(
queryWrapper
,
ExamineQaResponseModel
.
class
);
}
...
...
@@ -457,6 +460,30 @@ public class ExamineServiceImpl implements ExamineService {
return
userExamineRecordMapper
.
selectOneByQueryAs
(
queryWrapper
,
ExamineRecordResponseModel
.
class
);
}
@Override
public
ExamineRecordResponseModel
examineRecordDetail
(
String
businessNo
)
{
QueryWrapper
queryWrapper
=
QueryWrapper
.
create
()
.
where
(
USER_EXAMINE_RECORD_ENTITY
.
BUSINESS_NO
.
eq
(
businessNo
));
return
userExamineRecordMapper
.
selectOneByQueryAs
(
queryWrapper
,
ExamineRecordResponseModel
.
class
);
}
@Override
public
void
saveExamineRecord
(
ExamineRecordSaveModel
dto
)
{
UserExamineRecordEntity
entity
=
BeanUtil
.
toBean
(
dto
,
UserExamineRecordEntity
.
class
);
entity
.
setUpdateTime
(
new
Date
());
userExamineRecordMapper
.
insertOrUpdateSelective
(
entity
);
dto
.
setId
(
entity
.
getId
());
}
@Override
public
void
saveExamineRecordDetail
(
ExamineRecordDetailSaveModel
dto
)
{
UserExamineDetailRecordEntity
entity
=
BeanUtil
.
toBean
(
dto
,
UserExamineDetailRecordEntity
.
class
);
entity
.
setUpdateTime
(
new
Date
());
userExamineDetailRecordMapper
.
insertOrUpdateSelective
(
entity
);
}
@Override
public
Page
<
WikiCategoryResponseModel
>
wikiCategoryPaginQuery
(
WikiCategoryRequestModel
request
)
{
Integer
pageNo
=
ObjectUtil
.
defaultIfNull
(
request
.
getPageNo
(),
1
);
...
...
src/main/java/cn/breeze/elleai/infra/entity/UserExamineRecordEntity.java
View file @
ee350b41
...
...
@@ -42,6 +42,11 @@ public class UserExamineRecordEntity implements Serializable {
*/
private
String
userName
;
/**
* 考试流水号
*/
private
String
businessNo
;
/**
* 所属门店ID
*/
...
...
src/main/java/cn/breeze/elleai/infra/entity/table/UserExamineRecordTableDef.java
View file @
ee350b41
...
...
@@ -34,6 +34,12 @@ public class UserExamineRecordTableDef extends TableDef {
*/
public
final
QueryColumn
USER_NAME
=
new
QueryColumn
(
this
,
"user_name"
);
/**
* 考试流水号
*/
public
final
QueryColumn
BUSINESS_NO
=
new
QueryColumn
(
this
,
"business_no"
);
/**
* 所属门店ID
*/
...
...
@@ -92,7 +98,7 @@ public class UserExamineRecordTableDef extends TableDef {
/**
* 默认字段,不包含逻辑删除或者 large 等字段。
*/
public
final
QueryColumn
[]
DEFAULT_COLUMNS
=
new
QueryColumn
[]{
ID
,
USER_ID
,
USER_NAME
,
SHOP_ID
,
SHOP_NAME
,
SESSION_ID
,
EXAMINE_ID
,
EXAMINE_MODE
,
ANSWERED_NUM
,
OVERALL_SCORE
,
OVERALL_EVALUATION
,
CREATE_TIME
,
UPDATE_TIME
};
public
final
QueryColumn
[]
DEFAULT_COLUMNS
=
new
QueryColumn
[]{
ID
,
USER_ID
,
USER_NAME
,
BUSINESS_NO
,
SHOP_ID
,
SHOP_NAME
,
SESSION_ID
,
EXAMINE_ID
,
EXAMINE_MODE
,
ANSWERED_NUM
,
OVERALL_SCORE
,
OVERALL_EVALUATION
,
CREATE_TIME
,
UPDATE_TIME
};
public
UserExamineRecordTableDef
()
{
super
(
""
,
"ai_user_examine_record"
);
...
...
src/main/resources/application.yml
View file @
ee350b41
...
...
@@ -21,8 +21,8 @@ springdoc:
swagger-ui
:
path
:
/swagger-ui.html
dify
:
api_base
:
http
://dify-api:5001
/v1
api_key
:
app-
ilgoEphXjLw0I7x7fGeCyKYk
api_base
:
http
s://app-api.tech.breezeai.cn
/v1
api_key
:
app-
mJFu7K2wl3qEYsILkQBgRAKO
# token配置
token
:
# 令牌自定义标识
...
...
target/classes/application.yml
View file @
ee350b41
...
...
@@ -21,9 +21,16 @@ springdoc:
swagger-ui
:
path
:
/swagger-ui.html
dify
:
api_base
:
http://dify-api:5001/v1
api_key
:
app-ilgoEphXjLw0I7x7fGeCyKYk
api_base
:
https://app-api.tech.breezeai.cn/v1
api_key
:
app-mJFu7K2wl3qEYsILkQBgRAKO
# token配置
token
:
# 令牌自定义标识
header
:
Authorization
# 令牌密钥
secret
:
fhgaf%^$#%cHDFDhUHLKnhkhj
# 令牌有效期(默认30分钟)
expireTime
:
2628000
---
spring
:
config
:
...
...
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