refactor:采集设备/采集设备子列表重构

main
黄伟杰 3 months ago
parent 0cfe869931
commit ff32d0f197

@ -21,6 +21,8 @@ export interface DeviceVO {
url: string // 端点url
username: string // 用户名
password: string // 密码
certificate?: string // 证书
secretKey?: string // 秘钥
}
// 物联设备 API
@ -53,6 +55,11 @@ export const DeviceApi = {
return await request.delete({ url: `/iot/device/delete?id=` + id })
},
// 复制物联设备
copyDevice: async (id: number) => {
return await request.post({ url: `/iot/device/copy`, params: { id } })
},
// 导出物联设备 Excel
exportDevice: async (params) => {
return await request.download({ url: `/iot/device/export-excel`, params })

@ -1,18 +1,31 @@
<template>
<Dialog :title="dialogTitle" v-model="dialogVisible">
<template #title>
<div class="flex flex-col">
<div>{{ dialogTitle }}</div>
<div
v-if="formType === 'setting' && formData.deviceName"
class="text-12px leading-16px text-[var(--el-text-color-secondary)]"
>
设备名称{{ formData.deviceName }}
</div>
</div>
</template>
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
:rules="activeRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="formData.deviceCode" placeholder="请输入设备编号" />
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="formData.deviceName" placeholder="请输入设备名称" />
</el-form-item>
<template v-if="formType === 'create'">
<el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="formData.deviceCode" placeholder="请输入设备编号" />
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="formData.deviceName" placeholder="请输入设备名称" />
</el-form-item>
</template>
<!-- <el-form-item label="设备类型" prop="deviceType">
<el-select v-model="formData.deviceType" placeholder="请选择设备类型">
<el-option
@ -49,56 +62,73 @@
<!-- <el-form-item label="离线间隔" prop="offLineDuration">
<el-input v-model="formData.offLineDuration" placeholder="请输入离线间隔" />
</el-form-item> -->
<el-form-item label="模型选择" prop="deviceModelId">
<el-select
v-model="formData.deviceModelId"
clearable
filterable
placeholder="请选择设备模型"
>
<el-option
v-for="item in modelList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-form-item label="采集周期/s" prop="sampleCycle">
<el-input v-model="formData.sampleCycle" placeholder="请输入采集周期" />
</el-form-item>
<el-form-item label="端点URL" prop="url">
<el-input v-model="formData.url" placeholder="请输入端点URL" />
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="formData.password" placeholder="请输入密码" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="是否启用" prop="isEnable">
<el-radio-group v-model="formData.isEnable">
<el-radio
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value"
:label="dict.value"
<template v-if="formType === 'create'">
<el-form-item label="模型选择" prop="deviceModelId">
<el-select
v-model="formData.deviceModelId"
clearable
filterable
placeholder="请选择设备模型"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
<el-option v-for="item in modelList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="采集周期/s" prop="sampleCycle">
<el-input v-model="formData.sampleCycle" placeholder="请输入采集周期" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="是否启用" prop="isEnable">
<el-radio-group v-model="formData.isEnable">
<el-radio
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<template v-else-if="formType === 'update'">
<el-form-item label="采集周期/s" prop="sampleCycle">
<el-input v-model="formData.sampleCycle" placeholder="请输入采集周期" />
</el-form-item>
<el-form-item label="是否启用" prop="isEnable">
<el-radio-group v-model="formData.isEnable">
<el-radio
v-for="dict in getBoolDictOptions(DICT_TYPE.INFRA_BOOLEAN_STRING)"
:key="dict.value"
:label="dict.value"
>
{{ dict.label }}
</el-radio>
</el-radio-group>
</el-form-item>
</template>
<template v-else>
<el-form-item label="端点URL" prop="url">
<el-input v-model="formData.url" placeholder="请输入端点URL" />
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input v-model="formData.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input v-model="formData.password" placeholder="请输入密码" show-password />
</el-form-item>
</template>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { getStrDictOptions, getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import { getBoolDictOptions, DICT_TYPE } from '@/utils/dict'
import { DeviceApi, DeviceVO } from '@/api/iot/device'
import {DeviceModelApi, DeviceModelVO} from "@/api/iot/devicemodel";
@ -135,16 +165,28 @@ const formData = ref({
password: undefined,
})
const formRules = reactive({
deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }],
deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
isEnable: [{ required: true, message: '是否启用不能为空', trigger: 'blur' }]
create: {
deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }],
deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
isEnable: [{ required: true, message: '是否启用不能为空', trigger: 'blur' }]
},
update: {
isEnable: [{ required: true, message: '是否启用不能为空', trigger: 'blur' }]
},
setting: {
url: [{ required: true, message: '端点URL不能为空', trigger: 'blur' }]
}
})
const activeRules = computed(() => {
return (formRules as any)[formType.value] ?? {}
})
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
dialogTitle.value = t('action.' + type)
dialogTitle.value = type === 'setting' ? '设备设置' : t('action.' + type)
formType.value = type
resetForm()
//
@ -167,11 +209,18 @@ const submitForm = async () => {
//
formLoading.value = true
try {
const data = formData.value as unknown as DeviceVO
const { id, deviceCode, deviceName, deviceModelId, sampleCycle, remark, isEnable, url, username, password } = formData.value as any
if (formType.value === 'create') {
await DeviceApi.createDevice(data)
const data: Partial<DeviceVO> = { deviceCode, deviceName, deviceModelId, sampleCycle, remark, isEnable }
await DeviceApi.createDevice(data as DeviceVO)
message.success(t('common.createSuccess'))
} else if (formType.value === 'update') {
const data: any = { id, deviceCode, deviceName, deviceModelId, sampleCycle, isEnable }
await DeviceApi.updateDevice(data)
message.success(t('common.updateSuccess'))
} else {
const data: any = { id, deviceCode, deviceName, deviceModelId, isEnable, url, username, password }
await DeviceApi.updateDevice(data)
message.success(t('common.updateSuccess'))
}
@ -198,7 +247,13 @@ const resetForm = () => {
offLineDuration: undefined,
lastOnlineTime: undefined,
remark: undefined,
isEnable: true
isEnable: true,
deviceModelId: undefined,
protocol: undefined,
sampleCycle: undefined,
url: undefined,
username: undefined,
password: undefined,
}
formRef.value?.resetFields()
}

@ -101,7 +101,7 @@ const formData = ref({
ratio: undefined as string | undefined,
sort: undefined as string | undefined,
remark: undefined as string | undefined,
deviceModelId: undefined as number | undefined
deviceId: undefined as number | undefined
})
const handleAttributeCodeInput = (val: string) => {
@ -174,8 +174,15 @@ const buildSubmitData = () => {
ratio,
sort,
remark,
deviceModelId
deviceId
} = formData.value
const parsedSort =
sort === undefined || sort === null || sort === ''
? undefined
: Number.isNaN(Number(sort))
? undefined
: Number(sort)
const data: any = {
attributeCode,
attributeName,
@ -184,9 +191,9 @@ const buildSubmitData = () => {
address,
dataUnit,
ratio,
sort,
sort: parsedSort,
remark,
deviceModelId
deviceId
}
if (formType.value === 'update') {
data.id = id
@ -200,16 +207,22 @@ const open = async (type: string, id?: number, deviceId: number) => {
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
formData.value.deviceModelId = deviceId
formData.value.deviceId = deviceId
await loadTypeList()
//
if (id) {
formLoading.value = true
try {
formData.value = await DeviceApi.getDeviceAttribute(id)
if (!(formData.value as any)?.deviceModelId) {
;(formData.value as any).deviceModelId = deviceId
if (!(formData.value as any)?.deviceId) {
;(formData.value as any).deviceId = deviceId
}
const currentSort = (formData.value as any)?.sort
if (currentSort !== undefined && currentSort !== null) {
;(formData.value as any).sort = String(currentSort)
}
const currentType = (formData.value as any)?.attributeType
if (currentType !== undefined && currentType !== null && currentType !== '') {
const matched = typeList.value.find(
@ -267,7 +280,7 @@ const resetForm = () => {
ratio: undefined,
sort: undefined,
remark: undefined,
deviceModelId: undefined
deviceId: undefined
}
formRef.value?.resetFields()
}

@ -27,7 +27,7 @@
/>
</el-form-item>
<el-form-item label="连接状态" prop="status">
<!-- <el-form-item label="连接状态" prop="status">
<el-select
v-model="queryParams.status"
placeholder="请选择状态"
@ -41,9 +41,9 @@
:value="dict.value"
/>
</el-select>
</el-form-item>
</el-form-item> -->
<el-form-item label="创建时间" prop="createTime">
<!-- <el-form-item label="创建时间" prop="createTime">
<el-date-picker
v-model="queryParams.createTime"
value-format="YYYY-MM-DD HH:mm:ss"
@ -53,7 +53,7 @@
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
class="!w-240px"
/>
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
@ -86,37 +86,38 @@
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="设备编号" align="left" prop="deviceCode" width="150px"/>
<el-table-column label="设备名称" align="left" prop="deviceName" width="200px"/>
<el-table-column label="设备编号" align="left" prop="deviceCode" width="200px"/>
<el-table-column label="设备名称" align="left" prop="deviceName" width="250px"/>
<!-- <el-table-column label="设备类型" align="left" prop="deviceType" width="150px"> -->
<!-- <template #default="scope">
<dict-tag :type="DICT_TYPE.IOT_DEVICE_TYPE" :value="scope.row.deviceType" />
</template>
</el-table-column> -->
<el-table-column label="通讯协议" align="left" prop="protocol" width="200px">
<el-table-column label="采集协议" align="left" prop="protocol" width="250px">
<template #default="scope">
<dict-tag :type="DICT_TYPE.IOT_PROTOCOL" :value="scope.row.procotol" />
</template>
</el-table-column>
<el-table-column label="采集周期" align="left" prop="sampleCycle" width="150px"/>
<el-table-column label="状态" align="center" prop="status">
<el-table-column label="连接状态" align="center" prop="status">
<template #default="scope">
<dict-tag :type="DICT_TYPE.IOT_GATEWAY_STATUS" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column label="采集周期(s)" align="left" prop="sampleCycle" width="150px"/>
<!-- <el-table-column label="读主题" align="center" prop="readTopic" />
<el-table-column label="写主题" align="center" prop="writeTopic" />
<el-table-column label="网关id" align="center" prop="gatewayId" /> -->
<!-- <el-table-column label="设备品牌id" align="center" prop="deviceBrandId" />-->
<!-- <el-table-column label="离线间隔" align="center" prop="offLineDuration" /> -->
<el-table-column
<!-- <el-table-column
label="最后上线时间"
align="center"
prop="lastOnlineTime"
:formatter="dateFormatter"
width="180px"
/>
<el-table-column label="备注" align="center" prop="remark" />
/> -->
<!-- <el-table-column label="备注" align="center" prop="remark" /> -->
<!-- <el-table-column
label="创建时间"
align="center"
@ -129,9 +130,25 @@
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.isEnable" />
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="220px">
<el-table-column label="操作" align="center" fixed="right" width="320px">
<template #default="scope">
<el-button link type="primary" @click.stop="handleShowAttribute(scope.row)">点位</el-button>
<el-button
link
type="primary"
@click="openForm('setting', scope.row.id)"
v-hasPermi="['iot:device:update']"
>
设置
</el-button>
<el-button
link
type="primary"
@click="handleCopy(scope.row.id)"
v-hasPermi="['iot:device:create']"
>
复制
</el-button>
<el-button
link
type="primary"
@ -254,6 +271,14 @@ const handleDelete = async (id: number) => {
} catch {}
}
const handleCopy = async (id: number) => {
try {
await DeviceApi.copyDevice(id)
message.success('复制成功')
await getList()
} catch {}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {

Loading…
Cancel
Save