feat(静态资源): 用图片替换场地、商品、赛事等占位图标
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
// 南京场地示例仅供交互演示,不代表实时价格或可订状态。
|
||||
export const venues = [
|
||||
{ id: 'lining', name: '李宁迪拓运动馆', district: '雨花台', address: '雨花台区示意路 1 号', distance: '1.2km', surface: '室内木地板', price: 80, rating: '4.9', courts: 6, band: 'main', note: '室内木地板 · 配套更衣室', color: 'green', mapX: 55, mapY: 55, features: ['室内木地板', '更衣室', '停车场', '饮水区'] },
|
||||
{ id: 'olympic', name: '奥体全民健身园', district: '建邺', address: '建邺区示意路 2 号', distance: '3.8km', surface: '户外塑胶', price: 30, rating: '4.7', courts: 4, band: 'budget', note: '户外塑胶 · 配套夜间照明', color: 'mint', mapX: 23, mapY: 39, features: ['户外塑胶', '夜间照明', '公共交通'] },
|
||||
{ id: 'honey', name: '蜜糖体育中心', district: '雨花台', address: '雨花台区示意路 3 号', distance: '2.5km', surface: '4 人包场', price: 75, rating: '4.8', courts: 4, band: 'main', note: '室内场地 · 配套休息区', color: 'deep', mapX: 72, mapY: 76, features: ['室内场地', '更衣室', '休息区'] },
|
||||
{ id: 'sky', name: '金鹰 51FLOOR 空中馆', district: '建邺', address: '建邺区示意路 4 号', distance: '4.2km', surface: '云端景观', price: 129, rating: '5.0', courts: 11, band: 'premium', note: '室内场地 · 配套淋浴', color: 'gold', mapX: 38, mapY: 21, features: ['室内场地', '淋浴', '休息区', '停车场'] }
|
||||
{ id: 'lining', name: '李宁迪拓运动馆', district: '雨花台', address: '雨花台区示意路 1 号', distance: '1.2km', surface: '室内木地板', price: 80, rating: '4.9', courts: 6, band: 'main', note: '室内木地板 · 配套更衣室', color: 'green', image: '/static/visuals/indoor-court.jpg', mapX: 55, mapY: 55, features: ['室内木地板', '更衣室', '停车场', '饮水区'] },
|
||||
{ id: 'olympic', name: '奥体全民健身园', district: '建邺', address: '建邺区示意路 2 号', distance: '3.8km', surface: '户外塑胶', price: 30, rating: '4.7', courts: 4, band: 'budget', note: '户外塑胶 · 配套夜间照明', color: 'mint', image: '/static/visuals/outdoor-court.jpg', mapX: 23, mapY: 39, features: ['户外塑胶', '夜间照明', '公共交通'] },
|
||||
{ id: 'honey', name: '蜜糖体育中心', district: '雨花台', address: '雨花台区示意路 3 号', distance: '2.5km', surface: '4 人包场', price: 75, rating: '4.8', courts: 4, band: 'main', note: '室内场地 · 配套休息区', color: 'deep', image: '/static/visuals/indoor-court.jpg', mapX: 72, mapY: 76, features: ['室内场地', '更衣室', '休息区'] },
|
||||
{ id: 'sky', name: '金鹰 51FLOOR 空中馆', district: '建邺', address: '建邺区示意路 4 号', distance: '4.2km', surface: '云端景观', price: 129, rating: '5.0', courts: 11, band: 'premium', note: '室内场地 · 配套淋浴', color: 'gold', image: '/static/visuals/indoor-court.jpg', mapX: 38, mapY: 21, features: ['室内场地', '淋浴', '休息区', '停车场'] }
|
||||
];
|
||||
|
||||
// 根据指定的演示时间生成客户端当地日期。
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// 商品数据来自演示配置,真实项目可替换为小程序商城或一件代发服务的接口。
|
||||
export const shopProducts = [
|
||||
{ id: 'starter-kit', name: '新球友入门礼包', category: 'all', tag: '官方补贴', price: 9.9, originalPrice: 29.9, stock: 99, sales: '已售 2,480', color: 'teal', icon: 'P', desc: '木拍 ×1 · 匹克球 ×2 · 护腕 · 入门手册' },
|
||||
{ id: 'starter-kit', name: '新球友入门礼包', category: 'all', tag: '官方补贴', price: 9.9, originalPrice: 29.9, stock: 99, sales: '已售 2,480', color: 'teal', icon: 'P', image: '/static/visuals/starter-kit.jpg', desc: '木拍 ×1 · 匹克球 ×2 · 护腕 · 入门手册' },
|
||||
{ id: 'indoor-balls', name: '户外专用匹克球 · 40孔 × 3 只装', category: 'ball', tag: '耗材回购', price: 19.9, originalPrice: 35, stock: 35, sales: '已售 1,246', color: 'green', icon: 'O', desc: '耐打耐磨 · 适合日常训练与户外对局' },
|
||||
{ id: 'paddle', name: '玻纤入门拍 · 蓝白 235g', category: 'paddle', tag: '官方补贴', price: 49, originalPrice: 89, stock: 18, sales: '已售 860', color: 'blue', icon: '◐', desc: '轻量玻纤面 · 新手好上手 · 含拍套' },
|
||||
{ id: 'grip', name: '吸汗手胶 3 条装', category: 'accessory', tag: '新 人 专享', price: 12.9, originalPrice: 19.9, stock: 50, sales: '已售 738', color: 'amber', icon: '≈', desc: '防滑吸汗 · 适配主流球拍手柄' },
|
||||
|
||||
@@ -37,10 +37,10 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
</view>
|
||||
|
||||
<view class="event-banner">
|
||||
<image class="event-image" src="/static/visuals/tournament.jpg" mode="aspectFill" />
|
||||
<view class="event-top">赛事报名中 <text>南京站</text></view>
|
||||
<view class="event-title">拍立方杯 CPC 积分赛</view>
|
||||
<view class="event-sub">分级别公开赛 · 冠军直通年度总决赛</view>
|
||||
<view class="event-mark">P</view>
|
||||
</view>
|
||||
|
||||
<view class="quick-grid">
|
||||
@@ -64,8 +64,7 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
|
||||
<view v-if="!visibleVenues.length" class="empty">没有找到符合条件的场地</view>
|
||||
<view v-for="venue in visibleVenues" :key="venue.id" class="venue-card card" @tap="showVenue(venue)">
|
||||
<view class="venue-art" :class="venue.color"><text class="court-count">{{ venue.courts }} 片</text><text
|
||||
class="court-symbol">⊕</text></view>
|
||||
<view class="venue-art" :class="venue.color"><image :src="venue.image" mode="aspectFill" /><text class="court-count">{{ venue.courts }} 片 · 示意</text></view>
|
||||
<view class="venue-main">
|
||||
<view class="venue-title">{{ venue.name }} <text class="district">{{ venue.district }}</text></view>
|
||||
<view class="venue-meta">⌖ {{ venue.distance }} · {{ venue.surface }}</view>
|
||||
@@ -131,7 +130,14 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
padding: 29rpx;
|
||||
border-radius: 18rpx;
|
||||
color: #fff;
|
||||
background: linear-gradient(120deg, #216c37, #4cae5d);
|
||||
background: #075059;
|
||||
}
|
||||
|
||||
.event-image {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.event-top {
|
||||
@@ -164,16 +170,6 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
|
||||
.event-mark {
|
||||
position: absolute;
|
||||
right: -18rpx;
|
||||
bottom: -70rpx;
|
||||
font-weight: 900;
|
||||
font-size: 300rpx;
|
||||
line-height: 1;
|
||||
color: rgba(255, 255, 255, .12);
|
||||
}
|
||||
|
||||
.quick-grid {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
@@ -227,6 +223,7 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
.venue-art {
|
||||
position: relative;
|
||||
width: 152rpx;
|
||||
height: 148rpx;
|
||||
flex: none;
|
||||
border-radius: 13rpx;
|
||||
display: flex;
|
||||
@@ -235,6 +232,12 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.venue-art image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: inherit;
|
||||
}
|
||||
|
||||
.venue-art.green {
|
||||
background: #55aa5d;
|
||||
}
|
||||
@@ -261,11 +264,6 @@ function openTab(url) { uni.switchTab({ url }); }
|
||||
font-size: 19rpx;
|
||||
}
|
||||
|
||||
.court-symbol {
|
||||
font-size: 69rpx;
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
.venue-main {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
@@ -101,8 +101,8 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
<view class="product-grid">
|
||||
<view v-for="product in visibleProducts" :key="product.id" class="product-card card"
|
||||
@tap="openProduct(product)">
|
||||
<view class="product-art" :class="product.color"><text class="product-tag">{{ product.tag }}</text><text
|
||||
class="product-icon">{{ product.icon }}</text></view>
|
||||
<view class="product-art" :class="product.color"><image v-if="product.image" :src="product.image" mode="aspectFill" /><text class="product-tag">{{ product.tag }}</text><text
|
||||
v-if="!product.image" class="product-icon">{{ product.icon }}</text></view>
|
||||
<view class="product-info">
|
||||
<view class="product-name">{{ product.name }}</view>
|
||||
<view class="product-desc">{{ product.desc }}</view>
|
||||
@@ -119,7 +119,7 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
<uni-popup ref="detailPopup" type="bottom" background-color="#fff" border-radius="24rpx 24rpx 0 0" @change="onDetailPopupChange">
|
||||
<view v-if="selectedProduct" class="detail-sheet">
|
||||
<view class="popup-heading"><text>商品详情</text><text class="popup-close" @tap="closeProduct">×</text></view>
|
||||
<view class="detail-art" :class="selectedProduct.color"><text>{{ selectedProduct.icon }}</text></view>
|
||||
<view class="detail-art" :class="selectedProduct.color"><image v-if="selectedProduct.image" :src="selectedProduct.image" mode="aspectFill" /><text v-else>{{ selectedProduct.icon }}</text></view>
|
||||
<view class="detail-title">{{ selectedProduct.name }}</view>
|
||||
<view class="detail-price">¥{{ selectedProduct.price }} <text>¥{{ selectedProduct.originalPrice }}</text></view>
|
||||
<view class="detail-stock">库存 {{ selectedProduct.stock }} · {{ selectedProduct.tag }}</view>
|
||||
@@ -133,7 +133,7 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
<scroll-view class="cart-items" scroll-y :style="{ height: cartListHeight }">
|
||||
<view v-if="!cart.items.length" class="cart-empty">购物车还是空的</view>
|
||||
<view v-for="line in cart.items" :key="line.productId" class="cart-line">
|
||||
<view class="cart-thumb" :class="line.product.color">{{ line.product.icon }}</view>
|
||||
<view class="cart-thumb" :class="line.product.color"><image v-if="line.product.image" :src="line.product.image" mode="aspectFill" /><text v-else>{{ line.product.icon }}</text></view>
|
||||
<view class="cart-main">
|
||||
<view class="cart-name">{{ line.product.name }}</view>
|
||||
<view class="cart-price">¥{{ line.product.price }}</view>
|
||||
@@ -373,6 +373,18 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
color: rgba(255, 255, 255, .9);
|
||||
}
|
||||
|
||||
.product-art image,
|
||||
.detail-art image,
|
||||
.cart-thumb image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.product-art image {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.product-art.teal, .cart-thumb.teal, .detail-art.teal {
|
||||
background: #49b3ad;
|
||||
}
|
||||
@@ -532,6 +544,7 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
border-radius: 12rpx;
|
||||
color: #fff;
|
||||
font-size: 43rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cart-main {
|
||||
@@ -607,6 +620,7 @@ function openOrders() { uni.navigateTo({ url: '/pages/shop/orders' }); }
|
||||
justify-content: center;
|
||||
border-radius: 18rpx;
|
||||
color: rgba(255, 255, 255, .9);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.detail-art text {
|
||||
|
||||
BIN
src/static/visuals/indoor-court.jpg
Normal file
BIN
src/static/visuals/indoor-court.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 147 KiB |
BIN
src/static/visuals/outdoor-court.jpg
Normal file
BIN
src/static/visuals/outdoor-court.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 304 KiB |
BIN
src/static/visuals/starter-kit.jpg
Normal file
BIN
src/static/visuals/starter-kit.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 124 KiB |
BIN
src/static/visuals/tournament.jpg
Normal file
BIN
src/static/visuals/tournament.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 116 KiB |
@@ -47,9 +47,7 @@ function startMatch() {
|
||||
<template>
|
||||
<view v-if="venue" class="page detail-page">
|
||||
<view class="court-art" :class="venue.color">
|
||||
<view class="court-lines">
|
||||
<view class="court-net"></view>
|
||||
</view>
|
||||
<image :src="venue.image" mode="aspectFill" />
|
||||
<view class="art-label">场地示意 · {{ venue.courts }} 片球场</view>
|
||||
</view>
|
||||
<view class="venue-heading">
|
||||
@@ -116,6 +114,11 @@ function startMatch() {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.court-art image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.court-art.green {
|
||||
background: #448d52;
|
||||
}
|
||||
@@ -132,41 +135,6 @@ function startMatch() {
|
||||
background: #d6a345;
|
||||
}
|
||||
|
||||
.court-lines {
|
||||
position: relative;
|
||||
width: 59%;
|
||||
height: 64%;
|
||||
border: 5rpx solid rgba(255, 255, 255, .82);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.court-lines::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
border-left: 4rpx solid rgba(255, 255, 255, .82);
|
||||
}
|
||||
|
||||
.court-lines::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 29%;
|
||||
border-top: 4rpx solid rgba(255, 255, 255, .82);
|
||||
}
|
||||
|
||||
.court-net {
|
||||
position: absolute;
|
||||
left: -9%;
|
||||
right: -9%;
|
||||
top: 50%;
|
||||
border-top: 6rpx dashed rgba(255, 255, 255, .95);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.art-label {
|
||||
position: absolute;
|
||||
left: 22rpx;
|
||||
|
||||
Reference in New Issue
Block a user