feat:【IoT 物联网】优化设备定位的部门实现

pull/790/MERGE
YunaiV 2025-07-05 10:19:27 +08:00
parent 79c08fc933
commit d5a28caa8e
13 changed files with 6219 additions and 7263 deletions

4
.env
View File

@ -23,3 +23,7 @@ VITE_APP_BAIDU_CODE = a1ff8825baa73c3a78eb96aa40325abc
VITE_APP_DEFAULT_LOGIN_TENANT = 芋道源码
VITE_APP_DEFAULT_LOGIN_USERNAME = admin
VITE_APP_DEFAULT_LOGIN_PASSWORD = admin123
# 高德地图
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'

View File

@ -34,11 +34,4 @@ VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
VITE_APP_CAPTCHA_ENABLE=true
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'
# 高德地图 API_KEY
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
# 高德地图 API 安全密钥
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -31,10 +31,4 @@ VITE_MALL_H5_DOMAIN='http://localhost:3000'
VITE_APP_CAPTCHA_ENABLE=false
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'
# 高德地图 API_KEY
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
# 高德地图 API 安全密钥
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -31,10 +31,4 @@ VITE_OUT_DIR=dist-prod
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'
# 高德地图 API_KEY
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
# 高德地图 API 安全密钥
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -31,10 +31,4 @@ VITE_OUT_DIR=dist-stage
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'
# 高德地图 API_KEY
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
# 高德地图 API 安全密钥
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'
VITE_GOVIEW_URL='http://127.0.0.1:3000'

View File

@ -31,10 +31,4 @@ VITE_OUT_DIR=dist-test
VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn'
# GoView域名
VITE_GOVIEW_URL='http://127.0.0.1:3000'
# 高德地图 API_KEY
VITE_AMAP_KEY='48eb85e0e245e293a0b61474943b177c'
# 高德地图 API 安全密钥
VITE_AMAP_SECURITY_CODE='86a45878caff8c0c60d88e80a93ddadd'
VITE_GOVIEW_URL='http://127.0.0.1:3000'

File diff suppressed because it is too large Load Diff

View File

@ -28,9 +28,9 @@ export enum DeviceTypeEnum {
}
// IOT 产品定位类型枚举类 0: 手动定位, 1: IP 定位, 2: 定位模块定位
export enum LocationTypeEnum {
MANUAL = 0, // 手动定位
IP = 1, // IP 定位
MODULE = 2 // 定位模块定位
MODULE = 2, // 设备定位
MANUAL = 3 // 手动定位
}
// IOT 数据格式(编解码器类型)枚举类
export enum CodecTypeEnum {

View File

@ -12,11 +12,10 @@
<span>设备信息</span>
</div>
</template>
<el-descriptions :column="2" border class="device-descriptions">
<el-descriptions :column="2" border>
<el-descriptions-item label="产品名称">{{ product.name }}</el-descriptions-item>
<el-descriptions-item label="ProductKey">
{{ product.productKey }}
<el-button @click="copyToClipboard(product.productKey)" link>复制</el-button>
</el-descriptions-item>
<el-descriptions-item label="设备类型">
<dict-tag :type="DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE" :value="product.deviceType" />
@ -26,7 +25,6 @@
</el-descriptions-item>
<el-descriptions-item label="DeviceName">
{{ device.deviceName }}
<el-button @click="copyToClipboard(device.deviceName)" link>复制</el-button>
</el-descriptions-item>
<el-descriptions-item label="备注名称">{{ device.nickname }}</el-descriptions-item>
<el-descriptions-item label="创建时间">
@ -45,7 +43,9 @@
{{ formatDate(device.offlineTime) }}
</el-descriptions-item>
<el-descriptions-item label="认证信息">
<el-button type="primary" @click="handleAuthInfoDialogOpen" plain>查看</el-button>
<el-button type="primary" @click="handleAuthInfoDialogOpen" plain size="small"
>查看</el-button
>
</el-descriptions-item>
</el-descriptions>
</el-card>
@ -61,9 +61,8 @@
<span>设备位置</span>
</div>
<div class="text-[14px] text-[var(--el-text-color-secondary)]">
最后上线时间{{
device.onlineTime ? formatDate(device.onlineTime, 'MM-DD HH:mm:ss') : '--'
}}
最后上线时间
{{ device.onlineTime ? formatDate(device.onlineTime) : '--' }}
</div>
</div>
</template>
@ -132,7 +131,6 @@
</div>
<!-- TODO 待开发设备标签 -->
<!-- TODO 待开发设备地图 -->
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
@ -152,6 +150,7 @@ const authDialogVisible = ref(false) // 定义设备认证信息弹框的可见
const authPasswordVisible = ref(false) //
const authInfo = ref<IotDeviceAuthInfoVO>({} as IotDeviceAuthInfoVO) //
// TODO @AI使 /** */
//
const showMap = computed(() => {
return !!(device.longitude && device.latitude)
@ -179,7 +178,6 @@ const copyToClipboard = async (text: string) => {
const handleAuthInfoDialogOpen = async () => {
try {
authInfo.value = await DeviceApi.getDeviceAuthInfo(device.id)
//
authDialogVisible.value = true
} catch (error) {
@ -193,16 +191,3 @@ const handleAuthInfoDialogClose = () => {
authDialogVisible.value = false
}
</script>
<style scoped>
/* 使用少量CSS覆盖el-descriptions组件的样式使其更符合Tailwind的间距设计 */
.device-descriptions :deep(.el-descriptions__label),
.device-descriptions :deep(.el-descriptions__content) {
@apply px-4 py-3 flex items-center;
min-height: 50px;
}
.device-descriptions :deep(.el-descriptions__body) {
@apply p-0;
}
</style>

View File

@ -2,7 +2,7 @@
<div class="app-container">
<!-- 固件信息 -->
<ContentWrap title="固件信息" class="mb-20px">
<el-descriptions :column="3" v-loading="firmwareLoading">
<el-descriptions :column="3" v-loading="firmwareLoading" border>
<el-descriptions-item label="固件名称">
{{ firmware?.name }}
</el-descriptions-item>

View File

@ -2,7 +2,7 @@
<Dialog v-model="dialogVisible" title="升级任务详情" width="1200px" append-to-body>
<!-- 任务信息 -->
<ContentWrap title="任务信息" class="mb-20px">
<el-descriptions :column="3" v-loading="taskLoading">
<el-descriptions :column="3" v-loading="taskLoading" border>
<el-descriptions-item label="任务编号">{{ task.id }}</el-descriptions-item>
<el-descriptions-item label="任务名称">{{ task.name }}</el-descriptions-item>
<el-descriptions-item label="升级范围">

View File

@ -34,7 +34,7 @@
</el-select>
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-radio-group v-model="formData.deviceType" :disabled="formType === 'update'">
<el-radioTO-group v-model="formData.deviceType" :disabled="formType === 'update'">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.IOT_PRODUCT_DEVICE_TYPE)"
:key="dict.value"
@ -42,18 +42,7 @@
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="定位类型" prop="locationType">
<el-radio-group v-model="formData.locationType" :disabled="formType === 'update'">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.IOT_LOCATION_TYPE)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-radioTO-group>
</el-form-item>
<el-form-item
v-if="[DeviceTypeEnum.DEVICE, DeviceTypeEnum.GATEWAY].includes(formData.deviceType)"
@ -73,6 +62,17 @@
/>
</el-select>
</el-form-item>
<el-form-item label="定位类型" prop="locationType">
<el-radio-group v-model="formData.locationType" :disabled="formType === 'update'">
<el-radio
v-for="dict in getIntDictOptions(DICT_TYPE.IOT_LOCATION_TYPE)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="数据格式" prop="codecType">
<el-radio-group v-model="formData.codecType" :disabled="formType === 'update'">
<el-radio
@ -139,7 +139,7 @@ const formRules = reactive({
name: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }],
categoryId: [{ required: true, message: '产品分类不能为空', trigger: 'change' }],
deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'change' }],
locationType: [{ required: false, message: '定位类型不能为空', trigger: 'change' }],
locationType: [{ required: true, message: '定位类型不能为空', trigger: 'change' }],
netType: [
{
required: true,

View File

@ -1,6 +1,6 @@
<template>
<ContentWrap>
<el-descriptions :column="3" title="产品信息">
<el-descriptions :column="3" title="产品信息" border>
<el-descriptions-item label="产品名称">{{ product.name }}</el-descriptions-item>
<el-descriptions-item label="所属分类">{{ product.categoryName }}</el-descriptions-item>
<el-descriptions-item label="设备类型">