houzhongjian
2024-08-08 820397e43a0b64d35c6d31d2a55475061438593b
提交 | 用户 | 时间
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>