first commit

This commit is contained in:
lxj
2025-06-26 12:38:35 +08:00
commit c536475e19
1236 changed files with 186274 additions and 0 deletions

711
pages/tabbar/guide.vue Normal file
View File

@@ -0,0 +1,711 @@
<template>
<view class="waper">
<u-navbar left-icon-size="0" :placeholder="true" bgColor="#fff">
<view slot='center' class="navbar_title">导览</view>
</u-navbar>
<view class="tabs-box" v-if="!showSwiper">
<scroll-view scroll-x="true">
<view class="tab" :class="{active: activeType === item.id}" v-for="(item, index) in typeList" :key="index" @click="getMarkers(item.id)">{{item.potypeName}}</view>
</scroll-view>
</view>
<map id="map" :style="'height: calc(100% - ' + windowBottom + 'px)'"
:enable-building="enableBuilding" :show-location="showLocation" :latitude="latitude"
:longitude="longitude" :markers="markers" :scale="scale" :max-scale="14.5" @markertap="markertap" @labeltap="labeltap" :polyline="polyline"></map>
<view class="btn-box" :style="'bottom: ' + windowBottom2 + 'px'">
<view class="location" @click="changeLocation">
<image class="icon" src="https://common/location.png" mode=""></image>
</view>
<view class="location" @click="closeLine" v-if="showLine || showSwiper">
<image class="icon" src="https://common/out.png" mode=""></image>
</view>
</view>
<view class="line_btn" v-if="showBtn" @click="getGuideList" :style="'bottom: ' + windowBottom3 + 'px'">
<image class="img" src="https://common/lineBtn.png" mode=""></image>
<view>游览</view>
<view>线路</view>
</view>
<view class="line_swiper" v-if="showLine" :style="'bottom: ' + windowBottom1 + 'px'">
<swiper :interval="5000" :duration="1000" previous-margin="32rpx" next-margin="32rpx" :current="current1" @change="swiperChange1">
<swiper-item v-for="(i, index) in lineList" :key="index">
<view class="line_box">
<view class="line_waper">
<view class="title">{{i.name}}</view>
<view class="msg">预计游览{{i.duration}}小时</view>
<view class="tag">
<view>难度{{i.difficultyName}}</view>
</view>
<view class="btn" @click="startLine(i)">
<view>开始</view>
<view>游览</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
<!-- -->
<view class="detail_swiper" v-if="showSwiper" :style="'bottom: ' + windowBottom1 + 'px'">
<swiper :interval="5000" :duration="1000" previous-margin="32rpx" next-margin="32rpx" :current="current2" @change="swiperChange2">
<swiper-item v-for="(i, index) in lineInfo" :key="index" :class="[current2 == index ? 'activeClass' : 'defaultClass']" @click="goSpot(i)">
<view class="detail_box">
<view class="detail_waper">
<view class="num">{{index+1}}</view>
<view class="con-box">
<view class="title">
<view class="label">{{i.pointName}}</view>
<!-- <view class="voice">
<image class="icon" src="https://common/voice.png" mode=""></image>
<view class="time">2:30</view>
</view> -->
</view>
<view class="text">{{i.blurb}}</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
<view v-if="popup1" class="popup-box">
<view class="popup-content1">
<view class="head-box" v-if="data1.ticketId">
<view class="name">
<view class="h4">{{data1.ticketName}}</view>
<view class="price">
¥{{data1.salesRice}}
<text></text>
</view>
</view>
<view class="go" @click="buyTicket(data1.ticketId)">
去购买
<u-icon name="arrow-right" color="#666666" size="28rpx"></u-icon>
</view>
</view>
<view class="con">
<image class="con-img" :src="$utils.setImgUrl(data1.image)" mode=""></image>
<view class="con-right">
<view class="title">{{data1.pointName}}</view>
<view class="describe">{{data1.blurb}}</view>
</view>
</view>
<view class="btn">
<image class="btn-img" src="https://common/go.png" mode=""></image>
<view class="label" @click="goLocation(data1)">去这里</view>
</view>
</view>
</view>
<tabbar name="guide"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/index.vue'
import _config from '../../common/http/config.js'
export default {
components: {
tabbar
},
data() {
return {
windowBottom: 0,
windowBottom1: 0,
windowBottom2: 0,
windowBottom3: 0,
popup1: false,
mapCtx: null,
showLine: false,
showSwiper: false,
showBtn: true,
current1: 0,
current2: 0,
// 路线集合
lineList: [],
// 路线点集合
lineInfo: null,
id: 0,
bgColor: 'transparent',
scale: null,
enableBuilding: false,
showLocation: true,
latitude: null,
longitude: null,
polyline: [],
markers: [],
// tab类型集合
typeList: [],
showPointList: [],
// 所有数据
allData: {},
// 选中tab类型id、数据点类型id
activeType: '',
markerId: '',
// 数据点id
spotId: '',
// 当前tab类型点图标
pathIcon: '',
// 弹窗数据
data1: {},
// 是否点击查看所有路线
isAllLine: false,
};
},
onLoad() {
this.windowBottom = this.$safeAreaBottom + 50 + this.$paddingTop + uni.upx2px(72);
this.windowBottom1 = this.$safeAreaBottom + uni.upx2px(134);
this.windowBottom2 = this.$safeAreaBottom + uni.upx2px(340);
this.windowBottom3 = this.$safeAreaBottom + uni.upx2px(140);
this.mapCtx = uni.createMapContext('map', this);
this.pointMapList()
},
onReady() {},
onShow() {},
methods: {
async pointMapList() {
let info = await this.$http.pointMapList({mapId: 1})
if (info.code === 200) {
this.allData = info.data
this.typeList = this.allData.pointTypeList
this.activeType = this.typeList[0].id
this.latitude = this.allData.centerLatitude
this.longitude = this.allData.centerLongitude
this.scale = this.allData.zoomLevel
this.addImageLayer(this.allData);
this.getMarkers(this.activeType)
} else {
uni.$u.toast(info.msg);
}
},
addImageLayer(data) {
const imageLayerOptions = {
id: data.id,
src: _config.url + data.image,
zIndex: 1,
bounds: {
southwest: {
longitude: data.leftLongitude,
latitude: data.leftLatitude
},
northeast: {
longitude: data.rightLongitude,
latitude: data.rightLatitude
}
}
};
this.mapCtx.addGroundOverlay(imageLayerOptions);
},
getMarkers(id) {
this.activeType = id
this.popup1 = false;
this.showLine = false;
this.showSwiper = false;
this.showBtn = true;
this.getMarkersList()
},
getMarkersList() {
this.polyline = [];
this.markers = []
let index = null
this.typeList.forEach((n, i) => {
if (n.id == this.activeType) {
index = i
this.showPointList = this.typeList[index]
this.pathIcon = this.showPointList.image
}
})
if (!this.showPointList.pointDataList) return;
this.showPointList.pointDataList.forEach((e, i) => {
this.markers.push({
id: e.id,
latitude: e.latitude,
longitude: e.longitude,
width: '90rpx',
height: '90rpx',
iconPath: _config.url + this.pathIcon,
label: {
padding: '10rpx',
content: e.pointName,
color: '#fff',
fontSize: '24rpx',
anchorX: '0',
anchorY: '0',
borderRadius: '4rpx',
bgColor: 'rgba(0,0,0,0.5)',
textAlign: 'center'
}
})
})
},
labeltap (e) {
this.markerId = e.markerId
this.showDetail(this.markerId)
},
markertap(e) {
this.markerId = e.markerId
this.showDetail(this.markerId)
},
showDetail(id) {
if (!this.showLine && !this.showSwiper) {
this.showBtn = false;
this.isAllLine = false;
this.current1 = 0;
this.getGuide(id)
let f = this.showPointList.pointDataList.find(m => m.id == id)
if (f) {
this.data1 = f
this.popup1 = true
}
}
},
buyTicket(id) {
uni.navigateTo({ url: '/pages/scenic/ticket?id=' + id })
},
goLocation(data) {
let latitude = data.latitude;
let longitude = data.longitude;
uni.openLocation({
latitude: Number(latitude),
longitude: Number(longitude),
name: data.pointName,
address: '',
})
},
getGuide(id) {
this.spotId = id;
this.guideList()
},
async guideList() {
let info = await this.$http.guideLineList({spotId: this.spotId})
if (info.code === 200) {
this.showLine = true
this.lineList = info.data
} else {
uni.$u.toast(info.msg);
}
},
async startLine (i) {
let info = await this.$http.guideDetail({id: i.id})
if (info.code === 200) {
this.windowBottom = this.$safeAreaBottom + 50 + this.$paddingTop;
this.showLine = false
this.showSwiper = true
this.popup1 = false
this.current2 = 0
this.lineInfo = info.data.spotGuideList;
if (!this.lineInfo) {
return false;
}
this.polyline = [];
this.getLine(info.data.coordinate);
let markers = [];
let numArr = ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩']
this.lineInfo.forEach((e, i) => {
markers.push({
id: e.id,
latitude: e.latitude,
longitude: e.longitude,
width: '90rpx',
height: '90rpx',
iconPath: _config.url + e.image,
title: i,
label: {
padding: '10rpx',
content: numArr[i] + ' ' + e.pointName,
color: '#fff',
fontSize: '24rpx',
anchorX: '0',
anchorY: '0',
borderRadius: '4rpx',
bgColor: 'rgba(0,0,0,0.5)',
textAlign: 'center'
},
callout: {
bgColor: 'transparent'
}
})
})
this.markers = markers;
} else {
uni.$u.toast(info.msg);
}
},
getLine (line) {
let array = JSON.parse(line);
if (!array) return false;
this.polyline = ([
{ points: array, color: '#EFE7A7', width: 8, dottedLine: false },
{ points: array, color: '#743F00', width: 2, dottedLine: true }
]);
},
async getGuideList () {
this.showBtn = false;
this.isAllLine = true;
this.current1 = 0;
this.getGuide('')
},
closeLine () {
this.popup1 = false;
if (this.showLine) {
this.showLine = false;
this.showBtn = true;
} else if (this.showSwiper) {
this.windowBottom = this.$safeAreaBottom + 50 + this.$paddingTop + uni.upx2px(72);
this.showLine = true;
this.showBtn = false;
this.guideList()
if (!this.isAllLine) this.popup1 = true;
}
this.showSwiper = false;
this.getMarkersList()
},
changeLocation() {
let mapObjs = uni.createMapContext('map', this)
mapObjs.moveToLocation({
complete: res => {
console.log('移动完成:', res)
}
})
},
swiperChange1(e) {
this.current1 = e.detail.current
},
swiperChange2(e) {
this.current2 = e.detail.current
},
goSpot(i) {
if (!i.spotId) return;
uni.navigateTo({ url: '/pages/scenic/spot?id=' + i.spotId })
}
}
}
</script>
<style lang="scss" scoped>
.line_btn{
width: 180rpx;
height: 180rpx;
position: relative;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 32rpx;
line-height: 46rpx;
position: fixed;
left: 50%;
transform: translateX(-50%);
.img {
position: absolute;
left: 0;
top: 0;
z-index: -1;
}
}
.line_swiper{
width: 100%; height: 188rpx; position: fixed; left: 0;
swiper{ width: 100%; height: 100%; }
.line_box{ width: 100%; height: 100%; box-sizing: border-box; padding: 0 12rpx; }
.line_waper{
width: 100%; height: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 24rpx 24rpx 0; position: relative; padding-right: 148rpx;
.title{ line-height: 46rpx; color: #333; font-size: 32rpx; font-weight: 500; }
.msg{ line-height: 34rpx; margin-top: 12rpx; color: #999; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 24rpx; }
.tag{
width: 100%; margin-top: 12rpx; display: flex; align-items: center;
view{
height: 32rpx; box-sizing: border-box; border: 2rpx solid #03AE80; border-radius: 2rpx; padding: 0 8rpx; line-height: 28rpx; color: #03AE80; font-size: 20rpx;
}
}
.btn{ width: 120rpx; height: 120rpx; background: #03AE80; display: flex; flex-direction: column; justify-content: center; align-items: center; color: #FCFCFC; font-size: 24rpx; line-height: 30rpx; border-radius: 50%; position: absolute; right: 24rpx; top: 50%; transform: translateY(-50%); }
}
}
.detail_swiper {
width: 100%; height: 204rpx; position: fixed; left: 0;
swiper{ width: 100%; }
.activeClass {
height: 204rpx !important;
box-sizing: border-box;
.detail_waper {
padding: 24rpx 32rpx;
}
}
.defaultClass {
height: 188rpx !important;
margin-top: 16rpx;
box-sizing: border-box;
.detail_waper {
padding: 16rpx 32rpx;
}
}
.detail_box{ width: 100%; height: 100%; box-sizing: border-box; padding: 0 12rpx; }
.detail_waper{
width: 100%; height: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box;
display: flex;
flex-direction: row;
justify-content: space-between;
.num {
width: 34rpx;
height: 34rpx;
background: #03AE80;
border-radius: 50%;
border: 2rpx solid #FFFFFF;
font-weight: 500;
font-size: 20rpx;
color: #FFFFFF;
line-height: 34rpx;
text-align: center;
margin-right: 12rpx;
}
.con-box {
flex: 1;
.title {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
.label {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.voice {
display: flex;
align-items: center;
.icon {
width: 32rpx;
height: 32rpx;
margin-right: 10rpx;
}
.time {
font-size: 24rpx;
color: #333333;
}
}
}
.text {
margin-top: 8rpx;
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 36rpx;
width: 528rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
}
}
.waper {
width: 100%;
height: 100vh;
background: #F4F6FA;
#map{ width: 100%; }
.tabs-box {
padding: 5rpx 0 11rpx;
background: #FFFFFF;
scroll-view{ width: 100%; white-space: nowrap; font-size: 0;}
.tab {
display: inline-block;
vertical-align: top;
height: 56rpx;
line-height: 56rpx;
padding: 0 38rpx;
background: #FFFFFF;
border-radius: 42rpx 42rpx 42rpx 42rpx;
font-size: 28rpx;
color: #000000;
&:first-child {
margin-left: 32rpx;
}
&:last-child {
margin-right: 32rpx;
}
}
.active {
background: #03AE80;
font-weight: 500;
font-size: 28rpx;
color: #FFFFFF;
}
}
// .map-box {
// width: 100%;
// height: 100%;
// position: fixed;
// left: 0;
// top: 0;
// .customCallout {
// display: flex;
// justify-content: center;
// align-items: center;
// box-sizing: border-box;
// padding: 8rpx 46rpx;
// background: #00BE69;
// border-radius: 30rpx;
// .txt {
// font-weight: 500;
// font-size: 28rpx;
// color: #FFFFFF;
// }
// .triangle {
// width: 0;
// height: 0;
// border-left: 10rpx solid transparent;
// /* 左边的透明部分 */
// border-right: 10rpx solid transparent;
// /* 右边的透明部分 */
// border-top: 14rpx solid #00BE69;
// /* 底部红色线条 */
// position: absolute;
// bottom: -13rpx;
// }
// }
// }
.btn-box {
position: fixed;
right: 18rpx;
z-index: 1;
.location {
width: 80rpx;
height: 80rpx;
border-radius: 10rpx;
background-color: #fff;
position: relative;
margin-top: 40rpx;
.icon {
width: 50rpx;
height: 50rpx;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
}
}
.head-box {
display: flex;
align-items: center;
flex-direction: row;
justify-content: space-between;
padding-bottom: 24rpx;
border-bottom: 1rpx solid #E8E8E8;
.name {
display: flex;
align-items: center;
flex-direction: row;
.h4 {
font-size: 32rpx;
color: #333333;
}
.price {
margin-left: 24rpx;
font-size: 32rpx;
color: #FF3333;
text {
font-size: 24rpx;
color: #333333;
}
}
}
.go {
display: flex;
align-items: center;
flex-direction: row;
font-size: 26rpx;
color: #666666;
}
}
.popup-box {
width: 638rpx;
height: 300rpx;
position: fixed;
left: 50%;
top: 400rpx;
transform: translateX(-50%);
}
.popup-content1 {
background: #FFFFFF;
border-radius: 10rpx;
padding: 32rpx;
width: 638rpx;
box-sizing: border-box;
.con {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 24rpx 0;
margin-bottom: 24rpx;
border-bottom: 1rpx solid #E8E8E8;
.con-img {
width: 169rpx;
height: 169rpx;
margin-right: 22rpx;
}
.con-right {
.title {
font-weight: 500;
font-size: 32rpx;
color: #333333;
}
.describe {
margin-top: 14rpx;
width: 385rpx;
font-size: 24rpx;
color: #333333;
line-height: 32rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
}
}
}
.btn {
width: 266rpx;
height: 70rpx;
border-radius: 70rpx;
background-color: #03AE80;
text-align: center;
line-height: 70rpx;
display: flex;
align-items: center;
flex-direction: row;
justify-content: center;
margin: 0 auto;
.btn-img {
width: 30rpx;
height: 30rpx;
margin-right: 12rpx;
}
.label {
font-weight: 500;
font-size: 28rpx;
color: #fff;
}
}
}
}
</style>

905
pages/tabbar/home.vue Normal file
View File

@@ -0,0 +1,905 @@
<template>
<view :style="'padding-bottom: ' + windowBottom + 'px;'">
<u-navbar left-icon-size="0" :placeholder="true" bgColor="#fff">
<view slot='center' class="navbar_title">{{title}}</view>
</u-navbar>
<mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption" :fixed="false">
<view class="header-show">
<swiper class="header-swiper" :autoplay="true" :interval="5000" :duration="1000">
<swiper-item v-for="(item, index) in banner" :key="index">
<image class="header-img" :src="$utils.setImgUrl(item)" mode=""></image>
</swiper-item>
</swiper>
<view class="header-pos" v-if="weather">
<view class="weather">
<image :src="getWeatherImg(weather.weather)" mode=""></image>
<view class="font-box">
<view>{{weather.temperature}}</view>
<view>{{weather.weather}}</view>
</view>
</view>
<view class="address">
<image src="../../static/image/weather/area.png" mode=""></image>
<view>{{weather.city}}</view>
<view>{{weather.reporttime ? weather.reporttime.substr(0, 10) : ''}}</view>
</view>
</view>
</view>
<view class="waper">
<view class="notice" v-if="notice">
<image src="../../static/image/home/notice.png" mode=""></image>
<u-notice-bar :url="'/pages/notice/detail?id=' + notice.id" bgColor="transparent" icon=" " style="padding-left: 0; padding-right: 0;" color="rgba(0,0,0,0.85)" :text="notice.title"></u-notice-bar>
<navigator class="more" hover-class="none" url="/pages/notice/index">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<view class="menu">
<view class="menu-box" v-for="(item, index) in menuList" :key="index" @click="menuClick(item)" v-if="item.config">
<view>
<image :src="item.icon" mode=""></image>
<view class="name">{{ item.name }}</view>
</view>
</view>
</view>
<view class="title-box" v-if="ticket.length > 0">
<view class="title">
<image src="../../static/image/home/recommend.png" mode=""></image>
<view>门票推荐</view>
</view>
<navigator class="more" hover-class="none" url="/pages/tabbar/ticketing">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<view class="shop-box" v-if="ticket.length > 0">
<navigator
hover-class="none"
class="shop box-style"
v-for="(item, index) in ticket"
:key="index"
:url="'/pages/scenic/ticket?id=' + item.id"
>
<image :src="$utils.setImgUrl(item.image11)" mode=""></image>
<view class="describe">
<view class="describe-tit">{{item.name}}</view>
<view class="orange">
<text v-if="item.isOrder == 1">提前预约</text>
<text v-if="item.refundRule == '0'">不可退</text>
<text v-if="item.refundRule == '3'">有效期可退</text>
<text v-if="item.refundRule == '4'">{{item.refundDay}}天内可退</text>
<text v-if="item.refundRule == '5'">未激活可退</text>
</view>
<view class="price">
<view><span v-if="item.salesRice > 0"></span>{{item.salesRice > 0 ? item.salesRice.toFixed(2) : '免费'}}</view>
<view v-if="item.price"><span></span>{{item.price}}</view>
</view>
</view>
</navigator>
</view>
<view class="title-box" v-if="archivesList.length">
<view class="title">
<image src="../../static/image/home/yanxue.png" mode=""></image>
<view>研学游</view>
</view>
<navigator class="more" hover-class="none" url="/pages/strategy/archieveList?id=10&name=研学游">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<navigator :url="'/pages/strategy/detail?id=' + archivesList[0].id" hover-class="none" class="banner-box box-style" v-if="archivesList.length">
<image :src="$utils.setImgUrl(archivesList[0].image)" mode=""></image>
<view class="banner-des">
{{archivesList[0].title}}
</view>
</navigator>
<view v-if="configData && configData.examine == 'false'">
<view class="title-box" v-if="recommendList.length > 0">
<view class="title">
<image src="../../static/image/home/haoli.png" mode=""></image>
<view>好礼推荐</view>
</view>
<navigator class="more" hover-class="none" url="/pages/shop/list">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<view class="three-box" v-if="recommendList.length > 0">
<navigator :url="'/pages/shop/detail?id=' + item.id" hover-class="none" class="three-shop box-style" v-for="(item, itemIndex) in recommendList" :key="itemIndex">
<image :src="$utils.setImgUrl(item.image)" mode=""></image>
<view class="three-shop-des">
<view class="three-shop-des-tit">{{item.title}}</view>
<view class="three-price"><span></span>{{item.price}}</view>
</view>
</navigator>
</view>
</view>
<view class="title-box" v-if="spot.length > 0">
<view class="title">
<image src="../../static/image/home/jingdian.png" mode=""></image>
<view>景点名片</view>
</view>
<navigator class="more" hover-class="none" url="/pages/scenic/list">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<view class="swiper-box" v-if="spot.length > 0">
<swiper :autoplay="true" :interval="5000" :duration="1000" @change="slideChange">
<swiper-item v-for="(item, index) in spot" :key="index">
<navigator
hover-class="none"
class="card-text"
:url="'/pages/scenic/spot?id=' + item.id"
>
<image :src="$utils.setImgUrl(item.image)" mode=""></image>
<view>{{item.scenicName}}</view>
</navigator>
</swiper-item>
</swiper>
<view class="swiper-dots">
<view class="swiper-dot" :class="swiperInd == index ? 'swiper-dot-active' : ''" v-for="(i, index) in spot" :key="index"></view>
</view>
</view>
<view class="title-box" v-if="strategy.length > 0">
<view class="title">
<image src="../../static/image/home/remen.png" mode=""></image>
<view>热门攻略</view>
</view>
<navigator class="more" hover-class="none" url="/pages/strategy/index">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<scroll-view class="scroll-show" scroll-x="true" v-if="strategy.length > 0">
<navigator
class="img-box card-text"
hover-class="none"
:url="'/pages/strategy/detail?id=' + item.id"
v-for="(item, index) in strategy"
:key="index"
>
<image :src="$utils.setImgUrl(item.image)" mode=""></image>
<view>{{item.title}}</view>
</navigator>
</scroll-view>
<view class="title-box" v-if="scenicSpotsList.length">
<view class="title">
<image src="../../static/image/home/zhoubian.png" mode=""></image>
<view>周边景区</view>
</view>
<navigator class="more" hover-class="none" url="/pages/strategy/archieveList?id=9&name=周边景区">
更多
<u-icon name="arrow-right" color="rgba(0, 0, 0, 0.25)" size="30rpx"></u-icon>
</navigator>
</view>
<view class="three-box" v-if="scenicSpotsList.length">
<navigator :url="'/pages/strategy/detail?id=' + item.id" hover-class="none" class="three-show box-style card-text" v-for="item in scenicSpotsList" :key="item">
<image :src="$utils.setImgUrl(item.image)" mode=""></image>
<view>{{item.title}}</view>
</navigator>
</view>
</view>
</mescroll-body>
<tabbar name="home"></tabbar>
</view>
</template>
<script>
import Vue from 'vue'
import tabbar from '@/components/tabbar/index.vue'
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
export default {
components: { tabbar },
mixins: [MescrollMixin],
data () {
return {
windowBottom: 0,
upOption: { use: false, auto: false },
down: { user: true, auto: true, beforeEndDelay: 500, native: false },
configData: null,
downOption: { auto: false },
title: '',
banner: [],
notice: null,
menuList: [
// { name: '景区介绍', icon: '../../static/image/home/menu1.png', path: '/pages/scenic/index', type: 'navigate', config: true },
{ name: '景交车辆', icon: '../../static/image/home/menu3.png', path: '/pages/strategy/archieveList?id=8&name=景交车辆', type: 'navigate', config: true },
{ name: '景点名片', icon: '../../static/image/home/menu4.png', path: '/pages/scenic/list', type: 'navigate', config: true },
{ name: '预约导游', icon: '../../static/image/home/menu5.png', path: '/pages/guide/list', type: 'navigate', config: true },
{ name: '文创特产', icon: '../../static/image/home/menu6.png', path: '/pages/shop/list', type: 'navigate', config: true },
{ name: '酒店民宿', icon: '../../static/image/home/menu9.png', path: '/pages/hotel/list', type: 'navigate', config: true },
{ name: '餐饮美食', icon: '../../static/image/home/menu9.png', path: '/pages/eatery/index', type: 'navigate', config: true }
],
activity: [],
current1: 0,
current2: 0,
ticket: [],
spot: [],
strategy: [],
area: '',
weather: null,
swiperInd: 0,
archivesList: [],
scenicSpotsList: [],
recommendList: [],
location:{}
}
},
computed: {
getDistance1({location}){
return item =>{
let lat1 = item.lat,lng1=item.lng,lat2=location.lat,lng2=location.lng;
return this.$utils.getDistance(lat1, lng1, lat2, lng2)
}
}
},
async onLoad () {
uni.getLocation({
type: 'gcj02',
isHighAccuracy:true,
success: (res) => {
let latitude = res.latitude;
let longitude = res.longitude;
this.location = {
lat:latitude,
lng:longitude
};
}
})
let info = uni.getSystemInfoSync();
this.windowBottom = info.windowBottom;
this.configData = uni.getStorageSync('configData');
if (this.configData.examine == 'true') {
this.menuList[3].config = false;
this.menuList[4].config = false;
}
this.getInitData();
},
onShareAppMessage () {
return {
title: '巴松措风景区',
path: '/pages/login/index'
}
},
methods: {
menuClick (info) {
if (info.type == 'program') {
uni.navigateToMiniProgram({ appId: info.path });
}
if (info.type == 'navigate') {
uni.navigateTo({ url: info.path })
}
if (info.type == 'reLaunch') {
uni.reLaunch({ url: info.path })
}
if (info.type == 'null') {
uni.showToast({ mask: true, title: '服务暂未开放', icon: 'none' })
}
},
downCallback () {
this.getInitData();
},
async getInitData () {
// 景区详情
let scenic = await this.$http.scenicDetail({ id: this.configData.scenic.id });
if(scenic.data) {
this.title = scenic.data.scenicName;
this.banner = scenic.data.imagePage ? scenic.data.imagePage.split(',') : [];
this.area = scenic.data.coordinate;
}
// 公告
let info = await this.$http.noticeList({ flag: 'top', pageNum: 1, pageSize: 1 });
if (info.rows.length > 0) {
this.notice = info.rows[0]
}
// 广告
let activity = await this.$http.activityZoneList({ flag: 'recommend', pageNum: 1, pageSize: 1 });
this.activity = activity.rows;
// 门票推荐
let ticket = await this.$http.ticketList({ scenicId: this.configData.scenic.id, flag: 'recommend' });
this.ticket = ticket.data;
// 景点名片
let spot = await this.$http.scenicSpotList({ pageNum: 1, pageSize: 3, scenicId: this.configData.scenic.id, flag: 'recommend' });
this.spot = spot.rows;
// 热门攻略
if (this.configData.examine != 'true') {
let strategy = await this.$http.introductionList({ pageNum: 1, pageSize: 3 });
this.strategy = strategy.rows;
}
// 好礼退款
let shop = await this.$shop.getGoodsList({ pageNum: 1, pageSize: 3, flag: 'recommend' });
this.recommendList = shop.rows;
// 研学游
let archivesReq = await this.$http.archivesList({
pageNum: 1,
pageSize: 1,
channelId: 10,
flag: 'recommend'
});
this.archivesList = archivesReq.rows
// 周边景区
let scenicSpotsReq = await this.$http.archivesList({
pageNum: 1,
pageSize: 3,
channelId: 9,
flag: 'recommend'
});
this.scenicSpotsList = scenicSpotsReq.rows
console.log(scenic)
uni.request({
url: 'https://restapi.amap.com/v3/weather/weatherInfo',
method :'GET',
data:{
key: '5b8b5a840f8708a02312af2d13832042',
city: scenic.data.areaCity ? scenic.data.areaCity.substr(0, 6) : '540421',
extensions: 'base',
},
success: (res) => {
if (res.data.status == '1' && res.data.lives && res.data.lives.length > 0) {
this.weather = res.data.lives[0];
uni.setStorageSync("weather",{date:new Date().getTime(),weather:res.data.lives[0]})
}
},
});
setTimeout(() => {
this.mescroll && this.mescroll.endSuccess(1, false)
}, 1500)
},
getWeatherImg (text) {
let key = '';
switch (text) {
case '晴':
key = '1';
break;
case '多云':
key = '2';
break;
case '阴':
key = '3';
break;
case '小雨':
key = '4';
break;
case '中雨':
key = '5';
break;
case '大雨':
key = '6';
break;
case '暴雨':
key = '7';
break;
case '阵雨':
key = '8';
break;
case '雷阵雨':
key = '9';
break;
case '雷电':
key = '10';
break;
case '冰雹':
key = '11';
break;
case '轻雾':
key = '12';
break;
case '雾':
key = '13';
break;
case '浓雾':
key = '14';
break;
case '霾':
key = '15';
break;
case '雨夹雪':
key = '16';
break;
case '小雪':
key = '17';
break;
case '中雪':
key = '18';
break;
case '大雪':
key = '19';
break;
case '暴雪':
key = '20';
break;
case '冻雨':
key = '21';
break;
case '霜冻':
key = '22';
break;
case '台风':
key = '23';
break;
case '浮尘':
key = '24';
break;
case '扬沙':
key = '25';
break;
case '沙尘暴':
key = '26';
break;
default:
key = '';
break;
}
return '../../static/image/weather/' + key + '.png';
},
slideChange(e) {
this.swiperInd = e.detail.current
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .u-notice-bar{ padding-left: 0 !important; padding-right: 0 !important; }
.header-show{
width: 100%;
height: 434rpx;
box-sizing: border-box;
position: relative;
&:after{ content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 180rpx; background: linear-gradient( 180deg, rgba(0, 0, 0, 0.7) 0%, rgba(0,0,0,0) 100%); z-index: 5; }
.header-swiper{
width: 100%;
height: 100%;
.header-img{
width: 100%;
height: 100%;
}
}
.header-pos{
position: absolute;
z-index: 6;
top: 40rpx;
left: 40rpx;
right: 40rpx;
}
.weather{
display: flex;
align-items: center;
&>image{
width: 80rpx;
height: 80rpx;
}
.font-box{
margin-left: 8rpx;
color: white;
&>view:nth-child(1) {
font-size: 30rpx;
}
&>view:nth-child(2) {
font-size: 28rpx;
}
}
}
.address{
display: flex;
align-items: center;
margin-left: 8rpx;
color: white;
font-size: 26rpx;
margin-top: 4rpx;
&>view {
margin-left: 10rpx;
}
&>image{
width: 28rpx;
height: 28rpx;
}
}
}
.waper{
margin-top: -64rpx;
background: white;
border-radius: 40rpx 40rpx 0 0;
box-sizing: border-box;
padding: 32rpx 24rpx;
position: relative;
.notice{
width: 100%;
height: 80rpx;
background: linear-gradient( 90deg, rgba(#03AE80,0) 0%, rgba(#03AE80,0.05) 50%, rgba(3,174,128,0) 100%);
border-radius: 10rpx;
color: rgba(0,0,0,0.85);
display: flex;
align-items: center;
&>image{
width: 48rpx;
min-width: 48rpx;
height: 48rpx;
margin-right: 12rpx;
}
.txt{
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
font-size: 28rpx;
}
}
.more{
display: flex;
align-items: center;
font-size: 24rpx;
color: rgba(0,0,0,0.25);
margin-left: 28rpx;
cursor: pointer;
&>image{
width: 32rpx;
height: 32rpx;
margin-left: 6rpx;
}
}
.menu{
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
padding: 0 12rpx;
box-sizing: border-box;
margin-top: 32rpx;
margin-bottom: 12rpx;
.menu-box{
margin-bottom: 24rpx;
margin-right: 30rpx;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
image{
width: 80rpx;
height: 80rpx;
margin: 0 auto 12rpx;
}
.name{
font-size: 26rpx;
color: rgba(0,0,0,0.85);
line-height: 30rpx;
}
&:nth-child(5n){ margin-right: 0; }
}
}
.title-box{
display: flex;
height: 53rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
.title{
display: flex;
align-items: center;
font-weight: 600;
font-size: 36rpx;
color: rgba(0,0,0,0.85);
&>image{
width: 36rpx;
height: 36rpx;
margin-right: 12rpx;
}
}
}
.box-style{
box-shadow: 0rpx 0rpx 32rpx 0rpx rgba(0,0,0,0.05);
border-radius: 10rpx;
overflow: hidden;
}
.shop-box{
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
margin-bottom: 12rpx;
.shop{
width: 341rpx;
height: 540rpx;
background: white;
margin-bottom: 20rpx;
&>image{
width: 100%;
height: 342rpx;
}
.describe{
box-sizing: border-box;
padding: 20rpx 24rpx 24rpx;
.describe-tit{
font-weight: 600;
height: 44rpx;
font-size: 30rpx;
color: rgba(0,0,0,0.85);
line-height: 44rpx;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.orange{
font-weight: 400;
font-size: 24rpx;
color: #FFA944;
line-height: 28rpx;
height: 36rpx;
margin: 6rpx 0rpx 20rpx;
&>span{
display: inline-block;
width: 1rpx;
height: 18rpx;
background: #FFA944;
margin: 0rpx 12rpx;
}
}
.price{
display: flex;
justify-content: space-between;
align-items: flex-end;
&>view:nth-child(1){
color: #FF3333;
font-family: Arial, Arial;
font-weight: bold;
font-size: 40rpx;
color: #FF3333;
line-height: 47rpx;
&>span{
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #FF3333;
line-height: 28rpx;
}
}
&>view:nth-child(2){
font-family: Arial, Arial;
font-weight: 400;
font-size: 24rpx;
color: rgba(0,0,0,0.25);
line-height: 28rpx;
text-decoration: line-through;
}
}
}
}
}
.banner-box{
height: 340rpx;
margin-bottom: 32rpx;
&>image{
width: 100%;
height: 236rpx;
}
.banner-des{
padding: 28rpx 20rpx;
box-sizing: border-box;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 600;
font-size: 32rpx;
color: rgba(0,0,0,0.85);
line-height: 38rpx;
}
}
.three-box{
display: flex;
align-items: center;
margin-bottom: 32rpx;
.three-shop{
width: 220rpx;
height: 328rpx;
margin-right: 21rpx;
&>image{
width: 220rpx;
height: 220rpx;
object-fit: contain;
}
.three-shop-des{
box-sizing: border-box;
padding: 12rpx 20rpx;
&-tit{
margin-bottom: 4rpx;
font-weight: 600;
font-size: 28rpx;
color: rgba(0,0,0,0.85);
line-height: 41rpx;
height: 41rpx;
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
}
.three-price{
font-size: 32rpx;
color: #FF3333;
line-height: 37rpx;
height: 37rpx;
&>span{
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
line-height: 28rpx;
}
}
}
.three-show{
width: 220rpx;
height: 294rpx;
margin-right: 21rpx;
&>image{
width: 220rpx;
height: 294rpx;
object-fit: contain;
}
&>p{
position: absolute;
left: 20rpx;
bottom: 20rpx;
font-weight: 400;
font-size: 28rpx;
color: #FFFFFF;
line-height: 33rpx;
}
}
.three-show:last-child, .three-shop:last-child{
margin-right: 0;
}
}
.canteen-box{
margin-bottom: 32rpx;
.canteen-show{
width: 100%;
overflow: hidden;
box-sizing: border-box;
margin-bottom: 20rpx;
padding: 20rpx;
display: flex;
align-items: center;
&>image{
width: 208rpx;
min-width: 208rpx;
height: 208rpx;
border-radius: 10rpx;
margin-right: 24rpx;
}
.canteen-des{
flex: 1;
overflow: hidden;
&-tit{
font-weight: 600;
font-size: 32rpx;
color: rgba(0,0,0,0.85);
line-height: 38rpx;
margin-top: 4rpx;
}
.canteen-label{
margin-top: 10rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20rpx;
.canteen-left>view{
display: inline-block;
}
.bg{
padding: 4rpx 8rpx;
background: rgba(238, 89, 90, 0.1);
border-radius: 4rpx;
font-weight: 400;
font-size: 22rpx;
color: #EE595A;
height: 38rpx;
line-height: 38rpx;
border-radius: 4rpx;
}
.canteen-price{
font-size: 24rpx;
color: rgba(0,0,0,0.25);
line-height: 28rpx;
margin-left: 20rpx;
}
.canteen-distance{
font-size: 24rpx;
color: rgba(0,0,0,0.25);
}
}
.canteen-tit{
width: 100%;
height: 42rpx;
display: flex;
align-items: center;
font-size: 28rpx;
color: rgba(0,0,0,0.65);
line-height: 33rpx;
margin-bottom: 4rpx;
overflow: hidden;
&>view{
white-space: nowrap;
margin-left: 8rpx;
text-overflow: ellipsis;
overflow: hidden;
}
.time{ margin-left: 12rpx; }
}
}
}
}
.card-text{
position: relative;
width: 100%;
height: 100%;
border-radius: 10rpx;
overflow: hidden;
&>view{
position: absolute;
left: 20rpx;
right: 20rpx;
bottom: 20rpx;
font-weight: 400;
font-size: 28rpx;
color: #FFFFFF;
line-height: 33rpx;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
&>image{
width: 100%;
height: 100%;
position: relative; border-radius: 10rpx;
&::after{ content: ""; width: 100%; height: 138rpx; background: linear-gradient( 180deg, rgba(0,0,0,0) 0%, #000000 100%); position: absolute; left: 0; bottom: 0; }
}
}
.swiper-box .card-text{
&>image{
&::after{ height: 94rpx; }
}
}
.three-box .card-text{
&>image{
&::after{ height: 130rpx; }
}
}
.swiper-box{
margin-bottom: 32rpx;
position: relative;
.swiper-dots{
bottom: 32rpx;
right: 52rpx;
position: absolute;
display: flex;
align-items: center;
height: 10rpx;
}
.swiper-dot{
width: 10rpx;
margin-right: 10rpx;
height: 10rpx;
border-radius: 5rpx;
background: rgba(255,255,255,0.3);
&:last-child{ margin-right: 0; }
}
.swiper-dot-active{
width: 30rpx;
background: #fff;
}
}
.scroll-show{
height: 266rpx;
margin-bottom: 32rpx;
white-space: nowrap;
.img-box{
width: 356rpx;
height: 266rpx;
margin-right: 20rpx;
display: inline-block;
}
}
}
</style>

258
pages/tabbar/mine.vue Normal file
View File

@@ -0,0 +1,258 @@
<template>
<view class="waper">
<view class="banner">
<image class="bgImg" src="../../static/image/mine/myBgimg.png" mode=""></image>
<view class="info" v-if="userInfo">
<view class="img">
<image :src="userInfo.avatar" mode=""></image>
</view>
<view class="text" v-if="userInfo.token">
<view>{{userInfo.nickname}}</view>
<view @click="toUrl({ url: '/pages/my/myProfile' })">查看并编辑个人资料</view>
</view>
<view class="text" v-else @click="login">
<view>请登录</view>
</view>
</view>
</view>
<view class="menu-box">
<!-- <image class="bgImg" src="../../static/image/mine/mineList.png" mode=""></image> -->
<view class="con-box">
<view class="waper_box">
<view class="waper_list" v-for="(i, index) in menuList" :key="index" v-if="!i.check || (configData && configData.examine == 'false')">
<view class="title">
<view>{{i.title}}</view>
</view>
<view class="cont">
<view class="list" v-for="(item, itemIndex) in i.list" :key="itemIndex" @click="toUrl(item)">
<view class="img">
<image :src="item.icon" mode=""></image>
</view>
<view class="text">{{item.name}}</view>
</view>
</view>
</view>
</view>
<view class="btn" v-if="userInfo && userInfo.token">
<view @click="logOut">退出登录</view>
</view>
</view>
</view>
<uni-popup class="popupRefund" ref="popup" background-color="#fff">
<view class="popup-content">
<image class="bgImg" src="https://common/refundPopup.png" mode=""></image>
<view class="con">
<view class="title">温馨提示</view>
<view class="text">确定退出登录吗</view>
<view class="btn-box">
<view class="close" @click="dialogClose">取消</view>
<view class="save" @click="dialogConfirm">确认</view>
</view>
</view>
</view>
</uni-popup>
<tabbar name="mine"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/index.vue'
export default {
components: { tabbar },
data () {
return {
userInfo: null,
configData: null,
menuList: [
{
title: '票务订单',
check: false,
list: [
{ name: '门票订单', icon: '../../static/image/mine/mpdd.png', url: '/pages/my/myOrder?index=' },
{ name: '商城订单', icon: '../../static/image/mine/scdd.png', url: '/pages/shop/order?index=0' },
{ name: '酒店订单', icon: '../../static/image/mine/jddd.png', url: '/pages/hotelOrder/list?index=1' },
]
},
{
title: '更多服务',
check: false,
list: [
{ name: '游客信息', icon: '../../static/image/mine/ykxx.png', url: '/pages/my/tourist' },
{ name: '我的收藏', icon: '../../static/image/mine/wdsc.png', url: '/pages/my/heart' },
{ name: '投诉建议', icon: '../../static/image/mine/tsjy.png', url: '/pages/my/complaint' },
{ name: '旅游年卡', icon: '../../static/image/mine/lynk.png', url: '/pages/my/annualCard' },
{ name: '一卡通', icon: '../../static/image/mine/ykt.png', url: '/pages/my/IPass' },
{ name: '联系客服', icon: '../../static/image/mine/lxkf.png', type: 'service' },
{ name: '投诉电话', icon: '../../static/image/mine/tsdh.png', type: 'complaint' },
{ name: '购物车', icon: '../../static/image/mine/gwc.png', url: '/pages/shop/cart' },
{ name: '收货地址', icon: '../../static/image/mine/shdz.png', url: '/pages/shop/addressList' }
]
}
]
}
},
onLoad () {
this.configData = uni.getStorageSync('configData');
},
onShow () {
this.getUesr();
},
methods: {
dialogConfirm() {
uni.removeStorageSync("ztc_token");
uni.removeStorageSync("user_nickname");
uni.removeStorageSync("user_avatar");
this.getUesr()
uni.showToast({ mask: true, title: '退出登录成功', icon: 'success' })
this.dialogClose()
},
dialogClose () {
this.$refs.popup.close()
},
logOut () {
this.$refs.popup.open()
},
getUesr () {
this.userInfo = {
nickname: uni.getStorageSync('user_nickname'),
avatar: uni.getStorageSync('user_avatar') ? this.$utils.setImgUrl(uni.getStorageSync('user_avatar')) : require('../../static/image/common/user.png'),
token: uni.getStorageSync('ztc_token')
}
},
login() {
uni.navigateTo({ url: '/pages/login/login' })
},
toUrl (info) {
if (info.url) {
if (!this.userInfo.token) {
uni.showToast({ title: '请登录后操作', icon: 'none', mask: true })
setTimeout(() => {
uni.navigateTo({
url: '/pages/login/login'
})
}, 1500)
return false;
}
uni.navigateTo({ url: info.url })
} else {
if (info.type === 'service') {
uni.makePhoneCall({ phoneNumber: this.configData.phone }).catch((e) => {});
} else if (info.type === 'complaint') {
uni.makePhoneCall({ phoneNumber: this.configData.complaintPhone }).catch((e) => {});
}
}
}
}
}
</script>
<style lang="scss">
.waper{
width: 100%;
.banner{
width: 100%; height: 400rpx; position: relative;
.bgImg {
width: 100%; height: 400rpx;
}
.info{
width: 100%; height: 148rpx; position: absolute; left: 0; bottom: 56rpx; box-sizing: border-box; padding: 0 32rpx; padding-left: 216rpx;
.img{
width: 148rpx; height: 148rpx; position: absolute; left: 32rpx; top: 0;
image{ border-radius: 50%; }
}
.text{
width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center;
view{
&:nth-child(1){ line-height: 56rpx; color: #333; font-size: 40rpx; font-weight: 500; }
&:nth-child(2){ margin-top: 10rpx; line-height: 34rpx; font-size: 24rpx; color: #666; }
}
}
}
}
.card {
position: relative;
margin: -20rpx 32rpx 0;
width: 686rpx;
height: 212rpx;
.bgImg {
width: 100%;
height: 100%;
}
.title {
position: absolute;
top: 24rpx;
left: 40rpx;
.name {
font-weight: bold;
font-size: 42rpx;
color: #FFFFFF;
}
.day {
margin-top: 12rpx;
font-size: 24rpx;
color: rgba(255,255,255,0.7);
}
}
.icon {
position: absolute;
width: 124rpx;
height: 124rpx;
top: -1rpx;
right: -1rpx;
}
}
.menu-box {
position: relative;
// margin-top: -78rpx;
.bgImg {
width: 750rpx;
height: 1088rpx;
}
.con-box {
padding-bottom: 40rpx;
// top: 52rpx;
width: 100%;
.waper_box{
width: 100%; box-sizing: border-box; padding: 0 32rpx;
// position: relative; margin-top: -20rpx;
.waper_list{
width: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 24rpx 0; margin-bottom: 20rpx;
.title{
box-sizing: border-box; padding-left: 24rpx;
view{ line-height: 50rpx; color: #333; font-size: 32rpx; font-weight: 500; position: relative; z-index: 3; }
}
.cont{
width: 100%; display: flex; flex-wrap: wrap;
.list{
width: 25%; display: flex; flex-direction: column; justify-content: center; align-items: center; margin-top: 36rpx;
.img{ width: 64rpx; height: 64rpx; }
.text{ margin-top: 8rpx; color: #333; font-size: 24rpx; }
}
}
&:last-child{ margin-bottom: 0; }
&:first-child{
.cont {
width: 100%; box-sizing: border-box; padding: 0 54rpx;
.list {
width: 120rpx; margin-right: 108rpx;
&:last-child{ margin-right: 0; }
.img {
width: 80rpx !important;
height: 80rpx !important;
}
.text{
font-size: 26rpx;
}
}
}
}
}
}
.btn{
width: 100%; margin-top: 80rpx; box-sizing: border-box; padding: 0 60rpx;
view{ height: 90rpx; background: #03AE80; border-radius: 100rpx; line-height: 90rpx; text-align: center; font-weight: 500; font-size: 32rpx; color: #F6F9FF; }
}
}
}
}
</style>

130
pages/tabbar/ticketing.vue Normal file
View File

@@ -0,0 +1,130 @@
<template>
<view class="waper" :style="'padding-bottom: ' + windowBottom + 'px;'">
<u-navbar left-icon-size="0" :placeholder="true" bgColor="#fff">
<view slot='center' class="navbar_title">购票</view>
</u-navbar>
<view class="waper_box">
<view class="list_waper" v-for="(i, index) in list" :key="index" v-if="i.children.length > 0">
<view class="title">{{i.name}}</view>
<view class="content">
<navigator hover-class="none" :url="(item.classify == '3' ? '/pages/scenic/otherTick?id=' : '/pages/scenic/ticket?id=') + item.id" class="list" v-for="(item, itemIndex) in i.children" :key="itemIndex">
<view class="img">
<image :src="$utils.setImgUrl(item.image11)" mode=""></image>
</view>
<view class="info">
<view class="name">{{item.name}}</view>
<view class="tag">
<text v-if="item.refundRule == '0'">不可退</text>
<text v-if="item.refundRule == '3'">有效期可退</text>
<text v-if="item.refundRule == '4'">{{item.refundDay}}天内可退</text>
<text v-if="item.refundRule == '5'">未激活可退</text>
</view>
<view class="price-box">
<view :class="'discounts' + (item.salesRice > 0 ? '' : ' free')">{{item.salesRice > 0 ? item.salesRice.toFixed('2') : '免费'}}</view>
<view class="lineation" v-if="item.price && item.price > 0">{{item.price}}</view>
</view>
<view class="btn">购票</view>
</view>
</navigator>
</view>
</view>
</view>
<tabbar name="ticketing"></tabbar>
</view>
</template>
<script>
import tabbar from '@/components/tabbar/index.vue'
export default {
components: { tabbar },
data () {
return {
windowBottom: 0,
list: []
}
},
async onLoad () {
let info = uni.getSystemInfoSync();
this.windowBottom = info.windowBottom;
let group = await this.$http.groupList();
for (var i = 0; i < group.data.length; i ++) {
group.data[i].children = [];
}
this.list = group.data;
let scenicId = this.$scenicId;
if (!scenicId) {
let config = await this.$http.getConfigData()
scenicId = config.data.scenic.id || '1';
}
let ticket = await this.$http.ticketList({scenicId: scenicId});
var f;
ticket.data.forEach((e, i) => {
f = this.list.find(m => m.id == e.groupId);
if (f) {
f.children.push(e)
}
})
}
}
</script>
<style lang="scss">
.waper_box{
width: 100%; box-sizing: border-box; padding: 24rpx 24rpx;
.list_waper{
width: 100%; margin-bottom: 40rpx;
&:last-child{ margin-bottom: 0; }
.title{
height: 46rpx; box-sizing: border-box; padding-left: 16rpx; position: relative; font-size: 32rpx; color: #333; font-weight: 500; line-height: 46rpx;
&::after{ content: ""; width: 6rpx; height: 28rpx; background: linear-gradient( 141deg, #54C76E 0%, #03AE80 100%); border-radius: 2rpx; position: absolute; left: 0; top: 50%; transform: translateY(-50%); }
}
.content{
width: 100%; margin-top: 24rpx;
.list{
width: 100%; background: #fff; border-radius: 10rpx; box-sizing: border-box; padding: 24rpx 24rpx 24rpx 252rpx; position: relative; margin-bottom: 20rpx;
&:last-child{ margin-bottom: 0; }
.img{
width: 208rpx; height: 208rpx; position: absolute; left: 24rpx; top: 24rpx;
image{ border-radius: 10rpx; }
}
.info{
width: 100%; height: 208rpx; position: relative; box-sizing: border-box; padding-top: 16rpx;
.name{ line-height: 48rpx; color: #333; font-size: 32rpx; font-weight: 500; width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag{
width: 100%; margin-top: 14rpx; display: flex; align-items: center; height: 36rpx;
text{
color: #FFA944; font-size: 24rpx; margin-right: 32rpx; position: relative;
&::after{ content: ""; width: 2rpx; height: 16rpx; background: #FFA944; position: absolute; right: -17rpx; top: 50%; transform: translateY(-50%); }
&:last-child{
margin-right: 0;
&::after{ width: 0; }
}
}
}
.price-box {
display: flex; align-items: baseline;
.discounts {
margin-top: 36rpx; line-height: 46rpx; color: #FF3333; font-size: 40rpx; font-weight: bold; box-sizing: border-box; padding-left: 24rpx; position: relative;
&::after{ content: "¥"; color: #FF3333; line-height: 34rpx; font-size: 24rpx; font-weight: 500; position: absolute; left: 0; bottom: 0; }
&.free{
padding-left: 0; font-size: 28rpx; margin-right: 10rpx;
&::after{ font-size: 0; }
}
}
.lineation {
font-weight: 400;
font-size: 24rpx;
color: #C8C8C8;
margin-left: 14rpx;
text-decoration: line-through;
}
}
.btn { position: absolute; right: 0; bottom: 0; width: 178rpx; height: 64rpx; line-height: 64rpx; background: linear-gradient( 141deg, #54C76E 0%, #03AE80 100%); border-radius: 32rpx; text-align: center; font-size: 28rpx; color: #fff;
}
}
}
}
}
}
</style>