Browse Source

提交

master
jiazhipeng 1 year ago
parent
commit
0a35bf04a7
  1. 29
      pages.json
  2. 31
      static/css/base.css
  3. 51
      static/js/CommonFunction.js
  4. 2
      static/js/request.js
  5. 273
      subPackages/hotelHomestay/hotelHomestay.vue
  6. 714
      subPackages/ticketBooking/detail.vue
  7. 349
      subPackages/ticketBooking/order.vue
  8. 191
      subPackages/ticketBooking/ticketBooking.vue
  9. 2
      uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue

29
pages.json

@ -30,7 +30,34 @@
"root" : "subPackages",
"pages": [
{
"path" : "ticketBooking/ticketBooking",
"style" :
{
"navigationBarTitleText" : "门票预订",
"navigationStyle":"custom"
}
},
{
"path" : "ticketBooking/detail",
"style" :
{
"navigationBarTitleText" : "景区详情"
}
},
{
"path" : "ticketBooking/order",
"style" :
{
"navigationBarTitleText" : "门票预订"
}
},
{
"path" : "hotelHomestay/hotelHomestay",
"style" :
{
"navigationBarTitleText" : "酒店民宿",
"navigationStyle":"custom"
}
}
]
}

31
static/css/base.css

@ -108,3 +108,34 @@ view {
width: 67rpx;
height: 67rpx;
}
.flex{
display: flex;
}
.flex-shrink-0{
flex-shrink: 0;
}
.flex-1{
flex: 1;
}
.flex-wrap{
flex-wrap: wrap;
}
.w-full{
width: 100%;
}
.w-1rpx{
width: 1rpx;
}
.h-1rpx{
height: 1rpx;
}
.relative{
position: relative;
}
.absolute{
position: absolute;
}
.flex-items-center{
align-items: center;
}

51
static/js/CommonFunction.js

@ -65,7 +65,7 @@ Vue.prototype.showImg = img => {
if (img.indexOf('https://') != -1 || img.indexOf('http://') != -1) {
return img;
} else {
return 'https://static.ticket.sz-trip.com' + img;
return 'https://tongli.sz-trip.com' + img;
}
}
@ -146,3 +146,52 @@ Vue.prototype.clickPhone = (phone) => {
phoneNumber:phone
})
}
//周几
Vue.prototype.ShowDateDay = day => {
let stateTxt = "";
switch (day) {
case 0:
stateTxt = '周日'
break;
case 1:
stateTxt = '周一'
break;
case 2:
stateTxt = '周二'
break;
case 3:
stateTxt = '周三'
break;
case 4:
stateTxt = '周四'
break;
case 5:
stateTxt = '周五'
break;
case 6:
stateTxt = '周六'
break;
}
return stateTxt
}
Date.prototype.Format = function(fmt)
{ //author: meizz
var o = {
"Y+" : this.getFullYear(), //月份
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours(), //小时
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt))
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
for(var k in o)
if(new RegExp("("+ k +")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
return fmt;
}

2
static/js/request.js

@ -16,7 +16,7 @@ Vue.prototype.Post = (params, apiurl) => {
data: params || {},
header: params.header || {
'content-type': 'application/json',
'token': params.token || '41ba9f3e-1add-4d5c-ae47-330e0864ad56'
'token': params.token || '2dd9b712-f118-41f6-b3a8-602e4fbb0ce3'
},
success: res => {
uni.hideLoading()

273
subPackages/hotelHomestay/hotelHomestay.vue

@ -0,0 +1,273 @@
<template>
<view class="bg">
<view class="topImg relative">
<img v-if="headImg" :src="showImg(headImg)" class="topImg" mode="aspectFill">
<view class="icon-back" :style="{top:systemInfo.textTop,left:'19rpx'}" @click="goBack()" >
<uni-icons type="left" size="24" color="#242424"></uni-icons>
</view>
</view>
<view class="goodBox">
<navigator :url="'/subPackages/ticketBooking/detail?id='+item.id" class="goodItem flex-column" v-for="(item,index) in list" :key="index">
<view class="left-image flex-shrink-0 relative">
<image class="left-image " :src="showImg(item.image)" mode="aspectFill"></image>
<view class="collect" @click="like(item)">
<image src="https://tongli.sz-trip.com/uploads/20240826/81b1f86ff8534db09472853b4c0b6748.png" v-if="item.is_collect"></image>
<image src="https://tongli.sz-trip.com/uploads/20240826/564af778708591f5de29174d3b14bbff.png" v-else></image>
</view>
</view>
<view class="contentBox flex-column flex-1 h-1rpx">
<view class="title text-overflow">{{item.title}}</view>
<view class="flex-between">
<view class="tag-container">
<view class="tag">盐都精选</view>
<view class="tag">盐都精选</view>
</view>
<view class="priceBox">
<view class="price">{{showPrice(item.price)}}</view>
</view>
</view>
<view class="flex-between">
<view class="distance">距您约602m</view>
<view class="order-btn">立即预定</view>
</view>
</view>
</navigator>
</view>
<view class="finished-text" v-if="finished">没有更多数据了</view>
</view>
</template>
<script>
export default{
data(){
return {
systemInfo: {
height:"0px",
textHeight:"0px",
textTop:"0px",
contentTop: '0px',
},
list: [],
finished: false,
headImg:null,
navList: [],
actNavIndex: 0,
type_id: 9,//id
}
},
onShow() {
this.headImg = 'https://tongli.sz-trip.com/uploads/20240826/8653c32761e01ee683505eddba1ae22b.png'
this.finished = false
this.list = [
{id:1, title:'景点名称景点名称景点名称 景点名称',
address:'景点名称景点名称景点名称 景点名称景点名称景点名称景点名称 景点名称',price:10000,
image:'https://tongli.sz-trip.com/uploads/20240826/a87488f6225789aa19dbb437671d388d.png',
}
]
// this.getHeadImg('piaowu')
},
onLoad(options) {
let that = this
uni.getSystemInfo({
success(res) {
console.log(res)
that.systemInfo.height =res.windowHeight+'px'
const menu=uni.getMenuButtonBoundingClientRect()
that.systemInfo.textHeight=menu.height+"px"
that.systemInfo.textTop=menu.top+"px"
that.systemInfo.contentTop = (menu.height + menu.top)+"px"
console.log(that.systemInfo)
}
})
},
methods: {
//
showPrice(price) {
return (price && price != 0) ? (price / 100).toFixed(0) : '0'
},
getHeadImg(type){
this.headImg = null
this.Post(
{
type,
},
'https://yjdtadmin.sz-trip.com/api/public_service/getKumgangHeadImgList'
).then(res => {
this.headImg = res.data[0].image
});
},
//
getList(){
this.Post({
tag_id: this.navList[this.actNavIndex].id,
offset: this.list.length,
limit: 10
},'https://yjdtadmin.sz-trip.com/api/scenic/getScenicByTagId').then(res => {
this.list = [...this.list, ...res.data];
if (res.data.length < 10) {
this.finished = true
}
})
},
//
like(item){
this.Post({
type: 2,
id: item.id
}, 'https://yjdtadmin.sz-trip.com/api/scenic/collect').then(res => {
if (res.code == 200) {
uni.showToast({title: res.msg})
if (item.is_collect == 1) {
item.is_collect = 0
} else {
item.is_collect = 1
}
}
})
},
},
onReachBottom() {
setTimeout(() => {
if (!this.finished) this.getList()
},1000)
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
font-family: PingFangSC;
}
.bg{
min-height: 100vh;
background: #FFFFFF;
}
.topImg{
width: 100%;
height: 440rpx;
.icon-back{
position: absolute;
display: flex;
align-items: center;
z-index: 50;
}
}
.goodBox{
width: 100%;
z-index: 2;
padding: 26rpx;
.goodItem{
width: 100%;
height: 525rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 9rpx 0rpx rgba(153,153,153,0.38);
margin-bottom: 26rpx;
border-radius: 13rpx;
.left-image{
width: 100%;
height: 321rpx;
border-radius: 13rpx 13rpx 0rpx 0rpx;
.collect{
position: absolute;
top: 22rpx;
right: 22rpx;
width: 51rpx;
height: 51rpx;
background: rgba(0,0,0,0.5);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
image{
width: 35rpx;
height: 35rpx;
}
}
}
.contentBox{
padding:19rpx 26rpx;
width: 100%;
justify-content: space-between;
.title{
width: 100%;
font-weight: bold;
font-size: 31rpx;
color: #000000;
}
.tag-container{
display: flex;
.tag{
background: rgba(205,233,209,0.3);
border-radius: 7rpx 5rpx 5rpx 7rpx;
border: 1px solid rgba(135,205,147,0.3);
padding: 4rpx 14rpx;
font-weight: 500;
font-size: 25rpx;
color: #4E7956;
text-align: center;
margin-right: 12rpx;
}
}
.priceBox{
.price{
font-family: PingFang SC;
font-weight: bold;
font-size: 33rpx;
color: #F02A2A;
text-align: right;
}
.price::before{
content: '¥';
color: #F02A2A;
font-size: 24rpx;
}
.price::after{
content: '起';
color: #999;
font-size: 24rpx;
font-weight: normal;
}
}
.distance{
font-family: PingFang SC;
font-weight: 500;
font-size: 27rpx;
color: #999999;
}
.order-btn{
width: 173rpx;
height: 55rpx;
background: #70B57F;
border-radius: 27rpx 27rpx 27rpx 27rpx;
font-weight: bold;
font-size: 29rpx;
color: #FFFFFF;
text-align: center;
line-height: 55rpx;
}
}
}
}
</style>

714
subPackages/ticketBooking/detail.vue

@ -0,0 +1,714 @@
<template>
<view class="bg">
<view class="swipe-box">
<swiper class="swiper" :autoplay="true" :interval="3000" :duration="1000" circular indicator-dots indicator-color="rgba(255,255,255,.5)" indicator-active-color="#fff">
<swiper-item v-for="(item, index) in info.list_images.split(',')" :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="common-container relative" style="top: -40rpx;">
<view class="flex-between">
<view class="title text-overflowRows">{{info.title}}</view>
<view>收藏</view>
</view>
<view>
营业时间 {{info.times_list_info.start}}-{{info.times_list_info.end}}
</view>
<view class="flex-between">
<view class="flex flex-1 flex-shrink-0 flex-items-center">
<img class="address-icon flex-shrink-0" src="https://tongli.sz-trip.com/uploads/20240826/c937c7f6509de9cc2961cb0984d3c526.png">
<view class="title text-overflowRows">
景区地址 {{info.address}}
</view>
</view>
<view>
<img class="address-icon" src="https://tongli.sz-trip.com/uploads/20240826/c937c7f6509de9cc2961cb0984d3c526.png">
</view>
</view>
</view>
<view class="common-container">
<view>门票预定</view>
<view class="scenic-list" v-for="(item, index) in sku" :key="index">
<view class="list-title text-overflow">{{ item.title }}</view>
<view class="scenic-item com-flex-tao" v-for="(itemSku, indexSku) in item.specifications" :key="indexSku">
<view class="w-1rpx flex-1">
<view class="title text-overflow">{{ itemSku.title }}</view>
<view class="tags-box">
<view class="tags text-overflow" v-if="itemSku.specifications_new_tag">
<view v-for="(tagSku,tagSkuIndex) in itemSku.specifications_new_tag.split(',').slice(0, 2)"
:key="tagSkuIndex">{{ tagSku }}</view>
</view>
</view>
<view class="bottom com-flex-tao ">
<view class="notice" @click="showSkuInfo(item, itemSku)">
预订须知 >
</view>
<view></view>
</view>
</view>
<view class="item-right com-flex-tao flex-shrink-0">
<view class="price">
<view>{{showNoPriceNew(itemSku.price)}}</view>
</view>
<view class="btn" @click="changeSku(itemSku, item)">
预订
</view>
</view>
</view>
</view>
</view>
<view class="common-container">
<view>景点简介</view>
<view class="" id="cpts" v-html="formateRichText(info.feature_content)"></view>
</view>
</view>
<!-- 预订须知的弹窗 -->
<uni-popup ref="popupRule" type="bottom" :safe-area="false">
<view class="popup-content-date" >
<view class="popup-content-title flex">
<view class="flex-1 w-1rpx text-overflow">
{{skuInfo.title}}
</view>
<img src="https://static.ticket.sz-trip.com/taizhou/images/cha.png" @click="closePopupRule"
style="width: 31rpx;height: 31rpx;" class="flex-shrink-0">
</view>
<view class="content">
<view class="detail-content" v-html="skuInfo.info"></view>
</view>
</view>
</uni-popup>
<!-- 预定弹窗 -->
<uni-popup ref="popup" type="bottom" :safe-area="false">
<view class="popup-content-date" >
<view class="popup-content-title flex">
<view class="flex-1 w-1rpx text-overflow">
{{skuInfo.title}}
</view>
<img src="https://static.ticket.sz-trip.com/taizhou/images/cha.png" @click="closePopup"
style="width: 31rpx;height: 31rpx;" class="flex-shrink-0">
</view>
<view>
<view class="relative">
<view class="sku-title">使用日期</view>
<view class="date-content">
<view :class="['item', item.store>0?'':'disabled',seldDateIndex===index?'active':'']"
v-for="(item,index) in allSeldDate" :key="index"
@click="clickTab(item,index)">
<view>{{ShowDateDay(new Date(item.date).getDay())}}</view>
<view>{{item.date.slice(-5)}}</view>
<view class="price" v-if="item.store > 0">{{showNoPriceNew(item.money)}}</view>
<view v-else>不可定</view>
</view>
</view>
<view class="dateMore" @click="openCalendar">
<view>更多日期</view>
<view>></view>
</view>
</view>
<view v-if="timesArr.length > 0 && skuInfo.is_time_stock">
<view class="sku-title">选择时段</view>
<view class="time-box">
<view v-for="(item,index) in timesArr" :key="index"
:class="['time-item',{'time-disable': item.store < 1, 'time-active': item.store > 0 && index == seldTimeIndex}]"
@click="changeTime(item,index)">
{{ item.start_time }}-{{ item.end_time }}
{{item.store < 10 ? (item.store === -1 ? '不可定' : item.store === 0 ? '无票' : '(余票' + item.store + ')') : '有票'}}
</view>
</view>
</view>
</view>
<view class="sku-bottom">
<view class="flex" style="align-items: baseline;">
合计<view class="bottom-price">{{allSeldDate[seldDateIndex].money / 100 || 0}}</view>
</view>
<view class="bottom-btn" @click="addBuyCard">
下一步
</view>
</view>
</view>
</uni-popup>
<uni-calendar ref="calendar" class="uni-calendar--hook" :clear-date="true"
:date="allSeldDate[seldDateIndex].date" :insert="false" :startDate="calendarParam.startDate"
:endDate="calendarParam.endDate" @confirm="confirmCalendar" :selected="calendarParam.selected"/>
</view>
</template>
<script>
export default {
data() {
return {
headImg: null,
id: null,
info: {list_images:'', times_list_info: {start:'',end:''}},
sku: [],
skuInfo: {}, //
selectGoods: {}, //
minSeldDate: new Date().Format('yyyy-MM-dd'),
maxSeldDate: new Date((new Date()).getFullYear(), (new Date()).getMonth() + 3, 0).Format('yyyy-MM-dd'),
allSeldDate: [],
seldDateIndex: 0,
timesArr: [],
seldTimeIndex: -1,
calendarParam: {
stratDate:'',endDate: '', selected: []
},
}
},
onShow(options) {
this.headImg = 'https://tongli.sz-trip.com/uploads/20240826/8653c32761e01ee683505eddba1ae22b.png'
},
onLoad(options) {
this.id = options.id;
this.getInfo();
this.getGoodsList()
},
methods: {
//
getInfo() {
this.Post({id: this.id},'/api/scenic/getScenicById').then(res => {
if (res.data.flag == 0) {
uni.showToast({title: '商品不存在或已下架',icon: 'none'})
setTimeout(() => {this.goBack()}, 2000)
}
let info = res.data;
try {
info.times_list_info = JSON.parse(info.times_list)[0]
} catch(e) {
console.log(e)
info.times_list_info = {start:'',end:''}
}
this.info = info
console.log(info)
// this.isCollect = this.info.is_collect;
// this.getComment()
});
},
// id
getGoodsList(){
this.Post({
scenic_id: this.id
},'/api/scenic/getGoodsByScenicId').then(res => {
this.sku = res.data || []
// res.data.forEach(item => {
// if(item.specifications){
// item.specifications.forEach(items => {
// this.sku.push(items)
// })
// }
// })
//
// this.sku = this.maopao(this.sku,'sort');
})
},
showSkuInfo (itemSku,goods) {
this.skuInfo = itemSku
this.selectGoods = goods
this.openPopRule()
},
//
changeSku(itemSku,goods) {
this.skuInfo = itemSku
this.selectGoods = goods
//
// if(this.skuInfo.ticket_type == 2) {
// this.addBuyCard()
// }else {
// this.getDays(itemSku,goods)
// }
this.getPriceCal(itemSku,goods)
},
openCalendar () {
this.calendarParam = {
startDate: (this.allSeldDate.find(v=>v.store>0) || {}).date,
endDate: (this.allSeldDate[this.allSeldDate.findLastIndex(v=>v.store>0)]||{}).date,
selected: this.allSeldDate.filter(v=>v.store>0).map(v=>{
return {
date: v.date,
info: '¥'+this.showNoPriceNew(v.money),
notNeedDot:true,
}
})
}
this.$refs.calendar.open();
},
//
getPriceCal(itemSku,goods) {
this.Post({
specifications_id: itemSku.id,
goods_id: goods.id,
limit: 60
}, '/api/goods/getPriceCalendarListBySpecifications').then(res => {
this.allSeldDate = res.data || []
this.seldDateIndex = this.allSeldDate.findIndex(item => item.store != 0)
this.getTimeStock(this.allSeldDate[this.seldDateIndex].date)
this.openPop()
})
},
//
getTimeStock(date) {
this.Post({
specifications_id: this.skuInfo.id,
date: date
}, '/api/goods/getTimeStock').then(res => {
if (res.data.length > 0) {
this.timesArr = res.data || []
this.seldTimeIndex = this.stockList.findIndex(item => item.store != 0)
}
})
},
//
clickTab(item, index) {
this.seldDateIndex = index
this.getTimeStock(item.date)
},
//
changeTime(item, index) {
if(item.store > 0) {
this.seldTimeIndex = index
}
},
confirmCalendar (val) {
let index = this.allSeldDate.find(v=>v.date == val.fulldate)
if (index) {
this.clickTab({date:val.fulldate},index)
}
},
addBuyCard() {
let that = this;
//
// if(that.skuInfo.is_time_stock && that.seldTimeIndex < 0) {
// uni.showToast({title:''})
// return;
// }
this.selectGoods.specifications.forEach(v=>{v.buyNum = 0;v.selPeople = []})
let orderSkuIndex = this.selectGoods.specifications.findIndex(v=>v.id == that.skuInfo.id)
let item = this.selectGoods.specifications.splice(orderSkuIndex, 1)[0]; //
item.buyNum = 1
item.selPeople = [{}]
this.selectGoods.specifications.unshift(item);
let param = {
sInfo: this.skuInfo,
pInfo: this.selectGoods,
minSeldDate: this.minSeldDate,
maxSeldDate: this.maxSeldDate,
calendarParam: this.calendarParam,
allSeldDate: this.allSeldDate,
seldDateIndex: this.seldDateIndex,
timesArr: this.timesArr,
seldTimeIndex: this.seldTimeIndex,
}
// that.gotoBuy(pInfo, sInfo);
uni.navigateTo({
url:'/subPackages/ticketBooking/order',
success() {
uni.$emit("updateDataByConnect", {msgType:'updateTicketBookingOrder',data:param})
}
})
},
gotoBuy(pInfo, sInfo) {
console.log(pInfo, sInfo);
let that = this;
if (
(pInfo.flag != 1 || sInfo.flag !== "on" || sInfo.stock <= 0) &&
sInfo.is_third_stock == 0
)
return;
// that.buryPoint("scene_order");
// that.checkIsCanBuy(that.detail.title,
// function() {
let params = {
pInfo: pInfo,
sInfo: sInfo,
minSeldDate: this.minSeldDate,
maxSeldDate: this.maxSeldDate,
calendarParam: this.calendarParam,
allSeldDate: this.allSeldDate,
seldDateIndex: this.seldDateIndex,
timesArr: this.timesArr,
seldTimeIndex: this.seldTimeIndex,
};
if (that.detail.allowance) {
sInfo.allowance_data = that.detail.allowance;
let spread_price = Number(
sInfo.allowance_data.discount_limit_price -
sInfo.allowance_data.user_used_price
);
if (spread_price > 0) {
if (
spread_price <
(sInfo.allowance_data.discount_rate / 100) *
sInfo.price
)
sInfo.allowance_price = spread_price;
else
sInfo.allowance_price =
(sInfo.allowance_data.discount_rate / 100) *
sInfo.price;
}
}
// },
// );
},
closePopup() {
this.$refs.popup.close()
},
openPop(){
this.$refs.popup.open()
},
closePopupRule() {
this.$refs.popupRule.close()
},
openPopRule(){
this.$refs.popupRule.open()
},
//
showNoPriceNew(price) {
if (price && price > 0) {
return (price / 100)
} else {
return '0'
}
},
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
}
.bg{
min-height: 100vh;
background: #F8F8F8;
}
.swipe-box {
height: 484rpx;
position: relative;
.swiper-item-num {
width: 90rpx;
height: 40rpx;
background: rgba(0, 0, 0, 0.5);
border-radius: 20rpx;
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #ffffff;
text-align: center;
line-height: 40rpx;
position: absolute;
right: 30rpx;
bottom: 50rpx;
}
}
.swiper {
height: 484rpx;
position: relative;
.swiper-item {
width: 100%;
height: 484rpx;
.item-img {
width: 750rpx;
height: 484rpx;
}
}
}
.detail-container{
width: 100%;
z-index: 2;
padding: 26rpx;
}
.common-container{
background: white;
border-radius: 20rpx;
margin-bottom: 30rpx;
}
.address-icon{
width: 21rpx;
height: 25rpx;
margin-right: 9rpx;
}
.scenic-list {
/* background: #ffffff; */
margin-bottom: 36rpx;
}
.scenic-list .list-title {
font-size: 46rpx;
color: #000000;
font-weight: bold;
padding: 40rpx 28rpx;
}
.scenic-list .scenic-item {
/* border-top: 1px solid #d9d9d9; */
padding: 40rpx;
text-align: left;
background: rgba(11, 137, 142, .06);
border-radius: 20rpx;
margin-bottom: 27rpx;
display: flex;
}
.scenic-list .scenic-item .title {
font-size: 44rpx;
font-weight: bold;
color: #333333;
width: 100%;
}
.scenic-list .scenic-item .tags-box {
margin: 29rpx 0;
overflow: hidden;
}
.scenic-list .scenic-item .tags-box .tags {
flex: 1;
}
.scenic-list .scenic-item .tags-box .tags view {
/* padding: 0 0.2rem; */
font-weight: 400;
font-size: 34rpx;
color: #666666;
line-height: 24rpx;
/* line-height: 0.57rem; */
/* border: 1px solid #0b898e;
border-radius: 0.23rem;
margin-right: 0.1rem; */
}
.scenic-list .scenic-item .tags-box .tags view::after {
content: '丨'
}
.scenic-list .scenic-item .tags-box .tags view:last-of-type:after {
display: none;
}
.scenic-list .scenic-item .item-right {
width: 140rpx;
}
.scenic-list .scenic-item .item-right .price {
font-size: 30rpx;
font-weight: 400;
color: #8d8d8d;
}
.scenic-list .scenic-item .item-right .price view {
font-size: 50rpx;
font-weight: 500;
color: #d62828;
}
.scenic-list .scenic-item .item-right .price view:before {
display: inline-block;
content: "¥";
font-size: 36rpx;
font-weight: 400;
color: #d62828;
}
.scenic-list .scenic-item .item-right .btn {
width: 140rpx;
height: 120rpx;
background: #0B898E;
border-radius: 20rpx;
text-align: center;
line-height: 120rpx;
font-weight: 500;
font-size: 46rpx;
color: #FFFFFF;
margin-left: 25rpx;
}
.scenic-list .scenic-item .bottom .notice {
font-weight: 400;
font-size: 34rpx;
color: #0B898E;
}
.scenic-list .scenic-item .bottom .buy {
font-size:44rpx;
font-weight: 500;
text-align: center;
color: #ffffff;
width: 264rpx;
height: 98rpx;
line-height: 98rpx;
background: #d62828;
border-radius: 44rpx;
}
.scenic-list .scenic-item .bottom .buy.disabled {
background-color: #d7d7d7;
color: #ffffff;
}
.popup-content-date {
background-color: white;
padding: 0rpx 39rpx 51rpx 39rpx;
height: auto;
border-radius: 20rpx 20rpx 0 0 ;
.popup-content-title{
padding: 20rpx 0;
}
.dateMore{
width: 120rpx;
height: 180rpx;
background: #fff;
font-weight: 400;
font-size: 32rpx;
padding-left: 15rpx;
color: #0b898e;
display: flex;
justify-content: center;
align-items: center;
position: absolute;
right: 0;
bottom: 0;
}
.date-content{
width: 100%;
display: flex;
overflow-y: auto;
position: relative;
padding-right: 140rpx;
.item{
min-width: 160rpx;
height: 180rpx;
background: #f5f5f5;
border-radius: 10rpx;
margin-right: 20rpx;
font-weight: 500;
font-size: 32rpx;
color: #000;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
}
.item.active{
background: #0b898e;
color: #fff;
}
.item.disabled{
color: #999;
}
}
.date-content::-webkit-scrollbar{
display: none;
}
}
.time-box {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.time-item {
width: 48%;
background: #F5F5F5;
border-radius: 10rpx;
text-align: center;
font-weight: 400;
font-size: 34rpx;
color: #000000;
margin-bottom: 20rpx;
padding: 5rpx;
}
.time-active {
background: #0B898E;
color: #fff;
}
.time-disable {
color: #999999;
}
}
.sku-bottom {
width: 100%;
height: 120rpx;
background: #FFFFFF;
padding: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
font-weight: 400;
font-size: 36rpx;
color: #393B3E;
line-height: 80rpx;
.bottom-price {
font-weight: 500;
font-size: 50rpx;
color: #D62828;
}
.bottom-price::before {
font-size: 27rpx;
content: '¥';
}
.bottom-btn {
width: 360rpx;
background: #D62828;
border-radius: 40rpx;
text-align: center;
font-weight: bold;
font-size: 42rpx;
color: #FFFFFF;
}
}
</style>

349
subPackages/ticketBooking/order.vue

@ -0,0 +1,349 @@
<template>
<view class="bg">
<view class="top-box" >
<view class="top-left">
<view class="text-overflow">{{ pInfo.title }}</view>
<view style="margin-top: 20rpx;">
<view class="left-subtitle" v-if="allSeldDate.length > 0">{{allSeldDate[seldDateIndex].date}} {{ShowDateDay(new Date(allSeldDate[seldDateIndex].date).getDay())}}</view>
<view class="left-subtitle" v-if="timesArr.length > 0">{{ timesArr[seldTimeIndex].start_time }}-{{ timesArr[seldTimeIndex].end_time }} 入园</view>
</view>
</view>
<view @click="showSkuPopup = true" v-if="this.sInfo.ticket_type != 2">修改 ></view>
</view>
<view class="num-box" v-for="(skuItem,skuIndex) in pInfo.specifications" :key="skuIndex">
<view style="display: flex;justify-content: space-between;align-items: center;">
<view class="left-title text-overflow">{{skuItem.title}}</view>
<view class="left-price">{{skuItem.price / 100}}</view>
<view class="num-right">
<view class="btn-num" v-if="!skuItem.originate_order_id && !skuItem.gp_id" :class="{no:skuItem.originate_order_id}" @click="delNumber(skuItem)" :style="{color: skuItem.buyNum > 1 ? '#fff': '', backgroundColor: skuItem.buyNum > 1 ? '#0B898E' : ''}">-</view>
<view class="num-span">{{ skuItem.buyNum }}</view>
<view class="btn-num" v-if="!skuItem.originate_order_id && !skuItem.gp_id" :class="{no:skuItem.originate_order_id}" @click="addNumber(skuItem)" style="color: #fff;background: #0B898E;">+</view>
</view>
</view>
<view class="num-subtitle text-overflow" v-if="skuItem.display_tags" @click="showNoticePopup = true">
<view class="num-span" v-for="(tagSku,tagSkuIndex) in skuItem.display_tags.split(',').slice(0, 2)" :key="tagSkuIndex">{{ tagSku }} |</view>
<view class="num-span">预订须知 ></view>
</view>
</view>
<view class="people-box" >
<view class="people-box-sku" v-for="(skuItem,skuIndex) in pInfo.specifications.filter(v=>v.buyNum>=1)" :key="skuIndex">
<view>{{skuItem.title}}</view>
<view v-for="(person,personIndex) in skuItem.selPeople" :key="personIndex">
<view v-if="person.id">123</view>
<view v-else>点击添加出行人信息</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
pInfo: {specifications: []}, //
sInfo: {sku_model: {}}, //
minSeldDate: new Date().Format('yyyy-MM-dd'),
maxSeldDate: new Date((new Date()).getFullYear(), (new Date()).getMonth() + 3, 0).Format('yyyy-MM-dd'),
calendarParam: {
stratDate:'',endDate: '', selected: []
},
allSeldDate: [],
seldDateIndex: 0,
timesArr: [],
seldTimeIndex: 0,
buyNum: 0
}
},
onLoad(options) {
// this.getList();
uni.$on("updateDataByConnect",this.getDataByConnect)
},
onShow() {
this.handlePageData()
},
onUnload () {
uni.$off("updateDataByConnect",this.getDataByConnect)
},
methods: {
getDataByConnect(data) {
if (data.msgType == "updateTicketBookingOrder") {
uni.setStorageSync('tempData', JSON.stringify(data.data));
// this.pInfo = data.data.pInfo
// this.sInfo = data.data.sInfo
// this.minSeldDate=data.data.minSeldDate
// this.maxSeldDate = data.data.maxSeldDate
// this.calendarParam = data.data.calendarParam
// this.allSeldDate = data.data.allSeldDate
// this.seldDateIndex = data.data.seldDateIndex
// this.timesArr = data.data.timesArr
// this.seldTimeIndex = data.data.seldTimeIndex
}
},
handlePageData () {
let data = uni.getStorageSync('tempData');
try{
data = JSON.parse(data)
this.pInfo = data.pInfo
this.sInfo = data.sInfo
this.minSeldDate=data.minSeldDate
this.maxSeldDate = data.maxSeldDate
this.calendarParam = data.calendarParam
this.allSeldDate = data.allSeldDate
this.seldDateIndex = data.seldDateIndex
this.timesArr = data.timesArr
this.seldTimeIndex = data.seldTimeIndex
} catch(e){
console.log(e)
}
},
//
delNumber(skuItem) {
if (skuItem.buyNum <= 0) {
return
}
// if(this.buyNum == this.seldPeople.length) {
// this.allSeldPeople.forEach(item => {
// if(item.id == this.seldPeople[this.seldPeople.length -1].id) {
// item.is_seld = false
// item.selected = false
// }
// })
// this.seldPeople.pop()
// }
skuItem.buyNum -= 1
skuItem.selPeople.pop()
// this.removeSeldCoupon()
},
//
addNumber(skuItem) {
skuItem.buyNum += 1
// if(this.max_num && this.buyNum > this.max_num){
// this.buyNum = this.max_num
// this.$toast(""+this.max_num+"")
// }
if (Array.isArray(skuItem.selPeople)) {
skuItem.selPeople.push({})
} else {
skuItem.selPeople = [{}]
}
},
//
changeTime(item, index) {
if(item.stock_number > 0) {
this.seldTimeIndex = index
}
},
//
clickTab(item, index) {
this.seldDateIndex = index
this.getTimes()
},
confirmCalendar (val) {
let index = this.allSeldDate.find(v=>v.date == val.fulldate)
if (index) {
this.clickTab({},index)
}
},
//
getDays() {
let that = this
that.Post({
url: '',
start_date: that.minSeldDate,
end_date: that.maxSeldDate,
sku_id: that.skuInfo.id
},'https://api.cloud.sz-trip.com/api/product/product_date_price').then(function (result) {
let res = result.data
if (res) {
that.allSeldDate = res
//
for (let i = 0; i < that.allSeldDate.length; i++) {
if (that.allSeldDate[i].stock > 0) {
that.seldDateIndex = i
break;
}
// that.allSeldDate[i].price = that.sInfo.price
}
that.openPop()
that.getTimes()
}
})
},
getTimes() {
let that = this
//
if (!that.skuInfo.sku_model.is_time_stock) {
return
}
if (that.seldDateIndex < 0) {
return;
}
that.seldTimeIndex = -1
that.Post({
url: '',
date: that.allSeldDate[that.seldDateIndex].date,
sku_id: that.allSeldDate[that.seldDateIndex].sku_id ? that.allSeldDate[that.seldDateIndex].sku_id : that.skuInfo.id
},'https://api.cloud.sz-trip.com/api/product/product_timestock_price').then(function (result) {
let res = result.data
if (res) {
that.timesArr = res
for (let i = 0; i < that.timesArr.length; i++) {
if (that.timesArr[i].stock_number > 0) {
that.seldTimeIndex = i
break;
}
}
}
})
},
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
}
.bg{
min-height: 100vh;
padding: 20rpx;
background-color: rgb(247, 247, 247);
}
.top-box {
width: 100%;
background: #FFFFFF;
border-radius: 18rpx;
padding: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: 500;
font-size: 36rpx;
color: #0B898E;
.top-left {
display: flex;
flex-direction: column;
justify-content: space-between;
font-weight: bold;
font-size: 45rpx;
color: #000000;
flex: 1;
width: 1rpx;
.left-subtitle {
font-weight: 400;
font-size: 36rpx;
color: #666666;
}
}
}
.num-box {
width: 100%;
// height: 3.22rem;
background: #FFFFFF;
border-radius: 18rpx;
display: flex;
justify-content: space-between;
flex-direction: column;
margin: 20rpx 0;
padding: 20rpx;
.num-left {
width: 100%;
// padding: .5rem 0 .6rem .32rem;
box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: space-between;
font-weight: 400;
font-size: 27rpx;
color: #666666;
.left-title {
font-weight: bold;
font-size: 45rpx;
color: #000000;
width: 450rpx;
}
.left-price {
font-weight: 500;
font-size: 45rpx;
color: #D62828;
}
.left-price::before {
font-size: 27rpx;
content: '¥';
}
}
.num-subtitle {
font-weight: 400;
font-size: 27rpx;
color: #0B898E;
width: 100%;
display: flex;
}
.num-right {
font-weight: 500;
font-size: 36rpx;
color: #000000;
display: flex;
text-align: center;
.num-span {
width: 90rpx;
line-height: 63rpx;
}
.btn-num {
width: 63rpx;
height: 63rpx;
line-height: 63rpx;
background: rgba(135,205,147,0);
border-radius: 50%;
border: 1px solid #999999;
font-weight: 500;
font-size: 45rpx;
color: #999999;
}
}
}
.people-box{
width: 100%;
// height: 3.22rem;
.people-box-sku{
width: 100%;
background: #FFFFFF;
border-radius: 18rpx;
// display: flex;
// justify-content: space-between;
margin: 20rpx 0;
padding: 20rpx;
}
}
</style>

191
subPackages/ticketBooking/ticketBooking.vue

@ -0,0 +1,191 @@
<template>
<view class="bg">
<view class="topImg relative">
<img v-if="headImg" :src="showImg(headImg)" class="topImg" mode="aspectFill">
<view class="icon-back" :style="{top:systemInfo.textTop,left:'19rpx'}" @click="goBack()" >
<uni-icons type="left" size="24" color="#242424"></uni-icons>
</view>
</view>
<view class="goodBox">
<navigator :url="'/subPackages/ticketBooking/detail?id='+item.id" class="goodItem" v-for="(item,index) in list" :key="index">
<image class="left-image" :src="showImg(item.image||'')" mode="aspectFill"></image>
<view class="contentBox flex-column flex-1 w-1rpx">
<view class="title text-overflowRows">{{item.title}}</view>
<view class="subtitle flex">
<img class="address-icon flex-shrink-0" src="https://tongli.sz-trip.com/uploads/20240826/c937c7f6509de9cc2961cb0984d3c526.png">
<view class="text-overflow">{{item.address}}</view>
</view>
<view class="priceBox">
<view class="price">{{showPrice(item.price)}}</view>
</view>
</view>
</navigator>
</view>
<view class="finished-text" v-if="finished">没有更多数据了</view>
</view>
</template>
<script>
export default{
data(){
return {
systemInfo: {
height:"0px",
textHeight:"0px",
textTop:"0px",
contentTop: '0px',
},
list: [],
finished: false,
headImg:null,
type_id: 10,//id
}
},
onShow() {
this.headImg = 'https://tongli.sz-trip.com/uploads/20240826/8653c32761e01ee683505eddba1ae22b.png'
this.finished = false
this.getList()
// this.getHeadImg('piaowu')
},
onLoad(options) {
let that = this
uni.getSystemInfo({
success(res) {
console.log(res)
that.systemInfo.height =res.windowHeight+'px'
const menu=uni.getMenuButtonBoundingClientRect()
that.systemInfo.textHeight=menu.height+"px"
that.systemInfo.textTop=menu.top+"px"
that.systemInfo.contentTop = (menu.height + menu.top)+"px"
console.log(that.systemInfo)
}
})
},
methods: {
//
showPrice(price) {
return (price && price != 0) ? (price / 100).toFixed(0) : '0'
},
getHeadImg(type){
this.headImg = null
this.Post(
{
type,
},
'https://yjdtadmin.sz-trip.com/api/public_service/getKumgangHeadImgList'
).then(res => {
this.headImg = res.data[0].image
});
},
//
getList(){
this.Post({scenic_type_id: this.type_id,offset: this.list.length,limit: 10},
'api/Scenic/getScenicByType').then(res => {
this.list = [...this.list, ...res.data];
if (res.data.length < 10) {
this.finished = true
}
})
},
},
onReachBottom() {
setTimeout(() => {
if (!this.finished) this.getList()
},1000)
}
}
</script>
<style scoped lang="scss">
*{
box-sizing: border-box;
font-family: PingFangSC;
}
.bg{
min-height: 100vh;
background: #FFFFFF;
}
.topImg{
width: 100%;
height: 440rpx;
.icon-back{
position: absolute;
display: flex;
align-items: center;
z-index: 50;
}
}
.goodBox{
width: 100%;
z-index: 2;
padding: 26rpx;
.goodItem{
width: 100%;
height: 226rpx;
background: #FFFFFF;
box-shadow: 0rpx 0rpx 9rpx 0rpx rgba(153,153,153,0.38);
margin-bottom: 26rpx;
display: flex;
border-radius: 13rpx;
.left-image{
width: 280rpx;
height: 226rpx;
border-radius: 13rpx;
}
.contentBox{
padding: 20rpx;
justify-content: space-between;
.title{
width: 100%;
font-weight: bold;
font-size: 31rpx;
color: #000000;
}
.subtitle{
font-weight: 500;
font-size: 27rpx;
color: #666666;
align-items: center;
.address-icon{
width: 21rpx;
height: 25rpx;
margin-right: 9rpx;
}
}
.priceBox{
.price{
font-family: PingFang SC;
font-weight: bold;
font-size: 33rpx;
color: #F02A2A;
text-align: right;
}
.price::before{
content: '¥';
color: #F02A2A;
font-size: 24rpx;
}
.price::after{
content: '起';
color: #999;
font-size: 24rpx;
font-weight: normal;
}
}
}
}
}
</style>

2
uni_modules/uni-calendar/components/uni-calendar/uni-calendar-item.vue

@ -9,7 +9,7 @@
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text v-if="selected&&weeks.extraInfo&&!weeks.extraInfo.notNeedDot" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,

Loading…
Cancel
Save