feat(iot):【网关设备:30%】增加网关设备绑定能力(优化代码),基于 optimized-pondering-dragon.md 规划
parent
2515caed35
commit
2076a27a26
|
|
@ -178,11 +178,8 @@ export const DeviceApi = {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
// 获取可绑定到网关的子设备列表
|
// 获取未绑定网关的子设备分页
|
||||||
getBindableSubDeviceList: async (gatewayId?: number) => {
|
getUnboundSubDevicePage: async (params: any) => {
|
||||||
return await request.get<DeviceVO[]>({
|
return await request.get({ url: `/iot/device/unbound-sub-device-page`, params })
|
||||||
url: `/iot/device/bindable-sub-device-list`,
|
|
||||||
params: { gatewayId }
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,8 @@ export const ProductApi = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// 查询产品(精简)列表
|
// 查询产品(精简)列表
|
||||||
getSimpleProductList() {
|
getSimpleProductList(deviceType?: number) {
|
||||||
return request.get({ url: '/iot/product/simple-list' })
|
return request.get({ url: '/iot/product/simple-list', params: { deviceType } })
|
||||||
},
|
},
|
||||||
|
|
||||||
// 根据 ProductKey 获取产品信息
|
// 根据 ProductKey 获取产品信息
|
||||||
|
|
|
||||||
|
|
@ -62,40 +62,82 @@
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
|
|
||||||
<!-- 添加子设备弹窗 -->
|
<!-- 添加子设备弹窗 -->
|
||||||
<!-- TODO @AI:需要增加检索:产品、设备等检索,可以一起讨论下; -->
|
<Dialog title="添加子设备" v-model="bindDialogVisible" width="900px">
|
||||||
<Dialog title="添加子设备" v-model="bindDialogVisible" width="800px">
|
<ContentWrap>
|
||||||
<el-table
|
<!-- 搜索区域 -->
|
||||||
ref="bindTableRef"
|
<el-form :model="bindQueryParams" ref="bindQueryFormRef" :inline="true" class="-mb-15px">
|
||||||
v-loading="bindFormLoading"
|
<el-form-item label="产品" prop="productId">
|
||||||
:data="bindableDevices"
|
<ProductSelect
|
||||||
:stripe="true"
|
v-model="bindQueryParams.productId"
|
||||||
:show-overflow-tooltip="true"
|
:device-type="DeviceTypeEnum.GATEWAY_SUB"
|
||||||
@selection-change="handleBindSelectionChange"
|
class="!w-200px"
|
||||||
max-height="400px"
|
/>
|
||||||
>
|
</el-form-item>
|
||||||
<el-table-column type="selection" width="55" />
|
<el-form-item label="设备名称" prop="deviceName">
|
||||||
<el-table-column label="DeviceName" align="center" prop="deviceName" />
|
<el-input
|
||||||
<el-table-column label="备注名称" align="center" prop="nickname" />
|
v-model="bindQueryParams.deviceName"
|
||||||
<el-table-column label="产品名称" align="center" prop="productName" />
|
placeholder="请输入设备名称"
|
||||||
<el-table-column label="设备状态" align="center" prop="state">
|
clearable
|
||||||
<template #default="{ row }">
|
class="!w-200px"
|
||||||
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="row.state" />
|
/>
|
||||||
</template>
|
</el-form-item>
|
||||||
</el-table-column>
|
<el-form-item>
|
||||||
</el-table>
|
<el-button type="primary" @click="getBindableDevicePage">
|
||||||
|
<Icon icon="ep:search" class="mr-5px" /> 搜索
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetBindQuery">
|
||||||
|
<Icon icon="ep:refresh" class="mr-5px" /> 重置
|
||||||
|
</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<ContentWrap>
|
||||||
|
<!-- 分页表格 -->
|
||||||
|
<el-table
|
||||||
|
ref="bindTableRef"
|
||||||
|
v-loading="bindFormLoading"
|
||||||
|
:data="bindableDevices"
|
||||||
|
:stripe="true"
|
||||||
|
:show-overflow-tooltip="true"
|
||||||
|
@selection-change="handleBindSelectionChange"
|
||||||
|
max-height="400px"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column label="DeviceName" align="center" prop="deviceName" />
|
||||||
|
<el-table-column label="备注名称" align="center" prop="nickname" />
|
||||||
|
<el-table-column label="产品名称" align="center" prop="productName" />
|
||||||
|
<el-table-column label="设备状态" align="center" prop="state">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<dict-tag :type="DICT_TYPE.IOT_DEVICE_STATE" :value="row.state" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<Pagination
|
||||||
|
v-model:page="bindQueryParams.pageNo"
|
||||||
|
v-model:limit="bindQueryParams.pageSize"
|
||||||
|
:total="bindTotal"
|
||||||
|
@pagination="getBindableDevicePage"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<el-button @click="bindDialogVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="handleBindSubmit" :loading="bindFormLoading">
|
<el-button type="primary" @click="handleBindSubmit" :loading="bindFormLoading">
|
||||||
确定(已选 {{ bindSelectedIds.length }} 个)
|
确定(已选 {{ bindSelectedIds.length }} 个)
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button @click="bindDialogVisible = false">取消</el-button>
|
||||||
</template>
|
</template>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
import { DeviceApi, DeviceVO } from '@/api/iot/device/device'
|
||||||
|
import { DeviceTypeEnum } from '@/api/iot/product/product'
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
import { DICT_TYPE } from '@/utils/dict'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
import ProductSelect from '@/views/iot/product/product/components/ProductSelect.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
gatewayId: number
|
gatewayId: number
|
||||||
|
|
@ -104,18 +146,23 @@ const props = defineProps<{
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
const { push } = useRouter()
|
const { push } = useRouter()
|
||||||
|
|
||||||
// TODO @AI:注释使用尾注释;
|
const loading = ref(false) // 列表加载状态
|
||||||
// 列表数据
|
const subDeviceList = ref<DeviceVO[]>([]) // 子设备列表
|
||||||
const loading = ref(false)
|
const selectedIds = ref<number[]>([]) // 选中的设备ID
|
||||||
const subDeviceList = ref<DeviceVO[]>([])
|
|
||||||
const selectedIds = ref<number[]>([])
|
|
||||||
|
|
||||||
// 绑定弹窗数据
|
const bindDialogVisible = ref(false) // 绑定弹窗可见性
|
||||||
const bindDialogVisible = ref(false)
|
const bindFormLoading = ref(false) // 绑定弹窗加载状态
|
||||||
const bindFormLoading = ref(false)
|
|
||||||
const bindTableRef = ref()
|
const bindTableRef = ref()
|
||||||
const bindableDevices = ref<DeviceVO[]>([])
|
const bindQueryFormRef = ref()
|
||||||
const bindSelectedIds = ref<number[]>([])
|
const bindableDevices = ref<DeviceVO[]>([]) // 可绑定设备列表
|
||||||
|
const bindSelectedIds = ref<number[]>([]) // 绑定选中的设备ID
|
||||||
|
const bindTotal = ref(0) // 可绑定设备总数
|
||||||
|
const bindQueryParams = reactive({
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
productId: undefined as number | undefined,
|
||||||
|
deviceName: ''
|
||||||
|
})
|
||||||
|
|
||||||
/** 获取子设备列表 */
|
/** 获取子设备列表 */
|
||||||
const getSubDeviceList = async () => {
|
const getSubDeviceList = async () => {
|
||||||
|
|
@ -141,18 +188,29 @@ const handleSelectionChange = (selection: DeviceVO[]) => {
|
||||||
const openBindDialog = async () => {
|
const openBindDialog = async () => {
|
||||||
bindSelectedIds.value = []
|
bindSelectedIds.value = []
|
||||||
bindDialogVisible.value = true
|
bindDialogVisible.value = true
|
||||||
|
await getBindableDevicePage()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 获取可绑定设备分页 */
|
||||||
|
const getBindableDevicePage = async () => {
|
||||||
bindFormLoading.value = true
|
bindFormLoading.value = true
|
||||||
try {
|
try {
|
||||||
// 获取可绑定的子设备列表
|
const result = await DeviceApi.getUnboundSubDevicePage(bindQueryParams)
|
||||||
const list = await DeviceApi.getBindableSubDeviceList(props.gatewayId)
|
bindableDevices.value = result.list
|
||||||
// 排除已绑定到当前网关的设备
|
bindTotal.value = result.total
|
||||||
// TODO @AI:不用排除,后端已经排除;
|
|
||||||
bindableDevices.value = list.filter((device: DeviceVO) => device.gatewayId !== props.gatewayId)
|
|
||||||
} finally {
|
} finally {
|
||||||
bindFormLoading.value = false
|
bindFormLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 重置绑定弹窗搜索条件 */
|
||||||
|
const resetBindQuery = () => {
|
||||||
|
bindQueryParams.pageNo = 1
|
||||||
|
bindQueryParams.productId = undefined
|
||||||
|
bindQueryParams.deviceName = ''
|
||||||
|
getBindableDevicePage()
|
||||||
|
}
|
||||||
|
|
||||||
/** 绑定弹窗多选框选中数据 */
|
/** 绑定弹窗多选框选中数据 */
|
||||||
const handleBindSelectionChange = (selection: DeviceVO[]) => {
|
const handleBindSelectionChange = (selection: DeviceVO[]) => {
|
||||||
bindSelectedIds.value = selection.map((item) => item.id)
|
bindSelectedIds.value = selection.map((item) => item.id)
|
||||||
|
|
@ -203,8 +261,4 @@ const handleUnbindBatch = async () => {
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getSubDeviceList()
|
await getSubDeviceList()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 暴露刷新方法
|
|
||||||
// TODO @AI:refresh 需要提供么?
|
|
||||||
defineExpose({ refresh: getSubDeviceList })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue