Files
short-drama-agent-front/src/features/subject-identity/components/CastingCandidateDialog.vue
T

96 lines
4.4 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import { NAlert, NButton, NCheckbox, NInput, NInputNumber } from 'naive-ui'
import { computed, ref, watch } from 'vue'
import { AppDialog } from '../../../components/ui'
import { validImageSize } from '../../subject-images/model'
import type { GenerateCastingCandidateInput } from '../types'
/** Character 选角候选表单固定使用 primary,每次独立生成且不会自动选择演员。 */
const props = defineProps<{ subjectId: string; subjectName: string; disabled: boolean }>()
const open = defineModel<boolean>('open', { default: false })
const emit = defineEmits<{ generate: [input: GenerateCastingCandidateInput] }>()
const prompt = ref('')
const width = ref<number | ''>('')
const height = ref<number | ''>('')
const acknowledged = ref(false)
const valid = computed(() => validImageSize(width.value, height.value))
/** 每次切换角色或重新打开都清空自定义覆盖与费用确认。 */
function reset() {
prompt.value = ''
width.value = ''
height.value = ''
acknowledged.value = false
}
watch([() => props.subjectId, open], reset)
/** 只发送选角候选接口接受的字段,不携带普通身份图视角参数。 */
function submit() {
if (props.disabled || !valid.value || !acknowledged.value) return
emit('generate', {
provider: 'seedream',
...(prompt.value.trim() ? { prompt: prompt.value.trim() } : {}),
...(width.value !== '' && height.value !== '' ? { width: width.value, height: height.value } : {})
})
open.value = false
}
</script>
<template>
<AppDialog v-model:open="open" title="生成角色选角候选" :description="`${subjectName} · 候选不会自动成为身份母版`">
<form class="mt-5 space-y-4" @submit.prevent="submit">
<NAlert type="info" :show-icon="false" class="text-xs">
后端会依据角色 Identity项目视觉风格和默认选角约束独立生成一张 primary
候选不会复用当前身份母版生成完成后仍需人工点击确认选角”。
</NAlert>
<label class="block">
<span class="field-label">覆盖本次完整提示词可选</span>
<NInput
placeholder="建议留空,使用后端编译的稳定身份和选角约束;未明确人物背景时默认中国人物"
:input-props="{ id: 'casting-candidate-prompt' }"
class="min-h-24"
v-model:value="prompt"
type="textarea"
:autosize="{ minRows: 3, maxRows: 12 }"
></NInput>
</label>
<p v-if="prompt.trim()" class="text-xs text-danger">
自定义文本会替换后端完整提示词请自行包含人物身份基础服装和中性参考图要求
</p>
<div class="grid grid-cols-2 gap-4">
<label
><span class="field-label">宽度px</span
><NInputNumber
placeholder="后端默认"
:value="typeof width === 'number' ? width : null"
@update:value="width = $event ?? ''"
:min="1"
></NInputNumber
></label>
<label
><span class="field-label">高度px</span
><NInputNumber
placeholder="后端默认"
:value="typeof height === 'number' ? height : null"
@update:value="height = $event ?? ''"
:min="1"
></NInputNumber
></label>
</div>
<p v-if="!valid" class="text-xs text-danger">宽高需要同时留空或同时填写正整数</p>
<NCheckbox
id="casting-candidate-cost"
v-model:checked="acknowledged"
class="flex items-start gap-2 text-xs leading-6"
>我已确认调用 Seedream 可能产生费用且当前没有同项目生成任务
</NCheckbox>
<div class="dialog-footer">
<NButton @click="open = false">取消</NButton>
<NButton :disabled="disabled || !valid || !acknowledged" type="primary" attr-type="submit">
确认生成候选
</NButton>
</div>
</form>
</AppDialog>
</template>