feat: 完成整体内容开发

This commit is contained in:
2026-05-22 16:27:35 +08:00
parent 5e05bf4f63
commit d3cb786edb
72 changed files with 2410 additions and 29 deletions
+108
View File
@@ -0,0 +1,108 @@
<!-- app/components/home/AnswerForm.vue - 答题提交表单状态全部来自 Pinia store -->
<script lang="ts" setup>
import { Search } from "lucide-vue-next";
import { storeToRefs } from "pinia";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle
} from "@/components/ui/card";
import { Label } from "@/components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import type { QuestionType } from "@/interfaces";
import { QUESTION_TYPE_OPTIONS, useAnswerStore } from "@/stores/answer";
const answerStore = useAnswerStore();
const { question, questionType, options, searchLoading } =
storeToRefs(answerStore);
const AUTO_TYPE_VALUE = "__auto__";
/** shadcn Select 不使用空字符串作为 item value,这里只在组件边界做一次映射 */
const selectedQuestionType = computed({
get: () => questionType.value || AUTO_TYPE_VALUE,
set: (value: string) => {
questionType.value =
value === AUTO_TYPE_VALUE ? "" : (value as QuestionType);
}
});
/** 表单提交只触发 store action,组件不直接接触请求服务 */
const onSubmit = () => {
void answerStore.searchAnswer();
};
</script>
<template>
<Card>
<CardHeader>
<CardTitle class="text-xl">题目查询</CardTitle>
<CardDescription
>服务端流式请求模型前端返回普通 JSON 结果</CardDescription
>
</CardHeader>
<CardContent>
<form class="grid gap-4" @submit.prevent="onSubmit">
<div class="grid gap-2">
<Label for="answer-question">题目</Label>
<Textarea
id="answer-question"
v-model="question"
class="min-h-32 resize-y"
placeholder="输入题目内容"
/>
</div>
<div
class="grid gap-4 md:grid-cols-[220px_minmax(0,1fr)] md:items-start"
>
<div class="grid gap-2">
<Label for="answer-type">题型</Label>
<Select v-model="selectedQuestionType">
<SelectTrigger id="answer-type" class="w-full">
<SelectValue placeholder="自动判断" />
</SelectTrigger>
<SelectContent>
<SelectItem
v-for="item in QUESTION_TYPE_OPTIONS"
:key="item.value || AUTO_TYPE_VALUE"
:value="item.value || AUTO_TYPE_VALUE"
>
{{ item.label }}
</SelectItem>
</SelectContent>
</Select>
</div>
<div class="grid gap-2">
<Label for="answer-options">选项</Label>
<Textarea
id="answer-options"
v-model="options"
class="min-h-24 resize-y"
placeholder="A. 选项一&#10;B. 选项二"
/>
</div>
</div>
<div class="flex items-center justify-end">
<Button type="submit" :disabled="searchLoading">
<Search class="size-4" />
<span>{{ searchLoading ? "查询中" : "获取答案" }}</span>
</Button>
</div>
</form>
</CardContent>
</Card>
</template>