feat: 同步视觉风格与主体身份母版工作区

对齐后端 dev 059e597,新增项目风格编辑锁定、身份文本生成、身份参考图与母版切换。
整理六个工作区入口,接通人物及场景母版继承说明、形态图片来源追溯。
补充草稿保护、正式 ID 校验、费用确认及部分失败回执,67 项测试和静态检查、构建通过。
未修改后端,未调用真实模型;本环境未完成浏览器视觉验收。
This commit is contained in:
GouJ
2026-08-28 19:28:27 +08:00
parent 47443c0efe
commit 669f4d9df0
34 changed files with 2273 additions and 22 deletions
@@ -0,0 +1,79 @@
<script setup lang="ts">
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
><textarea
id="identity-description"
v-model="form.description"
class="input min-h-28"
placeholder="只描述跨形态不变的面部、结构、材质等特征"
/>
</label>
<label class="block"
><span class="field-label">身份核心提示词稳定事实</span
><textarea
id="identity-prompt"
v-model="form.generationPrompt"
class="input min-h-36"
placeholder="不固定某一形态的服装、伤势或临时状态"
/>
</label>
<p class="text-xs leading-6 text-muted">
{{
module === 'prop'
? '保留道具固定文字、编号、部件位置、结构与材质组合;不要泛化原有辨识细节,也不要写临时损伤或摆放状态。'
: module === 'scene'
? '保留建筑骨架、入口、窗户、楼梯与固定布局,不写临时天气、人群或灯光。'
: '保留有依据的五官、骨相、发际线与体型,不固定某套服装、临时表情或伤势。'
}}
这里保存身份事实背景视角和参考图约束由后端另行编译不是最终整段生图 Prompt
</p>
<label class="flex items-start gap-2 text-xs leading-6"
><input
id="identity-lock"
v-model="form.isLocked"
type="checkbox"
class="mt-1.5 accent-accent"
/>确认并锁定身份文本锁定后仍可人工保存生成图片及切换母版</label
>
<div class="flex flex-wrap items-center justify-between gap-3">
<span class="text-xs text-muted">{{
dirty ? '有未保存修改,自动刷新不会覆盖草稿。' : '图片以已保存的身份提示词为准。'
}}</span
><button class="button button-primary" type="submit" :disabled="disabled">保存主体身份</button>
</div>
</fieldset>
</form>
</template>