home page
This commit is contained in:
@ -10,6 +10,7 @@
|
||||
"build:stage": "vite build --mode staging",
|
||||
"build:caddy": "vite build --mode caddy",
|
||||
"preview": "vite preview",
|
||||
"preview:caddy": "caddy run --config ./Caddyfile",
|
||||
"format": "prettier --write \"**/*.{js,ts,tsx,jsx,vue,md}\"",
|
||||
"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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
||||
<script setup>
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { onActivated, onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { listProduct } from "@/api/product/product";
|
||||
import OperatingStatus from "@/views/iot/device/detail-panes/OperatingStatus.vue";
|
||||
import { addDevice, getDevice, updateDevice } from "@/api/iot/device";
|
||||
|
@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
|
||||
proxy: {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
"/dev-api": {
|
||||
target: "http://192.168.1.201:1616",
|
||||
target: "http://117.72.16.89/api",
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, ""),
|
||||
},
|
||||
|
Reference in New Issue
Block a user