提交 | 用户 | 时间
|
820397
|
1 |
<template> |
H |
2 |
<div class="absolute top-0 left-0 right-0 bottom-0 flex"> |
|
3 |
<Left |
|
4 |
:is-writing="isWriting" |
|
5 |
class="h-full" |
|
6 |
@submit="submit" |
|
7 |
@reset="reset" |
|
8 |
@example="handleExampleClick" |
|
9 |
/> |
|
10 |
<Right |
|
11 |
:is-writing="isWriting" |
|
12 |
@stop-stream="stopStream" |
|
13 |
ref="rightRef" |
|
14 |
class="flex-grow" |
|
15 |
v-model:content="writeResult" |
|
16 |
/> |
|
17 |
</div> |
|
18 |
</template> |
|
19 |
|
|
20 |
<script setup lang="ts"> |
|
21 |
import Left from './components/Left.vue' |
|
22 |
import Right from './components/Right.vue' |
|
23 |
import { WriteApi, WriteVO } from '@/api/ai/write' |
|
24 |
import { WriteExample } from '@/views/ai/utils/constants' |
|
25 |
|
|
26 |
const message = useMessage() |
|
27 |
|
|
28 |
const writeResult = ref('') // 写作结果 |
|
29 |
const isWriting = ref(false) // 是否正在写作中 |
|
30 |
const abortController = ref<AbortController>() // // 写作进行中 abort 控制器(控制 stream 写作) |
|
31 |
|
|
32 |
/** 停止 stream 生成 */ |
|
33 |
const stopStream = () => { |
|
34 |
abortController.value?.abort() |
|
35 |
isWriting.value = false |
|
36 |
} |
|
37 |
|
|
38 |
/** 执行写作 */ |
|
39 |
const rightRef = ref<InstanceType<typeof Right>>() |
|
40 |
const submit = (data: WriteVO) => { |
|
41 |
abortController.value = new AbortController() |
|
42 |
writeResult.value = '' |
|
43 |
isWriting.value = true |
|
44 |
WriteApi.writeStream({ |
|
45 |
data, |
|
46 |
onMessage: async (res) => { |
|
47 |
const { code, data, msg } = JSON.parse(res.data) |
|
48 |
if (code !== 0) { |
|
49 |
message.alert(`写作异常! ${msg}`) |
|
50 |
stopStream() |
|
51 |
return |
|
52 |
} |
|
53 |
writeResult.value = writeResult.value + data |
|
54 |
// 滚动到底部 |
|
55 |
await nextTick() |
|
56 |
rightRef.value?.scrollToBottom() |
|
57 |
}, |
|
58 |
ctrl: abortController.value, |
|
59 |
onClose: stopStream, |
|
60 |
onError: (...err) => { |
|
61 |
console.error('写作异常', ...err) |
|
62 |
stopStream() |
|
63 |
} |
|
64 |
}) |
|
65 |
} |
|
66 |
|
|
67 |
/** 点击示例触发 */ |
|
68 |
const handleExampleClick = (type: keyof typeof WriteExample) => { |
|
69 |
writeResult.value = WriteExample[type].data |
|
70 |
} |
|
71 |
|
|
72 |
/** 点击重置的时候清空写作的结果**/ |
|
73 |
const reset = () => { |
|
74 |
writeResult.value = '' |
|
75 |
} |
|
76 |
</script> |