update: 初始化:新疆大屏基础搭建

This commit is contained in:
xf
2025-07-02 13:48:50 +08:00
parent 1cbda373e0
commit ff493d83d9
24 changed files with 1482 additions and 14 deletions
+487
View File
@@ -0,0 +1,487 @@
<template>
<div class="sun-center-map">
<div class="map-box">
<div class="tab-list">
<div v-for="(item, i) in list" :class="[currentIndex == i ? 'active' : '']" class="tab" @click="changeTab(item, i)">
{{ item.name }}
</div>
</div>
<div v-show="currentIndex == list.length - 1" class="route-navigation">
<a-form :model="formState" layout="inline">
<a-form-item class="form-item-self" label="起点">
<a-input v-model:value="formState.start" placeholder="请输入起点"></a-input>
</a-form-item>
<a-form-item class="form-item-self" label="终点">
<a-input v-model:value="formState.end" placeholder="请输入终点"></a-input>
</a-form-item>
<a-form-item>
<a-button class="reset-btn" @click="removeInput">清空</a-button>
<a-button class="search-btn" @click="searchRoute" :loading="searchFlag" :disabled="searchFlag"> 路线规划 </a-button>
</a-form-item>
</a-form>
<div v-show="showRoutePanel" v-click-outside="outClick" class="line-container">
<div v-show="routeList.length" class="has-data">
<div class="line-title"> {{ panelTitle }}</div>
<div class="line-content">
<div class="start">起点</div>
<div class="line-body">
<div class="line"></div>
<div class="line-desc">
<p v-for="(item, i) in routeList" :key="i">{{ item }}</p>
</div>
</div>
<div class="end">终点</div>
</div>
</div>
<div v-show="!routeList.length" class="empty-data"> 暂无数据</div>
</div>
</div>
<div class="map">
<div style="flex: 1; overflow: hidden; margin: 0 0 10px">
<div id="xianmapContainer" class="xianmapContainer"></div>
</div>
</div>
<div v-show="false" id="container"></div>
<div v-show="false" id="panel"></div>
<div class="map-legend">
<div v-for="(item, i) in legendList" :key="i" class="legend-item">
<div :style="{ color: item.color }"><img :src="item.img" alt="" class="legend-img" /> {{ item.text }}</div>
</div>
</div>
</div>
<div class="center-footer" v-if="showFooter">
<div class="count-item">
<div class="num">{{ useDetail?.alerdyreceive || '0' }}</div>
<div class="text">累计受理</div>
</div>
<div class="count-item">
<div class="num">{{ useDetail?.totalacceptance || '0' }}</div>
<div class="text">累计处置</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { tabList, legendList } from '/@/views/indexSun/indexSun.ts';
import { message } from 'ant-design-vue';
import { innerLineLight, outerLineOption } from '/@/assets/mapUtils/mapConstant.ts';
import { Map } from '/@/assets/mapUtils/map.ts';
import { aircraft, getKmStr, getTimeStr, mapApiSwitch, TabType } from '/@/components/xianMap/xianMapHooks.ts';
import { useDetailStore } from '/@/store/modules/detailData.ts';
const list = ref(tabList);
const currentIndex = ref(0);
let searchFlag = ref(false);
const formState = ref({
start: '',
end: '',
});
const props = defineProps({
//是否展示底部统计
showFooter: {
type: Boolean,
default: () => {
return true;
},
},
});
const useDetail = useDetailStore();
const showRoutePanel = ref(false);
const panelTitle = ref();
const level = ref(0);
const routeList = ref([]);
const emits = defineEmits(['clearHospitalList']);
const showDrivingPanel = ref(false);
onMounted(() => {
const op = {
el: 'xianmapContainer',
innerLineOption: innerLineLight,
outerLineOption: outerLineOption,
};
Map.initMap(op).then(() => {
getMapData(tabList[0].type);
Map.map && Map.map.on('zoomend', setLevel);
Map.map && Map.map.on('zoomend', setLevel);
});
});
function setLevel() {
//获取当前地图级别
level.value = Map.map.getZoom();
}
function removeInput() {
formState.value.start = '';
formState.value.end = '';
searchFlag.value = false;
}
function changeTab(item, i: number) {
currentIndex.value = i;
Map.clearActiveHospital();
closeDrivingElement();
Map.map.off('moveend', logMapinfo);
if (TabType.diFangYiYuan == item.type) {
let { lng, lat } = Map.getMapCenter();
Map.getAddressByPoint([lng, lat]).then((text, data) => {
// console.log('data', data, data.citycode);
});
Map.removeOverlayGroup();
Map.map.on('moveend', logMapinfo);
return;
}
if (TabType.zhiShengJi == item.type) {
Map.createAircraft(aircraft);
return;
} else {
getMapData(item.type, { type: item.type });
}
}
function searchRoute(callback: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null) {
showRoutePanel.value = false;
panelTitle.value = '';
if (!formState.value.start) {
return message.warn('请输入起点');
}
if (!formState.value.end) {
return message.warn('请输入终点');
}
searchFlag.value = true;
let map = new AMap.Map('container', {
resizeEnable: true,
center: [116.397428, 39.90923], //地图中心点
zoom: 13, //地图显示的缩放级别
});
let driving = new AMap.Driving({
map: map,
panel: 'panel',
});
driving.search([{ keyword: formState.value.start }, { keyword: formState.value.end }], function (status, result) {
// result 即是对应的驾车导航信息,相关数据结构文档请参考 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DrivingResult
if (status === 'complete') {
// console.log('绘制驾车路线完成');
searchFlag.value = false;
} else {
console.log('获取驾车数据失败:', result);
searchFlag.value = false;
}
});
AMap.Event.addListener(driving, 'complete', (res) => {
const data = JSON.parse(JSON.stringify(res));
searchFlag.value = false;
console.log('查询结果', data);
if (data.info == 'OK') {
const { routes } = data;
setTitle(routes[0]);
let arr = [];
arr.push(data.originName);
routes[0].steps.map((item: any) => {
arr.push(item.instruction);
});
arr.push(data.destinationName);
showRoutePanel.value = true;
routeList.value = arr;
}
});
}
async function getMapData(type, params = {}) {
try {
const { code, result } = await mapApiSwitch(type, params);
if (code == 200) {
if (Array.isArray(result) && result.length > 0) {
Map.createOverlay(
result,
{
content: (val) => {
return `<div style="
width: 21px;
height: 44px;
position: absolute;
left: -20px;
top: -20px;" title="${val?.name}">
</div>`;
},
},
() => {},
true
);
} else {
Map.removeOverlayGroup();
}
}
} catch (e) {
console.warn(e);
}
}
function closeDrivingElement() {
Map.clearNavigationElements();
formState.value.start = '';
formState.value.end = '';
showDrivingPanel.value = false;
emits('clearHospitalList');
}
function setTitle({ time, distance }) {
let str = '全程';
str += getTimeStr(time);
str += getKmStr(distance);
panelTitle.value = str;
}
function outClick() {
showRoutePanel.value = false;
}
const currentCityCode = ref('');
function logMapinfo() {
Map.map.getCity(function (info) {
const { citycode } = info;
if (currentCityCode.value != citycode) {
Map.createActiveHospital(citycode);
currentCityCode.value = citycode;
}
});
}
</script>
<style lang="less" scoped>
.sun-center-map {
flex: 1;
color: #fff;
display: flex;
flex-direction: column;
align-content: space-between;
position: relative;
.map-box {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
.tab-list {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
font-size: 16px;
letter-spacing: 1px;
.tab {
width: calc(100% / 8);
height: 40px;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
background: #082147;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s;
&.active {
color: #00ccff;
background: #073063;
font-weight: bold;
}
}
}
.route-navigation {
--fontColor: #607ddb;
margin: 12px 0;
width: 100%;
height: 46px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 6px;
position: absolute;
top: 36px;
z-index: 999;
transition: all 0.3s;
:deep(.form-item-self) {
label {
color: var(--fontColor) !important;
}
.ant-input {
width: 280px;
border-radius: 2px 2px 2px 2px;
color: var(--fontColor);
background: #d7ddf6;
border: 1px solid #a8bcff;
&::placeholder {
color: var(--fontColor);
}
}
}
.reset-btn {
width: 64px;
height: 32px;
border-radius: 5px;
color: var(--fontColor);
background: #c7d4ff;
border: 1px solid #7092ff;
}
.search-btn {
margin-left: 10px;
width: 120px;
height: 32px;
color: #fff;
background: #6d8bf1;
border-radius: 5px;
}
.line-container {
position: absolute;
right: 0;
top: 54px;
width: 288px;
padding: 9px 18px;
min-height: 200px;
max-height: 473px;
overflow: auto;
background: rgba(0, 0, 0, 0.7);
border-radius: 2px;
//border: 1px solid #1b7ef2;
.line-title {
margin-bottom: 9px;
font-size: 14px;
font-weight: 700;
color: var(--cardFontColor);
}
.line-content {
font-size: 12px;
color: var(--cardFontColor);
.start {
display: flex;
align-items: center;
&::before {
content: '起';
color: var(--cardFontFFF);
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--circelBg);
}
}
.end {
display: flex;
align-items: center;
&::before {
content: '终';
color: var(--cardFontFFF);
width: 20px;
height: 20px;
margin-right: 7px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
background: var(--circelBg);
}
}
.line-body {
display: flex;
color: var(--cardFontColor);
}
.line {
width: 1px;
background-color: var(--circelBg);
margin: 5px 19px 5px 8px;
}
.line-desc {
flex: 1;
}
}
.empty-data {
margin-top: 30%;
text-align: center;
}
}
}
.map {
display: flex;
flex: 1;
.xianmapContainer {
flex: 1;
height: calc(100% + 22px);
margin: 10px 0;
}
}
.map-legend {
position: absolute;
bottom: 20px;
left: 10px;
padding: 0 20px 0 10px;
display: flex;
border-radius: 6px;
flex-direction: column;
.legend-item {
width: 100%;
font-size: 14px;
font-weight: 400;
margin: 5px 0;
color: #607ddb;
letter-spacing: 2px;
.legend-img {
width: 20px;
margin-right: 5px;
}
}
}
}
.center-footer {
position: absolute;
left: 50%;
bottom: 20px;
transform: translateX(-50%);
display: flex;
justify-content: center;
margin-bottom: 10px;
gap: 20px;
> :nth-child(1) {
background: url('/@/assets/indexSun/footerBlue.png') no-repeat;
background-size: 100% 100%;
color: #22e8ff;
margin-right: 80px;
}
> :nth-child(2) {
background: url('/@/assets/indexSun/footerGreen.png') no-repeat;
background-size: 100% 100%;
color: #45ffa1;
}
.count-item {
width: 240px;
height: 120px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
//background: url('/@/assets/images/footer-num.png') no-repeat;
//border-radius: 14px;
.num {
font-size: 24px;
font-weight: 700;
}
.text {
font-size: 16px;
font-weight: 400;
}
}
}
}
</style>