Files
xdd-uniapp-new/pages/chose-city/chose-city.vue
T

767 lines
20 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="chose-city">
<view class="header">
<view class="search-box flex jc-between ai-center">
<input
v-model="keyword"
type="text"
placeholder="搜索城市"
placeholder-style="color:#999"
@confirm="search"
>
<image
:src="webUrl + '/orderIcon/search.png'"
class="icon"
mode="scaleToFill"
@click="search"
/>
</view>
</view>
<view class="aside" id="aside">
<view
v-for="(item, index) in listGroup"
:key="index"
:class="index === navActive ? 'on' : ''"
class="item flex jc-center ai-center"
@click="asideTap(index)"
>
<view class="name">{{ item.label }}</view>
</view>
</view>
<view class="content">
<mescroll-body
ref="mescrollRef"
:up="upOption"
:down="downOption"
top="16rpx"
bottom="0"
class='cotent-scroll'
@up="upCallback"
@down="downCallback"
@init="mescrollInit"
@emptyclick="emptyClick"
>
<view class="fixed-box">
<view class="line-location flex ai-center">
<image :src="webUrl + '/20220903142929759087.png'" mode="scaleToFill"></image>
<text class="bold" v-if="location">当前定位{{ location }}</text>
<view style="color:#f66" @click="reload()" v-else>定位失败
<image :src="webUrl + '/20231215213824297278.png'" mode="scaleToFill" />
</view>
</view>
<image
v-if="banner"
:src="banner.icon"
class="banner"
mode="scaleToFill"
@click="bannerItemTapHandle(banner)"
/>
</view>
<!--全国特产和文玩的推荐信息-->
<view
v-if="recommendInfo && type < 2"
class="recommendInfo"
>
<!--bug#1060-增加控制-->
<template
v-if="recommendInfo.displayStatus === 1 &&
(
(type === 0 && recommendInfo.hotelList) ||
(type === 1 && recommendInfo.productList)
)
"
>
<view class="red-border-title">{{ recommendInfo.title }}</view>
<image
:src="recommendInfo.backgroundImage"
class="bg-custom"
mode="scaleToFill"
/>
<scroll-view
enable-flex
scroll-x
class="scroll-box flex"
>
<template v-if="type === 0">
<view
v-for="(item,index) in recommendInfo.hotelList"
:key="index"
class="item flex-0 flex flex-col jc-between ai-center"
@click="goToStore(item.hotelId || '')"
>
<image
:src="item.hotelImage + (item.hotelImage.indexOf('.mp4') > -1 ? '?vframe/jpg/offset/1' : '')"
class="cover"
mode="scaleToFill"
/>
<image class="logo" :src="item.hotelLogo" mode="scaleToFill" />
<view style="width: 100%;box-sizing: border-box;padding:0 8rpx">
<view class="name tc one-t">{{ item.hotelName }}</view>
<rich-text class="text tc one-t" :nodes="item.hotelText" />
</view>
</view>
</template>
<template v-if="type === 1">
<view
v-for="(item,index) in recommendInfo.productList"
:key="index"
class="item flex-0 flex flex-col jc-between ai-center"
@click="goToGoods(item.productId || '')"
>
<image class="cover" :src="item.productImage" mode="scaleToFill" />
<image class="logo" :src="item.merLogo" mode="scaleToFill" />
<view style="width: 100%">
<view class="name tc one-t">{{ item.productName }}</view>
<rich-text class="text tc one-t" :nodes="item.productText" />
</view>
</view>
</template>
</scroll-view>
</template>
</view>
<view class="red-border-title" style="margin-left: 38rpx;">{{ provinceName }}</view>
<view class="group-list custom-list flex flex-wrap">
<view class="item"
v-for="(item, index) in listCity"
:key="index"
@click="select(item)"
>
<view class="has-goods" v-if="type === 0 && item.hasData === 0">暂无特产</view>
<view class="has-goods" v-if="type > 0 && type < 6 && item.hasShop === 0 && item.hasAncientTown === 0">暂无店铺</view>
<view class="has-goods" v-if="type === 6 && item.hasData === 0">暂无景点</view>
<image :src="item.icon" mode="scaleToFill"></image>
<view class="one-t">{{ item.cityName }}</view>
</view>
</view>
</mescroll-body>
</view>
<FunctionGuide :maxStep="maxStep" @hide="setGuide(pageKeyId)" :guideData="functionGuideData" ref="FunctionGuide"></FunctionGuide>
</view>
</template>
<script>
import MescrollMixins from '@/mixins/mescroll-mixins.js'
import {fetchCity} from '@/api/wenwan'
import MescrollBody from '@/components/mescroll-uni/mescroll-body.vue'
import {getCurAddress, getLocation} from '@/utils/common.js'
import { pageListenMixins } from '@/mixins/pageListenMixins'
import FunctionGuide from '@/components/FunctionGuide'
import GuideMixins from '@/mixins/GuideMixins'
export default {
name: 'ChoseCity',
components: {
MescrollBody,
FunctionGuide
},
mixins: [
MescrollMixins({
getPageData(mescroll) {
mescroll.endSuccess(10)
}
}),
pageListenMixins,
GuideMixins
],
data() {
return {
webUrl: this.$VUE_APP_RESOURCES_URL,
upOption: {
// 如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
noMoreSize: 10,
auto: false,
empty: {
tip: '暂无城市'
}
},
downOption: {
auto: true
},
listGroup: [],
provinceName: '',
listCity: [],
navActive: 0,
keyword: '',
// 0、特产;1、文玩;2、七彩云上;3、特色礼品;4、康养食材;5、千县名品;6、景点门票
type: null,
location: '',
banner: {},
// 推荐信息
recommendInfo: null,
pageKeyId: ''
}
},
computed: {
maxStep() {
const stepsMap = {
0: 1,
1: 2,
}
return stepsMap[this.type] || 1
}
},
onLoad(options) {
const type = Number(options.type)
this.type = type
switch(type) {
case 0:
this.pageKeyId = 'goodsIndex'
break
case 1:
this.pageKeyId = 'wenwanIndex'
break
case 3:
this.pageKeyId = 'customizedGiftIndex'
break
case 4:
this.pageKeyId = 'wellnessFoodIndex'
break
case 5:
this.pageKeyId = 'countyFamousIndex'
break
default:
this.pageKeyId = ''
break
}
this.location = options.city
if (this.location === undefined) {
this.getMapData()
}
this.init()
if([0,1] .includes(type)) {
this.queryGuide(this.pageKeyId)
}
},
methods: {
showFunctionGuide() {
if(this._step == this.functionGuideData.step) return
if(this.functionGuideData.step == 1) {
this._step = this.functionGuideData.step
const imgs = [
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-1.png',
style: {
position: 'absolute',
zIndex: 99,
width: '357rpx',
top: '100rpx',
left: '-110rpx',
right: 0,
margin: 'auto',
height: '382rpx',
/* px: ; */
},
isBtn: false
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-2.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: -120*2+'rpx',
right: 0,
margin: 'auto',
height: '46rpx',
},
isBtn: 'jump'
},
{
url: this.webUrl + '/引导页素材/全国特产/Group 1-3.png',
style: {
position: 'absolute',
zIndex: 99,
width: '117rpx',
top: 125*2+'rpx',
left: 170*2+'rpx',
height: '46rpx',
},
isBtn: 'next'
},
]
this.getElementData('#aside', res=>{
this.setFunctionGuideData({
imgs: imgs,
tipsPosition: '420rpx',
btnGroupPosition: '',
position: {
top: res.top*2 + 'rpx',
left: res.left*2 + 'rpx',
width: `${res.width*2}rpx`,
height: `${res.height*2}rpx`,
}
})
})
return
} else {
if(this.type === 1) {
this.$refs.FunctionGuide.show = false
}
return
}
},
reload() {
uni.getSetting({
success(res) {
if (res.authSetting['scope.userLocation']) {
} else {
uni.showModal({
title: '提示',
content: '当前定位未开启,请点击确定手动开启定位',
duration: 5000,
success(result) {
if (result.confirm) {
uni.openSetting({
success(openRes) {
if (openRes.authSetting['scope.userLocation']) {
} else {
uni.showToast({
title: '你拒绝了授权,无法继续',
icon: 'none'
})
}
}
})
} else if (result.cancel) {
uni.showToast({
title: '你拒绝了授权,无法获取定位信息',
icon: 'none'
})
}
}
})
}
}
})
},
async getMapData() {
const map = await getLocation()
if (map) {
const {latitude, longitude} = map[1]
const address = await getCurAddress(latitude, longitude)
this.location = address[1].data.result.ad_info.city
}
},
init() {
fetchCity(this.type).then(res => {
if (res.success) {
this.listGroup = res.data.group
if (this.listGroup.length > 0) {
this.listCity = this.listGroup[0].city
this.provinceName = this.listGroup[0].label
this.recommendInfo = this.listGroup[0].recommendInfo
this.banner = {
...this.listGroup[0],
icon: this.listGroup[0].icon,
url: this.listGroup[0].uniappUrl
}
}
}
})
},
asideTap(index) {
this.navActive = index
this.listCity = this.listGroup[index].city
this.provinceName = this.listGroup[index].label
this.recommendInfo = this.listGroup[index].recommendInfo
this.banner = {
...this.listGroup[index],
icon: this.listGroup[index].icon,
url: this.listGroup[index].uniappUrl
}
// 触发加载请求
this.mescroll.scrollTo(0, 0)
this.mescroll && this.mescroll.resetUpScroll(false)
},
emptyClick: function () {
//触发加载请求
this.mescroll && this.mescroll.triggerDownScroll()
},
search() {
this.listGroup.findIndex((group, index) => {
let result
group.city.forEach(item => {
result = item.cityName.indexOf(this.keyword, 0)
if (result !== -1) {
this.asideTap(index);
return null;
}
})
if (result !== -1) {
return result
}
})
},
select(item) {
if (this.type === 0 && item.hasData === 0) return
if ((this.type === 1 || this.type === 2) && item.hasShop === 0 && item.hasAncientTown === 0) return
uni.setStorageSync("cityName", item.cityName)
switch (this.type) {
case 0:
uni.navigateTo({
url: `/pkg_product/views/nativeList?cityId=${item.cityId}`
})
break
case 1:
uni.navigateTo({
url: `/wenwan/views/storeList?cityId=${item.cityId}`
})
break
case 6:
uni.navigateTo({
url: `/pkg_product/views/scenicSpot?cityId=${item.cityId}`
})
break
default:
uni.navigateBack()
break
}
},
goToStore(id) {
if (!id) {
return
}
uni.navigateTo({
url: '/pagesInn/inn/innHome?id=' + id + '&from=' + this.getOptionsParams()
})
},
goToGoods(productId) {
if (!productId) {
return
}
uni.navigateTo({
url: `/pages/shop/GoodsCon/index?id=${productId}&from=${this.getOptionsParams()}`
})
},
goToExhibition(linkExhibitionId) {
if (!linkExhibitionId) {
return
}
uni.navigateTo({
url: `/pkg_product/views/expoDetails?id=${linkExhibitionId}&from=${this.getOptionsParams()}`
})
},
getOptionsParams() {
// 0、特产;1、文玩;2、七彩云上;3、特色礼品;4、康养食材;5、千县名品;6、景点门票
let from = ''
switch(this.type) {
case 0:
from = 'techan'
break
case 1:
from = 'wenwan'
break
case 3:
from = 'gift'
break
case 4:
from = 'wellness'
break
case 5:
from = 'famous'
break
default:
from = ''
break
}
return from
},
bannerItemTapHandle(banner) {
if (!banner) {
return
}
const url = banner.url || ''
if (url) {
this.$global.commonJump(url)
} else {
const linkType = banner.linkType
if (linkType > 0) {
switch(linkType) {
case 1:
this.goToStore(banner.linkHotelId)
break
case 2:
this.goToGoods(banner.linkProductId)
break
case 3:
this.goToExhibition(banner.linkExhibitionId)
break
default:
break
}
}
}
}
}
};
</script>
<style scoped lang="less">
.chose-city {
height: 100%;
background: #fff;
color: #033333;
.banner {
width: 520rpx;
height: 200rpx;
vertical-align: middle;
margin: 16rpx auto 0;
border-radius: 8rpx;
}
.custom-list {
.item {
width: 160rpx;
margin-right: 20rpx;
font-size: 24rpx;
image {
width: 160rpx;
height: 160rpx;
border-radius: 8rpx;
vertical-align: middle;
}
.one-t {
margin-top: 14rpx;
line-height: 34rpx;
}
}
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
padding: 16rpx 32rpx 28rpx;
box-sizing: border-box;
background: #fff;
border-bottom: 2rpx solid #E9E9E9;
z-index: 9;
.search-box {
width: 686rpx;
height: 64rpx;
padding: 0 24rpx 0 32rpx;
box-sizing: border-box;
background: #F7F7F7;
border-radius: 32rpx;
input {
width: 560rpx;
font-size: 22rpx;
}
.icon {
width: 40rpx;
height: 40rpx;
}
}
}
.aside {
position: fixed;
width: 161rpx;
left: 0;
top: 110rpx;
bottom: 0 !important;
box-sizing: border-box;
border-right: 2rpx solid #E9E9E9;
background: #fff;
overflow-y: auto;
overflow-x: hidden;
overflow-scrolling: touch;
.item {
width: 100%;
height: 96rpx;
border-bottom: 2rpx solid #E9E9E9;
.name {
font-size: 28rpx;
text-align: center;
}
}
.item.on {
border-left: 6rpx solid #C52733;
.name {
color: #C52733;
font-weight: bold;
}
}
}
.aside::-webkit-scrollbar {
width: 0 !important
}
.content {
margin-left: 161rpx;
margin-top: 110rpx;
.red-border-title {
display: inline-flex;
align-items: center;
box-sizing: border-box;
margin: 18rpx 0;
padding: 8rpx 0 0 8rpx;
border-left: 6rpx solid #C52733;
color: #262626;
font-size: 30rpx;
line-height: 30rpx;
font-weight: bold;
vertical-align: bottom;
}
.fixed-box {
padding: 32rpx 0 0 38rpx;
.line-location {
font-size: 28rpx;
image {
width: 36rpx;
height: 36rpx;
margin-right: 4rpx;
}
}
.top-box {
.tips {
margin: 36rpx 0 20rpx;
font-size: 28rpx;
line-height: 40px;
color: #666666;
}
.top-list {
overflow-x: auto;
}
.top-list::-webkit-scrollbar {
width: 0 !important
}
}
}
.recommendInfo {
position: relative;
margin-left: 38rpx;
.scroll-box {
position: relative;
width: 520rpx;
height: 314rpx;
box-sizing: border-box;
padding: 70rpx 20rpx 0 20rpx;
border-radius: 20rpx;
background-repeat: no-repeat;
background-size: 520rpx 314rpx;
}
.item {
position: relative;
width: 136rpx;
height: 220rpx;
margin-right: 28rpx;
border-radius: 8rpx;
background: linear-gradient(180deg, #08255D 0%, #6FA2FF 100%);
color: #FFFFFF;
line-height: 1;
//overflow: hidden;
image {
vertical-align: middle;
}
.cover {
width: 136rpx;
height: 136rpx;
border-radius: 8rpx;
}
.logo {
position: absolute;
left: 68rpx;
top: 136rpx;
transform: translate(-50%, -50%);
width: 40rpx;
height: 40rpx;
border-radius: 50%;
}
.name {
padding-bottom: 8rpx;
font-size: 22rpx;
line-height: 1.3;
}
.text {
padding-bottom: 8rpx;
font-size: 16rpx;
}
}
.item::after {
content: '';
position: absolute;
right: -14rpx;
top: 26rpx;
width: 2rpx;
height: 172rpx;
background: #D2E0E8;
}
.item:last-child::after{
display: none;
}
}
.province-name {
margin: 0 38rpx 24rpx;
font-size: 28rpx;
line-height: 40rpx;
color: #666666;
}
.group-list {
padding-left: 38rpx;
}
.item {
position: relative;
margin-bottom: 28rpx;
.has-goods {
position: absolute;
right: 0;
top: 0;
padding: 7rpx 8rpx;
border-radius: 0 8px 0 8px;
background: #f66;
color: #fff;
font-size: 24rpx;
line-height: 1;
}
}
}
.bg-custom {
position: absolute;
left: 0;
top: 74rpx;
width: 520rpx;
height: 314rpx;
}
}
</style>