合并:中奖名单公示页搜索修复(feature/venue-discount-rights-filter → xuchao)
冲突解决:venue 列表灰底间距与卡片内边距取 feature 侧设计修正;card-address 保留 min-width:0;index 页面取页级滚动方案。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+115
-12
@@ -15,7 +15,7 @@
|
||||
<view class="store-info">
|
||||
<text class="store-name">{{ store.name }}</text>
|
||||
<text class="store-category">{{ store.category }}</text>
|
||||
<text class="store-hours">营业时间:{{ store.businessTime }}</text>
|
||||
<text class="store-hours" v-if="store.businessTime">营业时间:{{ store.businessTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="divider"></view>
|
||||
@@ -42,8 +42,8 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息(内容取商铺门票信息字段) -->
|
||||
<view class="discount-section" v-if="ticketInfoList.length">
|
||||
<!-- 商品信息(仅商户折扣板块展示,内容取商铺门票信息字段) -->
|
||||
<view class="discount-section" v-if="!isVenue && ticketInfoList.length">
|
||||
<view class="section-title">
|
||||
<image src="https://aliyunoss.hn12301.net/hhrs/hhrs_qysm.png" style="width: 30rpx;height: 30rpx;"></image>
|
||||
<text class="discount-title">商品信息</text>
|
||||
@@ -53,16 +53,31 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商户优惠 -->
|
||||
<view class="discount-section">
|
||||
<!-- 文旅场馆显示「使用说明」(1001板块备注),商户折扣显示「商户优惠」(1002板块备注) -->
|
||||
<view class="discount-section" v-if="remarkList.length">
|
||||
<view class="section-title">
|
||||
<image src="https://aliyunoss.hn12301.net/hhrs/hhrs_qysm.png" style="width: 30rpx;height: 30rpx;"></image>
|
||||
<text class="discount-title">商户优惠</text>
|
||||
<text class="discount-title">{{ isVenue ? '使用说明' : '商户优惠' }}</text>
|
||||
</view>
|
||||
<view class="discount-list">
|
||||
<text class="discount-item" v-for="(item, index) in discountList" :key="index">{{ item }}</text>
|
||||
<text class="discount-item" v-for="(item, index) in remarkList" :key="index">{{ item }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- xuchao: 怀化石油汽油券购买模块(shopId 写死特判,只服务该门店,决策 1/10/15) -->
|
||||
<view class="voucher-card" v-if="isPetrol">
|
||||
<view class="section-title">
|
||||
<image src="https://aliyunoss.hn12301.net/hhrs/hhrs_qysm.png" style="width: 30rpx;height: 30rpx;"></image>
|
||||
<text class="discount-title">汽油电子券</text>
|
||||
</view>
|
||||
<view class="voucher-ticket">
|
||||
<view class="voucher-amt">200元 <text class="voucher-amt-sub">汽油电子券</text></view>
|
||||
<view class="voucher-rule">无门槛 | 90 天有效 | 单日限用 1 张 | 可叠加</view>
|
||||
<text class="voucher-wm">90天</text>
|
||||
</view>
|
||||
<view class="voucher-tip">支付成功后券码即时展示;到店出示二维码,收银员以“中石油汽油券”通道扫码核销。券一经售出不支持退换。</view>
|
||||
<view class="voucher-btn" @click="onVoucherClick">{{ voucherBtnText }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- xuchao: 门店不存在或加载失败时的提示态,避免纯空白 -->
|
||||
<view class="page" v-else-if="loaded">
|
||||
@@ -80,21 +95,47 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { PETROL_SHOP_ID, bizOk, bizData } from '@/common/petrolVoucher.js'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
store: null,
|
||||
loaded: false
|
||||
loaded: false,
|
||||
detailType: '1',
|
||||
shopId: '',
|
||||
voucher: null // xuchao: 石油券最新订单状态(statusCode 语义见 common/petrolVoucher.js)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// xuchao: 入口板块:type=2 商户折扣,其余(含缺省)按文旅场馆渲染
|
||||
isVenue() {
|
||||
return this.detailType !== '2'
|
||||
},
|
||||
isPetrol() {
|
||||
// xuchao: 业务调整:该商铺不再需要特殊购买处理,前端入口整体隐藏;券页面/接口/SDK注入均保留,恢复时去掉下面的 return false 即可
|
||||
return false
|
||||
// xuchao: 后端券服务探活(latest 返回 price)后才展示购券模块——后端未部署期间整模块自动隐藏,无死入口
|
||||
// return this.loaded && String(this.shopId) === PETROL_SHOP_ID && !this.isVenue && !!(this.voucher && this.voucher.price)
|
||||
},
|
||||
voucherBtnText() {
|
||||
const s = this.voucher ? this.voucher.statusCode : -1
|
||||
if (s === 0) return '继续支付'
|
||||
if (s === 1 || s === 2) return '查看我的券'
|
||||
if (s === 3 || s === 4) return '重新购买'
|
||||
// xuchao: 购买按钮金额取服务端下发价(测试期 0.01);未登录无数据时用中性文案
|
||||
if (this.voucher && this.voucher.price) return '¥' + (this.voucher.price / 100).toFixed(2) + ' 购买'
|
||||
return '购买汽油券'
|
||||
},
|
||||
ticketInfoList() {
|
||||
if (!this.store || !this.store.ticketInfo) return []
|
||||
return this.store.ticketInfo.split('\n')
|
||||
},
|
||||
discountList() {
|
||||
if (!this.store || !this.store.merchantDiscount) return []
|
||||
return this.store.merchantDiscount.split('\n')
|
||||
remarkList() {
|
||||
if (!this.store) return []
|
||||
const text = this.isVenue ? this.store.usageNote : this.store.merchantDiscount
|
||||
if (!text) return []
|
||||
return text.split('\n')
|
||||
},
|
||||
// xuchao: 客服电话列表:按常见分隔符切分;无分隔符连写的多个11位手机号也自动拆开
|
||||
servicePhoneList() {
|
||||
@@ -121,11 +162,39 @@ export default {
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
if (options.type) this.detailType = String(options.type)
|
||||
if (options.id) {
|
||||
this.shopId = String(options.id)
|
||||
this.loadDetail(options.id)
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
// xuchao: 支付/购券流程返回时刷新券按钮状态
|
||||
if (String(this.shopId) === PETROL_SHOP_ID) this.loadVoucher()
|
||||
},
|
||||
methods: {
|
||||
// xuchao: 拉取石油券最新订单状态(未登录也调用:作为后端服务探活,price 决定模块显隐)
|
||||
loadVoucher() {
|
||||
const phone = uni.getStorageSync('phone') || ''
|
||||
this.$u.api.voucherLatest({ phone }).then(res => {
|
||||
this.voucher = bizOk(res) ? bizData(res) : null
|
||||
}).catch(() => { this.voucher = null })
|
||||
},
|
||||
onVoucherClick() {
|
||||
const phone = uni.getStorageSync('phone')
|
||||
if (!phone) {
|
||||
uni.navigateTo({ url: '/pages/index/login?redirect=' + encodeURIComponent('/pages/venue/detail?id=' + this.shopId + '&type=' + this.detailType) })
|
||||
return
|
||||
}
|
||||
const s = this.voucher ? this.voucher.statusCode : -1
|
||||
if (s === 2 || s === 1) {
|
||||
uni.navigateTo({ url: '/pages/petrol/voucherDetail' })
|
||||
} else if (s === 0) {
|
||||
uni.navigateTo({ url: '/pages/petrol/orderConfirm?orderNo=' + this.voucher.orderNo })
|
||||
} else {
|
||||
uni.navigateTo({ url: '/pages/petrol/orderConfirm' })
|
||||
}
|
||||
},
|
||||
// xuchao: 点击某个商户电话唤起拨号(多个号码时逐个可点)
|
||||
callPhone(phone) {
|
||||
if (!phone) return
|
||||
@@ -251,7 +320,7 @@ export default {
|
||||
color: #999999;
|
||||
}
|
||||
|
||||
/* 商户优惠 */
|
||||
/* 使用说明 */
|
||||
.discount-section {
|
||||
background-color: #ffffff;
|
||||
margin: 12px;
|
||||
@@ -294,6 +363,40 @@ export default {
|
||||
color: #0088ff;
|
||||
}
|
||||
|
||||
/* xuchao: 石油汽油券购买模块 */
|
||||
.voucher-card {
|
||||
background-color: #ffffff;
|
||||
margin: 12px;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.voucher-ticket {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(135deg, #0d6fe0, #2f9bff);
|
||||
border-radius: 8px;
|
||||
padding: 14px;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.voucher-amt { font-size: 22px; font-weight: 700; }
|
||||
.voucher-amt-sub { font-size: 12px; font-weight: 400; opacity: 0.9; margin-left: 4px; }
|
||||
.voucher-rule { font-size: 12px; opacity: 0.9; margin-top: 6px; }
|
||||
.voucher-wm { position: absolute; right: 4px; bottom: -12px; font-size: 52px; font-weight: 800; opacity: 0.1; }
|
||||
.voucher-tip { font-size: 12px; color: #666666; line-height: 1.7; margin-top: 12px; }
|
||||
.voucher-btn {
|
||||
height: 42px;
|
||||
margin-top: 12px;
|
||||
border-radius: 8px;
|
||||
background-color: #0088ff;
|
||||
color: #ffffff;
|
||||
font-size: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* xuchao: 加载失败提示态 */
|
||||
.load-failed {
|
||||
display: flex;
|
||||
|
||||
+74
-9
@@ -13,12 +13,19 @@
|
||||
<view class="search-btn" @click="onSearch">搜索</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- xuchao: 所属县区 + 所属类型筛选,选项与联动条数由列表接口一并返回 -->
|
||||
<hhrs-filter-bar :districts="filters.districts" :categories="filters.categories"
|
||||
:district-id="districtId" :category="category" @change="onFilterChange" />
|
||||
</view>
|
||||
|
||||
<!-- 场馆列表 -->
|
||||
<view class="list-area">
|
||||
<view class="venue-card" v-for="item in list" :key="item.shopId" @click="goDetail(item)">
|
||||
<image class="card-img" :src="item.image" mode="aspectFill" />
|
||||
<view class="venue-card" v-for="item in list" :key="item.shopId">
|
||||
<view class="card-thumb">
|
||||
<image class="card-img" :src="item.image" mode="aspectFill" />
|
||||
<!-- xuchao: 左上角所属地区角标(districtName 来自商铺「所在地区」,未录入则不显示) -->
|
||||
<text class="card-area" v-if="item.districtName">{{ shortDistrict(item.districtName) }}</text>
|
||||
</view>
|
||||
<view class="card-info">
|
||||
<text class="card-name">{{ item.name }}</text>
|
||||
<text class="card-category">{{ item.category }}</text>
|
||||
@@ -39,7 +46,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// xuchao: 角标区县简称(后端返回的是行政区划全称)
|
||||
import { shortDistrict } from '@/common/district.js'
|
||||
// xuchao: 县区 + 类型筛选条,三个列表页共用(pages.json 的 easycom 只给 u- 前缀配了规则,这里显式引入)
|
||||
import HhrsFilterBar from '@/components/hhrs-filter-bar/hhrs-filter-bar.vue'
|
||||
|
||||
export default {
|
||||
components: { HhrsFilterBar },
|
||||
data() {
|
||||
return {
|
||||
keyword: '',
|
||||
@@ -52,7 +65,11 @@ export default {
|
||||
lat: '',
|
||||
loadStatus: 'loadmore',
|
||||
hasScrolled: false,
|
||||
reqSeq: 0
|
||||
reqSeq: 0,
|
||||
// xuchao: 筛选条件与面板选项(选项由列表响应带回)
|
||||
districtId: '',
|
||||
category: '',
|
||||
filters: { districts: [], categories: [] }
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
@@ -70,6 +87,7 @@ export default {
|
||||
this.loadMore()
|
||||
},
|
||||
methods: {
|
||||
shortDistrict,
|
||||
loadList() {
|
||||
// xuchao: 请求序号 —— 新请求直接取代在途请求,过期响应整体丢弃(修复搜索竞态,故不再用 loading 提前 return)
|
||||
const seq = ++this.reqSeq
|
||||
@@ -83,9 +101,16 @@ export default {
|
||||
}
|
||||
if (this.lng) params.lng = this.lng
|
||||
if (this.lat) params.lat = this.lat
|
||||
if (this.districtId) params.districtId = this.districtId
|
||||
if (this.category) params.category = this.category
|
||||
this.$u.api.getStoreList(params).then(res => {
|
||||
if (seq !== this.reqSeq) return
|
||||
if (res.errcode === 0 && res.data) {
|
||||
// xuchao: 面板选项随列表一起回来(后端已按关键词与另一维度算好条数)
|
||||
this.filters = {
|
||||
districts: res.data.districts || [],
|
||||
categories: res.data.categories || []
|
||||
}
|
||||
const list = res.data.list || []
|
||||
if (this.pageNo === 1) {
|
||||
this.list = list
|
||||
@@ -124,13 +149,16 @@ export default {
|
||||
uni.reLaunch({ url: '/pages/index/index' })
|
||||
}
|
||||
},
|
||||
goDetail(item) {
|
||||
uni.navigateTo({ url: '/pages/venue/detail?id=' + item.shopId })
|
||||
},
|
||||
onSearch() {
|
||||
this.pageNo = 1
|
||||
this.list = []
|
||||
this.loadList()
|
||||
},
|
||||
// xuchao: 换筛选条件即回第 1 页重查(关键词保持不变,两者为 AND)
|
||||
onFilterChange(e) {
|
||||
this.districtId = e.districtId
|
||||
this.category = e.category
|
||||
this.onSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +173,11 @@ export default {
|
||||
|
||||
.search-area {
|
||||
background-color: #ffffff;
|
||||
padding: 6px 12px;
|
||||
padding: 6px 12px 0;
|
||||
/* xuchao: 滚动时固定在页面顶部;z-index 高于筛选遮罩(90),保证面板与选中态不被压住 */
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.nav-row {
|
||||
@@ -196,6 +228,8 @@ export default {
|
||||
}
|
||||
|
||||
.list-area {
|
||||
/* xuchao: 顶部 12px 必须是页面灰底(不能放进头部的白底里),否则与白色卡片连成一片看不出间隔 */
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.venue-card {
|
||||
@@ -204,21 +238,49 @@ export default {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #f2f2f7;
|
||||
border-radius: 6px;
|
||||
padding: 12px;
|
||||
padding: 24px 12px;
|
||||
gap: 12px;
|
||||
box-shadow: 0 2px 3px #f2f2f7;
|
||||
margin: 12px;
|
||||
}
|
||||
|
||||
.card-img {
|
||||
.card-thumb {
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* xuchao: image 由 thumb 裁圆角,自身不再设圆角 */
|
||||
.card-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-area {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
padding: 1px 5px;
|
||||
border-radius: 0 0 6px 0;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
color: #ffffff;
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.card-info {
|
||||
flex: 1;
|
||||
/* xuchao: flex 项默认 min-width:auto,nowrap 地址会把列宽撑破卡片;置 0 后子元素在实宽内省略 */
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
@@ -240,6 +302,9 @@ export default {
|
||||
font-size: 14px;
|
||||
color: #727272;
|
||||
margin-top: 8px;
|
||||
/* xuchao: 分类为空也预留一行高度,防止卡片内容底部对齐时名称上下跳动 */
|
||||
min-height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.card-bottom {
|
||||
|
||||
Reference in New Issue
Block a user