feat: 支持图库瀑布流切换并调整列表间距
This commit is contained in:
@@ -17,7 +17,17 @@ import {
|
||||
} from 'naive-ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { Search, RefreshCw, Download, ImagePlus, ArrowLeft, ArrowRight, LayoutGrid, AlertTriangle } from '@lucide/vue'
|
||||
import {
|
||||
Search,
|
||||
RefreshCw,
|
||||
Download,
|
||||
ImagePlus,
|
||||
ArrowLeft,
|
||||
ArrowRight,
|
||||
LayoutGrid,
|
||||
Columns3,
|
||||
AlertTriangle
|
||||
} from '@lucide/vue'
|
||||
import { AssetImage, EmptyState, StatusBadge } from '../../components/ui'
|
||||
import { downloadText } from '../../lib/format'
|
||||
import ConfirmAction from '../workflows/ConfirmAction.vue'
|
||||
@@ -30,6 +40,7 @@ import FormPromptDialog from './components/FormPromptDialog.vue'
|
||||
import FormPromptBatch from './components/FormPromptBatch.vue'
|
||||
import { useKeyframeImpact } from './useKeyframeImpact'
|
||||
import { queryText, referenceLocation, referenceTargets } from '../production/asset-links'
|
||||
import { formCoverAspectRatio, type GalleryLayout } from './layout'
|
||||
|
||||
/** 形态图库以正式数据库为准;首次读取、手动刷新和自身操作完成后更新,不定时刷新。 */
|
||||
const route = useRoute()
|
||||
@@ -123,6 +134,8 @@ watch(
|
||||
}
|
||||
)
|
||||
const search = ref('')
|
||||
/** 切换排版复用同一份卡片和查询结果,不重新读取图库或清空筛选。 */
|
||||
const layout = ref<GalleryLayout>('grid')
|
||||
const module = ref('all')
|
||||
const onlyMissing = ref(false)
|
||||
const onlyStale = ref(false)
|
||||
@@ -491,7 +504,33 @@ async function showStaleForms() {
|
||||
<NCheckbox v-model:checked="onlyMissing">仅看缺少主图</NCheckbox>
|
||||
<NCheckbox v-model:checked="onlyStale">仅看身份过期</NCheckbox>
|
||||
</div>
|
||||
<span class="filter-result-count">{{ filtered.length }} 个形态</span>
|
||||
<div class="form-image-display-controls">
|
||||
<span class="filter-result-count">{{ filtered.length }} 个形态</span>
|
||||
<div class="gallery-layout-switch" role="group" aria-label="图库显示方式">
|
||||
<NButton
|
||||
class="icon-button"
|
||||
size="small"
|
||||
:type="layout === 'grid' ? 'primary' : 'default'"
|
||||
:aria-pressed="layout === 'grid'"
|
||||
aria-label="网格布局"
|
||||
title="网格布局"
|
||||
@click="layout = 'grid'"
|
||||
>
|
||||
<template #icon><LayoutGrid :size="16" /></template>
|
||||
</NButton>
|
||||
<NButton
|
||||
class="icon-button"
|
||||
size="small"
|
||||
:type="layout === 'masonry' ? 'primary' : 'default'"
|
||||
:aria-pressed="layout === 'masonry'"
|
||||
aria-label="瀑布流布局"
|
||||
title="瀑布流布局"
|
||||
@click="layout = 'masonry'"
|
||||
>
|
||||
<template #icon><Columns3 :size="16" /></template>
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -559,7 +598,11 @@ async function showStaleForms() {
|
||||
<p v-if="!query.data.value && query.loading.value" class="py-10 text-sm text-muted" role="status">
|
||||
正在读取形态和已有图片…
|
||||
</p>
|
||||
<div v-else-if="filtered.length" class="form-image-grid">
|
||||
<div
|
||||
v-else-if="filtered.length"
|
||||
class="form-image-grid"
|
||||
:class="{ 'form-image-masonry': layout === 'masonry' }"
|
||||
>
|
||||
<article
|
||||
v-for="form in filtered"
|
||||
:key="form.id"
|
||||
@@ -569,11 +612,12 @@ async function showStaleForms() {
|
||||
'form-image-card-focused': targetFormId === form.id
|
||||
}"
|
||||
:data-form-id="form.id"
|
||||
:style="{ '--form-image-aspect': formCoverAspectRatio(form) }"
|
||||
>
|
||||
<AssetImage
|
||||
:src="coverImage(form)?.imageUrl"
|
||||
:alt="`${form.subject.name} · ${form.name}`"
|
||||
object-fit="cover"
|
||||
:object-fit="layout === 'masonry' ? 'contain' : 'cover'"
|
||||
preview
|
||||
:empty-text="hasRunningImages(form.images) ? '后台正在生成图片' : '尚未生成图片'"
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user