Browse Source

feat: 设备地图增加暗黑模式兼容,级联管理接口对接

yanglzh 9 months ago
parent
commit
164a82c5d3

+ 6 - 0
src/api/system/index.ts

@@ -205,5 +205,11 @@ export default {
     down: (params: object) => file('/system/monitor/downloadLog', params),
     delete: (params: object) => del('/system/monitor/lastLinesLog/delete', params),
   },
+  cascade: {
+    getList: (params: object) => get('/cascade/subplatform/list', params),
+    deviceList: (params: object) => get('/cascade/device/list', params),
+    sync: () => post('/cascade/subplatform/sync'),
+    statistic: () => get('/cascade/subplatform/statistic'),
+  },
   getInfoByKey: (ConfigKey: string) => get('/common/config/getInfoByKey', { ConfigKey })
 }

+ 46 - 0
src/views/iot/cascade/deviceList.vue

@@ -0,0 +1,46 @@
+<template>
+	<el-dialog v-model="visible" title="设备列表" width="800px" destroy-on-close>
+		<div class="device-list">
+			<el-table :data="tableData" style="width: 100%" v-loading="loading">
+				<el-table-column prop="deviceName" label="设备名称" />
+				<el-table-column prop="deviceCode" label="设备编号" />
+				<el-table-column prop="status" label="状态">
+					<template #default="scope">
+						<el-tag :type="scope.row.status === 1 ? 'success' : 'danger'">
+							{{ scope.row.status === 1 ? '在线' : '离线' }}
+						</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="createTime" label="创建时间" />
+			</el-table>
+		</div>
+	</el-dialog>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import api from '/@/api/system'
+import { useSearch } from '/@/hooks/useCommon'
+
+const visible = ref(false)
+
+const { params, tableData, getList, loading } = useSearch<any[]>(api.cascade.deviceList, 'list', {
+	tenantCode: '',
+})
+
+// 打开弹窗
+const open = async (row: any) => {
+	tableData.value = []
+	params.tenantCode = row.tenantCode
+	visible.value = true
+	getList(1)
+}
+
+defineExpose({ open })
+</script>
+
+<style scoped>
+.device-list {
+	padding: 0 20px;
+}
+</style>

+ 168 - 0
src/views/iot/cascade/index.vue

@@ -0,0 +1,168 @@
+<template>
+	<div class="page-full">
+		<div class="search flex-row mb-4 gap-4">
+			<el-card shadow="nover" class="home-card-top-part flex1">
+				<div class="top">
+					<div class="label">子平台</div>
+					<span class="font30">{{ count.PlatformTotal }}</span>
+				</div>
+				<div class="divider"></div>
+				<div class="card-bottom">
+					<div class="flex" style="gap: 10px">
+						<img src="/@/assets/ok.svg" alt="" class="icon" />
+						<span class="info" :style="{ color: '#3cd357' }">在线</span>
+						<div class="num">{{ count.PlatformOnline }}</div>
+					</div>
+					<div class="split"></div>
+					<div class="flex" style="gap: 10px">
+						<img src="/@/assets/stop.svg" alt="" class="icon" />
+						<span class="info" :style="{ color: '#FFBB73' }">离线</span>
+						<div class="num">{{ count.PlatformOffline }}</div>
+					</div>
+				</div>
+			</el-card>
+			<el-card shadow="nover" class="home-card-top-part flex1">
+				<div class="top">
+					<div class="label">设备总数</div>
+					<span class="font30">{{ count.DeviceTotal }}</span>
+				</div>
+				<div class="divider"></div>
+				<div class="card-bottom">
+					<div class="flex" style="gap: 10px">
+						<img src="/@/assets/ok.svg" alt="" class="icon" />
+						<span class="info" :style="{ color: '#3cd357' }">在线</span>
+						<div class="num">{{ count.DeviceOnline }}</div>
+					</div>
+					<div class="split"></div>
+					<div class="flex" style="gap: 10px">
+						<img src="/@/assets/stop.svg" alt="" class="icon" />
+						<span class="info" :style="{ color: '#FFBB73' }">离线</span>
+						<div class="num">{{ count.DeviceOffline }}</div>
+					</div>
+				</div>
+			</el-card>
+		</div>
+		<el-card shadow="nover" class="page-full-part">
+			<el-table :data="tableData" style="width: 100%" row-key="id" v-loading="loading">
+				<el-table-column type="index" label="序号" width="100" align="center"></el-table-column>
+				<el-table-column prop="name" label="子平台" show-overflow-tooltip v-col="'name'" align="center"></el-table-column>
+				<el-table-column prop="address" label="地址" v-col="'address'" align="center"></el-table-column>
+				<el-table-column prop="deviceOnline" label="设备" v-col="'deviceOnline'" align="center">
+					<template #default="{ row }">{{ row.deviceOnline }}/{{ row.deviceOnline + row.deviceOffline }} </template>
+				</el-table-column>
+				<el-table-column prop="status" label="状态" v-col="'status'" :formatter="(row, a) => (a ? '在线' : '离线')" align="center"></el-table-column>
+				<el-table-column prop="lastTime" label="最后更新时间" width="180" align="center" v-col="'lastTime'"></el-table-column>
+				<el-table-column label="操作" width="160" align="center">
+					<template #default="{ row }">
+						<!-- <el-button size="small" text type="warning" v-auth="'sync'" :loading="row.loading" @click="sync(row)">同步</el-button> -->
+						<el-button size="small" text type="primary" v-auth="'detail'" @click="viewDeviceList(row)">查看设备</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			<pagination v-if="params.total" :total="params.total" v-model:page="params.pageNum" v-model:limit="params.pageSize" @pagination="getList()" />
+		</el-card>
+		<deviceList ref="deviceListRef" />
+	</div>
+</template>
+
+<script lang="ts" setup>
+import { ElMessage } from 'element-plus'
+import { ref, reactive } from 'vue'
+import api from '/@/api/system'
+import { useSearch } from '/@/hooks/useCommon'
+import deviceList from './deviceList.vue'
+
+const deviceListRef = ref()
+const { params, tableData, getList, loading } = useSearch<any[]>(api.cascade.getList, 'list', {})
+getList()
+
+const count = reactive({
+	PlatformTotal: '-',
+	PlatformOnline: '-',
+	PlatformOffline: '-',
+	DeviceTotal: '-',
+	DeviceOnline: '-',
+	DeviceOffline: '-',
+})
+
+api.cascade.statistic().then(({ data: res = {} }: any) => {
+	Object.assign(count, res)
+})
+
+const viewDeviceList = (row: any) => {
+	deviceListRef.value?.open(row)
+}
+
+const sync = (row?: any) => {
+	row.loading = true
+	api.cascade
+		.sync()
+		.then(() => {
+			ElMessage.success('同步成功')
+		})
+		.finally(() => {
+			row.loading = false
+		})
+}
+</script>
+<style lang="scss" scoped>
+.home-card-top-part {
+	background-color: var(--el-color-white);
+	padding: 0;
+
+	.top {
+		display: flex;
+		justify-content: center;
+		overflow: hidden;
+		align-items: center;
+	}
+
+	.icoimg {
+		width: 54px !important;
+		height: 54px !important;
+		margin-right: 12px;
+	}
+
+	.label {
+		font-size: 14px;
+		font-weight: 500;
+		margin-right: 12px;
+		margin-top: 3px;
+	}
+
+	.divider {
+		border-top: 1px solid var(--el-border-color-light);
+		margin: 5px 0 10px;
+	}
+
+	.font30 {
+		color: #4285f4;
+		font-weight: bold;
+		font-size: 30px;
+	}
+
+	.card-bottom {
+		font-size: 12px;
+		display: flex;
+		align-items: center;
+		justify-content: space-around;
+		gap: 12px;
+		white-space: nowrap;
+
+		.split {
+			border-right: 1px solid var(--el-border-color-light);
+			height: 20px;
+		}
+
+		.icon {
+			width: 17px;
+			height: 17px;
+		}
+
+		.info {
+			font-size: 12px;
+			font-weight: 500;
+		}
+	}
+}
+</style>

+ 15 - 7
src/views/iot/property/deviceMap/index.vue

@@ -17,9 +17,12 @@
 
 <script lang="ts" setup>
 import { initMap, MapStyleJson } from '/@/utils/map'
-import { onMounted, ref } from 'vue'
+import { onMounted, ref, watch } from 'vue'
 import api from '/@/api/device'
 import { ElMessage } from 'element-plus'
+import { useStore } from '/@/store/index'
+
+const store = useStore()
 
 let BMapGL: any = null
 let map: any = null
@@ -32,16 +35,18 @@ api.product.getLists().then((res: any) => {
 	productData.value = res.product
 })
 
-onMounted(async () => {
+const initMapFunc = async () => {
 	const { BMapGL: theBMapGL } = await initMap()
 
 	BMapGL = theBMapGL
 
 	map = new BMapGL.Map('device-map')
 
-	map.setMapStyleV2({
-		styleJson: MapStyleJson,
-	})
+	if (store.state.themeConfig.themeConfig.isIsDark) {
+		map.setMapStyleV2({
+			styleJson: MapStyleJson,
+		})
+	}
 
 	map.enableScrollWheelZoom(true)
 	map.centerAndZoom('四川', 5)
@@ -50,7 +55,11 @@ onMounted(async () => {
 	map.addEventListener('click', function () {
 		map.closeInfoWindow()
 	})
-})
+}
+
+onMounted(initMapFunc)
+
+watch(() => store.state.themeConfig.themeConfig.isIsDark, initMapFunc)
 
 // 监听产品变化
 const handleProductChange = () => {
@@ -58,7 +67,6 @@ const handleProductChange = () => {
 }
 
 async function setMarker() {
-	console.log('setMarker')
 	loading.value = true
 	try {
 		const { device } = await api.device.allList({ productKey: productKey.value })