pagetype列表页增加显示image_field字段图片
This commit is contained in:
parent
3d34392946
commit
96d7d50c0b
@ -130,6 +130,10 @@
|
||||
@click.stop="toggleSelection(row.name)"
|
||||
/>
|
||||
</div>
|
||||
<!-- 卡片图片 -->
|
||||
<div v-if="imageFieldName && getImageUrl(row)" class="card-image">
|
||||
<img :src="getImageUrl(row) || ''" :alt="row[primaryLabel] || row.name" />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div class="info" @click.stop="openDetail(row.name)">
|
||||
<div class="title">{{ row[primaryLabel] || row.name }}</div>
|
||||
@ -180,7 +184,7 @@
|
||||
</div>
|
||||
|
||||
<!-- 列表视图 -->
|
||||
<div v-else class="agent-list">
|
||||
<div v-else class="agent-list" :class="{ 'has-image': imageFieldName }">
|
||||
<div class="list-header">
|
||||
<div class="col-checkbox">
|
||||
<input
|
||||
@ -190,6 +194,8 @@
|
||||
@change="toggleSelectAll"
|
||||
/>
|
||||
</div>
|
||||
<!-- 列表图片列 -->
|
||||
<div v-if="imageFieldName" class="col-image">{{ t('Image') }}</div>
|
||||
<div v-for="col in displayColumns" :key="col.key" :class="`col-${col.key}`">{{ t(col.title) }}</div>
|
||||
<div class="col-actions">{{ t('Actions') }}</div>
|
||||
</div>
|
||||
@ -208,6 +214,11 @@
|
||||
@click.stop="toggleSelection(row.name)"
|
||||
/>
|
||||
</div>
|
||||
<!-- 列表图片 -->
|
||||
<div v-if="imageFieldName" class="col-image" @click.stop="openDetail(row.name)">
|
||||
<img v-if="getImageUrl(row)" :src="getImageUrl(row) || ''" :alt="row[primaryLabel] || row.name" />
|
||||
<span v-else class="image-placeholder">—</span>
|
||||
</div>
|
||||
<div v-for="col in displayColumns" :key="col.key" :class="`col-${col.key}`" @click.stop="openDetail(row.name)">
|
||||
<template v-if="isBooleanField(col.key) && (row[col.key] === 1 || row[col.key] === 0 || typeof row[col.key] === 'boolean')">
|
||||
<span v-if="row[col.key] === 1 || row[col.key] === true" class="boolean-true">✓</span>
|
||||
@ -368,7 +379,21 @@ const cardBadges = computed(() => {
|
||||
return keys.map((k: string) => ({ key: k }))
|
||||
})
|
||||
|
||||
// 获取图片字段名
|
||||
const imageFieldName = computed(() => {
|
||||
return pageMeta.value?.image_field || ''
|
||||
})
|
||||
|
||||
// 获取图片URL
|
||||
function getImageUrl(row: any): string | null {
|
||||
if (!imageFieldName.value) return null
|
||||
const imageValue = row[imageFieldName.value]
|
||||
if (!imageValue || typeof imageValue !== 'string') return null
|
||||
return imageValue.trim() || null
|
||||
}
|
||||
|
||||
const metaFields = ref<any[]>([])
|
||||
const pageMeta = ref<any>({})
|
||||
const linkTitleCache = ref<Record<string, string>>({})
|
||||
const pageTypeConfigCache = ref<Record<string, any>>({})
|
||||
const cacheAccessOrder = ref<string[]>([]) // 记录访问顺序,用于LRU
|
||||
@ -497,7 +522,9 @@ async function loadMeta() {
|
||||
try {
|
||||
const url = `/api/data/PageType/${encodeURIComponent(entity.value)}`
|
||||
const res = await axios.get(url, { headers: get_session_api_headers(), withCredentials: true })
|
||||
metaFields.value = res.data?.data?.fields || []
|
||||
const data = res.data?.data || {}
|
||||
metaFields.value = data.fields || []
|
||||
pageMeta.value = data // 保存完整的pageMeta,包含image_field等配置
|
||||
|
||||
// 检查是否为单页模式
|
||||
isSinglePage.value = await isSinglePageType(entity.value)
|
||||
@ -635,7 +662,11 @@ async function loadData() {
|
||||
try {
|
||||
const listUrl = `/api/data/${encodeURIComponent(entity.value)}`
|
||||
// 仅请求所需字段,避免接口默认不返回
|
||||
const fieldNames = displayColumns.value.map((c: any) => c.key).filter((k: string) => k && k !== 'actions')
|
||||
let fieldNames = displayColumns.value.map((c: any) => c.key).filter((k: string) => k && k !== 'actions')
|
||||
// 如果配置了image_field,确保包含该字段
|
||||
if (imageFieldName.value && !fieldNames.includes(imageFieldName.value)) {
|
||||
fieldNames.push(imageFieldName.value)
|
||||
}
|
||||
|
||||
// 构建过滤参数
|
||||
const params: any = {
|
||||
@ -968,6 +999,37 @@ function formatDisplayValue(value: any, fieldName: string) {
|
||||
height: 18px;
|
||||
}
|
||||
|
||||
.card-image {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.card-image::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.02) 100%);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.card-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.agent-card:hover .card-image img {
|
||||
transform: scale(1.08);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -1134,9 +1196,17 @@ function formatDisplayValue(value: any, fieldName: string) {
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.agent-list.has-image .list-header {
|
||||
grid-template-columns: 40px minmax(50px, 50px) repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
}
|
||||
|
||||
.agent-list:not(.has-image) .list-header {
|
||||
grid-template-columns: 40px repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
}
|
||||
|
||||
.list-header {
|
||||
display: grid;
|
||||
grid-template-columns: 40px repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 16px 20px;
|
||||
background: #f9fafb;
|
||||
@ -1151,9 +1221,17 @@ function formatDisplayValue(value: any, fieldName: string) {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.agent-list.has-image .list-item {
|
||||
grid-template-columns: 40px minmax(50px, 50px) repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
}
|
||||
|
||||
.agent-list:not(.has-image) .list-item {
|
||||
grid-template-columns: 40px repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
display: grid;
|
||||
grid-template-columns: 40px repeat(auto-fit, minmax(120px, 1fr)) 140px;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
padding: 16px 20px;
|
||||
border-bottom: 1px solid #f3f4f6;
|
||||
@ -1174,6 +1252,38 @@ function formatDisplayValue(value: any, fieldName: string) {
|
||||
border-color: #3b82f6;
|
||||
}
|
||||
|
||||
.col-image {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.col-image img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
object-fit: cover;
|
||||
object-position: center;
|
||||
border-radius: 8px;
|
||||
border: 1px solid #e5e7eb;
|
||||
background: #f9fafb;
|
||||
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.list-item:hover .col-image img {
|
||||
border-color: #3b82f6;
|
||||
box-shadow: 0 4px 12px rgba(59, 130, 246, 0.15);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.col-image .image-placeholder {
|
||||
color: #9ca3af;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.col-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -1219,6 +1329,14 @@ function formatDisplayValue(value: any, fieldName: string) {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 列表列通用样式 - 确保垂直居中 */
|
||||
.list-header > div:not(.col-checkbox),
|
||||
.list-item > div:not(.col-checkbox):not(.col-actions) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
}
|
||||
|
||||
/* 通用截断样式 */
|
||||
.col-title,
|
||||
.col-subtitle,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user