Files
hhrs/pages/rights/detail.vue
T
2026-07-15 16:53:38 +08:00

416 lines
8.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="page">
<view v-if="detail">
<!-- 门店信息卡片 -->
<view class="store-card">
<image class="store-img" :src="detail.shopImage" mode="aspectFill" />
<view class="store-info">
<text class="store-name">{{ detail.shopName }}</text>
<text class="store-category">{{ detail.category }}</text>
<text class="store-hours">营业时间:{{ detail.businessTime }}</text>
</view>
</view>
<!-- 地址行 -->
<view class="address-row">
<text class="address-text">{{ detail.address }}</text>
<view class="distance-row" v-if="detail.distance !== null">
<u-icon name="map" color="#999999" size="24"></u-icon>
<text class="distance-text">{{ detail.distance < 1 ? Math.round(detail.distance * 1000) + 'm' : Math.round(detail.distance) + 'km' }}</text>
</view>
</view>
<!-- 选择预约日期 -->
<view class="date-section">
<view class="section-title">
<image src="https://aliyunoss.hn12301.net/hhrs/hhrs_xzyyrq.png" style="width: 30rpx;height: 30rpx;"></image>
<text class="section-title-text">选择预约日期</text>
</view>
<view class="date-list">
<view
v-for="(item, index) in detail.dates"
:key="index"
class="date-card"
:class="{ active: selectedDate === index, disabled: item.disabled }"
@click="!item.disabled && selectDate(index)"
>
<text class="date-weekday">{{ item.weekday }}</text>
<text class="date-day">{{ item.day }}</text>
<text class="date-stock">{{ item.stock }}</text>
</view>
</view>
<!-- 时段选择 -->
<view class="time-slot-section" v-if="detail.dates[selectedDate] && detail.dates[selectedDate].timeSlots">
<text class="section-title-text" style="margin-top:16px;">选择时段</text>
<view class="time-slot-list">
<view v-for="(slot, idx) in detail.dates[selectedDate].timeSlots" :key="slot.id"
class="time-slot-card" :class="{ active: selectedTimeSlot === idx }"
@click="selectTimeSlot(idx)">
<text class="slot-name">{{ slot.name }}</text>
<text class="slot-time">{{ slot.time }}</text>
<text class="slot-stock">{{ slot.stock }}</text>
</view>
</view>
</view>
<text class="date-tip" v-if="detail.isAppointment">仅可预约近 {{ detail.appointmentDays }} 日内时段</text>
</view>
<!-- 使用说明 -->
<view class="discount-section">
<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="discount-list">
<text class="discount-item">{{ detail.cardInstruction }}</text>
</view>
</view>
<!-- 底部预约按钮 -->
<view class="bottom-bar">
<view class="book-btn" @click="onBook">立即预约</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
ruleId: '',
detail: null,
selectedDate: 0,
selectedTimeSlot: null
}
},
onLoad(options) {
if (options.id) {
this.ruleId = options.id
this.loadDetail(options.id)
}
},
methods: {
selectDate(index) {
this.selectedDate = index
this.selectedTimeSlot = null
},
selectTimeSlot(index) {
this.selectedTimeSlot = index
},
onBook() {
if (!this.detail) return
const date = this.detail.dates[this.selectedDate]
if (date.disabled) {
uni.showToast({ title: date.reason || '该日期不可预约', icon: 'none' })
return
}
if (this.detail.isAppointment && this.detail.dates[this.selectedDate].timeSlots && this.selectedTimeSlot === null) {
uni.showToast({ title: '请选择时段', icon: 'none' })
return
}
// TODO: 调用预约接口
uni.showToast({ title: '预约成功', icon: 'success' })
},
loadDetail(ruleId) {
const loc = uni.getStorageSync('lng') && uni.getStorageSync('lat')
? { lng: uni.getStorageSync('lng'), lat: uni.getStorageSync('lat') }
: null
const params = { ruleId: ruleId }
if (loc) {
params.lng = loc.lng
params.lat = loc.lat
}
this.$u.api.getRightsDetail(params).then(res => {
if (res.errcode === 0 && res.data) {
this.detail = res.data
const firstAvailable = res.data.dates.findIndex(d => !d.disabled)
this.selectedDate = firstAvailable >= 0 ? firstAvailable : 0
}
})
}
}
}
</script>
<style>
page {
background-color: #f2f2f7;
padding-top: 24rpx;
}
</style>
<style scoped lang="less">
/* 门店卡片 */
.store-card {
display: flex;
background-color: #ffffff;
margin:0rpx 12px 12px 12px;
border-radius: 8px;
padding: 12px;
gap: 12px;
}
.store-img {
width: 100px;
height: 100px;
border-radius: 6px;
flex-shrink: 0;
}
.store-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
gap: 6px;
}
.store-name {
font-size: 16px;
font-weight: 500;
color: #1a1818;
}
.store-category {
font-size: 13px;
color: #999999;
}
.store-hours {
font-size: 13px;
color: #666666;
}
/* 地址行 */
.address-row {
display: flex;
align-items: center;
justify-content: space-between;
background-color: #ffffff;
padding: 12px 16px;
}
.address-text {
font-size: 13px;
color: #999999;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.distance-row {
display: flex;
align-items: center;
gap: 2px;
flex-shrink: 0;
margin-left: 8px;
}
.distance-text {
font-size: 12px;
color: #999999;
}
/* 选择预约日期 */
.date-section {
background-color: #ffffff;
margin: 12px;
border-radius: 8px;
padding: 16px;
}
.section-title {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 16px;
}
.section-icon {
width: 18px;
height: 18px;
background-color: #0088ff;
color: #ffffff;
border-radius: 50%;
text-align: center;
line-height: 18px;
font-size: 12px;
font-weight: 700;
}
.section-title-text {
font-size: 15px;
font-weight: 600;
color: #1a1818;
}
.date-list {
display: flex;
gap: 12px;
}
.date-card {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 8px;
border: 1px solid #e8e8e8;
border-radius: 8px;
gap: 4px;
}
.date-card.active {
background-color: #0088ff;
border-color: #0088ff;
}
.date-card.disabled {
opacity: 0.4;
pointer-events: none;
}
.date-weekday {
font-size: 12px;
color: #999999;
}
.date-card.active .date-weekday {
color: rgba(255,255,255,0.8);
}
.date-day {
font-size: 15px;
font-weight: 600;
color: #1a1818;
}
.date-card.active .date-day {
color: #ffffff;
}
.date-stock {
font-size: 11px;
color: #999999;
}
.date-card.active .date-stock {
color: rgba(255,255,255,0.8);
}
.date-tip {
font-size: 12px;
color: #999999;
margin-top: 12px;
display: block;
}
.time-slot-section {
margin-top: 16px;
}
.time-slot-list {
display: flex;
gap: 12px;
margin-top: 12px;
}
.time-slot-card {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 12px 8px;
border: 1px solid #e8e8e8;
border-radius: 8px;
gap: 4px;
}
.time-slot-card.active {
background-color: #0088ff;
border-color: #0088ff;
}
.slot-name {
font-size: 13px;
font-weight: 600;
color: #1a1818;
}
.time-slot-card.active .slot-name {
color: #ffffff;
}
.slot-time {
font-size: 11px;
color: #999999;
}
.time-slot-card.active .slot-time {
color: rgba(255,255,255,0.8);
}
.slot-stock {
font-size: 11px;
color: #999999;
}
.time-slot-card.active .slot-stock {
color: rgba(255,255,255,0.8);
}
/* 商户优惠 */
.discount-section {
background-color: #ffffff;
margin: 12px;
border-radius: 8px;
padding: 16px;
}
.discount-tag-icon {
font-size: 16px;
color: #0088ff;
}
.discount-title {
font-size: 15px;
font-weight: 600;
color: #1a1818;
}
.discount-list {
display: flex;
flex-direction: column;
gap: 12px;
}
.discount-item {
font-size: 13px;
color: #666666;
line-height: 1.6;
}
/* 底部预约按钮 */
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #ffffff;
padding: 12px 16px;
padding-bottom: calc(12px + env(safe-area-inset-bottom));
z-index: 100;
}
.book-btn {
background-color: #0088ff;
color: #ffffff;
text-align: center;
font-size: 16px;
font-weight: 500;
height: 44px;
line-height: 44px;
border-radius: 22px;
}
</style>