From 8b59786fbf98e29dae45f8da973ca4e021bf7b58 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 14 Dec 2024 09:05:19 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91IoT=EF=BC=9A=E4=BC=98=E5=8C=96=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E7=AE=A1=E7=90=86=E7=9A=84=20card=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/iot/product/product/index.ts | 3 +- src/assets/imgs/iot/device.png | Bin 0 -> 10007 bytes src/assets/svgs/iot/cube.svg | 1 + src/views/iot/product/product/ProductForm.vue | 6 +- src/views/iot/product/product/index.vue | 124 ++++++++++++------ 5 files changed, 91 insertions(+), 43 deletions(-) create mode 100644 src/assets/imgs/iot/device.png create mode 100644 src/assets/svgs/iot/cube.svg diff --git a/src/api/iot/product/product/index.ts b/src/api/iot/product/product/index.ts index e9dfdcaf..496fb049 100644 --- a/src/api/iot/product/product/index.ts +++ b/src/api/iot/product/product/index.ts @@ -8,6 +8,8 @@ export interface ProductVO { protocolId: number // 协议编号 categoryId: number // 产品所属品类标识符 categoryName?: string // 产品所属品类名称 + icon: string // 产品图标 + picUrl: string // 产品图片 description: string // 产品描述 validateType: number // 数据校验级别 status: number // 产品状态 @@ -17,7 +19,6 @@ export interface ProductVO { dataFormat: number // 数据格式 deviceCount: number // 设备数量 createTime: Date // 创建时间 - picUrl: string // 产品图片 URL } // IOT 数据校验级别枚举类 diff --git a/src/assets/imgs/iot/device.png b/src/assets/imgs/iot/device.png new file mode 100644 index 0000000000000000000000000000000000000000..79339cdf486e64bff9f5c3f89f16a7c20a8aadeb GIT binary patch literal 10007 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 \ No newline at end of file diff --git a/src/views/iot/product/product/ProductForm.vue b/src/views/iot/product/product/ProductForm.vue index b974717b..f7fe4087 100644 --- a/src/views/iot/product/product/ProductForm.vue +++ b/src/views/iot/product/product/ProductForm.vue @@ -7,10 +7,10 @@ label-width="110px" v-loading="formLoading" > - + @@ -145,7 +145,7 @@ const formData = ref({ validateType: ValidateTypeEnum.WEAK }) const formRules = reactive({ - productKey: [{ required: true, message: '产品标识不能为空', trigger: 'blur' }], + productKey: [{ required: true, message: 'ProductKey 不能为空', trigger: 'blur' }], name: [{ required: true, message: '产品名称不能为空', trigger: 'blur' }], categoryId: [{ required: true, message: '产品分类不能为空', trigger: 'change' }], deviceType: [{ required: true, message: '设备类型不能为空', trigger: 'change' }], diff --git a/src/views/iot/product/product/index.vue b/src/views/iot/product/product/index.vue index 21ae605d..09bd1773 100644 --- a/src/views/iot/product/product/index.vue +++ b/src/views/iot/product/product/index.vue @@ -63,49 +63,93 @@ -
+
-
- -
-
{{ item.name }}
-
{{ item.productKey }}
+ +
+ +
+
+ +
+
{{ item.name }}
+
+ + +
+
+
+ 产品分类 + {{ item.categoryName }} +
+
+ 产品类型 + +
+
+ 产品标识 + {{ item.productKey }} +
+
+
+ +
+
+ + + + + +
+ + + 编辑 + + + + 详情 + + + + 物模型 + +
+ + +
-
-
- {{ item.categoryName }} - -
-
- - 编辑 - - - 删除 -
@@ -199,6 +243,8 @@ import { ProductApi, ProductVO } from '@/api/iot/product/product' import ProductForm from './ProductForm.vue' import { DICT_TYPE } from '@/utils/dict' import download from '@/utils/download' +import defaultPicUrl from '@/assets/imgs/iot/device.png' +import defaultIconUrl from '@/assets/svgs/iot/cube.svg' /** iot 产品列表 */ defineOptions({ name: 'IoTProduct' }) @@ -216,7 +262,7 @@ const queryParams = reactive({ productKey: undefined }) const queryFormRef = ref() // 搜索的表单 -const exportLoading = ref(false) // 导出的加载中 +const exportLoading = ref(false) // 导出加载中 const viewMode = ref<'card' | 'list'>('card') // 视图模式状态 /** 查询列表 */ From dde5911b5fa2941bd61c35a65cf18e93bdd94af4 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 14 Dec 2024 16:10:23 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E3=80=91IoT=EF=BC=9A=E8=AE=BE=E5=A4=87=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=97=B6=EF=BC=8C=E5=A2=9E=E5=8A=A0=20deviceKey?= =?UTF-8?q?=E3=80=81serialNumber=E3=80=81picUrl=20=E7=AD=89=E5=AD=97?= =?UTF-8?q?=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/iot/device/index.ts | 5 + .../iot/device/{ => device}/DeviceForm.vue | 110 +++++++++-- .../{ => device}/detail/DeviceDataDetail.vue | 0 .../detail/DeviceDetailsHeader.vue | 0 .../{ => device}/detail/DeviceDetailsInfo.vue | 0 .../detail/DeviceDetailsModel.vue | 0 .../iot/device/{ => device}/detail/index.vue | 0 src/views/iot/device/{ => device}/index.vue | 0 src/views/iot/product/product/ProductForm.vue | 15 +- .../product/product/detail/ProductTopic.vue | 40 ++-- .../iot/product/product/detail/index.vue | 7 +- src/views/iot/product/product/index.vue | 177 +++++++++--------- 12 files changed, 235 insertions(+), 119 deletions(-) rename src/views/iot/device/{ => device}/DeviceForm.vue (55%) rename src/views/iot/device/{ => device}/detail/DeviceDataDetail.vue (100%) rename src/views/iot/device/{ => device}/detail/DeviceDetailsHeader.vue (100%) rename src/views/iot/device/{ => device}/detail/DeviceDetailsInfo.vue (100%) rename src/views/iot/device/{ => device}/detail/DeviceDetailsModel.vue (100%) rename src/views/iot/device/{ => device}/detail/index.vue (100%) rename src/views/iot/device/{ => device}/index.vue (100%) diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts index 4f61d56d..2106e75a 100644 --- a/src/api/iot/device/index.ts +++ b/src/api/iot/device/index.ts @@ -91,6 +91,11 @@ export const DeviceApi = { return await request.get({ url: `/iot/device/count?productId=` + productId }) }, + // 获取设备的精简信息列表 + getSimpleDeviceList: async (deviceType?: number) => { + return await request.get({ url: `/iot/device/simple-list?`, params: { deviceType } }) + }, + // 获取设备属性最新数据 getDevicePropertiesLatestData: async (params: any) => { return await request.get({ url: `/iot/device/data/latest`, params }) diff --git a/src/views/iot/device/DeviceForm.vue b/src/views/iot/device/device/DeviceForm.vue similarity index 55% rename from src/views/iot/device/DeviceForm.vue rename to src/views/iot/device/device/DeviceForm.vue index 95eff822..138498b1 100644 --- a/src/views/iot/device/DeviceForm.vue +++ b/src/views/iot/device/device/DeviceForm.vue @@ -13,6 +13,7 @@ placeholder="请选择产品" :disabled="formType === 'update'" clearable + @change="handleProductChange" > + + + + + - - + + + + + + + + + + + + + + + + + + diff --git a/src/views/iot/device/detail/DeviceDataDetail.vue b/src/views/iot/device/device/detail/DeviceDataDetail.vue similarity index 100% rename from src/views/iot/device/detail/DeviceDataDetail.vue rename to src/views/iot/device/device/detail/DeviceDataDetail.vue diff --git a/src/views/iot/device/detail/DeviceDetailsHeader.vue b/src/views/iot/device/device/detail/DeviceDetailsHeader.vue similarity index 100% rename from src/views/iot/device/detail/DeviceDetailsHeader.vue rename to src/views/iot/device/device/detail/DeviceDetailsHeader.vue diff --git a/src/views/iot/device/detail/DeviceDetailsInfo.vue b/src/views/iot/device/device/detail/DeviceDetailsInfo.vue similarity index 100% rename from src/views/iot/device/detail/DeviceDetailsInfo.vue rename to src/views/iot/device/device/detail/DeviceDetailsInfo.vue diff --git a/src/views/iot/device/detail/DeviceDetailsModel.vue b/src/views/iot/device/device/detail/DeviceDetailsModel.vue similarity index 100% rename from src/views/iot/device/detail/DeviceDetailsModel.vue rename to src/views/iot/device/device/detail/DeviceDetailsModel.vue diff --git a/src/views/iot/device/detail/index.vue b/src/views/iot/device/device/detail/index.vue similarity index 100% rename from src/views/iot/device/detail/index.vue rename to src/views/iot/device/device/detail/index.vue diff --git a/src/views/iot/device/index.vue b/src/views/iot/device/device/index.vue similarity index 100% rename from src/views/iot/device/index.vue rename to src/views/iot/device/device/index.vue diff --git a/src/views/iot/product/product/ProductForm.vue b/src/views/iot/product/product/ProductForm.vue index f7fe4087..e4eec674 100644 --- a/src/views/iot/product/product/ProductForm.vue +++ b/src/views/iot/product/product/ProductForm.vue @@ -12,7 +12,13 @@ v-model="formData.productKey" placeholder="请输入 ProductKey" :readonly="formType === 'update'" - /> + > + + @@ -184,7 +190,7 @@ const open = async (type: string, id?: number) => { } } else { // 新增时,生成随机 productKey - formData.value.productKey = generateRandomStr(16) + generateProductKey() } // 加载分类列表 categoryList.value = await ProductCategoryApi.getSimpleProductCategoryList() @@ -231,4 +237,9 @@ const resetForm = () => { } formRef.value?.resetFields() } + +/** 生成 ProductKey */ +const generateProductKey = () => { + formData.value.productKey = generateRandomStr(16) +} diff --git a/src/views/iot/product/product/detail/ProductTopic.vue b/src/views/iot/product/product/detail/ProductTopic.vue index 1e95da5a..a691a614 100644 --- a/src/views/iot/product/product/detail/ProductTopic.vue +++ b/src/views/iot/product/product/detail/ProductTopic.vue @@ -3,9 +3,9 @@
() -// 定义列 -const columns1 = reactive([ +// TODO 芋艿:不确定未来会不会改,所以先写死 + +// 基础通信 Topic 列 +const basicColumn = reactive([ { label: '功能', field: 'function', width: 150 }, { label: 'Topic 类', field: 'topicClass', width: 800 }, { label: '操作权限', field: 'operationPermission', width: 100 }, { label: '描述', field: 'description' } ]) -const columns2 = reactive([ - { label: '功能', field: 'function', width: 150 }, - { label: 'Topic 类', field: 'topicClass', width: 800 }, - { label: '操作权限', field: 'operationPermission', width: 100 }, - { label: '描述', field: 'description' } -]) - -// TODO @haohao:这个,有没可能写到一个枚举里,方便后续维护? /Users/yunai/Java/yudao-ui-admin-vue3/src/views/ai/utils/constants.ts -const data1 = computed(() => { +// 基础通信 Topic 数据 +const basicData = computed(() => { if (!props.product || !props.product.productKey) return [] return [ { @@ -147,7 +142,16 @@ const data1 = computed(() => { ] }) -const data2 = computed(() => { +// 物模型通信 Topic 列 +const functionColumn = reactive([ + { label: '功能', field: 'function', width: 150 }, + { label: 'Topic 类', field: 'topicClass', width: 800 }, + { label: '操作权限', field: 'operationPermission', width: 100 }, + { label: '描述', field: 'description' } +]) + +// 物模型通信 Topic 数据 +const functionData = computed(() => { if (!props.product || !props.product.productKey) return [] return [ { diff --git a/src/views/iot/product/product/detail/index.vue b/src/views/iot/product/product/detail/index.vue index 5c4a32f6..baca1021 100644 --- a/src/views/iot/product/product/detail/index.vue +++ b/src/views/iot/product/product/detail/index.vue @@ -36,7 +36,7 @@ const message = useMessage() const id = Number(route.params.id) // 编号 const loading = ref(true) // 加载中 const product = ref({} as ProductVO) // 详情 -const activeTab = ref('info') // 默认激活的标签页 +const activeTab = ref('info') // 默认为 info 标签页 /** 获取详情 */ const getProductData = async (id: number) => { @@ -66,6 +66,11 @@ onMounted(async () => { return } await getProductData(id) + // 处理 tab 参数 + const { tab } = route.query + if (tab) { + activeTab.value = tab as string + } // 查询设备数量 if (product.value.id) { product.value.deviceCount = await getDeviceCount(product.value.id) diff --git a/src/views/iot/product/product/index.vue b/src/views/iot/product/product/index.vue index 09bd1773..1e48a594 100644 --- a/src/views/iot/product/product/index.vue +++ b/src/views/iot/product/product/index.vue @@ -63,96 +63,89 @@ -
- - -
- -
-
- + + + + +
+ +
+
+ +
+
{{ item.name }}
-
{{ item.name }}
-
- -
-
-
- 产品分类 - {{ item.categoryName }} + +
+
+
+ 产品分类 + {{ item.categoryName }} +
+
+ 产品类型 + +
+
+ 产品标识 + {{ item.productKey }} +
-
- 产品类型 - -
-
- 产品标识 - {{ item.productKey }} +
+
-
- + + + + + +
+ + + 编辑 + + + + 详情 + + + + 物模型 + +
+ + +
- - - - - -
- - - 编辑 - - - - 详情 - - - - 物模型 - -
- - - -
-
- -
+ + + @@ -251,8 +244,11 @@ defineOptions({ name: 'IoTProduct' }) const message = useMessage() // 消息弹窗 const { t } = useI18n() // 国际化 +const { push } = useRouter() +const route = useRoute() const loading = ref(true) // 列表的加载中 +const activeName = ref('info') // 当前激活的标签页 const list = ref([]) // 列表的数据 const total = ref(0) // 列表的总页数 const queryParams = reactive({ @@ -296,11 +292,19 @@ const openForm = (type: string, id?: number) => { } /** 打开详情 */ -const { push } = useRouter() const openDetail = (id: number) => { push({ name: 'IoTProductDetail', params: { id } }) } +/** 打开物模型 */ +const openObjectModel = (item: ProductVO) => { + push({ + name: 'IoTProductDetail', + params: { id: item.id }, + query: { tab: 'function' } + }) +} + /** 删除按钮操作 */ const handleDelete = async (id: number) => { try { @@ -332,5 +336,10 @@ const handleExport = async () => { /** 初始化 **/ onMounted(() => { getList() + // 处理 tab 参数 + const { tab } = route.query + if (tab) { + activeName.value = tab as string + } }) From 30b19c9100d74c9e0b7cdee9ed5d7b77310b56f5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 14 Dec 2024 17:24:33 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91IoT=EF=BC=9A=E6=96=B0=E5=A2=9E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=88=86=E7=BB=84=E7=9A=84=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/iot/device/group/index.ts | 37 ++++ .../iot/device/group/DeviceGroupForm.vue | 112 ++++++++++++ src/views/iot/device/group/index.vue | 168 ++++++++++++++++++ 3 files changed, 317 insertions(+) create mode 100644 src/api/iot/device/group/index.ts create mode 100644 src/views/iot/device/group/DeviceGroupForm.vue create mode 100644 src/views/iot/device/group/index.vue diff --git a/src/api/iot/device/group/index.ts b/src/api/iot/device/group/index.ts new file mode 100644 index 00000000..5d9f8df7 --- /dev/null +++ b/src/api/iot/device/group/index.ts @@ -0,0 +1,37 @@ +import request from '@/config/axios' + +// IoT 设备分组 VO +export interface DeviceGroupVO { + id: number // 分组 ID + name: string // 分组名字 + status: number // 分组状态 + description: string // 分组描述 +} + +// IoT 设备分组 API +export const DeviceGroupApi = { + // 查询IoT 设备分组分页 + getDeviceGroupPage: async (params: any) => { + return await request.get({ url: `/iot/device-group/page`, params }) + }, + + // 查询IoT 设备分组详情 + getDeviceGroup: async (id: number) => { + return await request.get({ url: `/iot/device-group/get?id=` + id }) + }, + + // 新增IoT 设备分组 + createDeviceGroup: async (data: DeviceGroupVO) => { + return await request.post({ url: `/iot/device-group/create`, data }) + }, + + // 修改IoT 设备分组 + updateDeviceGroup: async (data: DeviceGroupVO) => { + return await request.put({ url: `/iot/device-group/update`, data }) + }, + + // 删除IoT 设备分组 + deleteDeviceGroup: async (id: number) => { + return await request.delete({ url: `/iot/device-group/delete?id=` + id }) + } +} \ No newline at end of file diff --git a/src/views/iot/device/group/DeviceGroupForm.vue b/src/views/iot/device/group/DeviceGroupForm.vue new file mode 100644 index 00000000..64872573 --- /dev/null +++ b/src/views/iot/device/group/DeviceGroupForm.vue @@ -0,0 +1,112 @@ + + diff --git a/src/views/iot/device/group/index.vue b/src/views/iot/device/group/index.vue new file mode 100644 index 00000000..0646fc72 --- /dev/null +++ b/src/views/iot/device/group/index.vue @@ -0,0 +1,168 @@ + + + From 14fe6c559fa7f12bc7b7538b1d463a8820b2aab0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Sat, 14 Dec 2024 18:41:35 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E3=80=90=E5=8A=9F=E8=83=BD=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E3=80=91IoT=EF=BC=9A=E8=AE=BE=E5=A4=87=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E7=95=8C=E9=9D=A2=E5=A2=9E=E5=8A=A0=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=88=86=E7=BB=84=E9=80=89=E6=8B=A9=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/iot/device/group/index.ts | 8 ++- src/api/iot/device/index.ts | 1 + src/views/iot/device/device/DeviceForm.vue | 25 ++++++++- src/views/iot/device/device/index.vue | 61 ++++++++++++++-------- src/views/iot/device/group/index.vue | 1 + 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/api/iot/device/group/index.ts b/src/api/iot/device/group/index.ts index 5d9f8df7..02cca70b 100644 --- a/src/api/iot/device/group/index.ts +++ b/src/api/iot/device/group/index.ts @@ -6,6 +6,7 @@ export interface DeviceGroupVO { name: string // 分组名字 status: number // 分组状态 description: string // 分组描述 + deviceCount?: number // 设备数量 } // IoT 设备分组 API @@ -33,5 +34,10 @@ export const DeviceGroupApi = { // 删除IoT 设备分组 deleteDeviceGroup: async (id: number) => { return await request.delete({ url: `/iot/device-group/delete?id=` + id }) + }, + + // 获取设备分组的精简信息列表 + getSimpleDeviceGroupList: async () => { + return await request.get({ url: `/iot/device-group/simple-list` }) } -} \ No newline at end of file +} diff --git a/src/api/iot/device/index.ts b/src/api/iot/device/index.ts index 2106e75a..f9e388f2 100644 --- a/src/api/iot/device/index.ts +++ b/src/api/iot/device/index.ts @@ -28,6 +28,7 @@ export interface DeviceVO { areaId: number // 地区编码 address: string // 设备详细地址 serialNumber: string // 设备序列号 + groupIds?: number[] // 添加分组 ID } export interface DeviceUpdateStatusVO { diff --git a/src/views/iot/device/device/DeviceForm.vue b/src/views/iot/device/device/DeviceForm.vue index 138498b1..bda22adb 100644 --- a/src/views/iot/device/device/DeviceForm.vue +++ b/src/views/iot/device/device/DeviceForm.vue @@ -62,6 +62,16 @@ + + + + + @@ -76,6 +86,7 @@ diff --git a/src/views/iot/device/group/index.vue b/src/views/iot/device/group/index.vue index 0646fc72..ea2e4bea 100644 --- a/src/views/iot/device/group/index.vue +++ b/src/views/iot/device/group/index.vue @@ -61,6 +61,7 @@ :formatter="dateFormatter" width="180px" /> + - + @@ -127,6 +136,15 @@ + + +