roamfuding-xcx/page_fenbao/gonglue/gongluexq.vue

388 lines
17 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="page">
<u-navbar title="攻略详情" :border-bottom="false" :background="bgc" back-icon-color="#262B37" title-color='#262B37'
title-size='36' height='40' id="navbar">
</u-navbar>
<!-- 顶部大图 -->
<view class="hero">
<image class="hero-img" :src="globj.photo" mode="aspectFill" style="width: 100%; height: 420rpx;"></image>
</view>
<!-- 基本信息 -->
<view class="base-info">
<view class="title-row">
<view class="left">
<view class="name">{{globj.areaName}}</view>
<view class="meta">{{globj.areaAddress == null ? '--' : globj.areaAddress}}</view>
</view>
<view class="actions">
<image @click="btntel" src="https://api.ccttiot.com/smartmeter/img/static/uFSDCjc5wPk8Wq9XSyr4" style="width: 40rpx;height: 40rpx;" mode=""></image>
<image @click="btndh" src="https://api.ccttiot.com/smartmeter/img/static/uFDC6JRPVkfL2PYrRlz0" style="width: 54rpx;height: 52rpx;" mode=""></image>
</view>
</view>
</view>
<!-- 小节景区简介 -->
<view class="section-block" @click="btnjieshao">
<view class="section-hd"><text class="dot"></text><text class="txt">景区简介</text><text class="more">更多介绍</text> <image style="width: 32rpx;height: 32rpx;" src="https://api.ccttiot.com/smartmeter/img/static/uiUIIoq5dM91HwG6ifIS" mode=""></image> </view>
<view class="para">
{{globj.description}}
</view>
</view>
<!-- 小节核心景点 -->
<view class="section-block" style="padding-bottom: 0;" v-if="globj.coreSpots.length > 0">
<view class="section-hd"><text class="dot"></text><text class="txt">核心景点</text></view>
<view class="thumbs">
<view class="thumb-item" v-for="(item,index) in globj.coreSpots">
<image :src="item.picture" mode="aspectFill" class="thumb-img" style="width: 204rpx; height: 204rpx;"></image>
<view class="thumb-name">{{item.name}}</view>
</view>
</view>
</view>
<!-- 小节:行程概览 -->
<view class="section-block">
<view class="section-hd"><text class="dot"></text><text class="txt">行程概览</text></view>
<view class="facts list">
<view class="fact"> <image src="https://api.ccttiot.com/smartmeter/img/static/unOeWhbxfVsgh2jXJ0si" mode=""></image> <text class="f-t">行程天数:{{globj.days}}天</text></view>
<view class="fact"> <image src="https://api.ccttiot.com/smartmeter/img/static/uEz1yLuz7ID5iHVqGnfe" mode=""></image> <text class="f-t">游玩景点:{{globj.spotNum == null ? 0 : globj.spotNum}}个| <text style="margin-right: 6rpx;" v-for="(item,index) in globj.spotNames" :key="index">{{item}}</text> </text></view>
</view>
</view>
<!-- Day tabs绿色下划线 -->
<!-- <view class="day-tabs underline g">
<view class="tab active">第1天</view>
<view class="tab">第2天</view>
</view> -->
<!-- 行程推荐(黑灰系时间轴) -->
<view class="section-block">
<view class="timeline4">
<view class="row" v-for="(day, dIndex) in itinerary" :key="dIndex">
<view class="left">
<view class="n">{{ (dIndex+1).toString().padStart(2,'0') }}</view>
<view class="d">Day</view>
<view class="vl"></view>
</view>
<view class="right">
<view class="poi-card4" v-for="(poi, pIndex) in day.items" :key="pIndex">
<view class="poi-hd"><text class="sq"></text><text class="t">{{ poi.title }}</text></view>
<view class="poi-desc">{{ poi.desc }}</view>
<view class="grid-3">
<image v-for="(img, iidx) in poi.photos" :key="iidx" :src="img" mode="aspectFill" class="gimg" style="width: 200rpx; height: 200rpx;" @click="previewImage(img, poi.photos)" />
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#fff",
},
itinerary: [
{
items: []
},{
items: []
},
],
id:'',
globj:{},
strategyDetails:[],
// 按天数分组的数据对象
groupedStrategyDetails: {}
}
},
onLoad(option) {
this.id = option.id
this.getxq()
},
methods: {
// 点击更多介绍进行跳转
btnjieshao(){
uni.navigateTo({
url:'/page_fenbao/remenxq?id=' + this.globj.areaId
})
},
// 点击拨打电话
btntel(){
uni.makePhoneCall({
phoneNumber: this.globj.areaPhone,
success: function(res) {
console.log('拨打电话成功', res)
},
fail: function(err) {
console.error('拨打电话失败', err)
}
})
},
// 点击进行导航
btndh(){
// 检查坐标数据是否存在
if (!this.globj.areaLat || !this.globj.areaLon) {
uni.showToast({
title: '坐标数据不完整',
icon: 'none',
duration:3000
})
return
}
// 先申请位置权限
uni.getSetting({
success: (res) => {
if (res.authSetting['scope.userLocation'] === false) {
// 用户拒绝了位置权限,引导用户开启
uni.showModal({
title: '位置权限',
content: '需要获取您的位置信息才能进行导航,请在设置中开启位置权限',
confirmText: '去设置',
success: (modalRes) => {
if (modalRes.confirm) {
uni.openSetting()
}
}
})
return
}
// 权限正常,打开地图
this.openMap()
}
})
},
// 打开地图
openMap() {
uni.openLocation({
latitude: parseFloat(this.globj.areaLat), // 确保是数字类型
longitude: parseFloat(this.globj.areaLon), // 确保是数字类型
name: this.globj.areaName || '目的地', // 地点名称
success: function(res) {
console.log('打开地图成功', res);
},
fail: function(err) {
console.error('打开地图失败', err);
uni.showToast({
title: '打开地图失败: ' + (err.errMsg || '未知错误'),
icon: 'none',
duration: 3000
})
}
})
},
// 请求攻略详情
getxq(){
this.$u.get(`/app/strategy/detail/${this.id}?assembleDetail=true`).then((res) => {
if(res.code == 200){
this.globj = res.data
// 按dayNumber分组strategyDetails
this.groupedStrategyDetails = this.groupStrategyDetailsByDay(res.data.strategyDetails)
// 更新itinerary数据使用分组后的数据
this.updateItinerary(this.groupedStrategyDetails)
}
})
},
// 按天数分组策略详情数据
groupStrategyDetailsByDay(strategyDetails) {
const grouped = {}
strategyDetails.forEach(item => {
const dayNumber = item.dayNumber
if (!grouped[dayNumber]) {
grouped[dayNumber] = []
}
grouped[dayNumber].push(item)
})
// 按天数排序
const sortedGrouped = {}
Object.keys(grouped).sort((a, b) => parseInt(a) - parseInt(b)).forEach(dayNumber => {
sortedGrouped[dayNumber] = grouped[dayNumber]
})
return sortedGrouped
},
// 获取指定天数的数据
getDayData(dayNumber) {
return this.groupedStrategyDetails[dayNumber] || []
},
// 获取所有天数
getAllDays() {
return Object.keys(this.groupedStrategyDetails).map(day => parseInt(day)).sort((a, b) => a - b)
},
// 更新itinerary数据
updateItinerary(groupedDetails) {
this.itinerary = Object.keys(groupedDetails).map(dayNumber => {
return {
dayNumber: parseInt(dayNumber),
items: groupedDetails[dayNumber].map(item => ({
title: item.name || '景点',
desc: item.description || '暂无描述',
photos: item.photo ? item.photo.split(',').map(url => url.trim()) : []
}))
}
}).sort((a, b) => a.dayNumber - b.dayNumber)
},
// 预览图片
previewImage(current, urls) {
uni.previewImage({
current: current, // 当前显示图片的http链接
urls: urls, // 需要预览的图片http链接列表
success: function (res) {
console.log('预览图片成功')
},
fail: function (err) {
console.log('预览图片失败', err)
}
})
},
}
}
</script>
<style lang="scss">
page { background: #fff; }
.page { background: #fff; min-height: 100vh; }
/* 顶部大图 */
.hero { width: 100%; height: 420rpx; overflow: hidden; }
.hero-img { width: 100%; height: 100%; }
/* 基本信息 */
.base-info {
padding: 30rpx;
.title-row {
display: flex; align-items: center; justify-content: space-between;
.left {
.name { font-size: 52rpx; font-weight: 700; color: #262B37; }
.meta { margin-top: 8rpx; font-size: 28rpx; color: #3D3D3D; }
}
.actions { display: flex; gap: 30rpx;align-items: center; }
.act { padding: 8rpx 16rpx; border: 1rpx solid #e6e6e6; border-radius: 28rpx; font-size: 28rpx; color: #333; }
}
.tags {
margin-top: 20rpx; display: flex; gap: 16rpx; flex-wrap: wrap;
.tag { padding: 8rpx 18rpx; background: #f6f7f9; color: #555; font-size: 26rpx; border-radius: 28rpx; }
}
.gallery { margin-top: 20rpx; white-space: nowrap; height: 140rpx;
.g-img { width: 200rpx; height: 140rpx; border-radius: 12rpx; margin-right: 16rpx; }
}
}
/* 区块标题 */
.section { padding: 10rpx 30rpx 40rpx; }
.sec-title { font-size: 32rpx; font-weight: 700; color: #262B37; padding: 20rpx 0; }
/* 简介 */
.intro .intro-text { font-size: 26rpx; color: #555; line-height: 1.8; background: #f8f9fb; padding: 28rpx; border-radius: 16rpx; }
/* 精选景点 */
.picks .picks-scroll { white-space: nowrap; }
.pick-item { display: inline-flex; flex-direction: column; margin-right: 20rpx; }
.pick-img { border-radius: 12rpx; }
.pick-name { margin-top: 10rpx; font-size: 26rpx; color: #666; text-align: center; }
/* 行程概览 */
.overview .overview-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16rpx; }
.ov-item { background: #f6f7f9; border-radius: 12rpx; padding: 18rpx; }
.ov-k { font-size: 26rpx; color: #7a7f8a; }
.ov-v { margin-top: 6rpx; font-size: 28rpx; color: #262B37; font-weight: 600; }
/* Day tabs */
.day-tabs { display: flex; gap: 20rpx; padding-top: 0; }
.day-tabs .tab { padding: 10rpx 26rpx; border-radius: 999rpx; background: #f2fbf6; color: #20b26b; font-size: 28rpx; }
.day-tabs .tab.active { background: #20b26b; color: #fff; }
/* 时间轴 */
.timeline { position: relative; }
.day-block { position: relative; padding-left: 90rpx; }
.day-block:before { content: ''; position: absolute; left: 40rpx; top: 0; bottom: 0; width: 2rpx; background: #e0f3e9; }
.day-head { display: flex; align-items: center; margin: 10rpx 0 20rpx; }
.day-num { width: 64rpx; height: 64rpx; border-radius: 8rpx; background: #20b26b; color: #fff; display: flex; flex-direction: column; align-items: center; justify-content: center; position: absolute; left: 8rpx; box-shadow: 0 4rpx 12rpx rgba(32,178,107,0.3); }
.day-num .big { font-size: 26rpx; line-height: 26rpx; }
.day-num .small { font-size: 18rpx; opacity: 0.9; }
.day-text { margin-left: 10rpx; }
.d-title { font-size: 30rpx; font-weight: 600; color: #262B37; }
.d-sub { font-size: 28rpx; color: #7a7f8a; margin-top: 6rpx; }
.day-list { display: flex; flex-direction: column; gap: 26rpx; margin-bottom: 36rpx; }
.poi { display: flex; gap: 16rpx; position: relative; }
.poi-icon { position: absolute; left: 18rpx; top: 18rpx; font-size: 26rpx; color: #20b26b; }
.poi-card { flex: 1; background: #fff; border-radius: 16rpx; padding: 20rpx; box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.06); }
.poi-title { font-size: 28rpx; font-weight: 600; color: #262B37; }
.poi-desc { margin-top: 8rpx; font-size: 28rpx; color: #666; line-height: 1.6; }
.poi-photos { margin-top: 12rpx; display: grid; grid-template-columns: repeat(3, 1fr); gap: 12rpx; }
.pimg { width: 100%; height: 160rpx; border-radius: 10rpx; }
/* 信息卡 */
.info-card { padding: 18rpx 26rpx; background: #fff; border-radius: 16rpx; margin: -40rpx 20rpx 6rpx; box-shadow: 0 6rpx 18rpx rgba(0,0,0,0.06); border: 2rpx solid #eef0f3; }
.info-card.float { position: relative; z-index: 2; }
.title-wrap { display: flex; justify-content: space-between; align-items: center; }
.title-left .cn { font-size: 32rpx; font-weight: 800; color: #1f2a37; }
.title-left .en { margin-top: 6rpx; font-size: 20rpx; color: #9aa4b2; letter-spacing: 2rpx; }
.title-left .sub { margin-top: 8rpx; font-size: 26rpx; color: #8a949e; }
.title-right { display: flex; gap: 12rpx; }
.ic { width: 48rpx; height: 48rpx; border-radius: 10rpx; background: #f3f4f6; border: 2rpx solid #eef0f3; display: flex; align-items: center; justify-content: center; color: #374151; }
/* 小节标题 */
.section-block { padding: 10rpx 20rpx 20rpx; }
.section-hd { display: flex; align-items: center; gap: 12rpx; margin: 18rpx 2rpx; }
.section-hd .dot { width: 8rpx; height: 28rpx; background: #111827; border-radius: 4rpx; }
.section-hd .txt { font-size: 36rpx; font-weight: 800; color: #111827; }
.section-hd .more { margin-left: auto; font-size: 26rpx; color: #3D3D3D; }
.para { font-size: 28rpx; color: #4b5563; line-height: 1.8; }
/* 精选景点 */
.thumbs { display: flex; gap: 16rpx; overflow: scroll;padding-bottom: 20rpx;}
.thumb-item { width: 210rpx; }
.thumb-img { border-radius: 12rpx; border: 2rpx solid #eef0f3; }
.thumb-name { margin-top: 8rpx; text-align: center; color: #6b7280; font-size: 26rpx; }
/* 行程概览 */
.kv-row { display: flex; align-items: center; background: #f1f6ff; border-radius: 12rpx; padding: 16rpx; margin-bottom: 10rpx; border: 2rpx solid #cfe0ff; }
.kv { flex: 1; display: flex; justify-content: space-between; align-items: baseline; }
.k { font-size: 26rpx; color: #6f7c96; }
.v { font-size: 26rpx; color: #24324a; font-weight: 700; }
.divider { width: 1rpx; height: 28rpx; background: #ccd9f5; margin: 0 16rpx; }
.facts { margin-top: 10rpx; display: grid; grid-template-columns: 1fr; gap: 10rpx; }
.fact { display: flex; align-items: center; gap: 10rpx; color: #405072; font-size: 28rpx; }
.fact image{ width: 28rpx; height: 28rpx; }
.f-ic { color: #3a6fd9; }
/* Day tabs 下划线风格 */
.day-tabs.underline { display: flex; gap: 40rpx; padding: 4rpx 26rpx 8rpx; }
.day-tabs.underline .tab { font-size: 26rpx; color: #6f7c96; padding-bottom: 10rpx; }
.day-tabs.underline .tab.active { color: #24324a; font-weight: 700; border-bottom: 4rpx solid #3a6fd9; }
/* 新版时间轴蓝色 */
.timeline3 { padding-top: 8rpx; }
.timeline3 .row { display: flex; }
.timeline3 .left { width: 120rpx; align-items: center; display: flex; flex-direction: column; }
.timeline3 .n { font-size: 40rpx; font-weight: 800; color: #3a6fd9; }
.timeline3 .d { font-size: 20rpx; color: #3a6fd9; margin-top: -6rpx; }
.timeline3 .vl { width: 2rpx; flex: 1; background: #d7e6ff; margin-top: 12rpx; }
.timeline3 .right { flex: 1; padding-bottom: 26rpx; }
.rt-title { font-size: 28rpx; font-weight: 800; color: #24324a; }
.rt-sub { font-size: 28rpx; color: #6f7c96; margin-top: 6rpx; }
.poi-card3 { margin-top: 18rpx; background: #fff; border-radius: 12rpx; padding: 18rpx; box-shadow: 0 4rpx 14rpx rgba(0,0,0,0.06); border: 2rpx solid #e6efff; }
.poi-hd { display: flex; align-items: center; gap: 10rpx; }
.poi-hd .sq { width: 16rpx; height: 16rpx; background: #3a6fd9; border-radius: 4rpx; }
.poi-hd .t { font-size: 32rpx; font-weight: 700; color: #24324a; }
.poi-desc { margin-top: 6rpx; font-size: 28rpx; color: #56617a; line-height: 1.8; }
.grid-3 { margin-top: 12rpx; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10rpx; }
.gimg { border-radius: 10rpx; border: 2rpx solid #e6efff; }
/* 行程概览四行列表 */
.list { display: flex; flex-direction: column; gap: 14rpx; }
.fact { display: flex; align-items: center; gap: 12rpx; font-size: 28rpx; color: #4b5563; }
.f-ic { color: #10b981; }
.f-btn { margin-left: auto; font-size: 26rpx; color: #10b981; }
/* Day tabs 绿色下划线 */
.day-tabs.underline.g { display: flex; gap: 40rpx; padding: 6rpx 20rpx 8rpx; }
.day-tabs.underline.g .tab { font-size: 26rpx; color: #6b7280; padding-bottom: 10rpx; }
.day-tabs.underline.g .tab.active { color: #111827; font-weight: 700; border-bottom: 4rpx solid #10b981; }
/* 时间轴黑灰 */
.timeline4 { padding-top: 6rpx; }
.timeline4 .row { display: flex; }
.timeline4 .left { width: 66rpx; align-items: center; display: flex; flex-direction: column; }
.timeline4 .n { font-size: 40rpx; font-weight: 800; color: #111827; }
.timeline4 .d { font-size: 20rpx; color: #6b7280; margin-top: -6rpx; }
.timeline4 .vl { width: 2rpx; flex: 1; background: #e5e7eb; margin-top: 12rpx; }
.timeline4 .right { flex: 1; padding-bottom: 26rpx; padding-left: 6rpx; }
.rt-title { font-size: 28rpx; font-weight: 800; color: #111827; }
.rt-sub { font-size: 28rpx; color: #6b7280; margin-top: 6rpx; }
.poi-card4 { margin-top: 18rpx; background: #fff; border-radius: 12rpx; padding: 18rpx; box-shadow: 0 4rpx 14rpx rgba(0,0,0,0.06); border: 2rpx solid #f3f4f6; }
.poi-hd { display: flex; align-items: center; gap: 10rpx; }
.poi-hd .sq { width: 16rpx; height: 16rpx; background: #10b981; border-radius: 4rpx; }
.poi-hd .t { font-size: 32rpx; font-weight: 700; color: #111827; }
.poi-desc { margin-top: 6rpx; font-size: 28rpx; color: #4b5563; line-height: 1.8; }
.grid-3 { margin-top: 12rpx; display: grid; grid-template-columns: repeat(3, 1fr); gap: 10rpx; }
.gimg { border-radius: 10rpx; border: 2rpx solid #f3f4f6; }
</style>