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

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

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

@ -1,18 +1,31 @@
<template> <template>
<Dialog :title="dialogTitle" v-model="dialogVisible"> <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 <el-form
ref="formRef" ref="formRef"
:model="formData" :model="formData"
:rules="formRules" :rules="activeRules"
label-width="100px" label-width="100px"
v-loading="formLoading" v-loading="formLoading"
> >
<template v-if="formType === 'create'">
<el-form-item label="设备编号" prop="deviceCode"> <el-form-item label="设备编号" prop="deviceCode">
<el-input v-model="formData.deviceCode" placeholder="请输入设备编号" /> <el-input v-model="formData.deviceCode" placeholder="请输入设备编号" />
</el-form-item> </el-form-item>
<el-form-item label="设备名称" prop="deviceName"> <el-form-item label="设备名称" prop="deviceName">
<el-input v-model="formData.deviceName" placeholder="请输入设备名称" /> <el-input v-model="formData.deviceName" placeholder="请输入设备名称" />
</el-form-item> </el-form-item>
</template>
<!-- <el-form-item label="设备类型" prop="deviceType"> <!-- <el-form-item label="设备类型" prop="deviceType">
<el-select v-model="formData.deviceType" placeholder="请选择设备类型"> <el-select v-model="formData.deviceType" placeholder="请选择设备类型">
<el-option <el-option
@ -49,6 +62,7 @@
<!-- <el-form-item label="离线间隔" prop="offLineDuration"> <!-- <el-form-item label="离线间隔" prop="offLineDuration">
<el-input v-model="formData.offLineDuration" placeholder="请输入离线间隔" /> <el-input v-model="formData.offLineDuration" placeholder="请输入离线间隔" />
</el-form-item> --> </el-form-item> -->
<template v-if="formType === 'create'">
<el-form-item label="模型选择" prop="deviceModelId"> <el-form-item label="模型选择" prop="deviceModelId">
<el-select <el-select
v-model="formData.deviceModelId" v-model="formData.deviceModelId"
@ -56,26 +70,12 @@
filterable filterable
placeholder="请选择设备模型" placeholder="请选择设备模型"
> >
<el-option <el-option v-for="item in modelList" :key="item.id" :label="item.name" :value="item.id" />
v-for="item in modelList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="采集周期/s" prop="sampleCycle"> <el-form-item label="采集周期/s" prop="sampleCycle">
<el-input v-model="formData.sampleCycle" placeholder="请输入采集周期" /> <el-input v-model="formData.sampleCycle" placeholder="请输入采集周期" />
</el-form-item> </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-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" placeholder="请输入备注" /> <el-input v-model="formData.remark" placeholder="请输入备注" />
</el-form-item> </el-form-item>
@ -90,15 +90,45 @@
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </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> </el-form>
<template #footer> <template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false"> </el-button>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
<script setup lang="ts"> <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 { DeviceApi, DeviceVO } from '@/api/iot/device'
import {DeviceModelApi, DeviceModelVO} from "@/api/iot/devicemodel"; import {DeviceModelApi, DeviceModelVO} from "@/api/iot/devicemodel";
@ -135,16 +165,28 @@ const formData = ref({
password: undefined, password: undefined,
}) })
const formRules = reactive({ const formRules = reactive({
create: {
deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }], deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }],
deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }], deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
isEnable: [{ 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 formRef = ref() // Ref
/** 打开弹窗 */ /** 打开弹窗 */
const open = async (type: string, id?: number) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true
dialogTitle.value = t('action.' + type) dialogTitle.value = type === 'setting' ? '设备设置' : t('action.' + type)
formType.value = type formType.value = type
resetForm() resetForm()
// //
@ -167,11 +209,18 @@ const submitForm = async () => {
// //
formLoading.value = true formLoading.value = true
try { 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') { 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')) 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 { } else {
const data: any = { id, deviceCode, deviceName, deviceModelId, isEnable, url, username, password }
await DeviceApi.updateDevice(data) await DeviceApi.updateDevice(data)
message.success(t('common.updateSuccess')) message.success(t('common.updateSuccess'))
} }
@ -198,7 +247,13 @@ const resetForm = () => {
offLineDuration: undefined, offLineDuration: undefined,
lastOnlineTime: undefined, lastOnlineTime: undefined,
remark: undefined, remark: undefined,
isEnable: true isEnable: true,
deviceModelId: undefined,
protocol: undefined,
sampleCycle: undefined,
url: undefined,
username: undefined,
password: undefined,
} }
formRef.value?.resetFields() formRef.value?.resetFields()
} }

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

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

Loading…
Cancel
Save