188 lines
4.2 KiB
Vue
188 lines
4.2 KiB
Vue
<template>
|
||
<view class="mold-page">
|
||
<!-- 搜索框 -->
|
||
<view class="search-bar">
|
||
<input
|
||
class="search-bar__input"
|
||
type="text"
|
||
placeholder="搜索名称、款号、条码号、款式"
|
||
:value="keyword"
|
||
@input="onSearchInput"
|
||
@confirm="doSearch"
|
||
/>
|
||
</view>
|
||
|
||
<!-- 版房列表 -->
|
||
<view class="mold-list">
|
||
<view v-for="mold in filteredMolds" :key="mold.id" class="mold-card">
|
||
<text class="mold-card__name">{{ mold.name }}</text>
|
||
<scroll-view v-if="mold.images.length > 0" class="mold-card__images" scroll-x>
|
||
<image
|
||
v-for="(img, idx) in mold.images"
|
||
:key="idx"
|
||
class="mold-card__img"
|
||
:src="img"
|
||
mode="aspectFill"
|
||
/>
|
||
</scroll-view>
|
||
<view v-else class="mold-card__no-img">
|
||
<text>暂无图片</text>
|
||
</view>
|
||
<view class="mold-card__footer">
|
||
<text v-if="mold.styleNo" class="mold-card__tag">款号: {{ mold.styleNo }}</text>
|
||
<text v-if="mold.style" class="mold-card__tag">款式: {{ mold.style }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 空状态 -->
|
||
<view v-if="!loading && filteredMolds.length === 0" class="empty-tip">
|
||
<text>{{ keyword ? '未找到匹配结果' : '暂无版房信息' }}</text>
|
||
<view v-if="keyword" class="empty-tip__contact" @click="contactService">
|
||
联系客服咨询定制
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 加载中 -->
|
||
<view v-if="loading" class="loading-tip">
|
||
<text>加载中...</text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, computed, onMounted } from 'vue'
|
||
// @ts-ignore - uni-app 页面生命周期
|
||
import { onShow } from '@dcloudio/uni-app'
|
||
import type { MoldInfo } from '../../types/mold'
|
||
import { getMoldList } from '../../api/mold'
|
||
import { searchMolds } from '../../utils/moldSearch'
|
||
|
||
const molds = ref<MoldInfo[]>([])
|
||
const keyword = ref('')
|
||
const loading = ref(false)
|
||
|
||
const filteredMolds = computed(() => searchMolds(molds.value, keyword.value))
|
||
|
||
function onSearchInput(e: { detail: { value: string } }) {
|
||
keyword.value = e.detail.value
|
||
}
|
||
|
||
function doSearch() {
|
||
// 本地搜索,无需额外操作;也可选择调用后端搜索
|
||
}
|
||
|
||
function contactService() {
|
||
// 引导用户联系客服(Requirements 5.4)
|
||
uni.showModal({
|
||
title: '联系客服',
|
||
content: '如需定制服务,请添加客服微信咨询',
|
||
showCancel: false,
|
||
})
|
||
}
|
||
|
||
async function loadMolds() {
|
||
loading.value = true
|
||
try {
|
||
molds.value = await getMoldList()
|
||
} catch {
|
||
// 错误已在 request 中统一处理
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
loadMolds()
|
||
})
|
||
|
||
// 页面每次显示时刷新(后台修改版房信息后同步)
|
||
onShow(() => {
|
||
loadMolds()
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
.mold-page {
|
||
min-height: 100vh;
|
||
background: #f5f5f5;
|
||
}
|
||
.search-bar {
|
||
background: #fff;
|
||
padding: 16rpx 24rpx;
|
||
}
|
||
.search-bar__input {
|
||
background: #f5f5f5;
|
||
border-radius: 32rpx;
|
||
padding: 16rpx 24rpx;
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
}
|
||
.mold-list {
|
||
padding: 16rpx;
|
||
}
|
||
.mold-card {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 24rpx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
.mold-card__name {
|
||
font-size: 30rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
display: block;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
.mold-card__images {
|
||
white-space: nowrap;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.mold-card__img {
|
||
width: 200rpx;
|
||
height: 200rpx;
|
||
border-radius: 8rpx;
|
||
margin-right: 12rpx;
|
||
display: inline-block;
|
||
}
|
||
.mold-card__no-img {
|
||
height: 200rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
background: #f5f5f5;
|
||
border-radius: 8rpx;
|
||
color: #999;
|
||
font-size: 26rpx;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
.mold-card__footer {
|
||
display: flex;
|
||
gap: 16rpx;
|
||
}
|
||
.mold-card__tag {
|
||
font-size: 22rpx;
|
||
color: #999;
|
||
background: #f5f5f5;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 4rpx;
|
||
}
|
||
.empty-tip {
|
||
text-align: center;
|
||
padding: 80rpx 0;
|
||
color: #999;
|
||
font-size: 28rpx;
|
||
}
|
||
.empty-tip__contact {
|
||
margin-top: 20rpx;
|
||
color: #e4393c;
|
||
font-size: 26rpx;
|
||
}
|
||
.loading-tip {
|
||
text-align: center;
|
||
padding: 60rpx 0;
|
||
color: #999;
|
||
font-size: 28rpx;
|
||
}
|
||
</style>
|