新增首页 AW炫彩回收入口,支持后台配置展示图

首页第三入口点击查看回收说明图;配置项 mobile.aw_recycle 可配标题/图片;aw-recycle 走公开文件链路,首页鉴权预览兼容旧私有地址。
This commit is contained in:
yml2213
2026-07-19 22:50:16 +08:00
parent dabcec45cb
commit 9b1ee445b7
14 changed files with 533 additions and 18 deletions
@@ -2,11 +2,15 @@
import { computed, ref, watch } from 'vue'
import { RouterLink, useRoute, useRouter } from 'vue-router'
import {
defaultAWRecycleConfig,
defaultHomeAnnouncements,
defaultHomeBanners,
fetchMobileHomeConfig,
type AWRecycleConfig,
type HomeBannerSlide,
} from '@/features/listings/api/homeConfig'
import { ElMessage } from 'element-plus'
import AuthImage from '@/shared/components/business/AuthImage.vue'
import {
emptyListingPublishOptions,
type ListingPublishOptions,
@@ -37,6 +41,8 @@ import ListingCard from '../components/ListingCard.vue'
const announcements = ref<string[]>(defaultHomeAnnouncements)
const banners = ref<HomeBannerSlide[]>(defaultHomeBanners)
const awRecycle = ref<AWRecycleConfig>({ ...defaultAWRecycleConfig })
const awRecycleDialogVisible = ref(false)
const publishOptions = ref<ListingPublishOptions>(emptyListingPublishOptions)
const sortBy = ref('recommended')
const sortOptions = [
@@ -149,16 +155,26 @@ async function loadHome() {
const [, config] = await Promise.all([loadListingsPage(true), fetchMobileHomeConfig()])
announcements.value = config.announcements
banners.value = config.banners
awRecycle.value = config.aw_recycle
publishOptions.value = config.publish_options
} catch {
announcements.value = defaultHomeAnnouncements
banners.value = defaultHomeBanners
awRecycle.value = { ...defaultAWRecycleConfig }
publishOptions.value = emptyListingPublishOptions
} finally {
loading.value = false
}
}
function openAWRecycle() {
if (!awRecycle.value.image_url) {
ElMessage.warning('回收说明图片尚未配置,请稍后再试')
return
}
awRecycleDialogVisible.value = true
}
function updateFilters(partial: Partial<typeof filters>) {
Object.assign(filters, partial)
}
@@ -275,8 +291,36 @@ loadHome()
<strong>撞车 <em>NEW</em></strong>
<small>选购商品 · 支付后进群联系客服</small>
</RouterLink>
<button
v-if="awRecycle.enabled"
type="button"
class="biz-entry aw-recycle"
@click="openAWRecycle"
>
<strong>{{ awRecycle.title }}</strong>
<small>{{ awRecycle.subtitle }}</small>
</button>
</div>
<el-dialog
v-model="awRecycleDialogVisible"
:title="awRecycle.title"
width="720px"
class="aw-recycle-dialog"
align-center
destroy-on-close
>
<AuthImage
v-if="awRecycle.image_url"
:source="awRecycle.image_url"
:alt="awRecycle.title"
fit="contain"
image-class="aw-recycle-image"
:preview-src-list="[awRecycle.image_url]"
/>
<el-empty v-else description="暂无展示图片" />
</el-dialog>
<HomeFilters
:filters="filters"
:total-listings="totalListings"
@@ -353,7 +397,7 @@ loadHome()
.biz-entry-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 12px;
}
@@ -366,6 +410,9 @@ loadHome()
border: 1px solid #eef1f5;
background: #fff;
text-decoration: none;
text-align: left;
cursor: pointer;
font: inherit;
transition:
border-color 0.18s ease,
box-shadow 0.18s ease;
@@ -396,6 +443,26 @@ loadHome()
font-style: normal;
}
.biz-entry.aw-recycle {
border-color: #e8edff;
background: linear-gradient(135deg, #ffffff 0%, #f5f8ff 100%);
}
:deep(.aw-recycle-image) {
display: block;
width: 100%;
max-height: 70vh;
object-fit: contain;
border-radius: 10px;
background: #f8fafc;
}
@media (max-width: 960px) {
.biz-entry-grid {
grid-template-columns: 1fr;
}
}
.infinite-load-state {
padding: 6px 0 18px;
color: #94a3b8;