详情页面
This commit is contained in:
parent
67dce31b56
commit
d6f433bd84
181
src/views/devices/DetailsForm.vue
Normal file
181
src/views/devices/DetailsForm.vue
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog v-model="dialogVisible" :title="dialogTitle">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
v-loading="formLoading"
|
||||||
|
:model="formData"
|
||||||
|
label-width="100px"
|
||||||
|
:disabled="true"
|
||||||
|
>
|
||||||
|
<el-form-item label="设备ID">
|
||||||
|
<span>{{ formData.deviceKey }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备名称">
|
||||||
|
<span>{{ formData.deviceName }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="所属机构">
|
||||||
|
<span>{{ getOrgName(formData.productId) }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备类型">
|
||||||
|
<span>{{ getDeviceTypeName(formData.deviceType) }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备位置">
|
||||||
|
<span>{{ formData.address }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备状态">
|
||||||
|
<span>{{ getDeviceStateName(formData.state) }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="设备描述">
|
||||||
|
<span>{{ formData.description || '-' }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="dialogVisible = false">关 闭</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||||
|
import * as DeviceApi from '@/api/iot/device/device'
|
||||||
|
import * as ProductApi from '@/api/iot/product/product'
|
||||||
|
import { DeviceStateEnum } from '@/api/iot/device/device'
|
||||||
|
|
||||||
|
defineOptions({ name: 'DeviceDetailsForm' })
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中
|
||||||
|
const formData = ref<DeviceApi.DeviceVO>({
|
||||||
|
id: 0,
|
||||||
|
deviceKey: '',
|
||||||
|
deviceName: '',
|
||||||
|
productId: 0,
|
||||||
|
productKey: '',
|
||||||
|
deviceType: 0,
|
||||||
|
nickname: '',
|
||||||
|
gatewayId: 0,
|
||||||
|
state: DeviceStateEnum.INACTIVE,
|
||||||
|
onlineTime: new Date(),
|
||||||
|
offlineTime: new Date(),
|
||||||
|
activeTime: new Date(),
|
||||||
|
createTime: new Date(),
|
||||||
|
ip: '',
|
||||||
|
firmwareVersion: '',
|
||||||
|
deviceSecret: '',
|
||||||
|
mqttClientId: '',
|
||||||
|
mqttUsername: '',
|
||||||
|
mqttPassword: '',
|
||||||
|
authType: '',
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
areaId: 0,
|
||||||
|
address: '',
|
||||||
|
serialNumber: '',
|
||||||
|
config: '',
|
||||||
|
description: '',
|
||||||
|
groupIds: []
|
||||||
|
})
|
||||||
|
|
||||||
|
const productList = ref<ProductApi.ProductVO[]>([]) // 产品列表
|
||||||
|
|
||||||
|
// 获取机构名称
|
||||||
|
const getOrgName = (productId: number) => {
|
||||||
|
const product = productList.value.find(item => item.id === productId)
|
||||||
|
return product?.name || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取设备类型名称
|
||||||
|
const getDeviceTypeName = (type: number) => {
|
||||||
|
const dict = getIntDictOptions(DICT_TYPE.IOT_DEVICE_TYPE).find(item => item.value === type)
|
||||||
|
return dict?.label || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取设备状态名称
|
||||||
|
const getDeviceStateName = (state: number) => {
|
||||||
|
const dict = getIntDictOptions(DICT_TYPE.IOT_DEVICE_STATE).find(item => item.value === state)
|
||||||
|
return dict?.label || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (id: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = '设备详情'
|
||||||
|
resetForm()
|
||||||
|
// 获取设备数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
// 这里模拟获取设备数据,实际项目中应该调用API
|
||||||
|
const mockDeviceData = {
|
||||||
|
id: id,
|
||||||
|
deviceKey: 'Device' + id,
|
||||||
|
deviceName: '测试设备' + id,
|
||||||
|
deviceType: 1,
|
||||||
|
state: DeviceStateEnum.INACTIVE,
|
||||||
|
address: '北京市/海淀区/中关村',
|
||||||
|
description: '这是一个测试设备的描述信息',
|
||||||
|
productId: 1,
|
||||||
|
productKey: 'product_key_' + id,
|
||||||
|
nickname: '设备昵称' + id,
|
||||||
|
gatewayId: 1,
|
||||||
|
onlineTime: new Date(),
|
||||||
|
offlineTime: new Date(),
|
||||||
|
activeTime: new Date(),
|
||||||
|
createTime: new Date(),
|
||||||
|
ip: '192.168.1.1',
|
||||||
|
firmwareVersion: '1.0.0',
|
||||||
|
deviceSecret: 'secret_' + id,
|
||||||
|
mqttClientId: 'client_' + id,
|
||||||
|
mqttUsername: 'username_' + id,
|
||||||
|
mqttPassword: 'password_' + id,
|
||||||
|
authType: 'password',
|
||||||
|
latitude: 39.123456,
|
||||||
|
longitude: 117.123456,
|
||||||
|
areaId: 1,
|
||||||
|
serialNumber: 'SN' + id,
|
||||||
|
config: '{}',
|
||||||
|
groupIds: []
|
||||||
|
}
|
||||||
|
formData.value = mockDeviceData
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
id: 0,
|
||||||
|
deviceKey: '',
|
||||||
|
deviceName: '',
|
||||||
|
productId: 0,
|
||||||
|
productKey: '',
|
||||||
|
deviceType: 0,
|
||||||
|
nickname: '',
|
||||||
|
gatewayId: 0,
|
||||||
|
state: DeviceStateEnum.INACTIVE,
|
||||||
|
onlineTime: new Date(),
|
||||||
|
offlineTime: new Date(),
|
||||||
|
activeTime: new Date(),
|
||||||
|
createTime: new Date(),
|
||||||
|
ip: '',
|
||||||
|
firmwareVersion: '',
|
||||||
|
deviceSecret: '',
|
||||||
|
mqttClientId: '',
|
||||||
|
mqttUsername: '',
|
||||||
|
mqttPassword: '',
|
||||||
|
authType: '',
|
||||||
|
latitude: 0,
|
||||||
|
longitude: 0,
|
||||||
|
areaId: 0,
|
||||||
|
address: '',
|
||||||
|
serialNumber: '',
|
||||||
|
config: '',
|
||||||
|
description: '',
|
||||||
|
groupIds: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -6,10 +6,14 @@
|
|||||||
:model="formData"
|
:model="formData"
|
||||||
:rules="formRules"
|
:rules="formRules"
|
||||||
label-width="100px"
|
label-width="100px"
|
||||||
|
:disabled="isDetail"
|
||||||
>
|
>
|
||||||
<el-form-item label="设备ID" prop="deviceId">
|
<el-form-item label="设备ID" prop="deviceId">
|
||||||
<el-input v-model="formData.deviceId" placeholder="请输入设备ID" />
|
<el-input v-model="formData.deviceId" placeholder="请输入设备ID" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="设备名称" prop="deviceName">
|
||||||
|
<el-input v-model="formData.deviceName" placeholder="请输入设备名称" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="所属机构" prop="orgId">
|
<el-form-item label="所属机构" prop="orgId">
|
||||||
<el-select v-model="formData.orgId" placeholder="请选择所属机构" @change="handleProductChange">
|
<el-select v-model="formData.orgId" placeholder="请选择所属机构" @change="handleProductChange">
|
||||||
<el-option
|
<el-option
|
||||||
@ -67,8 +71,8 @@
|
|||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
<el-button v-if="!isDetail" type="primary" @click="submitForm">确 定</el-button>
|
||||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
<el-button @click="dialogVisible = false">{{ isDetail ? '关 闭' : '取 消' }}</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
@ -97,9 +101,10 @@ const dialogVisible = ref(false) // 弹窗的是否展示
|
|||||||
const dialogTitle = ref('') // 弹窗的标题
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const isDetail = ref(false) // 是否为详情模式
|
||||||
const formData = ref<DeviceApi.DeviceVO>({
|
const formData = ref<DeviceApi.DeviceVO>({
|
||||||
id: undefined,
|
id: undefined,
|
||||||
deviceKey: undefined,
|
deviceId: undefined,
|
||||||
deviceName: undefined,
|
deviceName: undefined,
|
||||||
productId: undefined,
|
productId: undefined,
|
||||||
productKey: undefined,
|
productKey: undefined,
|
||||||
@ -122,14 +127,16 @@ const formData = ref<DeviceApi.DeviceVO>({
|
|||||||
longitude: undefined,
|
longitude: undefined,
|
||||||
areaId: undefined,
|
areaId: undefined,
|
||||||
address: undefined,
|
address: undefined,
|
||||||
|
detailAddress: undefined,
|
||||||
serialNumber: undefined,
|
serialNumber: undefined,
|
||||||
config: undefined,
|
config: undefined,
|
||||||
|
description: undefined,
|
||||||
groupIds: []
|
groupIds: []
|
||||||
})
|
})
|
||||||
|
|
||||||
const formRules = reactive<FormRules>({
|
const formRules = reactive<FormRules>({
|
||||||
deviceId: [{ required: true, message: '设备ID不能为空', trigger: 'blur' }],
|
deviceId: [{ required: true, message: '设备ID不能为空', trigger: 'blur' }],
|
||||||
orgId: [{ required: true, message: '所属机构不能为空', trigger: 'blur' }],
|
deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
|
||||||
deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
|
deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'blur' }],
|
||||||
address: [{ required: true, message: '设备位置不能为空', trigger: 'blur' }],
|
address: [{ required: true, message: '设备位置不能为空', trigger: 'blur' }],
|
||||||
})
|
})
|
||||||
@ -145,12 +152,46 @@ const open = async (type: string, id?: number) => {
|
|||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
dialogTitle.value = t('action.' + type)
|
||||||
formType.value = type
|
formType.value = type
|
||||||
|
isDetail.value = type === 'details' // 设置是否为详情模式
|
||||||
resetForm()
|
resetForm()
|
||||||
// 修改时,设置数据
|
// 修改时,设置数据
|
||||||
if (id) {
|
if (id) {
|
||||||
formLoading.value = true
|
formLoading.value = true
|
||||||
try {
|
try {
|
||||||
formData.value = await DeviceApi.getDevice(id)
|
// 这里模拟获取设备数据,实际项目中应该调用API
|
||||||
|
const mockDeviceData = {
|
||||||
|
id: id,
|
||||||
|
deviceId: 'Device' + id,
|
||||||
|
deviceName: '测试设备' + id,
|
||||||
|
deviceType: 1,
|
||||||
|
state: DeviceStateEnum.INACTIVE,
|
||||||
|
address: '',
|
||||||
|
detailAddress: '测试地址123号',
|
||||||
|
description: '这是一个测试设备的描述信息',
|
||||||
|
productId: 1,
|
||||||
|
productKey: 'product_key_' + id,
|
||||||
|
nickname: '设备昵称' + id,
|
||||||
|
gatewayId: 1,
|
||||||
|
onlineTime: new Date(),
|
||||||
|
offlineTime: new Date(),
|
||||||
|
activeTime: new Date(),
|
||||||
|
createTime: new Date(),
|
||||||
|
ip: '192.168.1.1',
|
||||||
|
firmwareVersion: '1.0.0',
|
||||||
|
deviceSecret: 'secret_' + id,
|
||||||
|
mqttClientId: 'client_' + id,
|
||||||
|
mqttUsername: 'username_' + id,
|
||||||
|
mqttPassword: 'password_' + id,
|
||||||
|
authType: 'password',
|
||||||
|
latitude: 39.123456,
|
||||||
|
longitude: 117.123456,
|
||||||
|
areaId: 1,
|
||||||
|
serialNumber: 'SN' + id,
|
||||||
|
config: '{}',
|
||||||
|
groupIds: []
|
||||||
|
}
|
||||||
|
formData.value = mockDeviceData
|
||||||
|
|
||||||
// 处理地址数据
|
// 处理地址数据
|
||||||
if (formData.value.address) {
|
if (formData.value.address) {
|
||||||
const addressParts = formData.value.address.split('/')
|
const addressParts = formData.value.address.split('/')
|
||||||
@ -176,10 +217,6 @@ const open = async (type: string, id?: number) => {
|
|||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 获得产品列表
|
|
||||||
productList.value = await ProductApi.getSimpleProductList()
|
|
||||||
// 获得分组列表
|
|
||||||
groupList.value = await DeviceGroupApi.getSimpleDeviceGroupList()
|
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
@ -213,7 +250,7 @@ const submitForm = async () => {
|
|||||||
const resetForm = () => {
|
const resetForm = () => {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
deviceKey: undefined,
|
deviceId: undefined,
|
||||||
deviceName: undefined,
|
deviceName: undefined,
|
||||||
productId: undefined,
|
productId: undefined,
|
||||||
productKey: undefined,
|
productKey: undefined,
|
||||||
@ -236,8 +273,10 @@ const resetForm = () => {
|
|||||||
longitude: undefined,
|
longitude: undefined,
|
||||||
areaId: undefined,
|
areaId: undefined,
|
||||||
address: undefined,
|
address: undefined,
|
||||||
|
detailAddress: undefined,
|
||||||
serialNumber: undefined,
|
serialNumber: undefined,
|
||||||
config: undefined,
|
config: undefined,
|
||||||
|
description: undefined,
|
||||||
groupIds: []
|
groupIds: []
|
||||||
}
|
}
|
||||||
selectedOptions.value = []
|
selectedOptions.value = []
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="detail-item">
|
<p class="detail-item">
|
||||||
<span class="label">位置:</span>
|
<span class="label">位置:</span>
|
||||||
<span class="value">{{ deviceInfo.location }}</span>
|
<span class="value">{{ deviceInfo.address }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="divider"></div>
|
<div class="divider"></div>
|
||||||
@ -82,7 +82,7 @@ const props = defineProps({
|
|||||||
id: '',
|
id: '',
|
||||||
name: '',
|
name: '',
|
||||||
type: '',
|
type: '',
|
||||||
location: '',
|
address: '',
|
||||||
status: 'normal',
|
status: 'normal',
|
||||||
statusText: '正常'
|
statusText: '正常'
|
||||||
})
|
})
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
|
|
||||||
<!-- 设备表单 -->
|
<!-- 设备表单 -->
|
||||||
<DeviceForm ref="deviceFormRef" @success="handleQuery" />
|
<DeviceForm ref="deviceFormRef" @success="handleQuery" />
|
||||||
|
<DetailsForm ref="detailsFormRef" @success="handleQuery" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -85,6 +86,7 @@ import { getIntDictOptions } from '@/utils/dict'
|
|||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
import DeviceCard from '../devices/devices_cards.vue'
|
import DeviceCard from '../devices/devices_cards.vue'
|
||||||
import DeviceForm from './DevFrom.vue'
|
import DeviceForm from './DevFrom.vue'
|
||||||
|
import DetailsForm from './DetailsForm.vue'
|
||||||
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
interface QueryParams {
|
interface QueryParams {
|
||||||
@ -105,7 +107,7 @@ const deviceList = ref([
|
|||||||
id: 'Blood001',
|
id: 'Blood001',
|
||||||
name: '血压仪',
|
name: '血压仪',
|
||||||
type: '血压仪',
|
type: '血压仪',
|
||||||
location: '天津市/西青区/精武镇',
|
address: '天津市/市辖区/西青区/精武镇',
|
||||||
status: 'normal',
|
status: 'normal',
|
||||||
statusText: '在线'
|
statusText: '在线'
|
||||||
},
|
},
|
||||||
@ -113,7 +115,7 @@ const deviceList = ref([
|
|||||||
id: 'Glucose001',
|
id: 'Glucose001',
|
||||||
name: '血糖仪',
|
name: '血糖仪',
|
||||||
type: '血糖仪',
|
type: '血糖仪',
|
||||||
location: '河北省/廊坊市/安次区',
|
address: '河北省/廊坊市/安次区',
|
||||||
status: 'warning',
|
status: 'warning',
|
||||||
statusText: '待激活'
|
statusText: '待激活'
|
||||||
},
|
},
|
||||||
@ -121,7 +123,7 @@ const deviceList = ref([
|
|||||||
id: 'Oxygen001',
|
id: 'Oxygen001',
|
||||||
name: '血氧仪',
|
name: '血氧仪',
|
||||||
type: '血氧仪',
|
type: '血氧仪',
|
||||||
location: '四川省/绵阳市/涪城区',
|
address: '四川省/绵阳市/涪城区',
|
||||||
status: 'error',
|
status: 'error',
|
||||||
statusText: '离线'
|
statusText: '离线'
|
||||||
}
|
}
|
||||||
@ -131,6 +133,8 @@ const deviceList = ref([
|
|||||||
const queryFormRef = ref()
|
const queryFormRef = ref()
|
||||||
// 设备表单引用
|
// 设备表单引用
|
||||||
const deviceFormRef = ref()
|
const deviceFormRef = ref()
|
||||||
|
// 设备详情表单引用
|
||||||
|
const detailsFormRef = ref()
|
||||||
|
|
||||||
// 查询方法
|
// 查询方法
|
||||||
const handleQuery = () => {
|
const handleQuery = () => {
|
||||||
@ -145,14 +149,17 @@ const resetQuery = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 打开表单
|
// 打开表单
|
||||||
const openForm = (type: string, id?: number) => {
|
const openForm = (type: string) => {
|
||||||
deviceFormRef.value?.open(type, id)
|
deviceFormRef.value?.open(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理设备操作
|
// 处理设备操作
|
||||||
const handleDeviceAction = (action: any) => {
|
const handleDeviceAction = (action: any) => {
|
||||||
if (action.type === 'detail') {
|
if (action.action === 'details') {
|
||||||
openForm('update', action.device.id)
|
// 打开表单并加载设备数据
|
||||||
|
detailsFormRef.value?.open(action.deviceId)
|
||||||
|
} else {
|
||||||
|
console.log('设备操作:', action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user