fix(page): 🧩 修改请求使用最近hook-fetch的hooks
This commit is contained in:
parent
10100e0786
commit
0a8841424d
18
package.json
18
package.json
@ -36,7 +36,7 @@
|
|||||||
"@vueuse/core": "^13.3.0",
|
"@vueuse/core": "^13.3.0",
|
||||||
"@vueuse/integrations": "^13.3.0",
|
"@vueuse/integrations": "^13.3.0",
|
||||||
"element-plus": "^2.9.11",
|
"element-plus": "^2.9.11",
|
||||||
"hook-fetch": "1.1.2",
|
"hook-fetch": "^1.1.3",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.3.0",
|
"pinia-plugin-persistedstate": "^4.3.0",
|
||||||
@ -60,6 +60,13 @@
|
|||||||
"lint-staged": "^16.1.0",
|
"lint-staged": "^16.1.0",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"sass-embedded": "^1.89.1",
|
"sass-embedded": "^1.89.1",
|
||||||
|
"stylelint": "^16.20.0",
|
||||||
|
"stylelint-config-html": "^1.1.0",
|
||||||
|
"stylelint-config-recess-order": "^6.0.0",
|
||||||
|
"stylelint-config-recommended-scss": "^15.0.1",
|
||||||
|
"stylelint-config-recommended-vue": "^1.6.0",
|
||||||
|
"stylelint-config-standard": "^38.0.0",
|
||||||
|
"stylelint-config-standard-scss": "^15.0.1",
|
||||||
"typescript": "~5.8.3",
|
"typescript": "~5.8.3",
|
||||||
"typescript-api-pro": "^0.0.7",
|
"typescript-api-pro": "^0.0.7",
|
||||||
"unocss": "66.1.3",
|
"unocss": "66.1.3",
|
||||||
@ -68,14 +75,7 @@
|
|||||||
"vite": "^6.3.5",
|
"vite": "^6.3.5",
|
||||||
"vite-plugin-env-typed": "^0.0.2",
|
"vite-plugin-env-typed": "^0.0.2",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
"vue-tsc": "^2.2.10",
|
"vue-tsc": "^2.2.10"
|
||||||
"stylelint": "^16.20.0",
|
|
||||||
"stylelint-config-html": "^1.1.0",
|
|
||||||
"stylelint-config-recess-order": "^6.0.0",
|
|
||||||
"stylelint-config-recommended-scss": "^15.0.1",
|
|
||||||
"stylelint-config-recommended-vue": "^1.6.0",
|
|
||||||
"stylelint-config-standard": "^38.0.0",
|
|
||||||
"stylelint-config-standard-scss": "^15.0.1"
|
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"commitizen": {
|
"commitizen": {
|
||||||
|
|||||||
20
pnpm-lock.yaml
generated
20
pnpm-lock.yaml
generated
@ -33,8 +33,8 @@ importers:
|
|||||||
specifier: ^2.9.11
|
specifier: ^2.9.11
|
||||||
version: 2.9.11(vue@3.5.16(typescript@5.8.3))
|
version: 2.9.11(vue@3.5.16(typescript@5.8.3))
|
||||||
hook-fetch:
|
hook-fetch:
|
||||||
specifier: 1.1.2
|
specifier: ^1.1.3
|
||||||
version: 1.1.2(typescript-api-pro@0.0.7)
|
version: 1.1.3(react@19.1.0)(typescript-api-pro@0.0.7)(vue@3.5.16(typescript@5.8.3))
|
||||||
nprogress:
|
nprogress:
|
||||||
specifier: ^0.2.0
|
specifier: ^0.2.0
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
@ -2788,10 +2788,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
hook-fetch@1.1.2:
|
hook-fetch@1.1.3:
|
||||||
resolution: {integrity: sha512-Vi4Afdj7DY8LouCaeXjH1TKk6DtZDVtkEvVcvRH044BTamajzVgTjTws++tWkDvX90Ih/7/mZ8qB1h4Nwf5RXA==}
|
resolution: {integrity: sha512-FkWKUjZWr83gyew0YbRyEc72dlIGCYvNXiRfi4AXlb/hvIiFPQfcvlP3IFaIYKERUeKXmuBS9fuNuK8JPQiOCg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
react: ^19.1.0
|
||||||
typescript-api-pro: ^0.0.6
|
typescript-api-pro: ^0.0.6
|
||||||
|
vue: ^3.5.16
|
||||||
|
|
||||||
hookable@5.5.3:
|
hookable@5.5.3:
|
||||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||||
@ -3934,6 +3936,10 @@ packages:
|
|||||||
rc9@2.1.2:
|
rc9@2.1.2:
|
||||||
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
|
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
|
||||||
|
|
||||||
|
react@19.1.0:
|
||||||
|
resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
read-yaml-file@1.1.0:
|
read-yaml-file@1.1.0:
|
||||||
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
|
resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -8023,11 +8029,13 @@ snapshots:
|
|||||||
|
|
||||||
he@1.2.0: {}
|
he@1.2.0: {}
|
||||||
|
|
||||||
hook-fetch@1.1.2(typescript-api-pro@0.0.7):
|
hook-fetch@1.1.3(react@19.1.0)(typescript-api-pro@0.0.7)(vue@3.5.16(typescript@5.8.3)):
|
||||||
dependencies:
|
dependencies:
|
||||||
qs: 6.14.0
|
qs: 6.14.0
|
||||||
radash: 12.1.0
|
radash: 12.1.0
|
||||||
|
react: 19.1.0
|
||||||
typescript-api-pro: 0.0.7
|
typescript-api-pro: 0.0.7
|
||||||
|
vue: 3.5.16(typescript@5.8.3)
|
||||||
|
|
||||||
hookable@5.5.3: {}
|
hookable@5.5.3: {}
|
||||||
|
|
||||||
@ -9299,6 +9307,8 @@ snapshots:
|
|||||||
defu: 6.1.4
|
defu: 6.1.4
|
||||||
destr: 2.0.5
|
destr: 2.0.5
|
||||||
|
|
||||||
|
react@19.1.0: {}
|
||||||
|
|
||||||
read-yaml-file@1.1.0:
|
read-yaml-file@1.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
<!-- 每个回话对应的聊天内容 -->
|
<!-- 每个回话对应的聊天内容 -->
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { HookFetchRequest } from 'node_modules/hook-fetch/types/utils';
|
|
||||||
import type { AnyObject } from 'typescript-api-pro';
|
import type { AnyObject } from 'typescript-api-pro';
|
||||||
import type { Sender } from 'vue-element-plus-x';
|
import type { Sender } from 'vue-element-plus-x';
|
||||||
import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
|
import type { BubbleProps } from 'vue-element-plus-x/types/Bubble';
|
||||||
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
|
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
|
||||||
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
|
||||||
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
|
import type { ThinkingStatus } from 'vue-element-plus-x/types/Thinking';
|
||||||
|
import { useHookFetch } from 'hook-fetch/vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { send } from '@/api';
|
import { send } from '@/api';
|
||||||
import FilesSelect from '@/components/FilesSelect/index.vue';
|
import FilesSelect from '@/components/FilesSelect/index.vue';
|
||||||
@ -40,9 +40,13 @@ const inputValue = ref('');
|
|||||||
const senderRef = ref<InstanceType<typeof Sender> | null>(null);
|
const senderRef = ref<InstanceType<typeof Sender> | null>(null);
|
||||||
const bubbleItems = ref<MessageItem[]>([]);
|
const bubbleItems = ref<MessageItem[]>([]);
|
||||||
const bubbleListRef = ref<BubbleListInstance | null>(null);
|
const bubbleListRef = ref<BubbleListInstance | null>(null);
|
||||||
const isLoading = ref(false);
|
|
||||||
// 记录发送的返回
|
const { stream, loading: isLoading, cancel } = useHookFetch({
|
||||||
let sendRequest: HookFetchRequest<any, any> | null = null;
|
request: send,
|
||||||
|
onError: (err) => {
|
||||||
|
console.warn('测试错误拦截', err);
|
||||||
|
},
|
||||||
|
});
|
||||||
// 记录进入思考中
|
// 记录进入思考中
|
||||||
let isThinking = false;
|
let isThinking = false;
|
||||||
|
|
||||||
@ -91,7 +95,6 @@ watch(
|
|||||||
// 封装数据处理逻辑
|
// 封装数据处理逻辑
|
||||||
function handleDataChunk(chunk: AnyObject) {
|
function handleDataChunk(chunk: AnyObject) {
|
||||||
try {
|
try {
|
||||||
// console.log('New chunk:', chunk);
|
|
||||||
const reasoningChunk = chunk.choices?.[0].delta.reasoning_content;
|
const reasoningChunk = chunk.choices?.[0].delta.reasoning_content;
|
||||||
if (reasoningChunk) {
|
if (reasoningChunk) {
|
||||||
// 开始思考链状态
|
// 开始思考链状态
|
||||||
@ -153,14 +156,13 @@ async function startSSE(chatContent: string) {
|
|||||||
// console.log('chatContent', chatContent);
|
// console.log('chatContent', chatContent);
|
||||||
// 清空输入框
|
// 清空输入框
|
||||||
inputValue.value = '';
|
inputValue.value = '';
|
||||||
isLoading.value = true;
|
|
||||||
addMessage(chatContent, true);
|
addMessage(chatContent, true);
|
||||||
addMessage('', false);
|
addMessage('', false);
|
||||||
|
|
||||||
// 这里有必要调用一下 BubbleList 组件的滚动到底部 手动触发 自动滚动
|
// 这里有必要调用一下 BubbleList 组件的滚动到底部 手动触发 自动滚动
|
||||||
bubbleListRef.value?.scrollToBottom();
|
bubbleListRef.value?.scrollToBottom();
|
||||||
|
|
||||||
sendRequest = send({
|
for await (const chunk of stream({
|
||||||
messages: bubbleItems.value
|
messages: bubbleItems.value
|
||||||
.filter((item: any) => item.role === 'user')
|
.filter((item: any) => item.role === 'user')
|
||||||
.map((item: any) => ({
|
.map((item: any) => ({
|
||||||
@ -170,9 +172,7 @@ async function startSSE(chatContent: string) {
|
|||||||
sessionId: route.params?.id !== 'not_login' ? String(route.params?.id) : undefined,
|
sessionId: route.params?.id !== 'not_login' ? String(route.params?.id) : undefined,
|
||||||
userId: userStore.userInfo?.userId,
|
userId: userStore.userInfo?.userId,
|
||||||
model: modelStore.currentModelInfo.modelName ?? '',
|
model: modelStore.currentModelInfo.modelName ?? '',
|
||||||
});
|
})) {
|
||||||
|
|
||||||
for await (const chunk of sendRequest.stream()) {
|
|
||||||
handleDataChunk(chunk.result as AnyObject);
|
handleDataChunk(chunk.result as AnyObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,14 +185,12 @@ async function startSSE(chatContent: string) {
|
|||||||
if (bubbleItems.value.length) {
|
if (bubbleItems.value.length) {
|
||||||
bubbleItems.value[bubbleItems.value.length - 1].typing = false;
|
bubbleItems.value[bubbleItems.value.length - 1].typing = false;
|
||||||
}
|
}
|
||||||
isLoading.value = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 中断请求
|
// 中断请求
|
||||||
async function cancelSSE() {
|
async function cancelSSE() {
|
||||||
sendRequest?.abort();
|
cancel();
|
||||||
isLoading.value = false;
|
|
||||||
// 结束最后一条消息打字状态
|
// 结束最后一条消息打字状态
|
||||||
if (bubbleItems.value.length) {
|
if (bubbleItems.value.length) {
|
||||||
bubbleItems.value[bubbleItems.value.length - 1].typing = false;
|
bubbleItems.value[bubbleItems.value.length - 1].typing = false;
|
||||||
@ -252,38 +250,21 @@ watch(
|
|||||||
<BubbleList ref="bubbleListRef" :list="bubbleItems" max-height="calc(100vh - 240px)">
|
<BubbleList ref="bubbleListRef" :list="bubbleItems" max-height="calc(100vh - 240px)">
|
||||||
<template #header="{ item }">
|
<template #header="{ item }">
|
||||||
<Thinking
|
<Thinking
|
||||||
v-if="item.reasoning_content"
|
v-if="item.reasoning_content" v-model="item.thinlCollapse" :content="item.reasoning_content"
|
||||||
v-model="item.thinlCollapse"
|
:status="item.thinkingStatus" class="thinking-chain-warp" @change="handleChange"
|
||||||
:content="item.reasoning_content"
|
|
||||||
:status="item.thinkingStatus"
|
|
||||||
class="thinking-chain-warp"
|
|
||||||
@change="handleChange"
|
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</BubbleList>
|
</BubbleList>
|
||||||
|
|
||||||
<Sender
|
<Sender
|
||||||
ref="senderRef"
|
ref="senderRef" v-model="inputValue" class="chat-defaul-sender" :auto-size="{
|
||||||
v-model="inputValue"
|
|
||||||
class="chat-defaul-sender"
|
|
||||||
:auto-size="{
|
|
||||||
maxRows: 6,
|
maxRows: 6,
|
||||||
minRows: 2,
|
minRows: 2,
|
||||||
}"
|
}" variant="updown" clearable allow-speech :loading="isLoading" @submit="startSSE" @cancel="cancelSSE"
|
||||||
variant="updown"
|
|
||||||
clearable
|
|
||||||
allow-speech
|
|
||||||
:loading="isLoading"
|
|
||||||
@submit="startSSE"
|
|
||||||
@cancel="cancelSSE"
|
|
||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<div class="sender-header p-12px pt-6px pb-0px">
|
<div class="sender-header p-12px pt-6px pb-0px">
|
||||||
<Attachments
|
<Attachments :items="filesStore.filesList" :hide-upload="true" @delete-card="handleDeleteCard">
|
||||||
:items="filesStore.filesList"
|
|
||||||
:hide-upload="true"
|
|
||||||
@delete-card="handleDeleteCard"
|
|
||||||
>
|
|
||||||
<template #prev-button="{ show, onScrollLeft }">
|
<template #prev-button="{ show, onScrollLeft }">
|
||||||
<div
|
<div
|
||||||
v-if="show"
|
v-if="show"
|
||||||
|
|||||||
1
types/hook-fetch.d.ts
vendored
1
types/hook-fetch.d.ts
vendored
@ -1 +1,2 @@
|
|||||||
/// <reference types="hook-fetch/plugins" />
|
/// <reference types="hook-fetch/plugins" />
|
||||||
|
/// <reference types="hook-fetch/vue" />
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user