feat: 同步精简接口并统一表单校验

This commit is contained in:
GJ
2026-09-10 22:34:47 +08:00
parent 82d7bde631
commit 2eea0ea72e
66 changed files with 1611 additions and 1100 deletions
@@ -1,4 +1,7 @@
<script setup lang="ts">
import AppForm from '../../../components/ui/AppForm.vue'
import { NFormItem } from 'naive-ui'
import { requiredTextRule, integerRule } from '../../../lib/form-rules'
import { NAlert, NButton, NInput, NInputNumber } from 'naive-ui'
import { reactive, ref } from 'vue'
import { ArrowRight, LoaderCircle, Plus } from '@lucide/vue'
@@ -17,10 +20,6 @@ const form = reactive({ topic: '', style: '爽文反转', episodeCount: 3 })
async function submit() {
if (busy.value) return
error.value = ''
if (!form.topic.trim() || !Number.isSafeInteger(form.episodeCount) || form.episodeCount <= 0) {
error.value = '请填写故事主题,并输入大于 0 的整数集数。'
return
}
busy.value = true
try {
const result = await projectsApi.create({
@@ -37,6 +36,7 @@ async function submit() {
busy.value = false
}
}
const rules = { topic: requiredTextRule('故事主题'), episodeCount: integerRule('计划集数') }
</script>
<template>
@@ -49,40 +49,44 @@ async function submit() {
<template #trigger
><NButton @click="open = true" type="primary"><Plus :size="16" />新建剧本</NButton></template
>
<form class="mt-7 space-y-5" @submit.prevent="submit">
<div>
<label class="field-label" for="topic">故事主题 <span class="text-accent">*</span></label
<AppForm
:model="form"
:rules="rules"
:disabled="busy"
:reset-key="open"
class="mt-7 space-y-4"
@submit="submit"
>
<NFormItem path="topic" label="故事主题" :label-props="{ for: 'topic' }"
><NInput
placeholder="描述主角、故事背景,以及你希望展开的核心冲突……"
:disabled="busy"
:input-props="{ id: 'topic', required: true }"
:input-props="{ id: 'topic' }"
class="min-h-32 resize-y"
v-model:value="form.topic"
type="textarea"
:autosize="{ minRows: 3, maxRows: 12 }"
></NInput>
</div>
></NInput
></NFormItem>
<div class="grid grid-cols-[1fr_110px] gap-4">
<div>
<label class="field-label" for="style">剧本风格</label
<NFormItem path="style" label="剧本风格" :label-props="{ for: 'style' }"
><NInput
placeholder="如:都市悬疑、爽文反转"
:disabled="busy"
:input-props="{ id: 'style' }"
v-model:value="form.style"
></NInput>
</div>
<div>
<label class="field-label" for="episode-count">计划集数</label
></NInput
></NFormItem>
<NFormItem path="episodeCount" label="计划集数" :label-props="{ for: 'episode-count' }"
><NInputNumber
:disabled="busy"
:input-props="{ id: 'episode-count', required: true }"
:input-props="{ id: 'episode-count' }"
:value="typeof form.episodeCount === 'number' ? form.episodeCount : null"
@update:value="form.episodeCount = $event ?? 0"
:min="1"
:step="1"
></NInputNumber>
</div>
></NInputNumber
></NFormItem>
</div>
<p class="text-xs leading-5 text-muted">
建议先用 3 集验证生成效果生成会实际调用后端模型产生相应费用
@@ -96,6 +100,6 @@ async function submit() {
:size="16"
/></NButton>
</div>
</form>
</AppForm>
</AppDialog>
</template>