Browse Source

大模型优化,增加分页查询聊天信息

master^2
xueyinfei 5 days ago
parent
commit
4e8e2b5a94
  1. 6
      vue-fastapi-backend/module_admin/controller/aichat_controller.py
  2. 18
      vue-fastapi-backend/module_admin/dao/aichat_dao.py
  3. 10
      vue-fastapi-backend/module_admin/entity/vo/aichat_vo.py
  4. 4
      vue-fastapi-backend/module_admin/service/aichat_service.py
  5. 6
      vue-fastapi-frontend/src/api/aichat/aichat.js
  6. 18
      vue-fastapi-frontend/src/views/aichat/aichat.vue
  7. 63
      vue-fastapi-frontend/src/views/aichat/index.vue

6
vue-fastapi-backend/module_admin/controller/aichat_controller.py

@ -28,10 +28,10 @@ async def get_chat_session_list(request: Request,
return ResponseUtil.success(data=ai_session_list_result) return ResponseUtil.success(data=ai_session_list_result)
@aichatController.get("/chat/list/{sessionId}") @aichatController.get("/chat/list")
async def get_chat_list(request: Request, sessionId: str, query_db: AsyncSession = Depends(get_db), async def get_chat_list(request: Request, query: AiListQuery = Depends(AiListQuery.as_query), query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user)): current_user: CurrentUserModel = Depends(LoginService.get_current_user)):
ai_chat_list_result = await AiChatService.get_ai_chat_list_services(query_db, sessionId, current_user) ai_chat_list_result = await AiChatService.get_ai_chat_list_services(query_db, query, current_user)
logger.info('获取成功') logger.info('获取成功')
return ResponseUtil.success(data=ai_chat_list_result) return ResponseUtil.success(data=ai_chat_list_result)

18
vue-fastapi-backend/module_admin/dao/aichat_dao.py

@ -2,7 +2,8 @@ from sqlalchemy import desc, delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy.ext.asyncio import AsyncSession
from module_admin.entity.do.aichat_do import AiChatHistory from module_admin.entity.do.aichat_do import AiChatHistory
from module_admin.entity.do.aichat_do import AiChatSession from module_admin.entity.do.aichat_do import AiChatSession
from module_admin.entity.vo.aichat_vo import AiChatModel from module_admin.entity.vo.aichat_vo import AiChatModel, AiListQuery
from utils.page_util import PageUtil
class AiChatDao: class AiChatDao:
@ -21,14 +22,13 @@ class AiChatDao:
return session_list return session_list
@classmethod @classmethod
async def get_ai_chat_list(cls, db: AsyncSession, sessionId: str, user_id: int): async def get_ai_chat_list(cls, db: AsyncSession, query: AiListQuery, user_id: int):
chat_list = ( querySql = (
await db.execute( select(AiChatHistory).where(AiChatHistory.user == user_id, AiChatHistory.sessionId == query.session_id)
select(AiChatHistory).where(AiChatHistory.user == user_id, AiChatHistory.sessionId == sessionId) .order_by(desc(AiChatHistory.time))
.order_by(AiChatHistory.time) )
) result = await PageUtil.paginate(db, querySql, query.page_num, query.page_size, True)
).scalars().all() return result
return chat_list
@classmethod @classmethod
async def get_ai_chat_by_id(cls, sessionId: str, db: AsyncSession, user_id: int): async def get_ai_chat_by_id(cls, sessionId: str, db: AsyncSession, user_id: int):

10
vue-fastapi-backend/module_admin/entity/vo/aichat_vo.py

@ -1,5 +1,8 @@
from pydantic import BaseModel from pydantic import BaseModel
from typing import Union, Optional, List from typing import Union, Optional, List
from pydantic import BaseModel, ConfigDict, Field, model_validator
from module_admin.annotation.pydantic_annotation import as_query
from pydantic.alias_generators import to_camel
class CrudChatModel(BaseModel): class CrudChatModel(BaseModel):
@ -7,6 +10,13 @@ class CrudChatModel(BaseModel):
message: str message: str
@as_query
class AiListQuery(BaseModel):
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
session_id: str
page_num: int
page_size: int
class AiChatModel(BaseModel): class AiChatModel(BaseModel):
""" """
菜单表对应pydantic模型 菜单表对应pydantic模型

4
vue-fastapi-backend/module_admin/service/aichat_service.py

@ -22,9 +22,9 @@ class AiChatService:
return ai_session_list return ai_session_list
@classmethod @classmethod
async def get_ai_chat_list_services(cls, result_db: AsyncSession, sessionId: str, async def get_ai_chat_list_services(cls, result_db: AsyncSession, query: AiListQuery,
current_user: Optional[CurrentUserModel] = None): current_user: Optional[CurrentUserModel] = None):
ai_session_list = await AiChatDao.get_ai_chat_list(result_db, sessionId, current_user.user.user_id) # 查询最新的20条 ai_session_list = await AiChatDao.get_ai_chat_list(result_db, query, current_user.user.user_id) # 查询最新的20条
return CamelCaseUtil.transform_result(ai_session_list) return CamelCaseUtil.transform_result(ai_session_list)
@classmethod @classmethod

6
vue-fastapi-frontend/src/api/aichat/aichat.js

@ -14,11 +14,11 @@ export function listChatHistory(sessionId) {
}) })
} }
export function getChatList(sessionId) { export function getChatList(data) {
return request({ return request({
url: '/default-api/aichat/chat/list/'+sessionId, url: '/default-api/aichat/chat/list',
method: 'get', method: 'get',
params: {} params: data
}) })
} }

18
vue-fastapi-frontend/src/views/aichat/aichat.vue

@ -258,16 +258,15 @@ function setScrollBottom() {
scrollDiv.value.setScrollTop(getMaxHeight()) scrollDiv.value.setScrollTop(getMaxHeight())
} }
/** /**
* 滚动条距离最上面的高度 * 滚动条距离最上面的高度
*/ */
const scrollTop = ref(0) const scrollTop = ref(0)
const getMaxHeight = () => { const getMaxHeight = () => {
return dialogScrollbar.value.scrollHeight return dialogScrollbar.value?.scrollHeight ?? 0;
} }
const handleScrollTop = ($event) => { const handleScrollTop = ($event) => {
scrollTop.value = $event.scrollTop scrollTop.value = $event.scrollTop
emit('scroll', { ...$event, dialogScrollbar: dialogScrollbar.value, scrollDiv: scrollDiv.value }) emit('scroll', { ...$event, dialogScrollbar: dialogScrollbar.value, scrollDiv: scrollDiv.value })
@ -278,13 +277,13 @@ const handleScroll = () => {
// //
if (scrollDiv.value.wrapRef.offsetHeight < dialogScrollbar.value.scrollHeight) { if (scrollDiv.value.wrapRef.offsetHeight < dialogScrollbar.value.scrollHeight) {
// //
scrollDiv.value.setScrollTop(getMaxHeight()) // if (scorll.value) {
scrollDiv.value.setScrollTop(getMaxHeight())
// }
} }
} }
} }
/**文件上传中处理 */ /**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => { const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true; upload.isUploading = true;
@ -354,6 +353,7 @@ function changeThumb(index,chat){
function openUpload(){ function openUpload(){
upload.open = true upload.open = true
} }
function chooseMachine(val){ function chooseMachine(val){
inputValue.value = inputValue.value.slice(0,-1) inputValue.value = inputValue.value.slice(0,-1)
currentMachine.value = [val] currentMachine.value = [val]
@ -472,17 +472,20 @@ function sendChatMessage(data){
chatList.value.push({"type":"answer","content":[{"type":"text","content":"服务异常"}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":"","thumbDownReason":""}) chatList.value.push({"type":"answer","content":[{"type":"text","content":"服务异常"}],"isEnd":true,"isStop":false,"sessionId":chatList.value[0].sessionId,"sessionName":chatList.value[0].sessionName,"operate":"","thumbDownReason":""})
}) })
} }
watch( watch(
chatList, chatList,
() => { () => {
nextTick(() => { nextTick(() => {
// //
scrollDiv.value.setScrollTop(getMaxHeight()) // scrollDiv.value.setScrollTop(getMaxHeight())
handleScroll()
}) })
},{ },{
deep:true, immediate:true deep:true, immediate:true
} }
) )
const getWrite = (reader) => { const getWrite = (reader) => {
// 1tempResult // 1tempResult
let tempResult = ''; let tempResult = '';
@ -572,6 +575,7 @@ const stopChat = (index) => {
answer.content = JSON.stringify(answer.content) answer.content = JSON.stringify(answer.content)
addChat(answer) addChat(answer)
} }
const startChat = (index) => { const startChat = (index) => {
regenerationChart(index) regenerationChart(index)
} }

63
vue-fastapi-frontend/src/views/aichat/index.vue

@ -100,6 +100,12 @@ const currentRecordList = ref([])
const sessionId = ref(Cookies.get("chatSessionId")) // Id 'new' const sessionId = ref(Cookies.get("chatSessionId")) // Id 'new'
const mouseId = ref('') const mouseId = ref('')
const paginationConfig = reactive({
current_page: 1,
page_size: 20,
total: 0
})
function mouseenter(row) { function mouseenter(row) {
mouseId.value = row.sessionId mouseId.value = row.sessionId
} }
@ -124,7 +130,6 @@ function showChatHistory(){
}) })
} }
function newChat() { function newChat() {
currentRecordList.value = [] currentRecordList.value = []
sessionId.value = uuidv4() sessionId.value = uuidv4()
@ -133,16 +138,31 @@ function newChat() {
} }
function handleScroll(event) { function handleScroll(event) {
if (event.scrollTop === 0 && currentRecordList.value.length>0) { if (
event.scrollTop === 0 &&
paginationConfig.total > currentRecordList.value.length
) {
const history_height = event.dialogScrollbar.offsetHeight const history_height = event.dialogScrollbar.offsetHeight
event.scrollDiv.setScrollTop(event.dialogScrollbar.offsetHeight - history_height) paginationConfig.current_page += 1
getChatRecord({sessionId: sessionId.value, pageNum: paginationConfig.current_page, pageSize: paginationConfig.page_size}).then(() => {
event.scrollDiv.setScrollTop(event.dialogScrollbar.offsetHeight - history_height)
})
} }
} }
function clickListHandle(item){ function clickListHandle(item){
getChatList(item.sessionId).then(res=>{ paginationConfig.current_page = 1
currentRecordList.value = [] currentRecordList.value = []
let array = res.data sessionId.value = item.sessionId
Cookies.set("chatSessionId",sessionId.value)
getChatRecord({sessionId: item.sessionId, pageNum: paginationConfig.current_page, pageSize: paginationConfig.page_size})
show.value = false
}
function getChatRecord(data){
return getChatList(data).then(res=>{
let array = res.data.rows
paginationConfig.total = res.data.total
for (let i = 0; i < array.length; i++) { for (let i = 0; i < array.length; i++) {
if (array[i].type === 'answer'){ if (array[i].type === 'answer'){
array[i].content = JSON.parse(array[i].content) array[i].content = JSON.parse(array[i].content)
@ -150,12 +170,16 @@ function clickListHandle(item){
if (array[i].type === 'question'){ if (array[i].type === 'question'){
array[i].file = JSON.parse(array[i].file) array[i].file = JSON.parse(array[i].file)
} }
currentRecordList.value.push(array[i])
AiChatRef.value.setScrollBottom()
} }
show.value = false currentRecordList.value = [...array, ...currentRecordList.value].sort((a, b) =>
sessionId.value = item.sessionId a.time.localeCompare(b.time)
Cookies.set("chatSessionId",sessionId.value) )
if (paginationConfig.current_page === 1) {
nextTick(() => {
//
AiChatRef.value.setScrollBottom()
})
}
}) })
} }
watch(() => props.chatDataList, value => currentRecordList.value = JSON.parse(JSON.stringify(value))) watch(() => props.chatDataList, value => currentRecordList.value = JSON.parse(JSON.stringify(value)))
@ -163,22 +187,7 @@ onMounted(
()=>{ ()=>{
if (Cookies.get("chatSessionId")){ if (Cookies.get("chatSessionId")){
// //
getChatList(Cookies.get("chatSessionId")).then(res=>{ getChatRecord({sessionId: Cookies.get("chatSessionId"), pageNum: paginationConfig.current_page, pageSize: paginationConfig.page_size})
let array = res.data
if (array && array.length >0){
for (let i = 0; i < array.length; i++) {
if (array[i].type === 'answer'){
array[i].content = JSON.parse(array[i].content)
}
if (array[i].type === 'question'){
array[i].file = JSON.parse(array[i].file)
}
}
}
currentRecordList.value = array
}).then(()=>{
AiChatRef.value.setScrollBottom()
})
}else { }else {
Cookies.set("chatSessionId",uuidv4()) Cookies.set("chatSessionId",uuidv4())
} }

Loading…
Cancel
Save