138 lines
3.6 KiB
Vue
138 lines
3.6 KiB
Vue
<script lang="ts" setup>
|
||
import { toTypedSchema } from '@vee-validate/zod'
|
||
import { useForm } from 'vee-validate'
|
||
import { toast } from 'vue-sonner'
|
||
import { z } from 'zod'
|
||
|
||
const route = useRoute()
|
||
const router = useRouter()
|
||
|
||
const historyStore = useLlmHistories('course-research-plan')
|
||
const { conversations } = storeToRefs(historyStore)
|
||
const { updateConversation, appendChunkToLast, isConversationExist } =
|
||
historyStore
|
||
|
||
const activeConversationId = ref<string | null>(null)
|
||
|
||
watch(activeConversationId, (val) => {
|
||
if (val) {
|
||
router.replace({
|
||
query: {
|
||
fn: route.query.fn,
|
||
conversationId: val,
|
||
},
|
||
})
|
||
} else {
|
||
router.replace({
|
||
query: {
|
||
fn: route.query.fn,
|
||
},
|
||
})
|
||
}
|
||
})
|
||
|
||
onMounted(() => {
|
||
if (route.query.conversationId) {
|
||
if (isConversationExist(route.query.conversationId as string)) {
|
||
activeConversationId.value = route.query.conversationId as string
|
||
} else {
|
||
activeConversationId.value = null
|
||
toast.error('会话不存在')
|
||
}
|
||
}
|
||
})
|
||
|
||
const schema = z.object({
|
||
subject: z.string({ required_error: '请输入学科名称' }).describe('学科'),
|
||
backgroundAnalysis: z
|
||
.string({ required_error: '请输入当前学科的现状和背景分析' })
|
||
.describe('背景及现状分析'),
|
||
workGoal: z
|
||
.string({ required_error: '请输入教研计划的工作目标' })
|
||
.describe('工作目标'),
|
||
workFocusAndMeasures: z
|
||
.string({
|
||
required_error: '请输入教研计划的工作重点和措施',
|
||
})
|
||
.describe('工作重点和措施'),
|
||
})
|
||
|
||
const form = useForm({
|
||
validationSchema: toTypedSchema(schema),
|
||
})
|
||
|
||
const onSubmit = (values: z.infer<typeof schema>) => {
|
||
http_stream<z.infer<typeof schema>>(
|
||
'/ai/teaching-research-plan/stream',
|
||
values,
|
||
{
|
||
onStart(id, created_at) {
|
||
activeConversationId.value = id
|
||
updateConversation(id, {
|
||
id,
|
||
created_at,
|
||
title: values.subject,
|
||
messages: [
|
||
{
|
||
role: 'user',
|
||
content: `生成教研计划\n学科:${values.subject}\n背景及现状分析:${values.backgroundAnalysis}\n工作目标:${values.workGoal}\n工作重点和措施:${values.workFocusAndMeasures}`,
|
||
},
|
||
{
|
||
role: 'assistant',
|
||
content: '',
|
||
},
|
||
],
|
||
})
|
||
},
|
||
onTextChunk: (chunk) => {
|
||
appendChunkToLast(activeConversationId.value!, chunk)
|
||
},
|
||
onComplete: (id, finished_at) => {
|
||
updateConversation(id!, {
|
||
finished_at,
|
||
})
|
||
},
|
||
},
|
||
)
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<div>
|
||
<AiConversation
|
||
:form
|
||
:form-schema="schema"
|
||
:form-field-config="{
|
||
subject: {
|
||
inputProps: {
|
||
placeholder: '请输入学科名称,如:大学英语、电力电子技术',
|
||
},
|
||
},
|
||
backgroundAnalysis: {
|
||
inputProps: {
|
||
placeholder: '请输入当前学科的现状和背景分析',
|
||
},
|
||
},
|
||
workGoal: {
|
||
inputProps: {
|
||
placeholder: '请输入教研计划的工作目标,如:提升教学质量',
|
||
},
|
||
},
|
||
workFocusAndMeasures: {
|
||
inputProps: {
|
||
placeholder: '请输入教研计划的工作重点和措施,如:开展教学研讨',
|
||
},
|
||
},
|
||
}"
|
||
:conversations
|
||
:active-conversation-id="activeConversationId"
|
||
disable-user-input
|
||
@submit="onSubmit"
|
||
@update:conversation-id="activeConversationId = $event"
|
||
@delete-conversation="historyStore.removeConversation($event)"
|
||
/>
|
||
</div>
|
||
</template>
|
||
|
||
<style scoped></style>
|