时味苏州
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

874 lines
20 KiB

<template>
<view class="bg" v-if="info">
<view class="swipe-box">
<swiper class="swiper" :autoplay="true" :interval="3000" :duration="1000" circular>
<swiper-item v-for="(item, index) in info.listimg" :key="item.id">
<view class="swiper-item">
<image class="item-img" :src="showImg(item)" mode="aspectFill"></image>
</view>
</swiper-item>
</swiper>
</view>
<view class="detail-container">
<!-- 景点信息 -->
<view class="info-container">
<view class="wineScene-price">
<view class="price">
{{info.price / 100}}
<text class="old-price">¥{{info.market_price/100}}</text>
</view>
<view>已售{{info.sales_number||0}}份</view>
</view>
<view class="info-data">
<view class="text-overflowRows">{{info.title}}</view>
<view style="padding-top: 27rpx;" v-if="info.is_package">
<view class="wineScene-subtitle" v-for="(item,key,index) in info.product_data || []" :key="index">
<view>{{ key[0] }}</view>
<view class="wineScene-item">
<view class="flex-between" v-for="(data,dataI) in item" :key="dataI">
{{ data.title }}
<text>{{ data.unit }}</text>
</view>
</view>
<view class="wineScene-line"></view>
</view>
</view>
</view>
<view style="margin: 16rpx 0;">
<view class="map-container flex-between">
<view class="flex flex-column flex-1 w-1rpx" style="padding-right: 20rpx;">
<text class="text-overflow" style="font-size: 28rpx;color: #000000;">{{info.scene_name}}</text>
<text class="text-overflow" style="margin-top: 14rpx;">{{info.scene_address}}</text>
</view>
<view @click="goMap" class="flex flex-column flex-between flex-shrink-0">
<image style="width: 29rpx;height: 29rpx;" src="https://static.ticket.sz-trip.com/jundaosuzhou/images/wineScene/navigation.png"></image>
<text style="margin-top: 14rpx;">去这里</text>
</view>
</view>
</view>
<view class="scroll-all-box" id="menus">
<view :class="'scroll-menus' + (fixed ? ' fixed-menus' : '')">
<view :class="'scroll-menu-item' + (type == 1 ? ' active' : '')" @click="changeMenu(1)">产品特色</view>
<view :class="'scroll-menu-item' + (type == 2 ? ' active' : '')" @click="changeMenu(2)">费用说明</view>
<view :class="'scroll-menu-item' + (type == 3 ? ' active' : '')" @click="changeMenu(3)">预定须知</view>
</view>
<view style="height: 85rpx" v-if="fixed"></view>
<view class="info-box info-box-query" id="box1">
<view class="info-title">产品特色</view>
<view class="info-content" v-html="formateRichText(info.content)"></view>
</view>
<view class="info-box info-box-query" id="box2">
<view class="info-title">费用说明</view>
<view class="info-content" v-html="formateRichText(info.expense_info)"></view>
</view>
<view class="info-box info-box-query" id="box3">
<view class="info-title">预定须知</view>
<view class="info-content" v-html="formateRichText(info.book_info)"></view>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="btn-box flex-center">
<view style="width: 180rpx;" class="flex-between">
<button id="contact" open-type="contact" bindcontact="handleContact" session-from="sessionFrom">
<view class="icon-container">
<view class="icon-item">
<image src="https://static.ticket.sz-trip.com/uploads/20250611/627d67e48ac41903c40c31f1613f2444.png"></image>
<text>客服</text>
</view>
</view>
</button>
<view class="icon-container">
<view class="icon-item" style="position: relative;width: 80rpx;" @click="goCartPage()">
<image src="https://static.ticket.sz-trip.com/uploads/20250820/17eeecf12ba9fdc56bce3b84fd5fb45f.png" mode="aspectFill"></image>
<text>购物车</text>
<view class="cartNum" v-if="cartNum">{{cartNum}}</view>
</view>
</view>
</view>
<view class="flex">
<view class="btn" @click="openPop(true)">加入购物车</view>
<view class="btn" @click="openPop(false)">立即购买</view>
</view>
</view>
<!-- 购物车图标 -->
<!-- <view class="add-cart-icon" @click="goCartPage()">
<uni-badge class="uni-badge-left-margin" :text="cartNum" absolute="rightTop" :offset="[-3, -3]" size="small"
:custom-style="{background:'#DC2525',color:'#ffffff'}">
<image src="https://static.ticket.sz-trip.com/uploads/20250611/f8c2078ad76754a0b0251f9b65784dc2.png"></image>
</uni-badge>
</view> -->
<!-- 预定弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false" @change="changPopShow" style="position: relative;z-index: 50;">
<view class="popup-content" v-if="sku.length>0">
<view style="padding: 0rpx 39rpx 50rpx 39rpx;">
<view @click="closePopup" style="padding: 31rpx 0 0 639rpx;width: 50rpx;height: 80rpx;">
<uni-icons type="closeempty" size="24"></uni-icons>
</view>
<view class="bottom-productImg">
<img :src="showImg(sku[productIndex].headimg)" alt="">
<view class="right-content">
<view class="bottom-productPrice com-price">{{(sku[productIndex].price||0)/100}}</view>
<view class="bottom-content">已选择:{{sku[productIndex].sku_name}}</view>
</view>
</view>
<view>
<view class="sp">规格</view>
<view class="sp-container" style="">
<view style="position:relative;" v-for="(botItem,botIndex) in sku" :key="botIndex">
<view :class="['botProduct','text-overflow',{'noStore':botItem.store==0},{'botProducts':productIndex==botIndex}]"
@click="changeProduct(botItem,botIndex)">
{{botItem.sku_name}}
</view>
<view class="noStore-text" v-if="botItem.store==0">
不可购买
</view>
</view>
</view>
</view>
<view class="buy-num com-flex-tao">
数量
<view class="number-btn">
<view>
<text @click="delNumber">-</text>
</view>
<view style="width: 96rpx;height: 69rpx;margin: 0 14rpx;">{{ buyNum }}</view>
<view>
<text @click="addNumber">+</text>
</view>
</view>
</view>
</view>
<view class="sp-bottom-btn">
<view class="btn" @click="openPop">{{addCart?"加入购物车":"立即购买"}}</view>
</view>
</view>
</uni-popup>
</view>
</template>
<script>
export default {
data() {
return {
headImg: null,
id: null,
info: null,
down: false,
type: 1,
fixed: false,
sku: [],
productIndex: 0, // sku 选中的index
buyNum: 1,
popShow: false,
addCart: false, // 加入购物车、购买
skuInfo: {}, // 预定门票
selectGoods: {}, // 预定的商品
cartNum: 0,
}
},
onShow(options) {
this.getCartList()
},
onLoad(options) {
this.id = options.id;
this.getInfo();
// this.getGoodsList()
},
onPageScroll(e){
let query = uni.createSelectorQuery()
query.select("#menus").boundingClientRect(res => {
  if(res.top < 0){
this.fixed = true
}else{
this.fixed = false
}
}).exec()
if (this.down) {
return
}else{
this.down = true
query.selectAll(".info-box-query").boundingClientRect(res=>{
let i = res.findLastIndex(v=>v.top-100<=0)
if (i>=0) {
this.type = i+1
}
}).exec()
this.down = false
}
},
methods: {
// 获取景点信息
getInfo() {
this.Post({id: this.id,order:'desc'},'/api/product/get_product_detail').then(res => {
if (res.data.title) {
uni.setNavigationBarTitle({
title: res.data.title
})
}
let resData = res.data
try {
if (resData.product_data && resData.is_package==1) {
for(let key in resData.product_data) {
resData.product_data[key] = JSON.parse(resData.product_data[key])
}
}
} catch(e) {}
this.info = resData
this.sku = resData.sku
this.shareParam = {title: this.info.title, imageUrl: this.info.headimg}
});
},
goMap () {
if (!this.info.scene_lat || !this.info.scene_lon) {
uni.showToast({
title: '暂未配置地理位置',
icon: 'none'
})
return
}
uni.openLocation({
latitude: Number(this.info.scene_lat),
longitude: Number(this.info.scene_lon),
name: this.info.scene_name,
address: this.info.scene_address,
// success: function () {
// console.log('success');
// }
});
},
changeProduct(item,index) {
if (item.store==0) {
uni.showToast({
title:"库存不足!",
icon:'none'
})
return
}
this.productIndex = index
},
getCartList () {
this.Post({noForceLogin: true},'/api/cart/get_cart_count').then(res=>{
this.cartNum = res.data || 0
})
},
order() {
let goods = this.sku[this.productIndex]
goods.buyNum = this.buyNum
let orderInfo = [{
pInfo: this.info,
sInfo: goods,
}]
this.$store.commit("changeFoodOrderList", orderInfo);
uni.navigateTo({
url: '/subPackages/food/order'
});
},
addToCart () {
let goods = this.sku[this.productIndex]
goods.buyNum = this.buyNum
this.Post({sku_id: goods.id,num: this.buyNum },'/api/cart/add_sku').then(res => {
if (res.code == 1) {
uni.showToast({title: res.msg,icon: 'none'});
// uni.$emit("updateDataByConnect", {msgType:'updateCartDataInfo',data:null})
this.closePopup()
// this.$refs.cartDataVueRef.openPop()
this.getCartList()
}
});
},
closePopup() {
this.$refs.popup.close()
},
openPop(flag) {
if (!this.sku||this.sku.length<=0) {
uni.showToast({
title:'暂无可选规格',
icon:'none'
})
return
}
if (!this.popShow) {
this.addCart = flag
this.$refs.popup.open()
} else {
if (this.addCart) {
this.addToCart()
} else {
this.order()
}
}
},
//数量加减
addNumber() {
this.buyNum += 1;
},
delNumber() {
if (this.buyNum <= 1) {
return;
}
this.buyNum -= 1;
},
// 价格格式
showNoPriceNew(price) {
if (price && price > 0) {
return (price / 100)
} else {
return '0'
}
},
changPopShow (e) {
this.popShow = e.show
},
changeMenu(e) {
this.down = true
let index = e;
let that = this
const query = uni.createSelectorQuery(); //创建节点查询器
query.select('#box'+index).boundingClientRect(); //选择toViewid获取位置信息
query.selectViewport().scrollOffset(); //获取页面查询位置的
query.exec(function (res) {
let scrollTop = res[0].top + res[1].scrollTop;
uni.pageScrollTo({
scrollTop: scrollTop-50,
duration: 200,
fail: (e)=>{
console.log(e)
},
complete: ()=>{
that.type = index
setTimeout(()=>{that.down = false},1000)
}
});
});
},
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
}
.bg{
min-height: 100vh;
background: #F8F8F8;
}
.swipe-box {
height: 413rpx;
position: relative;
.swiper {
height: 413rpx;
position: relative;
.swiper-item {
width: 100%;
height: 413rpx;
.item-img {
width: 750rpx;
height: 413rpx;
}
}
}
}
.detail-container{
width: 100%;
z-index: 2;
padding: 26rpx 0;
position: relative;
top: -52rpx;
}
.info-container{
font-family: PingFang;
font-weight: 500;
font-size: 27rpx;
color: #666;
.wineScene-price{
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
display: flex;
align-items: flex-end;
justify-content: space-between;
width: 750rpx;
background: linear-gradient(-90deg, #FF413B, #FFAB2E);
border-radius: 20rpx 20rpx 0rpx 0rpx;
padding: 32rpx 26rpx;
.price{
font-size: 48rpx;
font-weight: bold;
&::before{
content: '¥';
font-size: 24rpx;
}
}
.old-price{
font-weight: 500;
font-size: 24rpx;
color: #FFFFFF;
text-decoration-line: line-through;
padding-left: 14rpx;
}
}
.info-data{
background: white;
width: 100%;
padding: 26rpx;
font-weight: bold;
font-size: 32rpx;
color: #000000;
.wineScene-subtitle {
display: flex;
font-weight: 500;
font-size: 24rpx;
color: #666666;
position: relative;
margin-bottom: 16rpx;
&>view:first-child {
width: 33rpx;
height: 33rpx;
background: #6A8A27;
border-radius: 50%;
line-height: 33rpx;
text-align: center;
font-weight: 500;
font-size: 23rpx;
color: #FFFFFF;
margin-right: 8rpx;
position: relative;
z-index: 2;
}
.wineScene-item {
flex: 1;
view:nth-child(n+2) {
margin-top: .3rem;
}
}
.wineScene-line {
width: 11rpx;
background: #D3E8A7;
border-radius: 5rpx;
height: 100%;
position: absolute;
left: 11rpx;
}
}
}
.map-container{
width: 100%;
height: 128rpx;
padding: 30rpx 27rpx;
font-weight: 500;
font-size: 24rpx;
color: #666666;
background-image: url("https://static.ticket.sz-trip.com/jundaosuzhou/images/wineScene/locationBg.png");
background-size: 100% 100%;
background-repeat: no-repeat;
}
}
.scroll-all-box {
margin: 20rpx 0;
background-color: #fff;
.scroll-menus {
padding: 0 40rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 29rpx;
color: #333;
height: 84rpx;
border-bottom: 1rpx solid #d9d9d9;
.scroll-menu-item {
position: relative;
line-height: 84rpx;
&.active{
font-weight: bold;
font-size: 33rpx;
color: #000000;
}
}
.scroll-menu-item.active::after {
content: '1';
font-size: 0;
display: block;
position: absolute;
width: 46rpx;
height: 6rpx;
border-radius: 3rpx;
background: #6A8A27;
left: 50%;
margin-left: -23rpx;
bottom: 0rpx;
}
}
.fixed-menus {
position: fixed;
top: 0;
left: 0;
right: 0;
background: white;
z-index: 1;
}
.info-box {
padding: 20rpx 0;
margin: 0 40rpx;
border-bottom: 1px solid #CCCCCC;
box-sizing: border-box;
.info-title {
font-size: 35rpx;
font-weight: bold;
color: #000;
}
.info-content {
width: 697rpx;
background: #FFFFFF;
border-radius: 20rpx;
padding: 22rpx 14rpx;
margin-top: 20rpx;
}
}
}
.fixed-menus {
position: fixed;
top: 0;
left: 0;
right: 0;
background: white;
z-index: 1;
}
.btn-box {
width: 750rpx;
height: 133rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(6,0,1,0.1);
position: fixed;
left: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 10;
padding: 0 26rpx;
.icon-container{
font-weight: 400;
font-size: 23rpx;
color: #666666;
text-align: center;
.icon-item{
display: flex;
align-items: center;
flex-direction: column;
width: 60rpx;
image{
width: 44rpx;
height: 42rpx;
margin-bottom: 8rpx;
}
}
}
.btn{
width: 200rpx;
height: 75rpx;
line-height: 75rpx;
font-weight: 500;
font-size: 31rpx;
color: #FFFFFF;
text-align: center;
background: #6A8A27;
border-radius: 0rpx 20rpx 20rpx 0rpx;
&:first-of-type{
background: #D3E8A7;
border-radius: 20rpx 0rpx 0rpx 20rpx;
color: #6A8A27;
}
}
}
.add-cart-icon{
width: 80rpx;
height: 80rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 20rpx 0rpx rgba(0,0,0,0.2);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
position: fixed;
bottom: 140rpx;
right: 20rpx;
z-index: 10;
image{
width: 43.33rpx;
height: 42rpx;
}
}
.popup-content {
background-color: white;
height: auto;
border-radius: 20rpx 20rpx 0 0;
.bottom-productImg {
display: flex;
margin-bottom: 23rpx;
flex-shrink: 0;
}
.bottom-productImg img {
width: 218rpx;
height: 179rpx;
background: #666666;
border-radius: 13rpx;
}
.right-content {
margin: 10rpx 0 0 41rpx;
flex: 1;
width: 1rpx;
}
.bottom-productPrice {
font-size: 40rpx;
color: #FC524B;
&:before {
content: "¥";
font-size: 26rpx;
}
}
.bottom-content {
width: 100%;
font-size: 27rpx;
font-family: PingFang SC;
font-weight: 400;
color: #666666;
}
.botProduct {
width: 320rpx;
// height: 78rpx;
border-radius: 13rpx;
background-color: #F5F5F5;
font-size: 29rpx;
font-family: PingFang SC;
font-weight: 400;
color: #333333;
line-height: 78rpx;
text-align: center;
margin-bottom: 25rpx;
display: inline-block;
position: relative;
padding: 0 40rpx;
}
.noStore{
background-color: rgba(239, 239, 239, 1);
color: rgba(153, 153, 153, 1);
}
.noStore-text{
width: 113rpx;
height: 43rpx;
background: #C0C0C0;
border-radius: 7rpx 0rpx 7rpx 0rpx;
text-align: center;
line-height: 43rpx;
position: absolute;
right: -14rpx;
top: -20rpx;
font-size: 23rpx;
font-family: PingFangSC;
font-weight: 400;
color: #FFFFFF;
}
.botProducts {
background: #6A8A27;
color: #FFFFFF;
}
.buy-num {
font-size: 29rpx;
font-family: PingFang SC;
font-weight: 400;
color: #333333;
padding: 39rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
}
.buy-num .number-btn {
display: flex;
}
.buy-num .number-btn view {
display: flex;
justify-content: center;
align-items: center;
width: 69rpx;
height: 69rpx;
border: 1rpx solid #CCCCCC;
border-radius: 7rpx;
}
.buy-num .number-btn>view text {
font-size: 46rpx;
}
.buy-btn {
width: 670rpx;
height: 78rpx;
text-align: center;
line-height: 78rpx;
background: linear-gradient(90deg, #F84A56, #FF9834);
border-radius: 40rpx;
font-size: 34rpx;
font-family: PingFangSC;
font-weight: 500;
color: #FFFFFF;
}
.btn-box {
width: 750rpx;
height: 151rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(6, 0, 1, 0.1);
display: flex;
align-items: center;
justify-content: center;
}
.sp {
width: 100%;
height: 30rpx;
font-size: 32rpx;
font-family: PingFangSC;
font-weight: 400;
color: #060001;
line-height: 30rpx;
border-top: solid 2rpx #ccc;
margin: 32rpx 0 60rpx;
padding-top: 30rpx;
}
.sp-container{
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
max-height: 400rpx;
overflow-y: auto;
padding-top: 20rpx;
padding-right: 20rpx;
overflow-x: hidden;
}
.sp-bottom-btn{
width: 750rpx;
height: 151rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 16rpx 0rpx rgba(6, 0, 1, 0.1);
display: flex;
align-items: center;
justify-content: center;
.btn{
width: 697rpx;
height: 73rpx;
background: #6A8A2D;
border-radius: 11rpx;
font-weight: bold;
font-size: 32rpx;
color: #FFFFFF;
text-align: center;
line-height: 73rpx;
}
}
}
button {
margin: 0;
padding: 0;
outline: none;
border-radius: 0;
background-color: transparent;
line-height: inherit;
}
button::after {
border: none;
}
.cartNum{
width: 28rpx;
height: 28rpx;
background: #DC2525;
border-radius: 50%;
border: 1px solid #DC2525;
font-weight: normal;
font-size: 23rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: -10rpx;
right: -6rpx;
}
</style>