style: 优化选角面板间距与角色卡片布局
This commit is contained in:
@@ -166,7 +166,7 @@ watch(
|
||||
title="角色选角总览与批量操作"
|
||||
:has-receipt="!!session.receipt"
|
||||
>
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div class="identity-tools-intro flex flex-wrap items-end justify-between gap-4">
|
||||
<div>
|
||||
<h2 class="text-lg font-semibold">主体身份</h2>
|
||||
<p class="mt-2 text-sm text-muted">
|
||||
@@ -294,21 +294,21 @@ watch(
|
||||
>
|
||||
并发数与本批上限都必须是正整数。
|
||||
</p>
|
||||
<div class="casting-list mt-5">
|
||||
<div class="casting-list" role="group" aria-label="角色选角进度">
|
||||
<NButton
|
||||
v-for="item in casting.items"
|
||||
:key="item.subjectId"
|
||||
@click="select(item.subjectId)"
|
||||
class="casting-item"
|
||||
:class="{ selected: selectedId === item.subjectId }"
|
||||
><span class="min-w-0">
|
||||
<span class="block truncate text-xs font-medium">{{
|
||||
item.subjectName
|
||||
}}</span>
|
||||
<span class="mt-1 block font-mono text-[10px] text-muted">{{
|
||||
:aria-pressed="selectedId === item.subjectId"
|
||||
><span class="casting-item-identity">
|
||||
<span class="casting-item-name">{{ item.subjectName }}</span>
|
||||
<span class="casting-item-ref">{{
|
||||
item.subjectRef
|
||||
}}</span> </span
|
||||
><StatusBadge
|
||||
class="casting-item-status"
|
||||
:status="item.status"
|
||||
:label="castingStatusLabel(item.status)"
|
||||
/></NButton>
|
||||
|
||||
@@ -527,6 +527,69 @@ describe('视觉风格与主体身份工作区', () => {
|
||||
expect(wrapper!.text()).toContain('当前身份母版')
|
||||
})
|
||||
|
||||
it('选角进度卡片分层显示长姓名、编号和状态,点击仍按正式 ID 切换主体', async () => {
|
||||
const longName = '来自记忆当铺的另一条时间线中尚未丢失记忆的林默'
|
||||
const items = [
|
||||
{
|
||||
subjectId: 'subject-db-1',
|
||||
subjectRef: '@CH0001',
|
||||
subjectName: longName,
|
||||
status: 'ready',
|
||||
isLocked: true
|
||||
},
|
||||
{
|
||||
subjectId: 'subject-db-2',
|
||||
subjectRef: '@CH0002',
|
||||
subjectName: '老周',
|
||||
status: 'candidate_pending',
|
||||
isLocked: false
|
||||
}
|
||||
]
|
||||
const fetcher = vi.fn<typeof fetch>().mockImplementation(async url => {
|
||||
const path = String(url)
|
||||
if (path.endsWith('/subject-forms')) return jsonResponse([formFixture()])
|
||||
if (path.endsWith('/visual-style')) return jsonResponse(styleFixture())
|
||||
if (path.endsWith('/character-casting/readiness'))
|
||||
return jsonResponse({
|
||||
total: 2,
|
||||
ready: 1,
|
||||
missingIdentity: 0,
|
||||
missingAnchor: 0,
|
||||
candidatePending: 1,
|
||||
unlocked: 0,
|
||||
locked: 1,
|
||||
items
|
||||
})
|
||||
if (path.endsWith('/identity/images')) return jsonResponse([])
|
||||
const second = path.includes('/subject-db-2/')
|
||||
return jsonResponse(
|
||||
identityFixture({
|
||||
subjectId: second ? 'subject-db-2' : 'subject-db-1',
|
||||
description: second ? '老周的稳定身份' : '林默的稳定身份'
|
||||
})
|
||||
)
|
||||
})
|
||||
vi.stubGlobal('fetch', fetcher)
|
||||
await mountAssets('identity')
|
||||
expect(wrapper!.get('.identity-tools-intro').text()).toContain('为同一个人物、场景或道具固定稳定特征')
|
||||
const cards = wrapper!.get('[aria-label="角色选角进度"]').findAll('.casting-item')
|
||||
expect(cards).toHaveLength(2)
|
||||
expect(cards[0]!.get('.casting-item-name').text()).toBe(longName)
|
||||
expect(cards[0]!.get('.casting-item-ref').text()).toBe('@CH0001')
|
||||
expect(cards[0]!.get('.casting-item-status').text()).toBe('选角已完成')
|
||||
expect(cards[0]!.find('.truncate').exists()).toBe(false)
|
||||
expect(cards[0]!.attributes('aria-pressed')).toBe('true')
|
||||
expect(cards[1]!.get('.casting-item-status').text()).toBe('等待确认演员')
|
||||
await cards[1]!.trigger('click')
|
||||
await flushPromises()
|
||||
expect(cards[0]!.attributes('aria-pressed')).toBe('false')
|
||||
expect(cards[1]!.attributes('aria-pressed')).toBe('true')
|
||||
expect(cards[1]!.classes()).toContain('selected')
|
||||
expect(wrapper!.get<HTMLTextAreaElement>('#identity-description').element.value).toBe('老周的稳定身份')
|
||||
expect(fetcher.mock.calls.some(([url]) => String(url).endsWith('/subjects/subject-db-2/identity'))).toBe(true)
|
||||
expect(fetcher.mock.calls.every(([, init]) => init?.method === 'GET')).toBe(true)
|
||||
})
|
||||
|
||||
it('Character 确认选角原子切换 Anchor 并锁定 Identity,不调用普通母版接口', async () => {
|
||||
let locked = false
|
||||
let selected = false
|
||||
|
||||
Reference in New Issue
Block a user