Files
hhrs/pages/venue/detail.vue
T

325 lines
7.2 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>
<view class="page" v-if="store">
<!-- xuchao: 顶部导航(返回+页面名称) -->
<view class="nav-bar">
<view class="nav-back" @click="goBack">
<u-icon name="arrow-left" color="#1a1818" size="40"></u-icon>
</view>
<text class="nav-title">{{ store.name }}</text>
</view>
<!-- 门店信息卡片(信息+地址合并容器) -->
<view class="store-card">
<view class="store-main">
<image class="store-img" :src="store.image" mode="aspectFill" />
<view class="store-info">
<text class="store-name">{{ store.name }}</text>
<text class="store-category">{{ store.category }}</text>
<text class="store-hours" v-if="store.businessTime">营业时间:{{ store.businessTime }}</text>
</view>
</view>
<view class="divider"></view>
<view class="address-row">
<text class="address-text">{{ store.address }}</text>
<view class="distance-row" v-if="store.distance !== null">
<u-icon name="map" color="#999999" size="24"></u-icon>
<text class="distance-text">{{ store.distance < 1 ? Math.round(store.distance * 1000) + 'm' : Math.round(store.distance) + 'km' }}</text>
</view>
</view>
</view>
<!-- 商户电话(取商铺客服电话字段,多个用,分隔,点击拨号) -->
<view class="discount-section" v-if="servicePhoneList.length">
<view class="section-title">
<u-icon name="phone-fill" color="#1296DB" size="34"></u-icon>
<text class="discount-title">商户电话</text>
</view>
<view class="discount-list">
<text class="discount-item">
<text v-for="(p, i) in servicePhoneList" :key="i" class="phone-link"
@click="callPhone(p)">{{ i > 0 ? ',' : '' }}{{ p }}</text>
</text>
</view>
</view>
<!-- 使用说明(内容取文旅场馆第三方设置里的备注 shop_relation.remark) -->
<view class="discount-section" v-if="discountList.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>
</view>
<view class="discount-list">
<text class="discount-item" v-for="(item, index) in discountList" :key="index">{{ item }}</text>
</view>
</view>
</view>
<!-- xuchao: 门店不存在或加载失败时的提示态,避免纯空白 -->
<view class="page" v-else-if="loaded">
<view class="nav-bar">
<view class="nav-back" @click="goBack">
<u-icon name="arrow-left" color="#1a1818" size="40"></u-icon>
</view>
<text class="nav-title">详情</text>
</view>
<view class="load-failed">
<text class="load-failed-text">门店信息加载失败,该门店可能不存在或已下架</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
store: null,
loaded: false
}
},
computed: {
discountList() {
if (!this.store || !this.store.merchantDiscount) return []
return this.store.merchantDiscount.split('\n')
},
// xuchao: 客服电话列表:按常见分隔符切分;无分隔符连写的多个11位手机号也自动拆开
servicePhoneList() {
if (!this.store || !this.store.servicePhone) return []
const parts = String(this.store.servicePhone).split(/[,,;;、\s\n]+/).filter(Boolean)
const out = []
parts.forEach(p => {
if (p.length > 11 && /^1[3-9]\d{9}$/.test(p.slice(0, 11))) {
let rest = p
const segs = []
while (rest.length >= 11 && /^1[3-9]\d{9}$/.test(rest.slice(0, 11))) {
segs.push(rest.slice(0, 11))
rest = rest.slice(11)
}
if (rest) segs[segs.length - 1] += rest
if (segs.length > 1) {
out.push(...segs)
return
}
}
out.push(p)
})
return out
}
},
onLoad(options) {
if (options.id) {
this.loadDetail(options.id)
}
},
methods: {
// xuchao: 点击某个商户电话唤起拨号(多个号码时逐个可点)
callPhone(phone) {
if (!phone) return
uni.makePhoneCall({ phoneNumber: String(phone) })
},
loadDetail(shopId) {
const loc = uni.getStorageSync('lng') && uni.getStorageSync('lat')
? { lng: uni.getStorageSync('lng'), lat: uni.getStorageSync('lat') }
: null
const params = { shopId: shopId }
if (loc) {
params.lng = loc.lng
params.lat = loc.lat
}
this.$u.api.getStoreDetail(params).then(res => {
if (res.errcode === 0 && res.data) {
this.store = res.data
}
this.loaded = true
}).catch(() => {
this.loaded = true
})
},
goBack() {
// xuchao: 直接通过链接进入(无历史栈)时回到首页,避免返回无响应
const pages = getCurrentPages()
if (pages.length > 1) {
uni.navigateBack()
} else {
uni.reLaunch({ url: '/pages/index/index' })
}
}
}
}
</script>
<style>
.page {
/* xuchao: 顶部导航条占用 56px,改为 min-height 让长内容正常滚动,避免底部被裁切 */
min-height: 100vh;
background-color: #f2f2f7;
}
/* 门店卡片(信息+地址合并容器) */
.store-card {
background-color: #ffffff;
margin: 12px;
border-radius: 8px;
overflow: hidden;
}
.store-main {
display: flex;
align-items: flex-start;
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: flex-start;
gap: 8px;
}
.store-name {
font-size: 16px;
font-weight: 500;
color: #1a1818;
}
.store-category {
font-size: 13px;
color: #999999;
}
.store-hours {
font-size: 13px;
color: #666666;
}
.divider {
height: 1px;
background-color: #f2f2f7;
margin: 0 12px;
}
/* 地址行 */
.address-row {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px;
}
.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;
}
/* 使用说明 */
.discount-section {
background-color: #ffffff;
margin: 12px;
border-radius: 8px;
padding: 16px;
}
.section-title {
display: flex;
align-items: center;
gap: 6px;
margin-bottom: 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;
}
/* xuchao: 可点击拨号的电话样式 */
.phone-link {
color: #0088ff;
}
/* xuchao: 加载失败提示态 */
.load-failed {
display: flex;
justify-content: center;
padding: 80px 24px;
}
.load-failed-text {
font-size: 14px;
color: #999999;
}
/* xuchao: 顶部返回导航条 */
.nav-bar {
display: flex;
align-items: center;
height: 56px;
background-color: #ffffff;
border-bottom: 1px solid #f0f0f0;
position: relative;
}
.nav-back {
position: absolute;
left: 12px;
top: 0;
bottom: 0;
display: flex;
align-items: center;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 17px;
font-weight: 600;
color: #1a1818;
padding: 0 56px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>