This commit is contained in:
weipengfei 2023-12-18 17:56:09 +08:00
parent 021d1d8376
commit 4b2a661487
11 changed files with 348 additions and 95 deletions

9
package-lock.json generated
View File

@ -15,6 +15,7 @@
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"v-click-outside": "^3.2.0",
"vue": "^3.3.8", "vue": "^3.3.8",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },
@ -1229,6 +1230,14 @@
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
}, },
"node_modules/v-click-outside": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/v-click-outside/-/v-click-outside-3.2.0.tgz",
"integrity": "sha512-QD0bDy38SHJXQBjgnllmkI/rbdiwmq9RC+/+pvrFjYJKTn8dtp7Penf9q1lLBta280fYG2q53mgLhQ+3l3z74w==",
"engines": {
"node": ">=6"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-5.0.2.tgz", "resolved": "https://registry.npmmirror.com/vite/-/vite-5.0.2.tgz",

View File

@ -16,6 +16,7 @@
"echarts-gl": "^2.0.9", "echarts-gl": "^2.0.9",
"mitt": "^3.0.1", "mitt": "^3.0.1",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"v-click-outside": "^3.2.0",
"vue": "^3.3.8", "vue": "^3.3.8",
"vue-router": "^4.2.5" "vue-router": "^4.2.5"
}, },

View File

@ -1,5 +1,5 @@
<script setup> <script setup>
import { defineProps, defineEmits, ref, nextTick, onMounted, } from "vue" import { defineProps, defineEmits, ref, nextTick, onMounted, onUnmounted, } from "vue"
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useAppStore } from "@/store/app.js"; import { useAppStore } from "@/store/app.js";
@ -80,19 +80,28 @@ defineExpose({
open, close, show open, close, show
}) })
const addressRef = ref(null);
const onClickOutside = (event) => {
const componentElement = addressRef.value;
if (!componentElement?.contains(event.target)) {
choseArea.value = false;
}
}
onMounted(() => { onMounted(() => {
// list.value.forEach(item => { document.addEventListener('click', onClickOutside);
// if (item.pinyin == appStore.map_info) { })
// choseTownFn(item)
// } onUnmounted(() => {
// }) document.removeEventListener('click', onClickOutside);
}) })
</script> </script>
<template> <template>
<transition name="fade"> <transition name="fade" mode="out-in">
<div class="address" v-show="choseArea == true"> <div ref="addressRef" class="address" v-if="choseArea == true">
<div <div
class="address-li" class="address-li"
@click="choseTownFn(item)" @click="choseTownFn(item)"
@ -110,8 +119,8 @@ onMounted(() => {
left: 1vw; left: 1vw;
top: 18px; top: 18px;
position: absolute; position: absolute;
width: 10vw; width: 8rem;
height: 18vh; height: 15rem;
background-color: #001e32; background-color: #001e32;
color: #c7dbe3; color: #c7dbe3;
z-index: 9999; z-index: 9999;

View File

@ -142,7 +142,7 @@ onMounted(() => {
</div> </div>
<div class="head-title">吟龙物流信息监控溯源可视化大屏</div> <div class="head-title">吟龙物流信息监控溯源可视化大屏</div>
<div class="right"> <div class="right">
<div class="item" @click="open" style="position: relative"> <div class="item" @click.stop="open" style="position: relative">
<img src="/src/assets/head_img/location.png" alt="" /> <img src="/src/assets/head_img/location.png" alt="" />
{{ info.address }}   {{ info.address }}  
<areaList <areaList

View File

@ -4,7 +4,7 @@ import App from './App.vue'
import dataV from '@jiaminghi/data-view' import dataV from '@jiaminghi/data-view'
import './assets/font/fonts.css'; import './assets/font/fonts.css';
import router from "./router"; import router from "./router";
import { createPinia } from 'pinia' import { createPinia } from 'pinia';
const pinia = createPinia(); const pinia = createPinia();

View File

@ -366,6 +366,7 @@ const initInfo = () => {
dateCangeCrderCount({ dateCangeCrderCount({
areaCode: appStore.delivery_address.areaCode, areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode, streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id
}).then(({ data }) => { }).then(({ data }) => {
let y1 = [], y2 = [], y3 = [], y4 = []; let y1 = [], y2 = [], y3 = [], y4 = [];
data.forEach((item) => { data.forEach((item) => {
@ -383,6 +384,7 @@ const initInfo = () => {
const pages = ref({ const pages = ref({
areaCode: appStore.delivery_address.areaCode, areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode, streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id,
page: 1, page: 1,
limit: 30 limit: 30
}) })

View File

@ -145,12 +145,14 @@ const loadInfo = () => {
latestLogistics({ latestLogistics({
areaCode: appStore.delivery_address.areaCode, areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode, streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id
}).then(res => { }).then(res => {
info.value = res.data; info.value = res.data;
}) })
logisticsCount({ logisticsCount({
areaCode: appStore.delivery_address.areaCode, areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.delivery_address.streetCode streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id
}).then(res => { }).then(res => {
delivery.value = res.data; delivery.value = res.data;
datas.dataArr[0].value = res.data.pending_order_count; datas.dataArr[0].value = res.data.pending_order_count;
@ -434,6 +436,7 @@ onMounted(() => {
height: 100%; height: 100%;
box-shadow: inset 1px 1px 40px rgba(91, 219, 246, 0.5); box-shadow: inset 1px 1px 40px rgba(91, 219, 246, 0.5);
pointer-events: none; pointer-events: none;
overflow: hidden;
} }
} }
.delivery { .delivery {

View File

@ -28,8 +28,9 @@ const max = ref(0)
const loadList = () => { const loadList = () => {
deliveredProductRanking({ deliveredProductRanking({
areaCode: appStore.address.areaCode, areaCode: appStore.delivery_address.areaCode,
streetCode: appStore.address.streetCode, streetCode: appStore.delivery_address.streetCode,
courier_id: appStore.delivery_address.courier_id
}).then((res) => { }).then((res) => {
items.value = res.data; items.value = res.data;
res.data.forEach(e => { res.data.forEach(e => {

View File

@ -33,9 +33,9 @@ onMounted(() => {
<template> <template>
<div class="box"> <div class="box">
<div class="ball"> <!-- <div class="ball">
<ball class="ball1"></ball> <ball class="ball1"></ball>
</div> </div> -->
<centerMap v-if="list.length > 0" class="c-map" :list="list"></centerMap> <centerMap v-if="list.length > 0" class="c-map" :list="list"></centerMap>
</div> </div>
</template> </template>

View File

@ -1,6 +1,6 @@
<script setup> <script setup>
import { onMounted, reactive, ref, inject, nextTick } from "vue"; import { onMounted, reactive, ref, inject, nextTick } from "vue";
import * as echarts from 'echarts'; import * as echarts from "echarts";
import mitt from "@/utils/mitt"; import mitt from "@/utils/mitt";
import luxian from "@/assets/json/luxian.json"; import luxian from "@/assets/json/luxian.json";
import hejiang from "@/assets/json/hejiang.json"; import hejiang from "@/assets/json/hejiang.json";
@ -21,65 +21,66 @@ const userStore = useUserStore();
const props = defineProps({ const props = defineProps({
list: { list: {
type: Object, type: Object,
default: () => [] default: () => [],
} },
}) });
const mapType = reactive({ const mapType = reactive({
name: '', name: "",
json: '' json: "",
}) });
const changeType = (name = 'luxian') => { const changeType = (name = "luxian") => {
mapType.name = name; mapType.name = name;
if (name == 'luxian') mapType.json = luxian; if (name == "luxian") mapType.json = luxian;
if (name == 'hejiang') mapType.json = hejiang; if (name == "hejiang") mapType.json = hejiang;
if (name == 'xuyong') mapType.json = xuyong; if (name == "xuyong") mapType.json = xuyong;
if (name == 'gulin') mapType.json = gulin; if (name == "gulin") mapType.json = gulin;
if (name == 'jiangyang') mapType.json = jiangyang; if (name == "jiangyang") mapType.json = jiangyang;
if (name == 'longma') mapType.json = longma; if (name == "longma") mapType.json = longma;
if (name == 'naxi') mapType.json = naxi; if (name == "naxi") mapType.json = naxi;
} };
let dataValue = [] let dataValue = [];
const customFormatter = (params) => { const customFormatter = (params) => {
// console.log(params.data); // console.log(params.data);
// return `{img|${params.data.street_name}}\n{t|${params.data.mer_count}, ${params.data.service_group_count}}` // return `{img|${params.data.street_name}}\n{t|${params.data.mer_count}, ${params.data.service_group_count}}`
return '' return "";
} };
const initDataValue = () => { const initDataValue = () => {
dataValue.forEach(item => { dataValue.forEach((item) => {
item.label = { item.label = {
show: true, // show: true, //
formatter: customFormatter, // 使{name}name formatter: customFormatter, // 使{name}name
fontSize: 12, // fontSize: 12, //
fontWeight: 'bold', // fontWeight: "bold", //
color: '#fff', // color: "#fff", //
offset: [-50, -40], // offset: [-50, -40], //
rich: { rich: {
img: { img: {
backgroundColor: { backgroundColor: {
image: 'https://lihai001.oss-cn-chengdu.aliyuncs.com/def/205f0202311291015185408.png' image:
"https://lihai001.oss-cn-chengdu.aliyuncs.com/def/205f0202311291015185408.png",
}, },
height: 40, height: 40,
width: 140, width: 140,
color: '#fff', color: "#fff",
fontSize: 14, fontSize: 14,
lineHeight: 14, lineHeight: 14,
fontFamily: 'ifonts', fontFamily: "ifonts",
align: 'center', align: "center",
padding: [0, 0, 20, 0] padding: [0, 0, 20, 0],
}, },
t: { t: {
fontSize: 10, fontSize: 10,
align: 'center' align: "center",
} },
} },
}; };
}) });
} };
const echartsRef = ref(null); const echartsRef = ref(null);
let chart = null; let chart = null;
@ -96,11 +97,11 @@ const initMap = () => {
title: { title: {
text: mapType.name, text: mapType.name,
textStyle: { textStyle: {
color: '#fff', color: "#fff",
fontSize: 20 fontSize: 20,
}, },
top: '10%', top: "10%",
left: '10%' left: "10%",
}, },
//geo //geo
geo: [ geo: [
@ -111,17 +112,17 @@ const initMap = () => {
show: false, show: false,
}, },
emphasis: { emphasis: {
disabled: true disabled: true,
}, },
select: { select: {
disabled: true disabled: true,
}, },
// aspectScale:0.75, // // aspectScale:0.75, //
// roam: true, // // roam: true, //
itemStyle: { itemStyle: {
normal: { normal: {
// color: '#546686', // // color: '#546686', //
borderColor: '#fff', //线00fcff 516a89 borderColor: "#fff", //线00fcff 516a89
borderWidth: 1, borderWidth: 1,
areaColor: "#3f5171", areaColor: "#3f5171",
shadowColor: "#5bdbf6", shadowColor: "#5bdbf6",
@ -140,16 +141,16 @@ const initMap = () => {
roam: false, // roam: false, //
show: true, show: true,
tooltip: { tooltip: {
show: false // show: false, //
}, },
label: { label: {
show: false show: false,
}, },
emphasis: { emphasis: {
disabled: true disabled: true,
}, },
select: { select: {
disabled: true disabled: true,
}, },
itemStyle: { itemStyle: {
normal: { normal: {
@ -169,11 +170,11 @@ const initMap = () => {
}, },
], ],
tooltip: { tooltip: {
trigger: 'item', trigger: "item",
formatter: function (params) { formatter: function (params) {
let obj = dataValue.find(item => item.street_name == params.name); let obj = dataValue.find((item) => item.street_name == params.name);
if (!obj) { if (!obj) {
obj = params.data obj = params.data;
} }
if (obj) { if (obj) {
return `<div return `<div
@ -184,22 +185,28 @@ const initMap = () => {
align-items: center; align-items: center;
width: 180px; width: 180px;
height: 80px;"> height: 80px;">
<div style="font-size: 15px;font-family: 'ifonts';">${obj?.street_name || ''}</div> <div style="font-size: 15px;font-family: 'ifonts';">${
obj?.street_name || ""
}</div>
<div style="font-size: 12px;"> <div style="font-size: 12px;">
<p style="padding: 0;margin: 0">店铺:${obj?.mer_count || '0'}</p> <p style="padding: 0;margin: 0">店铺:${
<p style="padding: 0;margin: 0">团队:${obj?.service_group_count || '0'}</p> obj?.mer_count || "0"
}</p>
<p style="padding: 0;margin: 0">团队:${
obj?.service_group_count || "0"
}</p>
</div> </div>
</div>`; </div>`;
} else return ''; } else return "";
}, },
position: 'top', position: "top",
// extraCssText: 'background-color: transparent; border: none;pdding: 0;', // CSS // extraCssText: 'background-color: transparent; border: none;pdding: 0;', // CSS
backgroundColor: 'rgba(0, 156, 255, 0)', // backgroundColor: "rgba(0, 156, 255, 0)", //
borderColor: "rgba(0, 156, 255, 0)", borderColor: "rgba(0, 156, 255, 0)",
padding: 0, padding: 0,
textStyle: { textStyle: {
color: '#fff' color: "#fff",
} },
}, },
series: [ series: [
{ {
@ -207,15 +214,15 @@ const initMap = () => {
map: mapType.name, map: mapType.name,
label: { label: {
emphasis: { emphasis: {
show: false show: false,
}, },
color: 'rgba(0,0,0,0)' color: "rgba(0,0,0,0)",
}, },
emphasis: { emphasis: {
disabled: false, disabled: false,
}, },
select: { select: {
disabled: true disabled: true,
}, },
itemStyle: { itemStyle: {
normal: { normal: {
@ -224,8 +231,8 @@ const initMap = () => {
borderWidth: 1, borderWidth: 1,
}, },
emphasis: { emphasis: {
areaColor: '#0680ca', // areaColor: "#0680ca", //
} },
}, },
}, },
{ {
@ -233,58 +240,279 @@ const initMap = () => {
type: "scatter", type: "scatter",
coordinateSystem: "geo", coordinateSystem: "geo",
data: dataValue, data: dataValue,
symbol: "image://https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6eb37202311281655342626.png", symbol:
"image://https://lihai001.oss-cn-chengdu.aliyuncs.com/def/6eb37202311281655342626.png",
symbolSize: [40, 30], symbolSize: [40, 30],
hoverSymbolSize: [60, 45], hoverSymbolSize: [60, 45],
label: { label: {
formatter: "", formatter: "",
position: "center", position: "center",
show: false show: false,
}, },
emphasis: { emphasis: {
label: { label: {
show: false show: false,
} },
} },
}, },
], ],
} };
option = {
geo: [
{
type: "map",
map: mapType.name,
aspectScale: 1,
zoom: 1,
layoutCenter: ["50%", "51%"],
layoutSize: "110%",
roam: false,
label: {
emphasis: {
show: false,
},
},
show: true,
map: mapType.name,
zoom: 1,
aspectScale: 1,
roam: false,
itemStyle: {
normal: {
areaColor: "transparent",
},
emphasis: {
areaColor: {
type: "radial", // linear 线 radial
x: 0.5, // 0.5
y: 0.5, // 0.5
r: 1,
colorStops: [
{
offset: 0,
color: "#A46759", // 0%
},
{
offset: 0.1,
color: "#A46759", // 0%
},
{
offset: 1,
color: "#FFB821", // 100%
},
],
},
// borderWidth: 0
},
},
tooltip: {
trigger: "item",
formatter: function (params) {
let obj = dataValue.find((item) => item.street_name == params.name);
if (!obj) {
obj = params.data;
}
if (obj) {
return `<div
style="background-image: url(\'/src/assets/img/item-box.png\');
background-size: 100% 100%;
display: flex;
justify-content: space-evenly;
align-items: center;
width: 180px;
height: 80px;">
<div style="font-size: 15px;font-family: 'ifonts';">${
obj?.street_name || ""
}</div>
<div style="font-size: 12px;">
<p style="padding: 0;margin: 0">店铺:${
obj?.mer_count || "0"
}</p>
<p style="padding: 0;margin: 0">团队:${
obj?.service_group_count || "0"
}</p>
</div>
</div>`;
} else return "";
},
position: "top",
// extraCssText: 'background-color: transparent; border: none;pdding: 0;', // CSS
backgroundColor: "rgba(0, 156, 255, 0)", //
borderColor: "rgba(0, 156, 255, 0)",
padding: 0,
textStyle: {
color: "#fff",
},
},
},
{
type: "map",
map: mapType.name,
zlevel: -1,
aspectScale: 1,
zoom: 1,
layoutCenter: ["50%", "51%"],
layoutSize: "110%",
roam: false,
silent: true,
itemStyle: {
normal: {
borderWidth: 1,
borderColor: "rgba(17, 149, 216,0.6)",
borderColor: "#5AD0E0",
shadowColor: "rgba(172, 122, 255,0.5)",
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: "rgba(5,21,35,0.1)",
},
},
},
{
type: "map",
map: mapType.name,
zlevel: -1,
aspectScale: 1,
zoom: 1,
layoutCenter: ["50%", "52%"],
layoutSize: "110%",
roam: false,
silent: true,
itemStyle: {
normal: {
borderWidth: 1,
borderColor: "rgba(17, 149, 216,0.6)",
borderColor: "#5AD0E0",
shadowColor: "rgba(172, 122, 255,0.5)",
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: "rgba(5,21,35,0.1)",
},
},
},
{
type: "map",
map: mapType.name,
zlevel: -2,
aspectScale: 1,
zoom: 1,
layoutCenter: ["50%", "53%"],
layoutSize: "110%",
roam: false,
silent: true,
itemStyle: {
normal: {
borderWidth: 1,
borderColor: "rgba(17, 149, 216,0.4)",
borderColor: "#5AD0E0",
shadowColor: "rgba(172, 122, 255,0.5)",
shadowOffsetY: 5,
shadowBlur: 15,
areaColor: "rgba(5,21,35,0.1)",
},
},
},
{
type: "map",
map: mapType.name,
zlevel: -4,
aspectScale: 1,
zoom: 1,
layoutCenter: ["50%", "54%"],
layoutSize: "110%",
roam: false,
silent: true,
itemStyle: {
normal: {
borderWidth: 5,
// borderColor: "rgba(11, 43, 97,0.8)",
borderColor: "rgba(5,9,57,0.8)",
shadowColor: "rgba(29, 111, 165,0.8)",
shadowOffsetY: 15,
shadowBlur: 10,
areaColor: "rgba(5,21,35,0.1)",
},
},
},
],
tooltip: {
show: true
},
color: '#1f7df5',
series: [
{
name: "地点名称",
type: "effectScatter",
coordinateSystem: "geo",
colorBy: 'series',
rippleEffect: {
period: 4, //
brushType: "fill", // stroke, fill
scale: 12, //
number: 2,
},
//
symbolSize: function (val) {
return 4;
// return val[2] / 10;
},
data: dataValue,
},
],
};
// 使 // 使
chart.setOption(option); chart.setOption(option);
} };
const mapInfo = () => { const mapInfo = () => {
let area = appStore.area.find(item => item.code == appStore.address.areaCode); let area = appStore.area.find(
(item) => item.code == appStore.address.areaCode
);
let map; let map;
if (area.name == "泸县") map = luxian_geo; if (area.name == "泸县") map = luxian_geo;
if (area.name == "江阳区") map = jiangyang_geo; if (area.name == "江阳区") map = jiangyang_geo;
if (area.name == "叙永县") map = xuyong_geo; if (area.name == "叙永县") map = xuyong_geo;
map = JSON.parse(JSON.stringify(map)); map = JSON.parse(JSON.stringify(map));
if (appStore.address.streetCode) { if (appStore.address.streetCode) {
let street = appStore.street.find(item => item.code == appStore.address.streetCode); let street = appStore.street.find(
(item) => item.code == appStore.address.streetCode
);
initStreetMap(street, map); initStreetMap(street, map);
dataValue = dataValue.filter(
(item) => item.street_code == appStore.address.streetCode
);
} else { } else {
mapType.name = area.name; mapType.name = area.name;
mapType.json = map; mapType.json = map;
} }
} };
const initStreetMap = (street, map) => { const initStreetMap = (street, map) => {
map.features = map.features.filter(item => item.properties.name == street.name); map.features = map.features.filter(
(item) => item.properties.name == street.name
);
mapType.name = street.name; mapType.name = street.name;
mapType.json = map; mapType.json = map;
} };
onMounted(() => { onMounted(() => {
dataValue = props.list; dataValue = props.list;
changeType('xuyong'); changeType("xuyong");
mapInfo(); mapInfo();
initDataValue(); // initDataValue();
setTimeout(() => { setTimeout(() => {
initMap(); initMap();
}) });
}) });
</script> </script>
<template> <template>

View File

@ -123,7 +123,7 @@ const submit = () => {
.login-box { .login-box {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url(../../assets/login_img/bg.png); background-image: url(https://lihai001.oss-cn-chengdu.aliyuncs.com/def/a0732202312131402421186.png);
background-size: 100% 100%; background-size: 100% 100%;
overflow: hidden; overflow: hidden;
position: relative; position: relative;