feat: 同步质量校验修复并精简工作台操作
This commit is contained in:
@@ -298,7 +298,7 @@ watch(
|
||||
!casting.missingAnchor
|
||||
"
|
||||
acknowledgement
|
||||
description="最多按本批上限为缺少 Anchor 的 Character 调用 Seedream,各自独立生成一张停用的 primary 候选,不复用旧身份母版。已有候选、已有母版或已完成选角的角色不会重复处理。"
|
||||
description="最多按本批上限为缺少 Anchor 的 Character 调用 图片模型,各自独立生成一张停用的 primary 候选,不复用旧身份母版。已有候选、已有母版或已完成选角的角色不会重复处理。"
|
||||
@confirm="generateCastingCandidates"
|
||||
/>
|
||||
</div>
|
||||
@@ -559,7 +559,7 @@ watch(
|
||||
? '演员身份已确认并锁定,可用于形态图与镜头首帧。'
|
||||
: '已有演员母版但 Identity 尚未锁定,镜头首帧仍会被阻塞。'
|
||||
: subject.module === 'prop'
|
||||
? '道具形态生图暂不自动引用此母版。'
|
||||
? '锁定后,后续道具形态图会继承当前母版。'
|
||||
: '后续场景形态图会继承此图的空间结构。'
|
||||
}}
|
||||
</p>
|
||||
|
||||
@@ -28,7 +28,6 @@ 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 } : {})
|
||||
})
|
||||
@@ -82,7 +81,7 @@ function submit() {
|
||||
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>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import DetailDisclosure from '../../../components/ui/DetailDisclosure.vue'
|
||||
import { NButton, NCheckbox, NInput } from 'naive-ui'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import type { SaveIdentityInput, SubjectIdentity } from '../types'
|
||||
@@ -57,26 +58,27 @@ function save() {
|
||||
:autosize="{ minRows: 3, maxRows: 12 }"
|
||||
></NInput>
|
||||
</label>
|
||||
<p class="text-xs leading-6 text-muted">
|
||||
{{
|
||||
module === 'prop'
|
||||
? '保留道具固定文字、编号、部件位置、结构与材质组合;不要泛化原有辨识细节,也不要写临时损伤或摆放状态。'
|
||||
: module === 'scene'
|
||||
? '保留建筑骨架、入口、窗户、楼梯与固定布局,不写临时天气、人群或灯光。'
|
||||
: '保留有依据的五官、骨相、发际线与体型,不固定某套服装、临时表情或伤势。'
|
||||
}}
|
||||
这里保存身份事实;背景、视角和参考图约束由后端另行编译,不是最终整段生图 Prompt。
|
||||
</p>
|
||||
<DetailDisclosure title="身份填写与锁定规则"
|
||||
><p class="text-xs leading-6 text-muted">
|
||||
{{
|
||||
module === 'prop'
|
||||
? '保留道具固定文字、编号、部件位置、结构与材质组合;不要泛化原有辨识细节,也不要写临时损伤或摆放状态。'
|
||||
: module === 'scene'
|
||||
? '保留建筑骨架、入口、窗户、楼梯与固定布局,不写临时天气、人群或灯光。'
|
||||
: '保留有依据的五官、骨相、发际线与体型,不固定某套服装、临时表情或伤势。'
|
||||
}}
|
||||
这里保存身份事实;背景、视角和参考图约束由后端另行编译,不是最终整段生图 Prompt。
|
||||
</p>
|
||||
<p class="mt-2 text-xs text-muted">
|
||||
人物需要同时确认母版并锁定身份,首帧才能就绪。锁定后仍可人工编辑、生成图片及切换母版。
|
||||
</p></DetailDisclosure
|
||||
>
|
||||
<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
|
||||
>{{ module === 'character' ? '确认并锁定演员身份' : '确认并锁定身份文本' }}</NCheckbox
|
||||
>
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<span class="text-xs text-muted">{{
|
||||
|
||||
@@ -45,11 +45,10 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
/** 提交显式的 Seedream 参数;省略空参考 ID 以保留后端自动选择逻辑。 */
|
||||
/** 提交生图参数;省略空参考 ID 以保留后端自动选择逻辑。 */
|
||||
function submit() {
|
||||
if (props.disabled || !valid.value || !acknowledged.value) return
|
||||
emit('generate', {
|
||||
provider: 'seedream',
|
||||
viewType: viewType.value,
|
||||
...(referenceImageId.value ? { referenceImageId: referenceImageId.value } : {}),
|
||||
...(prompt.value.trim() ? { prompt: prompt.value.trim() } : {}),
|
||||
@@ -63,7 +62,7 @@ function submit() {
|
||||
<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">
|
||||
调用 Seedream,每次新增一张图片,可能产生费用。第一张成功的 primary 图自动成为母版;已有母版时,新
|
||||
调用 图片模型,每次新增一张图片,可能产生费用。第一张成功的 primary 图自动成为母版;已有母版时,新
|
||||
primary 图仅作为停用候选保留。
|
||||
</NAlert>
|
||||
<label class="block"
|
||||
|
||||
@@ -292,7 +292,6 @@ describe('身份图与母版契约', () => {
|
||||
expect(wrapper.emitted('generate')).toEqual([
|
||||
[
|
||||
{
|
||||
provider: 'seedream',
|
||||
viewType: 'three-quarter',
|
||||
referenceImageId: 'identity-image-1',
|
||||
width: 2048,
|
||||
@@ -379,7 +378,7 @@ describe('身份图与母版契约', () => {
|
||||
expect(wrapper.emitted('anchor')).toEqual([['identity-image-1']])
|
||||
})
|
||||
|
||||
it('选角候选固定发送 Seedream,不携带普通身份图视角字段', async () => {
|
||||
it('选角候选不再发送 Provider,不携带普通身份图视角字段', async () => {
|
||||
wrapper = mount(CastingCandidateDialog, {
|
||||
attachTo: document.body,
|
||||
props: { open: true, subjectId: 'subject-1', subjectName: '林夏', disabled: false }
|
||||
@@ -389,7 +388,7 @@ describe('身份图与母版契约', () => {
|
||||
document.querySelector<HTMLInputElement>('#casting-candidate-cost')!.click()
|
||||
await flushPromises()
|
||||
button('确认生成候选').click()
|
||||
expect(wrapper.emitted('generate')).toEqual([[{ provider: 'seedream' }]])
|
||||
expect(wrapper.emitted('generate')).toEqual([[{}]])
|
||||
})
|
||||
|
||||
it('角色选角接口区分批量身份、候选生图与确认事务', async () => {
|
||||
@@ -411,7 +410,7 @@ describe('身份图与母版契约', () => {
|
||||
)
|
||||
vi.stubGlobal('fetch', fetcher)
|
||||
await subjectIdentityApi.generateCharacters('project/1', { force: false, concurrency: 2 })
|
||||
await subjectIdentityApi.generateCastingCandidate('subject/1', { provider: 'seedream' })
|
||||
await subjectIdentityApi.generateCastingCandidate('subject/1', {})
|
||||
await subjectIdentityApi.confirmCasting('subject/1', 'image/1')
|
||||
expect(fetcher.mock.calls.map(([url]) => url)).toEqual([
|
||||
'/api/projects/project%2F1/character-identities/generate',
|
||||
|
||||
@@ -46,7 +46,6 @@ export type SaveIdentityInput = Partial<Pick<SubjectIdentity, 'description' | 'g
|
||||
|
||||
/** 单张身份生图;空 referenceImageId 应省略,由后端自动引用当前母版。 */
|
||||
export interface GenerateIdentityImageInput {
|
||||
provider: 'seedream'
|
||||
viewType: IdentityViewType
|
||||
referenceImageId?: string
|
||||
prompt?: string
|
||||
@@ -56,7 +55,6 @@ export interface GenerateIdentityImageInput {
|
||||
|
||||
/** Character 选角候选固定独立生成 primary,不复用旧 Anchor,也不会自动成为新 Anchor。 */
|
||||
export interface GenerateCastingCandidateInput {
|
||||
provider: 'seedream'
|
||||
prompt?: string
|
||||
width?: number
|
||||
height?: number
|
||||
@@ -110,7 +108,6 @@ export interface CharacterCastingReadiness {
|
||||
|
||||
/** 小批量生成选角候选的配置。 */
|
||||
export interface GenerateCastingCandidatesInput {
|
||||
provider: 'seedream'
|
||||
limit: number
|
||||
concurrency: number
|
||||
width?: number
|
||||
|
||||
@@ -183,7 +183,6 @@ export function useSubjectIdentity() {
|
||||
kind: 'casting',
|
||||
title,
|
||||
result: await subjectIdentityApi.generateCastingCandidates(id, {
|
||||
provider: 'seedream',
|
||||
limit: candidateLimit.value,
|
||||
concurrency: concurrency.value
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user