fix(page): 🧩 修改请求使用最近hook-fetch的hooks

This commit is contained in:
Json_Lee 2025-06-11 09:42:50 +08:00
parent 10100e0786
commit 0a8841424d
4 changed files with 41 additions and 49 deletions

View File

@ -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
View File

@ -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

View File

@ -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"

View File

@ -1 +1,2 @@
/// <reference types="hook-fetch/plugins" /> /// <reference types="hook-fetch/plugins" />
/// <reference types="hook-fetch/vue" />