home page
This commit is contained in:
@ -10,6 +10,7 @@
|
|||||||
"build:stage": "vite build --mode staging",
|
"build:stage": "vite build --mode staging",
|
||||||
"build:caddy": "vite build --mode caddy",
|
"build:caddy": "vite build --mode caddy",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
|
"preview:caddy": "caddy run --config ./Caddyfile",
|
||||||
"format": "prettier --write \"**/*.{js,ts,tsx,jsx,vue,md}\"",
|
"format": "prettier --write \"**/*.{js,ts,tsx,jsx,vue,md}\"",
|
||||||
"commit-push": "prettier -w . && git add . && git commit -m"
|
"commit-push": "prettier -w . && git add . && git commit -m"
|
||||||
},
|
},
|
||||||
|
1
src/assets/icons/svg/map.svg
Normal file
1
src/assets/icons/svg/map.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 5.3 KiB |
121
src/views/device/deviceMap/index.vue
Normal file
121
src/views/device/deviceMap/index.vue
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
<script setup>
|
||||||
|
import { loadMap } from "@/utils/amap";
|
||||||
|
import {
|
||||||
|
onBeforeUnmount,
|
||||||
|
onMounted,
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
shallowRef,
|
||||||
|
toRefs,
|
||||||
|
} from "vue";
|
||||||
|
import { listDevice } from "@/api/iot/device";
|
||||||
|
import Pagination from "@/components/Pagination/index.vue";
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
const AMap = shallowRef();
|
||||||
|
const map = shallowRef();
|
||||||
|
const deviceList = ref([]);
|
||||||
|
const infoWindow = shallowRef(null);
|
||||||
|
const total = ref(0);
|
||||||
|
const data = reactive({
|
||||||
|
queryParams: {
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { queryParams } = toRefs(data);
|
||||||
|
const loadDeviceList = async () => {
|
||||||
|
map.value.clearMap();
|
||||||
|
const resp = await listDevice(queryParams.value);
|
||||||
|
deviceList.value = resp.rows;
|
||||||
|
total.value = resp.total;
|
||||||
|
const markers = resp.rows
|
||||||
|
?.filter((el) => el.longitude && el.latitude)
|
||||||
|
.map((el) => {
|
||||||
|
const marker = new AMap.value.Marker({
|
||||||
|
map: map.value,
|
||||||
|
position: new AMap.value.LngLat(el.longitude, el.latitude),
|
||||||
|
anchor: "bottom-center",
|
||||||
|
extData: el,
|
||||||
|
});
|
||||||
|
|
||||||
|
marker.on("mouseover", handleResultHover);
|
||||||
|
marker.on("mouseout", (ev) => {
|
||||||
|
infoWindow.value.close();
|
||||||
|
});
|
||||||
|
marker.on("click", handleResultClick);
|
||||||
|
return marker;
|
||||||
|
});
|
||||||
|
map.value.setFitView(markers);
|
||||||
|
};
|
||||||
|
const handleResultClick = (ev) => {
|
||||||
|
const id = ev.target.getExtData().deviceId;
|
||||||
|
router.push({
|
||||||
|
path: "/device/device/detail",
|
||||||
|
query: {
|
||||||
|
id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 鼠标悬停搜索结果标记
|
||||||
|
const handleResultHover = (ev) => {
|
||||||
|
infoWindow.value.setContent(`
|
||||||
|
<div>
|
||||||
|
设备名称 : ${ev.target.getExtData().deviceName}</div>
|
||||||
|
`);
|
||||||
|
infoWindow.value.open(map.value, [ev.lnglat.lng, ev.lnglat.lat]);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
AMap.value = await loadMap(["AMap.PlaceSearch", "AMap.Geocoder"]);
|
||||||
|
map.value = new AMap.value.Map("map-container", { zoom: 11 });
|
||||||
|
infoWindow.value = new AMap.value.InfoWindow({
|
||||||
|
anchor: "bottom-center",
|
||||||
|
offset: new AMap.value.Pixel(0, -20),
|
||||||
|
});
|
||||||
|
loadDeviceList();
|
||||||
|
});
|
||||||
|
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
map.value.destroy();
|
||||||
|
console.log("destroy");
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="map-wrap">
|
||||||
|
<div id="map-container"></div>
|
||||||
|
<pagination
|
||||||
|
v-show="total > 0"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
v-model:page="queryParams.pageNum"
|
||||||
|
:total="total"
|
||||||
|
class="map-pagination"
|
||||||
|
@pagination="loadDeviceList"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
#map-container {
|
||||||
|
min-height: calc(100vh - 50px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hasTagsView {
|
||||||
|
#map-container {
|
||||||
|
min-height: calc(100vh - 84px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-wrap {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.map-pagination {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 2023;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,3 +1,142 @@
|
|||||||
<template>
|
<template>
|
||||||
<p>123</p>
|
<div class="app-container">
|
||||||
|
<el-row :gutter="20" justify="space-between">
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card class="count-card-item">
|
||||||
|
<template #header>产品</template>
|
||||||
|
<div></div>
|
||||||
|
<div>数量 : 12</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card class="count-card-item">
|
||||||
|
<template #header>产品</template>
|
||||||
|
<div></div>
|
||||||
|
<div>数量 : 12</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card class="count-card-item">
|
||||||
|
<template #header>设备</template>
|
||||||
|
<div></div>
|
||||||
|
<div>数量 : 12</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<el-card class="count-card-item">
|
||||||
|
<template #header>产品</template>
|
||||||
|
<div></div>
|
||||||
|
<div>数量 : 12</div>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-card class="chart-card">
|
||||||
|
<template #header>设备</template>
|
||||||
|
<Line
|
||||||
|
id="line-chart-id"
|
||||||
|
:data="deviceChartData"
|
||||||
|
:options="{
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
display: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: '日期',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
display: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: '数量',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="chart-card">
|
||||||
|
<template #header>消息</template>
|
||||||
|
<Line
|
||||||
|
:data="noticeChartData"
|
||||||
|
:options="{
|
||||||
|
responsive: true,
|
||||||
|
scales: {
|
||||||
|
x: {
|
||||||
|
display: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: '日期',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
y: {
|
||||||
|
display: true,
|
||||||
|
title: {
|
||||||
|
display: true,
|
||||||
|
text: '数量',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Line } from "vue-chartjs";
|
||||||
|
import {
|
||||||
|
CategoryScale,
|
||||||
|
Chart as ChartJS,
|
||||||
|
Legend,
|
||||||
|
LinearScale,
|
||||||
|
LineElement,
|
||||||
|
PointElement,
|
||||||
|
Title,
|
||||||
|
Tooltip,
|
||||||
|
} from "chart.js";
|
||||||
|
import { reactive, toRefs } from "vue";
|
||||||
|
|
||||||
|
ChartJS.register(
|
||||||
|
Title,
|
||||||
|
LineElement,
|
||||||
|
Tooltip,
|
||||||
|
Legend,
|
||||||
|
CategoryScale,
|
||||||
|
LinearScale,
|
||||||
|
PointElement
|
||||||
|
);
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
deviceChartData: {
|
||||||
|
labels: [...Array(30).keys()].map((el) => `${(el + 1).toString()}日`),
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [...Array(30).keys()].map((el) => Math.random() * 100),
|
||||||
|
label: "设备",
|
||||||
|
backgroundColor: "#ff6384",
|
||||||
|
borderColor: "#ff6384",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
noticeChartData: {
|
||||||
|
labels: [...Array(30).keys()].map((el) => `${(el + 1).toString()}日`),
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [...Array(30).keys()].map((el) => Math.random() * 100),
|
||||||
|
label: "消息",
|
||||||
|
backgroundColor: "#36a2eb",
|
||||||
|
borderColor: "#36a2eb",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const { deviceChartData, noticeChartData } = toRefs(data);
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.chart-card {
|
||||||
|
margin-top: 20px;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -156,7 +156,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
import { onActivated, onMounted, reactive, ref, toRefs } from "vue";
|
||||||
import { listProduct } from "@/api/product/product";
|
import { listProduct } from "@/api/product/product";
|
||||||
import OperatingStatus from "@/views/iot/device/detail-panes/OperatingStatus.vue";
|
import OperatingStatus from "@/views/iot/device/detail-panes/OperatingStatus.vue";
|
||||||
import { addDevice, getDevice, updateDevice } from "@/api/iot/device";
|
import { addDevice, getDevice, updateDevice } from "@/api/iot/device";
|
||||||
|
@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
|
|||||||
proxy: {
|
proxy: {
|
||||||
// https://cn.vitejs.dev/config/#server-proxy
|
// https://cn.vitejs.dev/config/#server-proxy
|
||||||
"/dev-api": {
|
"/dev-api": {
|
||||||
target: "http://192.168.1.201:1616",
|
target: "http://117.72.16.89/api",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: (p) => p.replace(/^\/dev-api/, ""),
|
rewrite: (p) => p.replace(/^\/dev-api/, ""),
|
||||||
},
|
},
|
||||||
|
Reference in New Issue
Block a user