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

90 lines
4.3 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 { NButton, NCheckbox, NInput } from 'naive-ui'
import { computed, reactive, ref, watch } from 'vue'
import type { SaveIdentityInput, SubjectIdentity } from '../types'
/** 身份文本草稿不随轮询覆盖;父页面切换主体或保存成功后重建编辑器。 */
const props = defineProps<{ identity: SubjectIdentity | null; disabled: boolean; module: string }>()
const emit = defineEmits<{ save: [input: SaveIdentityInput]; dirty: [value: boolean] }>()
const form = reactive({ description: '', generationPrompt: '', isLocked: false })
const baseline = ref('')
const dirty = computed(() => JSON.stringify(form) !== baseline.value)
watch(
() => props.identity,
value => {
if (baseline.value && dirty.value) return
Object.assign(form, {
description: value?.description ?? '',
generationPrompt: value?.generationPrompt ?? '',
isLocked: value?.isLocked ?? false
})
baseline.value = JSON.stringify(form)
},
{ immediate: true }
)
watch(dirty, value => emit('dirty', value), { immediate: true })
/** 保存用户输入;空文本允许保存,但生图入口仍会检查必要 Prompt。 */
function save() {
if (!props.disabled) emit('save', { ...form })
}
</script>
<template>
<form class="mt-5" @submit.prevent="save">
<fieldset :disabled="disabled" class="space-y-4">
<label class="block"
><span class="field-label">稳定身份描述</span
><NInput
:disabled="disabled"
placeholder="只描述跨形态不变的面部、结构、材质等特征"
:input-props="{ id: 'identity-description' }"
class="min-h-28"
v-model:value="form.description"
type="textarea"
:autosize="{ minRows: 3, maxRows: 12 }"
></NInput>
</label>
<label class="block"
><span class="field-label">身份核心提示词稳定事实</span
><NInput
:disabled="disabled"
placeholder="不固定某一形态的服装、伤势或临时状态"
:input-props="{ id: 'identity-prompt' }"
class="min-h-36"
v-model:value="form.generationPrompt"
type="textarea"
:autosize="{ minRows: 3, maxRows: 12 }"
></NInput>
</label>
<p class="text-xs leading-6 text-muted">
{{
module === 'prop'
? '保留道具固定文字、编号、部件位置、结构与材质组合;不要泛化原有辨识细节,也不要写临时损伤或摆放状态。'
: module === 'scene'
? '保留建筑骨架、入口、窗户、楼梯与固定布局,不写临时天气、人群或灯光。'
: '保留有依据的五官、骨相、发际线与体型,不固定某套服装、临时表情或伤势。'
}}
这里保存身份事实背景视角和参考图约束由后端另行编译不是最终整段生图 Prompt
</p>
<NCheckbox
:disabled="disabled"
id="identity-lock"
v-model:checked="form.isLocked"
class="flex items-start gap-2 text-xs leading-6"
>{{
module === 'character'
? '确认并锁定演员身份。Character 必须同时具有身份母版并锁定 Identity,首帧才能进入就绪状态。'
: '确认并锁定身份文本。锁定后仍可人工保存、生成图片及切换母版。'
}}</NCheckbox
>
<div class="flex flex-wrap items-center justify-between gap-3">
<span class="text-xs text-muted">{{
dirty ? '有未保存修改,自动刷新不会覆盖草稿。' : '图片以已保存的身份提示词为准。'
}}</span
><NButton :disabled="disabled" type="primary" attr-type="submit">保存主体身份</NButton>
</div>
</fieldset>
</form>
</template>