feat: ai
This commit is contained in:
@@ -28,7 +28,6 @@ const props = defineProps({
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
/** 新建对话 */
|
||||
|
||||
// 定义钩子
|
||||
const emits = defineEmits([
|
||||
@@ -37,9 +36,11 @@ const emits = defineEmits([
|
||||
'onConversationClear',
|
||||
'onConversationDelete',
|
||||
]);
|
||||
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
connectedComponent: RoleRepository,
|
||||
});
|
||||
|
||||
// 定义属性
|
||||
const searchName = ref<string>(''); // 对话搜索
|
||||
const activeConversationId = ref<null | number>(null); // 选中的对话,默认为 null
|
||||
@@ -50,7 +51,7 @@ const loading = ref<boolean>(false); // 加载中
|
||||
const loadingTime = ref<any>();
|
||||
|
||||
/** 搜索对话 */
|
||||
const searchConversation = async () => {
|
||||
async function searchConversation() {
|
||||
// 恢复数据
|
||||
if (searchName.value.trim().length === 0) {
|
||||
conversationMap.value = await getConversationGroupByCreateTime(
|
||||
@@ -64,25 +65,25 @@ const searchConversation = async () => {
|
||||
conversationMap.value =
|
||||
await getConversationGroupByCreateTime(filterValues);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 点击对话 */
|
||||
const handleConversationClick = async (id: number) => {
|
||||
async function handleConversationClick(id: number) {
|
||||
// 过滤出选中的对话
|
||||
const filterConversation = conversationList.value.find((item) => {
|
||||
return item.id === id;
|
||||
});
|
||||
// 回调 onConversationClick
|
||||
// noinspection JSVoidFunctionReturnValueUsed
|
||||
const success = emits('onConversationClick', filterConversation);
|
||||
const success = emits('onConversationClick', filterConversation) as any;
|
||||
// 切换对话
|
||||
if (success) {
|
||||
activeConversationId.value = id;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取对话列表 */
|
||||
const getChatConversationList = async () => {
|
||||
async function getChatConversationList() {
|
||||
try {
|
||||
// 加载中
|
||||
loadingTime.value = setTimeout(() => {
|
||||
@@ -114,12 +115,12 @@ const getChatConversationList = async () => {
|
||||
// 加载完成
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 按照 creteTime 创建时间,进行分组 */
|
||||
const getConversationGroupByCreateTime = async (
|
||||
async function getConversationGroupByCreateTime(
|
||||
list: AiChatConversationApi.ChatConversationVO[],
|
||||
) => {
|
||||
) {
|
||||
// 排序、指定、时间分组(今天、一天前、三天前、七天前、30天前)
|
||||
// noinspection NonAsciiCharacters
|
||||
const groupMap: any = {
|
||||
@@ -159,8 +160,9 @@ const getConversationGroupByCreateTime = async (
|
||||
}
|
||||
}
|
||||
return groupMap;
|
||||
};
|
||||
const createConversation = async () => {
|
||||
}
|
||||
|
||||
async function createConversation() {
|
||||
// 1. 新建对话
|
||||
const conversationId = await createChatConversationMy(
|
||||
{} as unknown as AiChatConversationApi.ChatConversationVO,
|
||||
@@ -171,12 +173,12 @@ const createConversation = async () => {
|
||||
await handleConversationClick(conversationId);
|
||||
// 4. 回调
|
||||
emits('onConversationCreate');
|
||||
};
|
||||
}
|
||||
|
||||
/** 修改对话的标题 */
|
||||
const updateConversationTitle = async (
|
||||
async function updateConversationTitle(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) => {
|
||||
) {
|
||||
// 1. 二次确认
|
||||
prompt({
|
||||
async beforeClose(scope) {
|
||||
@@ -225,12 +227,12 @@ const updateConversationTitle = async (
|
||||
title: '修改标题',
|
||||
modelPropName: 'value',
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除聊天对话 */
|
||||
const deleteChatConversation = async (
|
||||
async function deleteChatConversation(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) => {
|
||||
) {
|
||||
try {
|
||||
// 删除的二次确认
|
||||
await confirm(`是否确认删除对话 - ${conversation.title}?`);
|
||||
@@ -242,8 +244,9 @@ const deleteChatConversation = async (
|
||||
// 回调
|
||||
emits('onConversationDelete', conversation);
|
||||
} catch {}
|
||||
};
|
||||
const handleClearConversation = async () => {
|
||||
}
|
||||
|
||||
async function handleClearConversation() {
|
||||
try {
|
||||
await confirm('确认后对话会全部清空,置顶的对话除外。');
|
||||
await deleteChatConversationMyByUnpinned();
|
||||
@@ -255,18 +258,18 @@ const handleClearConversation = async () => {
|
||||
// 回调 方法
|
||||
emits('onConversationClear');
|
||||
} catch {}
|
||||
};
|
||||
}
|
||||
|
||||
/** 对话置顶 */
|
||||
const handleTop = async (
|
||||
async function handleTop(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) => {
|
||||
) {
|
||||
// 更新对话置顶
|
||||
conversation.pinned = !conversation.pinned;
|
||||
await updateChatConversationMy(conversation);
|
||||
// 刷新对话
|
||||
await getChatConversationList();
|
||||
};
|
||||
}
|
||||
|
||||
// ============ 角色仓库 ============
|
||||
|
||||
|
||||
@@ -47,10 +47,10 @@ const documentList = computed(() => {
|
||||
});
|
||||
|
||||
/** 点击 document 处理 */
|
||||
const handleClick = (doc: any) => {
|
||||
function handleClick(doc: any) {
|
||||
document.value = doc;
|
||||
dialogVisible.value = true;
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useClipboard } from '@vueuse/core';
|
||||
import { Avatar, Button, message } from 'ant-design-vue';
|
||||
|
||||
import { deleteChatMessage } from '#/api/ai/chat/message';
|
||||
import MarkdownView from '#/components/MarkdownView/index.vue';
|
||||
import { MarkdownView } from '#/components/markdown-view';
|
||||
|
||||
import MessageKnowledge from './MessageKnowledge.vue';
|
||||
// 定义 props
|
||||
@@ -67,44 +67,44 @@ function handleScroll() {
|
||||
}
|
||||
|
||||
/** 回到底部 */
|
||||
const handleGoBottom = async () => {
|
||||
async function handleGoBottom() {
|
||||
const scrollContainer = messageContainer.value;
|
||||
scrollContainer.scrollTop = scrollContainer.scrollHeight;
|
||||
};
|
||||
}
|
||||
|
||||
/** 回到顶部 */
|
||||
const handlerGoTop = async () => {
|
||||
async function handlerGoTop() {
|
||||
const scrollContainer = messageContainer.value;
|
||||
scrollContainer.scrollTop = 0;
|
||||
};
|
||||
}
|
||||
|
||||
defineExpose({ scrollToBottom, handlerGoTop }); // 提供方法给 parent 调用
|
||||
|
||||
// ============ 处理消息操作 ==============
|
||||
|
||||
/** 复制 */
|
||||
const copyContent = async (content: string) => {
|
||||
async function copyContent(content: string) {
|
||||
await copy(content);
|
||||
message.success('复制成功!');
|
||||
};
|
||||
}
|
||||
/** 删除 */
|
||||
const onDelete = async (id: number) => {
|
||||
async function onDelete(id: number) {
|
||||
// 删除 message
|
||||
await deleteChatMessage(id);
|
||||
message.success('删除成功!');
|
||||
// 回调
|
||||
emits('onDeleteSuccess');
|
||||
};
|
||||
}
|
||||
|
||||
/** 刷新 */
|
||||
const onRefresh = async (message: AiChatMessageApi.ChatMessageVO) => {
|
||||
async function onRefresh(message: AiChatMessageApi.ChatMessageVO) {
|
||||
emits('onRefresh', message);
|
||||
};
|
||||
}
|
||||
|
||||
/** 编辑 */
|
||||
const onEdit = async (message: AiChatMessageApi.ChatMessageVO) => {
|
||||
async function onEdit(message: AiChatMessageApi.ChatMessageVO) {
|
||||
emits('onEdit', message);
|
||||
};
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
|
||||
@@ -11,9 +11,9 @@ const promptList = [
|
||||
prompt: '写一首好听的诗歌?',
|
||||
},
|
||||
]; /** 选中 prompt 点击 */
|
||||
const handlerPromptClick = async (prompt: any) => {
|
||||
async function handlerPromptClick(prompt: any) {
|
||||
emits('onPrompt', prompt.prompt);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="relative flex h-full w-full flex-row justify-center">
|
||||
|
||||
@@ -4,9 +4,9 @@ import { Button } from 'ant-design-vue';
|
||||
const emits = defineEmits(['onNewConversation']);
|
||||
|
||||
/** 新建 conversation 聊天对话 */
|
||||
const handlerNewChat = () => {
|
||||
function handlerNewChat() {
|
||||
emits('onNewConversation');
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -19,9 +19,9 @@ defineProps({
|
||||
const emits = defineEmits(['onCategoryClick']);
|
||||
|
||||
/** 处理分类点击事件 */
|
||||
const handleCategoryClick = async (category: string) => {
|
||||
async function handleCategoryClick(category: string) {
|
||||
emits('onCategoryClick', category);
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -33,7 +33,7 @@ const emits = defineEmits(['onDelete', 'onEdit', 'onUse', 'onPage']);
|
||||
const tabsRef = ref<any>();
|
||||
|
||||
/** 操作:编辑、删除 */
|
||||
const handleMoreClick = async (data: any) => {
|
||||
async function handleMoreClick(data: any) {
|
||||
const type = data[0];
|
||||
const role = data[1];
|
||||
if (type === 'delete') {
|
||||
@@ -41,22 +41,22 @@ const handleMoreClick = async (data: any) => {
|
||||
} else {
|
||||
emits('onEdit', role);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 选中 */
|
||||
const handleUseClick = (role: any) => {
|
||||
function handleUseClick(role: any) {
|
||||
emits('onUse', role);
|
||||
};
|
||||
}
|
||||
|
||||
/** 滚动 */
|
||||
const handleTabsScroll = async () => {
|
||||
async function handleTabsScroll() {
|
||||
if (tabsRef.value) {
|
||||
const { scrollTop, scrollHeight, clientHeight } = tabsRef.value;
|
||||
if (scrollTop + clientHeight >= scrollHeight - 20 && !props.loading) {
|
||||
await emits('onPage');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -46,15 +46,15 @@ const activeCategory = ref<string>('全部'); // 选择中的分类
|
||||
const categoryList = ref<string[]>([]); // 角色分类类别
|
||||
|
||||
/** tabs 点击 */
|
||||
const handleTabsClick = async (tab: any) => {
|
||||
async function handleTabsClick(tab: any) {
|
||||
// 设置切换状态
|
||||
activeTab.value = tab;
|
||||
// 切换的时候重新加载数据
|
||||
await getActiveTabsRole();
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取 my role 我的角色 */
|
||||
const getMyRole = async (append?: boolean) => {
|
||||
async function getMyRole(append?: boolean) {
|
||||
const params: AiModelChatRoleApi.ChatRolePageReqVO = {
|
||||
...myRoleParams,
|
||||
name: search.value,
|
||||
@@ -66,10 +66,10 @@ const getMyRole = async (append?: boolean) => {
|
||||
} else {
|
||||
myRoleList.value = list;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取 public role 公共角色 */
|
||||
const getPublicRole = async (append?: boolean) => {
|
||||
async function getPublicRole(append?: boolean) {
|
||||
const params: AiModelChatRoleApi.ChatRolePageReqVO = {
|
||||
...publicRoleParams,
|
||||
category: activeCategory.value === '全部' ? '' : activeCategory.value,
|
||||
@@ -82,10 +82,10 @@ const getPublicRole = async (append?: boolean) => {
|
||||
} else {
|
||||
publicRoleList.value = list;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取选中的 tabs 角色 */
|
||||
const getActiveTabsRole = async () => {
|
||||
async function getActiveTabsRole() {
|
||||
if (activeTab.value === 'my-role') {
|
||||
myRoleParams.pageNo = 1;
|
||||
await getMyRole();
|
||||
@@ -93,43 +93,44 @@ const getActiveTabsRole = async () => {
|
||||
publicRoleParams.pageNo = 1;
|
||||
await getPublicRole();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 获取角色分类列表 */
|
||||
const getRoleCategoryList = async () => {
|
||||
async function getRoleCategoryList() {
|
||||
categoryList.value = ['全部', ...(await getCategoryList())];
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理分类点击 */
|
||||
const handlerCategoryClick = async (category: string) => {
|
||||
async function handlerCategoryClick(category: string) {
|
||||
// 切换选择的分类
|
||||
activeCategory.value = category;
|
||||
// 筛选
|
||||
await getActiveTabsRole();
|
||||
};
|
||||
}
|
||||
|
||||
const handlerAddRole = async () => {
|
||||
async function handlerAddRole() {
|
||||
formModalApi.setData({ formType: 'my-create' }).open();
|
||||
};
|
||||
}
|
||||
/** 编辑角色 */
|
||||
const handlerCardEdit = async (role: any) => {
|
||||
async function handlerCardEdit(role: any) {
|
||||
formModalApi.setData({ formType: 'my-update', id: role.id }).open();
|
||||
};
|
||||
}
|
||||
|
||||
/** 添加角色成功 */
|
||||
const handlerAddRoleSuccess = async () => {
|
||||
async function handlerAddRoleSuccess() {
|
||||
// 刷新数据
|
||||
await getActiveTabsRole();
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除角色 */
|
||||
const handlerCardDelete = async (role: any) => {
|
||||
async function handlerCardDelete(role: any) {
|
||||
await deleteMy(role.id);
|
||||
// 刷新数据
|
||||
await getActiveTabsRole();
|
||||
};
|
||||
}
|
||||
|
||||
/** 角色分页:获取下一页 */
|
||||
const handlerCardPage = async (type: string) => {
|
||||
async function handlerCardPage(type: string) {
|
||||
try {
|
||||
loading.value = true;
|
||||
if (type === 'public') {
|
||||
@@ -142,10 +143,10 @@ const handlerCardPage = async (type: string) => {
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 选择 card 角色:新建聊天对话 */
|
||||
const handlerCardUse = async (role: any) => {
|
||||
async function handlerCardUse(role: any) {
|
||||
// 1. 创建对话
|
||||
const data: AiChatConversationApi.ChatConversationVO = {
|
||||
roleId: role.id,
|
||||
@@ -159,7 +160,8 @@ const handlerCardUse = async (role: any) => {
|
||||
conversationId,
|
||||
},
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
// 获取分类
|
||||
|
||||
@@ -61,7 +61,7 @@ const receiveMessageDisplayedText = ref('');
|
||||
// =========== 【聊天对话】相关 ===========
|
||||
|
||||
/** 获取对话信息 */
|
||||
const getConversation = async (id: null | number) => {
|
||||
async function getConversation(id: null | number) {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ const getConversation = async (id: null | number) => {
|
||||
}
|
||||
activeConversation.value = conversation;
|
||||
activeConversationId.value = conversation.id;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击某个对话
|
||||
@@ -80,9 +80,9 @@ const getConversation = async (id: null | number) => {
|
||||
* @param conversation 选中的对话
|
||||
* @return 是否切换成功
|
||||
*/
|
||||
const handleConversationClick = async (
|
||||
async function handleConversationClick(
|
||||
conversation: AiChatConversationApi.ChatConversationVO,
|
||||
) => {
|
||||
) {
|
||||
// 对话进行中,不允许切换
|
||||
if (conversationInProgress.value) {
|
||||
alert('对话中,不允许切换!');
|
||||
@@ -99,20 +99,20 @@ const handleConversationClick = async (
|
||||
// 清空输入框
|
||||
prompt.value = '';
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除某个对话*/
|
||||
const handlerConversationDelete = async (
|
||||
async function handlerConversationDelete(
|
||||
delConversation: AiChatConversationApi.ChatConversationVO,
|
||||
) => {
|
||||
) {
|
||||
// 删除的对话如果是当前选中的,那么就重置
|
||||
if (activeConversationId.value === delConversation.id) {
|
||||
await handleConversationClear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 清空选中的对话 */
|
||||
const handleConversationClear = async () => {
|
||||
async function handleConversationClear() {
|
||||
// 对话进行中,不允许切换
|
||||
if (conversationInProgress.value) {
|
||||
alert('对话中,不允许切换!');
|
||||
@@ -121,31 +121,31 @@ const handleConversationClear = async () => {
|
||||
activeConversationId.value = null;
|
||||
activeConversation.value = null;
|
||||
activeMessageList.value = [];
|
||||
};
|
||||
}
|
||||
|
||||
const openChatConversationUpdateForm = async () => {
|
||||
async function openChatConversationUpdateForm() {
|
||||
formModalApi.setData({ id: activeConversationId.value }).open();
|
||||
};
|
||||
const handleConversationUpdateSuccess = async () => {
|
||||
}
|
||||
async function handleConversationUpdateSuccess() {
|
||||
// 对话更新成功,刷新最新信息
|
||||
await getConversation(activeConversationId.value);
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理聊天对话的创建成功 */
|
||||
const handleConversationCreate = async () => {
|
||||
async function handleConversationCreate() {
|
||||
// 创建对话
|
||||
await conversationListRef.value.createConversation();
|
||||
};
|
||||
}
|
||||
/** 处理聊天对话的创建成功 */
|
||||
const handleConversationCreateSuccess = async () => {
|
||||
async function handleConversationCreateSuccess() {
|
||||
// 创建新的对话,清空输入框
|
||||
prompt.value = '';
|
||||
};
|
||||
}
|
||||
|
||||
// =========== 【消息列表】相关 ===========
|
||||
|
||||
/** 获取消息 message 列表 */
|
||||
const getMessageList = async () => {
|
||||
async function getMessageList() {
|
||||
try {
|
||||
if (activeConversationId.value === null) {
|
||||
return;
|
||||
@@ -171,7 +171,7 @@ const getMessageList = async () => {
|
||||
// 加载结束
|
||||
activeMessageListLoading.value = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息列表
|
||||
@@ -196,17 +196,17 @@ const messageList = computed(() => {
|
||||
});
|
||||
|
||||
/** 处理删除 message 消息 */
|
||||
const handleMessageDelete = () => {
|
||||
function handleMessageDelete() {
|
||||
if (conversationInProgress.value) {
|
||||
alert('回答中,不能删除!');
|
||||
return;
|
||||
}
|
||||
// 刷新 message 列表
|
||||
getMessageList();
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理 message 清空 */
|
||||
const handlerMessageClear = async () => {
|
||||
async function handlerMessageClear() {
|
||||
if (!activeConversationId.value) {
|
||||
return;
|
||||
}
|
||||
@@ -218,16 +218,16 @@ const handlerMessageClear = async () => {
|
||||
// 刷新 message 列表
|
||||
activeMessageList.value = [];
|
||||
} catch {}
|
||||
};
|
||||
}
|
||||
|
||||
/** 回到 message 列表的顶部 */
|
||||
const handleGoTopMessage = () => {
|
||||
function handleGoTopMessage() {
|
||||
messageRef.value.handlerGoTop();
|
||||
};
|
||||
}
|
||||
|
||||
// =========== 【发送消息】相关 ===========
|
||||
/** 处理来自 keydown 的发送消息 */
|
||||
const handleSendByKeydown = async (event: any) => {
|
||||
async function handleSendByKeydown(event: any) {
|
||||
// 判断用户是否在输入
|
||||
if (isComposing.value) {
|
||||
return;
|
||||
@@ -248,15 +248,15 @@ const handleSendByKeydown = async (event: any) => {
|
||||
event.preventDefault(); // 防止默认的提交行为
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理来自【发送】按钮的发送消息 */
|
||||
const handleSendByButton = () => {
|
||||
function handleSendByButton() {
|
||||
doSendMessage(prompt.value?.trim() as string);
|
||||
};
|
||||
}
|
||||
|
||||
/** 处理 prompt 输入变化 */
|
||||
const handlePromptInput = (event) => {
|
||||
function handlePromptInput(event: any) {
|
||||
// 非输入法 输入设置为 true
|
||||
if (!isComposing.value) {
|
||||
// 回车 event data 是 null
|
||||
@@ -273,27 +273,27 @@ const handlePromptInput = (event) => {
|
||||
inputTimeout.value = setTimeout(() => {
|
||||
isComposing.value = false;
|
||||
}, 400);
|
||||
};
|
||||
}
|
||||
|
||||
const onCompositionstart = () => {
|
||||
function onCompositionstart() {
|
||||
isComposing.value = true;
|
||||
};
|
||||
}
|
||||
|
||||
const onCompositionend = () => {
|
||||
function onCompositionend() {
|
||||
// console.log('输入结束...')
|
||||
setTimeout(() => {
|
||||
isComposing.value = false;
|
||||
}, 200);
|
||||
};
|
||||
}
|
||||
|
||||
/** 真正执行【发送】消息操作 */
|
||||
const doSendMessage = async (content: string) => {
|
||||
async function doSendMessage(content: string) {
|
||||
// 校验
|
||||
if (content.length === 0) {
|
||||
message.error('发送失败,原因:内容为空!');
|
||||
return;
|
||||
}
|
||||
if (activeConversationId.value == null) {
|
||||
if (activeConversationId.value === null) {
|
||||
message.error('还没创建对话,不能发送!');
|
||||
return;
|
||||
}
|
||||
@@ -304,12 +304,12 @@ const doSendMessage = async (content: string) => {
|
||||
conversationId: activeConversationId.value,
|
||||
content,
|
||||
} as AiChatMessageApi.ChatMessageVO);
|
||||
};
|
||||
}
|
||||
|
||||
/** 真正执行【发送】消息操作 */
|
||||
const doSendMessageStream = async (
|
||||
async function doSendMessageStream(
|
||||
userMessage: AiChatMessageApi.ChatMessageVO,
|
||||
) => {
|
||||
) {
|
||||
// 创建 AbortController 实例,以便中止请求
|
||||
conversationInAbortController.value = new AbortController();
|
||||
// 标记对话进行中
|
||||
@@ -385,40 +385,40 @@ const doSendMessageStream = async (
|
||||
},
|
||||
);
|
||||
} catch {}
|
||||
};
|
||||
}
|
||||
|
||||
/** 停止 stream 流式调用 */
|
||||
const stopStream = async () => {
|
||||
async function stopStream() {
|
||||
// tip:如果 stream 进行中的 message,就需要调用 controller 结束
|
||||
if (conversationInAbortController.value) {
|
||||
conversationInAbortController.value.abort();
|
||||
}
|
||||
// 设置为 false
|
||||
conversationInProgress.value = false;
|
||||
};
|
||||
}
|
||||
|
||||
/** 编辑 message:设置为 prompt,可以再次编辑 */
|
||||
const handleMessageEdit = (message: AiChatMessageApi.ChatMessageVO) => {
|
||||
function handleMessageEdit(message: AiChatMessageApi.ChatMessageVO) {
|
||||
prompt.value = message.content;
|
||||
};
|
||||
}
|
||||
|
||||
/** 刷新 message:基于指定消息,再次发起对话 */
|
||||
const handleMessageRefresh = (message: AiChatMessageApi.ChatMessageVO) => {
|
||||
function handleMessageRefresh(message: AiChatMessageApi.ChatMessageVO) {
|
||||
doSendMessage(message.content);
|
||||
};
|
||||
}
|
||||
|
||||
// ============== 【消息滚动】相关 =============
|
||||
|
||||
/** 滚动到 message 底部 */
|
||||
const scrollToBottom = async (isIgnore?: boolean) => {
|
||||
async function scrollToBottom(isIgnore?: boolean) {
|
||||
await nextTick();
|
||||
if (messageRef.value) {
|
||||
messageRef.value.scrollToBottom(isIgnore);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** 自提滚动效果 */
|
||||
const textRoll = async () => {
|
||||
async function textRoll() {
|
||||
let index = 0;
|
||||
try {
|
||||
// 只能执行一次
|
||||
@@ -475,7 +475,7 @@ const textRoll = async () => {
|
||||
};
|
||||
let timer = setTimeout(task, textSpeed.value);
|
||||
} catch {}
|
||||
};
|
||||
}
|
||||
|
||||
/** 初始化 */
|
||||
onMounted(async () => {
|
||||
@@ -569,8 +569,8 @@ onMounted(async () => {
|
||||
<MessageList
|
||||
v-if="!activeMessageListLoading && messageList.length > 0"
|
||||
ref="messageRef"
|
||||
:conversation="activeConversation"
|
||||
:list="messageList"
|
||||
:conversation="activeConversation as any"
|
||||
:list="messageList as any"
|
||||
@on-delete-success="handleMessageDelete"
|
||||
@on-edit="handleMessageEdit"
|
||||
@on-refresh="handleMessageRefresh"
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { VbenFormSchema } from '#/adapter/form';
|
||||
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
|
||||
|
||||
import { getSimpleUserList } from '#/api/system/user';
|
||||
import { DICT_TYPE } from '#/utils';
|
||||
import { DICT_TYPE, getRangePickerDefaultProps } from '#/utils';
|
||||
|
||||
/** 列表的搜索表单 */
|
||||
export function useGridFormSchemaConversation(): VbenFormSchema[] {
|
||||
@@ -22,8 +22,7 @@ export function useGridFormSchemaConversation(): VbenFormSchema[] {
|
||||
label: '创建时间',
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
placeholder: ['开始时间', '结束时间'],
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
...getRangePickerDefaultProps(),
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
@@ -118,8 +117,7 @@ export function useGridFormSchemaMessage(): VbenFormSchema[] {
|
||||
label: '创建时间',
|
||||
component: 'RangePicker',
|
||||
componentProps: {
|
||||
placeholder: ['开始时间', '结束时间'],
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||
...getRangePickerDefaultProps(),
|
||||
allowClear: true,
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user