【功能完善】IoT:设备新增时,增加 deviceKey、serialNumber、picUrl 等字段

This commit is contained in:
YunaiV
2024-12-14 16:10:23 +08:00
parent 8b59786fbf
commit dde5911b5f
12 changed files with 235 additions and 119 deletions

View File

@ -13,6 +13,7 @@
placeholder="请选择产品"
:disabled="formType === 'update'"
clearable
@change="handleProductChange"
>
<el-option
v-for="product in products"
@ -22,6 +23,19 @@
/>
</el-select>
</el-form-item>
<el-form-item label="DeviceKey" prop="deviceKey">
<el-input
v-model="formData.deviceKey"
placeholder="请输入 DeviceKey"
:disabled="formType === 'update'"
>
<template #append>
<el-button @click="generateDeviceKey" :disabled="formType === 'update'">
重新生成
</el-button>
</template>
</el-input>
</el-form-item>
<el-form-item label="DeviceName" prop="deviceName">
<el-input
v-model="formData.deviceName"
@ -29,9 +43,30 @@
:disabled="formType === 'update'"
/>
</el-form-item>
<el-form-item label="备注名称" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入备注名称" />
<el-form-item v-if="formData.deviceType === 1" label="网关设备" prop="gatewayId">
<el-select v-model="formData.gatewayId" placeholder="子设备可选择父设备" clearable>
<el-option
v-for="gateway in gatewayDevices"
:key="gateway.id"
:label="gateway.nickname || gateway.deviceName"
:value="gateway.id"
/>
</el-select>
</el-form-item>
<el-collapse>
<el-collapse-item title="更多配置">
<el-form-item label="备注名称" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入备注名称" />
</el-form-item>
<el-form-item label="设备图片" prop="picUrl">
<UploadImg v-model="formData.picUrl" :height="'120px'" :width="'120px'" />
</el-form-item>
<el-form-item label="设备序列号" prop="serialNumber">
<el-input v-model="formData.serialNumber" placeholder="请输入设备序列号" />
</el-form-item>
</el-collapse-item>
</el-collapse>
</el-form>
<template #footer>
<el-button @click="submitForm" type="primary" :disabled="formLoading"> </el-button>
@ -41,13 +76,15 @@
</template>
<script setup lang="ts">
import { DeviceApi, DeviceVO } from '@/api/iot/device'
import { ProductApi } from '@/api/iot/product/product'
import { DeviceTypeEnum, ProductApi, ProductVO } from '@/api/iot/product/product'
import { UploadImg } from '@/components/UploadFile'
import { generateRandomStr } from '@/utils'
/** IoT 设备 表单 */
/** IoT 设备表单 */
defineOptions({ name: 'IoTDeviceForm' })
const { t } = useI18n() //
const message = useMessage() //
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
@ -56,12 +93,26 @@ const formType = ref('') // 表单的类型create - 新增update - 修改
const formData = ref({
id: undefined,
productId: undefined,
deviceKey: undefined as string | undefined,
deviceName: undefined,
nickname: undefined
nickname: undefined,
picUrl: undefined,
gatewayId: undefined,
deviceType: undefined as number | undefined,
serialNumber: undefined
})
const formRules = reactive({
productId: [{ required: true, message: '产品不能为空', trigger: 'blur' }],
deviceKey: [
{ required: true, message: 'DeviceKey 不能为空', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9]+$/,
message: 'DeviceKey 只能包含字母和数字',
trigger: 'blur'
}
],
deviceName: [
{ required: true, message: 'DeviceName 不能为空', trigger: 'blur' },
{
pattern: /^[a-zA-Z0-9_.\-:@]{4,32}$/,
message:
@ -87,9 +138,18 @@ const formRules = reactive({
},
trigger: 'blur'
}
],
serialNumber: [
{
pattern: /^[a-zA-Z0-9-_]+$/,
message: '序列号只能包含字母、数字、中划线和下划线',
trigger: 'blur'
}
]
})
const formRef = ref() // Ref
const products = ref<ProductVO[]>([]) //
const gatewayDevices = ref<DeviceVO[]>([]) //
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
@ -97,6 +157,7 @@ const open = async (type: string, id?: number) => {
dialogTitle.value = t('action.' + type)
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
@ -105,7 +166,18 @@ const open = async (type: string, id?: number) => {
} finally {
formLoading.value = false
}
} else {
generateDeviceKey()
}
//
try {
gatewayDevices.value = await DeviceApi.getSimpleDeviceList(DeviceTypeEnum.GATEWAY)
} catch (error) {
console.error('加载网关设备列表失败:', error)
}
//
products.value = await ProductApi.getSimpleProductList()
}
defineExpose({ open }) // open
@ -138,19 +210,29 @@ const resetForm = () => {
formData.value = {
id: undefined,
productId: undefined,
deviceKey: undefined,
deviceName: undefined,
nickname: undefined
nickname: undefined,
picUrl: undefined,
gatewayId: undefined,
deviceType: undefined,
serialNumber: undefined
}
formRef.value?.resetFields()
}
/** 查询字典下拉列表 */
const products = ref()
const getProducts = async () => {
products.value = await ProductApi.getSimpleProductList()
/** 产品选择变化 */
const handleProductChange = (productId: number) => {
if (!productId) {
formData.value.deviceType = undefined
return
}
const product = products.value?.find((item) => item.id === productId)
formData.value.deviceType = product?.deviceType
}
onMounted(() => {
getProducts()
})
/** 生成 DeviceKey */
const generateDeviceKey = () => {
formData.value.deviceKey = generateRandomStr(16)
}
</script>