si@aidatagov.com 22 hours ago
parent
commit
c95a7f28e2
  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. 3
      vue-fastapi-frontend/src/layout/components/AppMain.vue
  7. 18
      vue-fastapi-frontend/src/views/aichat/aichat.vue
  8. 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)
@aichatController.get("/chat/list/{sessionId}")
async def get_chat_list(request: Request, sessionId: str, query_db: AsyncSession = Depends(get_db),
@aichatController.get("/chat/list")
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)):
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('获取成功')
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 module_admin.entity.do.aichat_do import AiChatHistory
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:
@ -21,14 +22,13 @@ class AiChatDao:
return session_list
@classmethod
async def get_ai_chat_list(cls, db: AsyncSession, sessionId: str, user_id: int):
chat_list = (
await db.execute(
select(AiChatHistory).where(AiChatHistory.user == user_id, AiChatHistory.sessionId == sessionId)
.order_by(AiChatHistory.time)
)
).scalars().all()
return chat_list
async def get_ai_chat_list(cls, db: AsyncSession, query: AiListQuery, user_id: int):
querySql = (
select(AiChatHistory).where(AiChatHistory.user == user_id, AiChatHistory.sessionId == query.session_id)
.order_by(desc(AiChatHistory.time))
)
result = await PageUtil.paginate(db, querySql, query.page_num, query.page_size, True)
return result
@classmethod
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 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):
@ -7,6 +10,13 @@ class CrudChatModel(BaseModel):
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):
"""
菜单表对应pydantic模型

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

@ -22,9 +22,9 @@ class AiChatService:
return ai_session_list
@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):
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)
@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({
url: '/default-api/aichat/chat/list/'+sessionId,
url: '/default-api/aichat/chat/list',
method: 'get',
params: {}
params: data
})
}

3
vue-fastapi-frontend/src/layout/components/AppMain.vue

@ -27,9 +27,6 @@ import iframeToggle from "./IframeToggle/index"
import useTagsViewStore from '@/store/modules/tagsView'
import { ref, onMounted, reactive, nextTick, computed } from 'vue'
import AichatIndex from "../../views/aichat/index.vue";
import Cookies from "js-cookie";
import {v4 as uuidv4} from "uuid";
import {getChatList} from "@/api/aichat/aichat.js";
const route = useRoute()
const tagsViewStore = useTagsViewStore()

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

@ -258,16 +258,15 @@ function setScrollBottom() {
scrollDiv.value.setScrollTop(getMaxHeight())
}
/**
* 滚动条距离最上面的高度
*/
const scrollTop = ref(0)
const getMaxHeight = () => {
return dialogScrollbar.value.scrollHeight
return dialogScrollbar.value?.scrollHeight ?? 0;
}
const handleScrollTop = ($event) => {
scrollTop.value = $event.scrollTop
emit('scroll', { ...$event, dialogScrollbar: dialogScrollbar.value, scrollDiv: scrollDiv.value })
@ -278,13 +277,13 @@ const handleScroll = () => {
//
if (scrollDiv.value.wrapRef.offsetHeight < dialogScrollbar.value.scrollHeight) {
//
scrollDiv.value.setScrollTop(getMaxHeight())
// if (scorll.value) {
scrollDiv.value.setScrollTop(getMaxHeight())
// }
}
}
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
@ -354,6 +353,7 @@ function changeThumb(index,chat){
function openUpload(){
upload.open = true
}
function chooseMachine(val){
inputValue.value = inputValue.value.slice(0,-1)
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":""})
})
}
watch(
chatList,
() => {
nextTick(() => {
//
scrollDiv.value.setScrollTop(getMaxHeight())
// scrollDiv.value.setScrollTop(getMaxHeight())
handleScroll()
})
},{
deep:true, immediate:true
}
)
const getWrite = (reader) => {
// 1tempResult
let tempResult = '';
@ -572,6 +575,7 @@ const stopChat = (index) => {
answer.content = JSON.stringify(answer.content)
addChat(answer)
}
const startChat = (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 mouseId = ref('')
const paginationConfig = reactive({
current_page: 1,
page_size: 20,
total: 0
})
function mouseenter(row) {
mouseId.value = row.sessionId
}
@ -124,7 +130,6 @@ function showChatHistory(){
})
}
function newChat() {
currentRecordList.value = []
sessionId.value = uuidv4()
@ -133,16 +138,31 @@ function newChat() {
}
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
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){
getChatList(item.sessionId).then(res=>{
currentRecordList.value = []
let array = res.data
paginationConfig.current_page = 1
currentRecordList.value = []
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++) {
if (array[i].type === 'answer'){
array[i].content = JSON.parse(array[i].content)
@ -150,12 +170,16 @@ function clickListHandle(item){
if (array[i].type === 'question'){
array[i].file = JSON.parse(array[i].file)
}
currentRecordList.value.push(array[i])
AiChatRef.value.setScrollBottom()
}
show.value = false
sessionId.value = item.sessionId
Cookies.set("chatSessionId",sessionId.value)
currentRecordList.value = [...array, ...currentRecordList.value].sort((a, b) =>
a.time.localeCompare(b.time)
)
if (paginationConfig.current_page === 1) {
nextTick(() => {
//
AiChatRef.value.setScrollBottom()
})
}
})
}
watch(() => props.chatDataList, value => currentRecordList.value = JSON.parse(JSON.stringify(value)))
@ -163,22 +187,7 @@ onMounted(
()=>{
if (Cookies.get("chatSessionId")){
//
getChatList(Cookies.get("chatSessionId")).then(res=>{
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()
})
getChatRecord({sessionId: Cookies.get("chatSessionId"), pageNum: paginationConfig.current_page, pageSize: paginationConfig.page_size})
}else {
Cookies.set("chatSessionId",uuidv4())
}

Loading…
Cancel
Save