update 看板接口对接 增加路由依赖

This commit is contained in:
zk
2023-12-06 16:19:47 +08:00
parent 458009709e
commit 80baa0c7c6
14 changed files with 9540 additions and 28525 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+36
View File
@@ -0,0 +1,36 @@
import { mapIcon1, mapIcon2, mapIcon3, mapIcon4 } from '/@/components/chinaMap/chinaHooks.ts';
/**
* @desc 创建icon
* */
export function createIcon({ icon, iconSize, imageSize }) {
return new AMap.Icon({
// 图标尺寸
size: new AMap.Size(21, 44),
// 图标的取图地址
image: icon,
// 图标所用图片大小
imageSize: new AMap.Size(...imageSize),
});
}
/**
* @desc 根据类型创建Icon
* @type 1:油田医院,2:合作医院,3:医疗点
*/
export function typeToIcon(type: string) {
const iconSize = [21, 44];
const imageSize = [21, 44];
if (type == '1') {
return createIcon({ icon: mapIcon1, iconSize, imageSize });
}
if (type == '2') {
return createIcon({ icon: mapIcon4, iconSize, imageSize });
}
if (type == '3') {
return createIcon({ icon: mapIcon2, iconSize, imageSize });
}
if (type == '4') {
return createIcon({ icon: mapIcon3, iconSize, imageSize });
}
}
+99
View File
@@ -0,0 +1,99 @@
import china from '/@/assets/lngLat/china.ts';
import chinaInner from '/@/assets/lngLat/chinaInner.ts';
import { typeToIcon } from '/@/assets/mapUtils/commonFun.ts';
export const defaultOption = {
center: [106.3, 37.87], //地图中心点
zoom: 4.3, //地图显示的缩放级别
mapStyle: 'darkblue', //地图样式
};
export const mapPlugin = ['AMap.ToolBar', 'AMap.Driving', 'AMap.GeoJSON'];
export const Map = {
map: null,
overlayGroup: null,
initMap({ el, option }) {
const { zoom, center, mapStyle } = { ...defaultOption, ...option };
//基本地图加载
this.map = new AMap.Map(el, {
resizeEnable: true,
center: center,
zoom: zoom,
mapStyle: 'amap://styles/' + mapStyle,
});
// 异步同时加载多个插件
new AMap.plugin(mapPlugin, () => {
this.drawInnerLine();
this.drawOutLine();
});
},
// 中国外层边界线
drawOutLine() {
let geojson = new AMap.GeoJSON({
geoJSON: china,
getPolygon: function (geojson, lnglats) {
return new AMap.Polyline({
path: lnglats[0],
strokeColor: '#6ccffe',
strokeWeight: 3,
lineJoin: 'round', //折线拐点的绘制样式
isOutline: true,
borderWeight: 2,
outlineColor: '#2d475f',
});
},
});
this.map.add(geojson);
},
// 中国内层边界线
drawInnerLine() {
let geojson = new AMap.GeoJSON({
geoJSON: chinaInner,
getPolygon: function (geojson, lnglats) {
return new AMap.Polyline({
path: lnglats[0],
strokeColor: '#359de5',
strokeWeight: 1,
});
},
});
this.map.add(geojson);
},
// 创建覆盖物组,用于批量处理点 (控制显隐,点击事件等)
createOverlay(result) {
if (this.overlayGroup) {
this.map.remove(this.overlayGroup);
this.overlayGroup = null;
}
this.overlayGroup = new AMap.OverlayGroup();
for (let i = 0; i < result.length; i++) {
let { type, lon, lat } = result[i];
// 创建一个 Icon
let startIcon = typeToIcon(type);
// 将 icon 传入 marker
let startMarker = new AMap.Marker({
// 点的坐标
position: [lon, lat],
// 指定点的icon,也可以是个url ,但这样就不能对图片进行设置了
icon: startIcon,
//启用点击事件 如果需要点击事件,必须开启
clickable: true,
//点额外携带的数据,用户自定义属性,支持JavaScript API任意数据类型
extData: result[i],
});
// 可以调用setExtData()设置自定义属性
//startMarker.setExtData('222')
//将组 挂载到地图上
this.overlayGroup.setMap(this.map);
//将需要批量控制的点放到一个组中,通过控制组,就可以操作组内所有所有覆盖物
this.overlayGroup.addOverlay(startMarker);
}
this.overlayGroup.on('click', function (e) {
//e.target触发事件的点对象
console.log(e.target);
//拿到点中携带的数据
console.log(e.target.getExtData());
});
},
};
@@ -94,3 +94,61 @@ export function useHealth() {
};
}
export function ringOption(chartData, total) {
return {
title: {
text: '总人数',
subtext: total + '',
x: 'center',
y: '35%',
textStyle: {
fontSize: 14,
color: '#ffffff',
fontWeight: 'normal',
},
subtextStyle: {
color: '#ffffff',
fontSize: 24,
fontWeight: 'bold',
},
},
color: ['#0098FA', '#0CD9B5', '#3B72AD'],
tooltip: {
trigger: 'item',
show: true,
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
},
legend: {
bottom: '0',
left: 'center',
icon: 'circle',
textStyle: {
color: '#ffffff',
fontSize: 16,
},
},
series: [
{
type: 'pie',
radius: ['50%', '80%'],
avoidLabelOverlap: false,
label: {
show: true,
position: 'inner',
formatter: '{d}%',
color: '#ffffff',
fontSize: 14,
},
labelLine: {
show: false,
},
data: chartData,
},
],
};
}
+1 -1
View File
@@ -3,7 +3,7 @@
<public-title title="健康终端报警" :isShowMore="true" @clickMore="handleDialog" />
<div class="inner">
<vue3-seamless-scroll :list="scrollList" class="scroll" :hover="true" :limitScrollNum="4" v-bind="classOption">
<div class="item" v-for="item in scrollList" :key="item.id">
<div class="item" v-for="(item, i) in scrollList" :key="i">
<span>{{ item?.realName }}</span>
<span>{{ item?.eventType_dictText }}</span>
<div class="time-icon">
+8 -62
View File
@@ -10,21 +10,18 @@
import PublicTitle from '../publicTitle.vue';
import { getHealthDataList } from '/@/components/body-d-right/right.api';
import { useSpin } from '/@/components/body-d-left/bodyLeftHooks.ts';
import { useHealth } from '/@/components/body-d-right/bodyRightHooks.ts';
import { ringOption, useHealth } from '/@/components/body-d-right/bodyRightHooks.ts';
const { setSpin, spinning } = useSpin();
const healthChart = ref<HTMLElement>();
onMounted(() => {
// let xdata = ['创伤类', '心血管', '心神类', '呼吸类', '消化类', '肿瘤类', '其他'];
// let ydata = [120, 200, 150, 80, 70, 110, 130];
// initChart(xdata, ydata);
init();
});
const { healthData, getValue, getName, setHealth } = useHealth();
const { healthData, getValue, setHealth } = useHealth();
async function init() {
try {
const { code, result } = await getHealthDataList();
const { code, result } = await getHealthDataList({});
setSpin(true);
if (code != 200) {
return;
@@ -32,66 +29,15 @@
setHealth(result);
const yData = unref(getValue);
let total = yData.reduce((accumulator, currentValue) => Number(accumulator) + Number(currentValue), 0);
console.log('yData', yData);
initChart(unref(healthData), total);
} catch {}
} catch {
initChart(unref(healthData), 0);
}
}
function initChart(chartData, total = 0) {
function initChart(chartData, total) {
let myChart = echarts.init(healthChart.value);
let options = {
title: {
text: '总人数\n',
subtext: total,
x: 'center',
y: 'center',
textStyle: {
fontSize: 16,
color: '#ffffff',
},
subtextStyle: {
color: '#ffffff',
fontSize: 22,
},
},
color: ['#0098FA', '#0CD9B5', '#3B72AD'],
tooltip: {
trigger: 'item',
show: true,
textStyle: {
color: '#fff',
},
backgroundColor: 'rgba(50,50,50,0.7)',
borderColor: '#1b7ef2',
},
legend: {
bottom: '0',
left: 'center',
icon: 'circle',
textStyle: {
color: '#ffffff',
fontSize: 16,
},
},
series: [
{
type: 'pie',
radius: ['50%', '80%'],
avoidLabelOverlap: false,
label: {
show: true,
position: 'inner',
formatter: '{d}%',
color: '#ffffff',
fontSize: 16,
},
labelLine: {
show: false,
},
data: chartData,
},
],
};
let options = ringOption(chartData, total);
myChart.setOption(options);
window.addEventListener('resize', () => {
myChart.resize();
+41 -109
View File
@@ -1,10 +1,11 @@
import { getAllList } from '/@/components/chinaMap/chinaMapApi.ts';
import { getAllList, getAmbulanceList } from '/@/components/chinaMap/chinaMapApi.ts';
export enum TabType {
all = '', //所有资源
youTianYiYuan = '1', //油田医院
heZuoYiYuan = '2', //合作医院
yiLiaoDian = '3', //医疗点
jiuHuChe = '4', //救护车
}
export const tabList = [
@@ -22,6 +23,7 @@ export const tabList = [
},
{
name: '救护车',
type: TabType.jiuHuChe,
},
{
name: '合作医院',
@@ -38,14 +40,50 @@ export const tabList = [
},
];
export function mapApiSwitch(type: string, params: any) {
// 直升机位置数据
export const aircraft = [
{
category: 3,
lat: 108.861377,
lon: 34.35965,
img: WebRoot + '/webpage/com/jeecg/show/img/helicopter.gif',
name: '直升机',
},
{
category: 3,
lat: 106.267358,
lon: 38.520079,
img: WebRoot + '/webpage/com/jeecg/show/img/helicopter.gif',
name: '直升机',
},
{
category: 3,
lat: 109.505282,
lon: 36.579381,
img: WebRoot + '/webpage/com/jeecg/show/img/helicopter.gif',
name: '直升机',
},
{
category: 3,
lat: 107.638372,
lon: 35.734218,
img: WebRoot + '/webpage/com/jeecg/show/img/helicopter.gif',
name: '直升机',
},
];
export function mapApiSwitch(type, params: any) {
const basicParams = {
lat: 34, //纬度34
lon: 108, //经度
};
if ([TabType.all, TabType.yiLiaoDian, TabType.heZuoYiYuan].includes(type)) {
// 全部 油田 医疗点 合作医院
if ([TabType.all, TabType.youTianYiYuan, TabType.yiLiaoDian, TabType.heZuoYiYuan].includes(type)) {
return getAllList({ ...basicParams, ...params });
}
if ([TabType.jiuHuChe].includes(type)) {
return getAmbulanceList({});
}
}
export const mapIcon1 = new URL('/@/assets/img/mapIcon1.png', import.meta.url).href;
@@ -61,7 +99,6 @@ export const legend3 = new URL('/@/assets/img/legend3.png', import.meta.url).hre
export const legend4 = new URL('/@/assets/img/legend4.png', import.meta.url).href;
export const legend5 = new URL('/@/assets/img/legend5.png', import.meta.url).href;
export const legend6 = new URL('/@/assets/img/legend6.png', import.meta.url).href;
export const mapIcons = [mapIcon1, mapIcon2, mapIcon3, mapIcon4, mapIcon5, mapIcon6];
export const legendList = [
{ img: legend1, text: '油田医院' },
@@ -71,111 +108,6 @@ export const legendList = [
{ img: legend5, text: '地方医院' },
{ img: legend6, text: '直升机' },
];
const bgImg = new URL('/@/assets/images/china-textur.jpg', import.meta.url).href;
export function createChartOption({ icons }) {
return {
tooltip: {
show: false,
// formatter: (params) => {
// console.log('params', params);
// if (!params?.data?.id) {
// return '';
// }
// return `<div style="color:red;width:300px"> ${params.name}</div>
// <div>id: ${params?.data?.id}</div>`;
// },
},
geo: [
{
map: 'china',
zlevel: 3,
aspectScale: 0.8, //长宽比
zoom: 1.1,
// roam: true,
// draggable: true,
top: '60',
left: 'center',
itemStyle: {
areaColor: '#173a58',
shadowColor: '#173a58',
shadowOffsetX: 0,
shadowOffsetY: 5,
borderWidth: 6, //外部边框
borderColor: '#6ccffe',
},
},
{
map: 'china',
zlevel: 2,
aspectScale: 0.8, //长宽比
zoom: 1.1,
// roam: true,
// draggable: true,
top: '60',
left: 'center',
itemStyle: {
areaColor: '#1e2c38',
shadowColor: '#1e2c38',
shadowOffsetX: 0,
shadowOffsetY: 10,
borderWidth: 6, //外部边框
borderColor: '#384d61',
},
},
],
series: [
{
map: 'china', // 这个是上面注册时的名字哦,registerMap'这个名字保持一致'
name: '中国地图',
type: 'map',
selected: {}, // 默认所有省份都是未选中状态
selectedMode: 'single', // 选中模式为单选
zlevel: 9,
zoom: 1.1,
aspectScale: 0.8, //长宽比
// roam: true,
// draggable: true,
hoverAnimation: false,
silent: false,
top: '60',
left: 'center',
label: {
show: true,
padding: [0, 10],
height: 31,
lineHeight: 31,
textStyle: {
color: '#fff',
fontSize: 13,
marginLeft: 5,
},
},
itemStyle: {
// 给地图添加背景图片
areaColor: {
type: 'pattern',
image: bgImg,
repeat: 'no-repeat',
},
borderColor: '#359de5',
borderWidth: 2, //内部边框,
},
// 鼠标悬浮
emphasis: {
label: {
color: '#fff',
},
itemStyle: {
// areaColor: '#008CFF',
areaColor: '#002e64',
},
},
},
...icons.value,
],
};
}
/**
* @description 秒转小时
+18 -97
View File
@@ -2,7 +2,7 @@
<div class="center-map">
<div class="china-map-box">
<div class="tab-list">
<div v-for="(item, i) in list" :class="[currentIndex == i ? 'active' : '']" class="tab" @click="changeTab(i)">
<div v-for="(item, i) in list" :class="[currentIndex == i ? 'active' : '']" class="tab" @click="changeTab(item, i)">
{{ item.name }}
</div>
</div>
@@ -36,7 +36,7 @@
<div v-show="!routeList.length" class="empty-data"> 暂无数据</div>
</div>
</div>
<div class="china-map-container"></div>
<div class="mapContainer" id="mapContainer"></div>
<div v-show="false" id="container"></div>
<div v-show="false" id="panel"></div>
<div class="map-legend">
@@ -59,11 +59,9 @@
</template>
<script lang="ts" setup>
import { onMounted, ref } from 'vue';
import * as echarts from 'echarts';
import mapJson from '/@/components/chinaMap/json/c.json';
import { tabList, mapIcons, legendList, getTimeStr, getKmStr, createChartOption, mapApiSwitch } from '/@/components/chinaMap/chinaHooks';
import { message } from 'ant-design-vue';
import { getAllList } from '/@/components/chinaMap/chinaMapApi';
import { Map } from '/@/assets/mapUtils/map';
import { tabList, legendList, getTimeStr, getKmStr, mapApiSwitch } from '/@/components/chinaMap/chinaHooks';
const formState = ref({
start: '西安北站',
@@ -71,105 +69,28 @@
});
const list = ref(tabList);
const currentIndex = ref(0);
const icons = ref([
{
type: 'scatter',
zlevel: 100,
coordinateSystem: 'geo',
//自定义图片的 位置(lng, lat)
data: [{ name: '西安', value: ['108.88', '34.40'], id: 'xian' }],
//自定义图片的 大小
symbolSize: [25, 63],
//自定义图片的 路径
// symbol: 'image://https://img2.baidu.com/it/u=1568770988,2090980470&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=567', // 图片 URL
symbol: 'image://' + mapIcons[0], // 图片 URL
},
]);
function changeTab(i: number) {
let x = Math.random() + 5 - Math.floor(Math.random() * 10) - i + Math.random() * 3.5;
let y = Math.floor(Math.random() * 10) - 5 + Math.random() + i + Math.random() * 5;
const o = {
type: 'scatter',
zlevel: 100,
coordinateSystem: 'geo',
//自定义图片的 位置(lng, lat)
data: [{ name: '太原', value: [112.55 + Math.random() + x, 37.98 + Math.random() + y], id: 'taiyuan' }],
//自定义图片的 大小
symbolSize: [25, 63],
symbol: 'image://' + mapIcons[Math.floor(Math.random() * 6)], // 图片 URL
};
icons.value = [];
icons.value.push(o);
// icons.value.push(line);
function changeTab(item, i: number) {
currentIndex.value = i;
let myChart = echarts.init(document.querySelector('.china-map-container'));
initMap(myChart);
getMapData(item.type, { type: item.type });
}
async function getMapData(params) {
const data = await mapApiSwitch(params.type, {});
console.log('--->data', data);
async function getMapData(type, params = {}) {
const { code, result } = await mapApiSwitch(type, params);
if (code == 200 && Array.isArray(result) && result.length > 0) {
Map.createOverlay(result);
}
console.log('--->data', result);
}
onMounted(() => {
console.log('reload');
let myChart = echarts.init(document.querySelector('.china-map-container'));
echarts.registerMap('china', mapJson);
initMap(myChart);
getMapData({ type: tabList[0].type });
initMap();
getMapData(tabList[0].type);
});
function initMap(myChart) {
let option = createChartOption({ icons });
myChart.setOption(option);
// 关闭之前的点击事件
myChart.off('click');
myChart.on('click', function (res) {
mapClick(res, myChart);
});
myChart.getZr().on('click', (params) => {
if (params.target) {
// alert('画布非空白区');
} else {
// alert('画布空白区');
myChart.dispatchAction({
// 如果绑定了 geo 图层(指定了geoIndex),则是 geoUnSelect 事件
type: 'unselect',
// 指定 series 的索引
seriesIndex: 0,
// 指定要取消选中数据的索引, 如果要取消全部选中,则把所有数据的下标数组作为 dataIndex 即可
dataIndex: new Array(101).fill(null).map((_, i) => i), // 0 代表取消选中 data 中第1项的选中,依此类推
});
myChart.dispatchAction({
// 如果绑定了 geo 图层(指定了geoIndex),则是 geoUnSelect 事件
type: 'geoUnSelect',
// 指定 series 的索引
seriesIndex: 0,
// 指定要取消选中数据的索引, 如果要取消全部选中,则把所有数据的下标数组作为 dataIndex 即可
dataIndex: new Array(101).fill(null).map((_, i) => i), // 0 代表取消选中 data 中第1项的选中,依此类推
});
}
});
window.addEventListener('resize', () => {
myChart.resize();
});
}
function mapClick(res, myChart) {
if (res.componentType !== 'series') {
myChart.setOption({
series: [{ selected: {} }], // 取消所有省份的选中状态
});
}
console.log('res', res);
if ('scatter' === res.componentSubType) {
// alert(`点击了 ${res.name} 图标`);
}
if ('map' === res.componentSubType) {
// alert(`点击了 ${res.name} 地图`);
}
function initMap() {
Map.initMap({ el: 'mapContainer' });
}
const routeList = ref([]);
@@ -412,9 +333,9 @@
}
}
.china-map-container {
.mapContainer {
flex: 1;
margin: 10px;
margin: 10px 0;
//border: 1px solid red;
}
+4 -2
View File
@@ -1,9 +1,11 @@
import {get} from '/@/api/request.ts';
import { get } from '/@/api/request.ts';
export enum Api {
allList = '/health-emergency/emergency/tblAmbulanceGps/getAllList',
getAmbulanceList = '/health-emergency/emergency/tblAmbulanceGps/getAmbulanceList',
}
// 获取所有资源
export const getAllList = (params) => get(Api.allList, params);
//获取救护车GPS信息
//获取救护车GPS信息
export const getAmbulanceList = (params) => get(Api.getAmbulanceList, params);
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff