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.

408 lines
9.3 KiB

4 months ago
<template>
3 months ago
<div class="container">
2 months ago
<div class="containertwo">
2 months ago
<!-- 地图区域 -->
2 months ago
<div class="mapareaone">
2 months ago
<!-- 展开/隐藏控制按钮放在盒子右侧外部 -->
<div class="collapse-control" @click="toggleCollapse">
2 months ago
<img v-show="!isCollapsed" src="@/assets/images/icon-sq@2x.png" alt="隐藏" class="control-icon">
<img v-show="isCollapsed" src="@/assets/images/icon-zk@2x.png" alt="展开" class="control-icon">
2 months ago
</div>
2 months ago
2 months ago
<!-- 左侧项目列表区域 -->
<div class="leftdiv" v-show="!isCollapsed">
<!-- 项目列表内容 -->
<div class="mainarea" style="background-color: #FFFFFF;">
2 months ago
<ProjectList />
</div>
</div>
2 months ago
2 months ago
<div class="rightdiv">
<el-input v-model="searchBox" placeholder="请输入地点名称" class="search-input" @input="handleSearchInput" clearable>
<el-button slot="append" icon="el-icon-search" @click="toSearch"></el-button>
</el-input>
</div>
<!-- 搜索结果列表 -->
<div class="search-results" v-if="searchList && searchList.length > 0">
<div class="search-item" v-for="(item, index) in searchList" :key="index" @click="centerMap(item)">
<div class="item-name">{{ item.name }}</div>
</div>
</div>
<!-- 右侧地图区域 -->
<div class="blueicon">
<div class="icondiv" v-if="showLocationIcon">
<img src="@/assets/images/detailsicon/icon-定位@2x.png" alt="定位" :style="iconPosition"
@click.stop="showDialog">
</div>
</div>
</div>
</div>
<!-- 悬浮窗 -->
<div class="app-container" v-show="dialogVisible" v-click-outside="closeDialog">
<div class="close-btn" @click="closeDialog">
<i class="el-icon-close"></i>
</div>
<div class="dialog-content">
<div class="dialog-title">{{ selectedProject.name }}</div>
<div class="dialog-info">
<p><span class="label">状态:</span>
<span class="value" :style="{ color: xzflColors[xzflMap[selectedProject.xzfl]] }">
{{ xzflMap[selectedProject.xzfl] }}
</span>
</p>
<p><span class="label">项目单位:</span> <span class="value">{{ selectedProject.xmfrdwxz }}</span></p>
<p><span class="label">总投资额:</span> <span class="value">{{ selectedProject.ztze }}</span></p>
<p><span class="label">联系人:</span> <span class="value">{{ selectedProject.projectLeader }}</span></p>
<p><span class="label">联系电话:</span><span class="value"> {{ selectedProject.phone }}</span></p>
</div>
2 months ago
</div>
3 months ago
</div>
</div>
4 months ago
</template>
<script>
2 months ago
import ProjectList from '@/views/components/analysis/projectList.vue'
2 months ago
import { getBasicInformationPage } from "@/api/ManageApi/index";
import { debounce } from 'lodash';
// 自定义指令,点击外部关闭弹窗
const clickOutside = {
bind(el, binding, vnode) {
el.clickOutsideEvent = function (event) {
if (!(el === event.target || el.contains(event.target))) {
vnode.context[binding.expression](event);
}
};
document.body.addEventListener('click', el.clickOutsideEvent);
},
unbind(el) {
document.body.removeEventListener('click', el.clickOutsideEvent);
}
};
2 months ago
3 months ago
export default {
2 months ago
components: {
ProjectList,
3 months ago
},
2 months ago
directives: {
'click-outside': clickOutside
},
2 months ago
data() {
return {
2 months ago
isCollapsed: false,
searchBox: '',
searchList: [],
dialogVisible: false,
selectedProject: {
name: '',
xzfl: '',
projectLeader: '',
phone: '',
ztze: '',
xmfrdwxz:''
},
showLocationIcon: false,
iconPosition: {
position: 'absolute',
top: '0px',
left: '0px'
},
hasSearched: false,
// 状态颜色映射
xzflColors: {
'在建': '#6EDABE',
'拟建': '#FFBF6B',
'已建': '#2B62F1'
},
xzflMap: {
1: '已建',
2: '在建',
3: '拟建'
},
};
},
created() {
this.debouncedSearch = debounce(this.toSearch, 300);
2 months ago
},
methods: {
toggleCollapse() {
this.isCollapsed = !this.isCollapsed;
2 months ago
},
handleSearchInput() {
if (this.searchBox.trim() === '') {
this.searchList = [];
this.hasSearched = false;
return;
}
this.debouncedSearch();
},
toSearch() {
if (!this.searchBox.trim()) {
this.searchList = [];
this.hasSearched = true;
return;
}
const params = {
name: this.searchBox,
current: 1,
size: 10
};
getBasicInformationPage(params)
.then(response => {
this.hasSearched = true;
if (response && response.code === 200 && response.data) {
this.searchList = response.data.records;
} else {
this.searchList = [];
}
})
.catch(error => {
console.error('搜索失败:', error);
this.hasSearched = true;
this.searchList = [];
});
},
centerMap(item) {
2 months ago
if (!item.jsdd) {
this.$message.warning('该项目未落图!');
return;
}
2 months ago
2 months ago
this.searchBox = item.name;
this.searchList = [];
this.selectedProject = {
name: item.name,
projectLeader: item.projectLeader || '暂无',
phone: item.phone || '暂无',
ztze: item.ztze || '暂无',
xmfrdwxz: item.xmfrdwxz || '暂无',
xzfl: item.xzfl || '暂无'
};
this.showLocationIcon = true;
this.setRandomIconPosition();
},
2 months ago
showDialog() {
if (this.selectedProject.name) {
this.dialogVisible = true;
} else {
this.$message.warning('请选择一个项目');
}
},
closeDialog() {
this.dialogVisible = false;
},
setRandomIconPosition() {
// icondiv宽9rem(约135px)高9rem(约135px)
// 图标宽1.7rem(约25.5px)高2rem(约30px)
// 计算最大可随机范围
const maxTop = 105; // 135 - 30
const maxLeft = 110; // 135 - 25
const randomTop = Math.floor(Math.random() * maxTop);
const randomLeft = Math.floor(Math.random() * maxLeft);
this.iconPosition = {
position: 'absolute',
top: `${randomTop}px`,
left: `${randomLeft}px`,
cursor: 'pointer'
};
2 months ago
}
}
2 months ago
}
3 months ago
</script>
4 months ago
<style scoped>
2 months ago
/* 原有样式保持不变 */
3 months ago
.container {
2 months ago
position: relative;
3 months ago
}
2 months ago
.containertwo {
position: relative;
3 months ago
}
2 months ago
.mapareaone {
height: 26.5rem;
grid-column: span 2;
3 months ago
width: 100%;
position: relative;
}
2 months ago
/* 控制按钮样式 */
.collapse-control {
position: absolute;
2 months ago
left: -1.5rem;
2 months ago
top: 12.5rem;
width: auto;
height: 2rem;
border-radius: 0 4px 4px 0;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
z-index: 20;
transition: all 0.3s ease;
}
.control-icon {
width: 3.5rem;
height: 3.5rem;
}
.leftdiv {
width: 36%;
height: 27rem;
position: absolute;
left: 0rem;
top: 0rem;
background: #FFFFFF;
border-radius: 0.5rem;
transition: all 0.3s ease;
z-index: 10;
}
.mainarea {
height: 100%;
overflow: auto;
}
2 months ago
.blueicon {
width: 20rem;
height: 20rem;
3 months ago
position: absolute;
2 months ago
background-image: url(../../../assets/images/行政区划@2x.png);
background-repeat: no-repeat;
background-size: 100% 100%;
top: 4.5rem;
right: 7.4rem;
2 months ago
display: flex;
justify-content: center;
align-items: center;
}
.icondiv {
width: 8rem;
height: 8rem;
position: relative;
}
.icondiv img {
width: 1.7rem;
height: 2rem;
transition: all 0.2s ease;
}
.icondiv img:hover {
transform: scale(1.1);
}
.rightdiv {
width: 30%;
position: absolute;
right: 1rem;
top: 1rem;
}
.search-results {
position: absolute;
right: 1rem;
top: 3.5rem;
width: 30%;
background-color: #FFFFFF;
border: 1px solid #E5E5E5;
border-radius: 0.5rem;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 15;
max-height: 15rem;
overflow-y: auto;
}
.search-item {
padding: 0.5rem;
cursor: pointer;
transition: background-color 0.3s ease;
}
.search-item:hover {
background-color: #F2F4F7;
}
.item-name {
/* font-weight: bold; */
margin-bottom: 0.3rem;
}
.item-address {
font-size: 0.88rem;
color: #606266;
}
/* 悬浮div样式 */
.app-container {
position: absolute;
top: 19%;
left: 39%;
height: 17rem;
width: 18rem;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
z-index: 2000;
padding: 15px;
}
.close-btn {
position: absolute;
top: 5px;
right: 5px;
cursor: pointer;
font-size: 16px;
color: #909399;
}
.close-btn:hover {
color: #409EFF;
}
.dialog-content {
height: 100%;
}
.dialog-title {
font-size: 16px;
/* font-weight: bold; */
font-family: aliregular;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #EBEEF5;
/* background-color:#F5F7FA; */
color: #2B62F1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.dialog-info {
font-size: 14px;
color: #606266;
}
.dialog-info p {
margin-bottom: 10px;
}
.label {
color: #9E9E9E;
font-family: aliregular;
width: 3rem;
}
.value{
color: #3D424C;
font-family: aliregular;
4 months ago
}
4 months ago
</style>