翠屏区智慧广电示范区
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

882 lines
30 KiB

<template>
<!-- 全域旅游 -->
<div class="eb-container" ref="appRef">
<MainTitle class="title" :title="title"></MainTitle>
<gis-map
ref="gisMapRef"
class="gismap"
pointType="全域旅游"
:point-list="dataList"
@currentPoint="currentPointFn"
:lngLat="lngLat"
list-item-key="name"
>
<template v-slot:content>
<div class="center-window">
<div
class="top-title"
v-for="(item, index) in iconList"
@click="changeType(item, index)"
>
<img :src="item.icon"/>
<div class="text">
<p class="text-name">{{ item.label }}</p>
<p class="text-type">
<CountTo
:startVal="0"
:endVal="item.count"
:duration="2000"
/>
</p>
</div>
</div>
</div>
<div class="travel-content" v-if="travleListLoading">
<div class="title-box-samll">
<span>旅游资源</span>
</div>
<div class="content-info">
<div class="content-inof-list">
<div
class="content-info-item"
v-for="(item, index) in travleList"
:key="index"
@click="selectTravelInfoById(item.id, item)"
>
<div
class="content-info-item-title"
style="font-size: 20px; color: #fff"
>
{{ item.name }}
</div>
</div>
</div>
</div>
</div>
<div class="detail-content" v-if="detailInfoLoading">
<div class="title-box-samll">
<span>{{ boxTitle }}</span>
</div>
<div class="content-info">
<!-- title -->
<div class="content-info-title">
<span
style="
font-size: 24px;
color: #fff;
font-weight: bold;
"
>{{ detailInfo.name }}</span
>
<span style="font-size: 18px; color: #c9c9c9">{{
typeList[detailInfo.type]
}}</span>
</div>
<!-- content -->
<div
class="content-info-content"
style="margin-top: 20px"
>
<span style="font-size: 24px; color: #fff"
>基础信息</span
>
<div style="margin-top: 10px" v-if="detailInfo.address">
<span style="font-size: 18px; color: #c9c9c9"
>地址:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.address
}}</span>
</div>
<!-- 工作时间 -->
<div style="margin-top: 10px" v-if="detailInfo.openHours">
<span style="font-size: 18px; color: #c9c9c9"
>工作时间:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.openHours
}}</span>
</div>
<!-- 简介 -->
<div style="margin-top: 10px" v-if="detailInfo.remark">
<span style="font-size: 18px; color: #c9c9c9"
>简介:
</span>
<span style="font-size: 18px; color: #fff">{{
detailInfo.remark
}}</span>
</div>
<!-- 图片 -->
<div style="margin-top: 10px" v-if="detailInfo.coverImage">
<span style="font-size: 18px; color: #c9c9c9"
>图片:
</span>
<img
:src="detailInfo.coverImage"
alt=""
style="width: 100%; height: 200px"
/>
</div>
<div
style="
display: flex;
align-items: center;
margin-top: 20px;
"
>
<Button
type="text"
class="text-button"
@click="
openLineOrPlayAudio(detailInfo.type)
"
>
{{
detailInfo.type == 4
? "播放音频"
: detailInfo.type == "2"
? "查看路线"
: ""
}}
</Button>
<!-- 音频播放 -->
<audio
ref="audioRef"
class="audio-controls"
v-if="detailInfo.type == 4"
:src="detailInfo.audioList"
controls
></audio>
</div>
</div>
</div>
</div>
</template>
</gis-map>
<div class="page-bottom-bg"></div>
<div class="page-left-bg"></div>
<div class="page-right-bg"></div>
<commonModal v-model="lineVisible" title="相关路线" width="600">
<div class="line-box">
<div
class="line-item"
v-for="(item, index) in lineList"
@click="openLine(item)"
:key="index"
>
<span class="line-title"
>线路名称:{{ item.lineName }}</span
>
<div class="line-content">
<span>线路途经{{ item.lineText }}</span>
</div>
</div>
</div>
</commonModal>
</div>
</template>
<script>
import {useIndex} from "../../utils/utilsDramAdmin";
import MainTitle from "./components/MainTitle.vue";
import gisMap from "./components/gisMapOfCounty.vue";
import commonModal from "@/views/common-components/common-modal.vue";
export default {
name: "GlobalTravel",
components: {MainTitle, gisMap, commonModal},
data() {
return {
title: "全域旅游",
boxTitle: "资源详情",
columns: [
// 序号
{
title: "序号",
type: "index",
width: 80,
align: "center",
},
// 选择
{
title: "选择",
type: "selection",
width: 80,
align: "center",
},
// 路线名称
{
title: "路线名称",
key: "lineName",
align: "center",
},
// 路线描述
{
title: "路线描述",
key: "intro",
align: "center",
},
],
lineList: [],
lineVisible: false,
// 1、住宿 2、景点 3、美食 4、讲解 5、商店 6、卫生间 7、 停车场 8、游客服务
typeList: {
1: "住宿",
2: "景点",
3: "美食",
4: "讲解",
5: "商店",
6: "卫生间",
7: "停车场",
8: "游客服务",
},
type: "",
iconList: [
// 1、酒店 2、景区 3、饭店 4、讲解 5、服务区 6、设备设施
{icon: require("@/assets/mapIcon/jd.png"), label: "住宿", count: 0, type: "1"},
{icon: require("@/assets/mapIcon/jq.png"), label: "景点", count: 0, type: "2"},
{icon: require("@/assets/mapIcon/fd.png"), label: "美食", count: 0, type: "3"},
{icon: require("@/assets/mapIcon/jj.png"), label: "讲解", count: 0, type: "4"},
{icon: require("@/assets/mapIcon/sd.png"), label: "商店", count: 0, type: "5"},
{icon: require("@/assets/mapIcon/wsj.png"), label: "卫生间", count: 0, type: "6"},
{icon: require("@/assets/mapIcon/fwq.png"), label: "停车场", count: 0, type: "7"},
{icon: require("@/assets/mapIcon/ykzx.png"), label: "游客服务", count: 0, type: "8"},
],
travleList: [],
detailInfo: {},
travleListLoading: false,
detailInfoLoading: false,
clickNode: null,
lngLat: [],
dataList: [],
selection: [],
driving: null,
lngList: [],
trimmedLngList: [],
};
},
computed: {},
created() {
},
mounted() {
const {calcRate, windowDraw} = useIndex(this.$refs.appRef);
calcRate();
windowDraw();
this.$nextTick(() => {
this.queryTravelInfoPage();
});
// this.getIconList();
},
beforeDestroy() {
},
methods: {
selectTravelLineById(id, index) {
this.$http
.post(
"/travel/selectTravelLineById",
this.common.request({id})
)
.then((res) => {
if (res.data.code == 200 && res.data.data) {
this.lineList[index].linePoint =
res.data.data.travelInfoList;
this.lineList[index].lineText =
res.data.data.travelInfoList
.map((item) => item.name)
.join("-");
this.$set(this.lineList, index, {
...this.lineList[index],
lineText: res.data.data.travelInfoList
.map((item) => item.name)
.join("-"),
});
}
});
},
changeType(item, index) {
this.type = item.type;
this.queryTravelInfoPage();
},
async initLine(lngList) {
console.log(lngList);
let _this = this.$refs.gisMapRef;
// 清除上一次路线
if (this.driving != null) {
this.driving.clear();
_this.map.clearMap();
}
this.driving = new AMap.Driving({
map: _this.map,
hideMarkers: true,
});
this.trimmedLngList = [];
// this.dataList.forEach((v, i) => {
// lngList.push(v.lnglat);
// });
// 去掉第一个和最后一个元素
if (lngList.length >= 2) {
this.trimmedLngList = lngList.slice(1, -1);
}
let lngLength = lngList.length;
// 根据起终点经纬度规划驾车导航路线
try {
const result = await new Promise((resolve, reject) => {
this.driving.search(
lngList[0],
lngList[lngLength - 1],
{waypoints: this.trimmedLngList},
(status, result) => {
console.log(status, "status");
if (status === "complete") {
const {routes = []} = result;
const {steps = []} = routes[0];
const pathArr = [];
steps.map((i) => {
pathArr.push(i.path);
return pathArr;
});
// 红色路线绘制红色轨迹
let strokeColor = "#04be02";
// 绘制轨迹
const polyline = new window.AMap.Polyline({
map: _this.map,
path: pathArr,
showDir: true,
strokeColor: strokeColor, // 线颜色
strokeOpacity: 1, // 线透明度
strokeWeight: 10, // 线宽
strokeStyle: "solid", // 线样式
lineJoin: "round", // 折线拐点的绘制样式
zIndex: 999,
});
polyline.setMap(_this.map);
resolve(result);
} else {
reject(new Error("获取行车路线失败"));
}
}
);
});
// 这里处理驾车导航信息
console.log(result);
// 创建起点和终点的标记
// const startPointIcon = new AMap.Icon({
// image: startImg, // 替换为您的起点图标URL
// imageSize: new AMap.Size(46, 46),
// offset: new AMap.Pixel(-23, -46),
// });
// const endPointIcon = new AMap.Icon({
// image: endImg, // 替换为您的终点图标URL
// imageSize: new AMap.Size(46, 46),
// offset: new AMap.Pixel(-64, -128),
// });
// const startMarker = new AMap.Marker({
// position: _lngList[0],
// icon: startPointIcon,
// offset: new AMap.Pixel(-23, -46),
// map: _this.map,
// });
// const endMarker = new AMap.Marker({
// position: _lngList[_lngList.length - 1],
// icon: endPointIcon,
// offset: new AMap.Pixel(-23, -46),
// map: _this.map,
// });
} catch (error) {
console.error(error);
}
},
openLine(item) {
this.dataList = item.linePoint.map((el) => {
el.lnglat = [el.lng, el.lat];
return el;
});
let list = item.linePoint.map((el) => [el.lng, el.lat]);
this.lineVisible = false;
this.initLine(list);
},
getLineList(id) {
this.$http
.post(
"/travel/queryTravelLinePage",
this.common.request({
travelId: id,
pageNum: 1,
pageSize: 10,
})
)
.then((res) => {
if (res.data.code == 200) {
this.lineList = res.data.data.records;
this.lineVisible = true;
this.lineList.forEach((item, index) => {
this.selectTravelLineById(item.id, index);
});
}
});
},
openLineOrPlayAudio(type) {
if (type == 4) {
this.$refs.audioRef.play();
} else if (type == 2) {
this.boxTitle = "旅游线路";
this.getLineList(this.detailInfo.id);
}
},
assembleData(data) {
let list = [];
if (data && data.length > 0) {
data.forEach((item) => {
if (item.children && item.children.length > 0) {
this.assembleData(item.children);
} else {
let dataItem = {...item};
dataItem.lnglat = [item.lng, item.lat];
try {
dataItem.imageList = eval(dataItem.imageList);
} catch (err) {
dataItem.imageList = [];
}
list.push(dataItem);
}
});
}
return list;
},
currentPointFn(data) {
this.clickNode = data;
this.detailInfo = data;
this.detailInfoLoading = false;
setTimeout(() => {
this.detailInfoLoading = true;
}, 100);
},
// getIconList() {
// this.$http.post("/travel/analysisTravelInfo", this.common.request()).then(res => {
// if (res.data.code == 200) {
// this.iconList = this.iconList.map(item => {
// return {
// ...item,
// count: res.data.data[item.name],
// };
// })
// }
// });
// },
selectTravelInfoById(id, item) {
// this.lngLat = [item.longitude, item.latitude];
if (this.driving != null) {
this.driving.clear();
this.$refs.gisMapRef.map.clearMap();
}
this.detailInfoLoading = false;
this.$http
.post(
"/travel/selectTravelInfoById",
this.common.request({id})
)
.then((res) => {
if (res.data.code == 200) {
this.detailInfo = res.data.data;
this.detailInfoLoading = true;
}
});
},
queryTravelInfoPage() {
if (this.driving != null) {
this.driving.clear();
this.$refs.gisMapRef.map.clearMap();
}
const params = {
pageNum: 1,
pageSize: 10000,
type: this.type,
};
this.travleListLoading = false;
this.detailInfoLoading = false;
this.$http
.post(
"/travel/queryTravelInfoPage",
this.common.request(params)
)
.then((res) => {
if (res.data.code == 200) {
this.travleList = this.assembleData(
res.data.data.records
);
if (!this.type) {
this.iconList.forEach((item) => {
let list = this.travleList.filter((element) => {
if (item.type == element.type) {
return true;
}
});
item.count = list.length;
});
}
this.travleListLoading = true;
this.dataList = this.travleList;
this.detailInfo = {};
this.$http
.post(
"/travel/selectTravelInfoById",
this.common.request({
id: this.travleList[0].id,
})
)
.then((res) => {
if (res.data.code == 200) {
this.detailInfo = res.data.data;
this.detailInfoLoading = true;
}
});
}
});
},
},
};
</script>
<style lang="less" scoped>
@import "../../styles/pbStyle.less";
.eb-container {
width: 1920px;
height: 1080px;
overflow-x: hidden;
transform: scale(var(--scale)) translate(-50%, -50%);
transform-origin: 0 0;
position: absolute;
left: 50%;
top: 50%;
background-image: url("../../assets/largeScreen/page-bg.png");
background-size: 100%;
.travel-content {
position: fixed;
top: 100px;
left: 50px;
width: 458px;
height: 920px;
.content-info {
.content-pub-style(100%, calc(100% - 44px));
.content-info-header {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
padding: 10px 10px;
box-sizing: border-box;
gap: 10px;
}
.content-inof-list {
display: flex;
flex-direction: column;
gap: 10px;
padding: 10px 10px;
box-sizing: border-box;
overflow-y: scroll;
height: 100%;
scroll-behavior: smooth;
&::-webkit-scrollbar {
width: 5px;
}
.content-info-item {
width: 100%;
height: 50px;
background: url("../../assets/largeScreen/list-item-bg.png") no-repeat;
background-size: 100% 100%;
display: flex;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
cursor: pointer;
padding: 20px;
box-sizing: border-box;
border-radius: 5px;
box-shadow: 0.5px 1px 1.5px #293240;
transition: all 0.1s ease-in-out;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
&:hover {
background-image: linear-gradient(90deg,
#12181f 0%,
#293240 100%);
}
}
}
}
}
.detail-content {
position: fixed;
top: 100px;
right: 50px;
width: 458px;
height: 920px;
.content-info {
.content-pub-style(100%, calc(100% - 44px));
padding: 10px 20px;
box-sizing: border-box;
.content-info-title {
display: flex;
flex-direction: column;
gap: 10px;
}
.text-button {
font-size: 18px;
color: #fff;
// 下划线
text-decoration: underline;
transition: all 0.2s ease-in-out;
text-underline-offset: 5px;
&:hover {
// 浅蓝色
color: #00bfff !important;
}
}
.line-item {
width: 100%;
height: 140px;
border-radius: 8px;
background: linear-gradient(180deg,
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px;
.line-title {
font-family: ShiShangZhongHeiJianTi;
font-size: 18px;
font-weight: 400;
text-align: left;
background: linear-gradient(to top, #bde1ef, #ffffff);
-webkit-background-clip: text;
color: transparent;
}
.line-content {
display: flex;
align-items: center;
flex-wrap: wrap;
span {
font-family: ShiShangZhongHeiJianTi;
font-size: 18px;
font-weight: 400;
text-align: left;
background: linear-gradient(to top, #bde1ef, #ffffff);
-webkit-background-clip: text;
color: transparent;
}
}
}
}
}
.center-window {
width: 800px;
height: 82px;
position: fixed;
top: 122px;
left: 50%;
transform: translateX(-50%);
font-family: "PingFang SC";
display: flex;
flex-wrap: wrap;
.top-title {
width: 120px;
height: 56px;
display: flex;
align-items: center;
margin-right: 10px;
margin-bottom: 10px;
color: #fff;
cursor: pointer;
img {
width: 30px;
height: 45px;
}
.text {
flex: 1;
margin-left: 6px;
.text-name {
width: 80px;
font-size: 16px;
display: inline-block;
overflow: hidden; /*超出部分隐藏*/
white-space: nowrap; /*禁止换行*/
text-overflow: ellipsis; /*省略号*/
}
.text-type {
font-family: Furore;
font-size: 24px;
}
}
}
}
}
.audio-controls {
width: 80%;
height: 40px;
background-color: transparent;
}
@keyframes slideLeftIn {
from {
transform: translateX(-100%);
}
to {
transform: translateX(0);
}
}
@keyframes slideRightIn {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
.travel-content {
animation: slideLeftIn 1s forwards;
}
.detail-content {
animation: slideRightIn 1s forwards;
}
.line-box {
width: 100%;
display: flex;
flex-direction: column;
.line-item {
width: 100%;
height: 140px;
border-radius: 8px;
background: linear-gradient(180deg,
rgba(0, 125, 165, 0.24) 0%,
rgba(1, 10, 43, 0) 100%);
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px;
cursor: pointer;
&:hover {
background-image: linear-gradient(90deg, #12181f 0%, #293240 100%);
}
.line-title {
font-family: ShiShangZhongHeiJianTi;
font-size: 18px;
font-weight: 400;
text-align: left;
background: linear-gradient(to top, #bde1ef, #ffffff);
-webkit-background-clip: text;
color: transparent;
}
.line-content {
display: flex;
align-items: center;
flex-wrap: wrap;
span {
font-family: ShiShangZhongHeiJianTi;
font-size: 18px;
font-weight: 400;
text-align: left;
background: linear-gradient(to top, #bde1ef, #ffffff);
-webkit-background-clip: text;
color: transparent;
}
}
}
}
/deep/ .ivu-select-input {
background-color: #262b32;
color: #fff;
border: 1px solid #262b32;
}
/deep/ .ivu-select-dropdown {
background-color: #262b32;
color: #fff;
}
/deep/ .ivu-select-item {
color: #fff;
transition: all 0.1s ease-in-out;
&:hover {
background-color: #3a3a3a !important;
}
}
/deep/ .ivu-modal-content {
background-image: linear-gradient(90deg, #293240 0%, #12181f 100%);
}
/deep/ .ivu-table th {
background-color: #262e36;
color: #fff;
}
/deep/ .ivu-table td {
background-color: #262e36;
color: #fff;
}
/deep/ .ivu-modal-header-inner {
color: #fff !important;
}
/deep/ .ivu-modal-footer {
border-top: none;
}
/deep/ .ivu-modal-header {
border-bottom: none;
}
</style>