From f5f56a1257794b91a934fe56142fdc6c891d3a2a Mon Sep 17 00:00:00 2001 From: wangshuaiswim Date: Sun, 29 Jan 2023 18:32:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=89=A9=E6=A8=A1=E5=9E=8B=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device/instance.ts | 7 +- src/api/device/product.ts | 9 +- src/components/Table/index.tsx | 2 +- src/store/instance.ts | 3 +- src/store/metadata.ts | 31 +++++ .../components/Metadata/Base/Edit/index.vue | 119 ++++++++++++++++++ .../components/Metadata/Base/columns.ts | 91 ++++++++++++++ .../device/components/Metadata/Base/index.vue | 100 +++++++++++++++ .../components/Metadata/Import/index.vue | 10 +- .../device/components/Metadata/metadata.ts | 61 +++++++++ 10 files changed, 425 insertions(+), 8 deletions(-) create mode 100644 src/store/metadata.ts create mode 100644 src/views/device/components/Metadata/Base/Edit/index.vue create mode 100644 src/views/device/components/Metadata/Base/columns.ts create mode 100644 src/views/device/components/Metadata/Base/index.vue create mode 100644 src/views/device/components/Metadata/metadata.ts diff --git a/src/api/device/instance.ts b/src/api/device/instance.ts index 9f051caf..19df86c2 100644 --- a/src/api/device/instance.ts +++ b/src/api/device/instance.ts @@ -1,6 +1,7 @@ +import { LocalStore } from '@/utils/comm' import server from '@/utils/request' -import { BASE_API_PATH } from '@/utils/variable' -import { DeviceInstance } from '@/views/device/instance/typings' +import { BASE_API_PATH, TOKEN_KEY } from '@/utils/variable' +import { DeviceInstance } from '@/views/device/Instance/typings' /** * 删除设备物模型 @@ -97,5 +98,5 @@ export const batchDeleteDevice = (data: string[]) => server.put(`/device-instanc * @param type 文件类型 * @returns */ - export const deviceExport = (productId: string, type: string) => `${BASE_API_PATH}/device-instance${!!productId ? '/' + productId : ''}/export.${type}` +export const deviceExport = (productId: string, type: string) => `${BASE_API_PATH}/device-instance${!!productId ? '/' + productId : ''}/export.${type}` diff --git a/src/api/device/product.ts b/src/api/device/product.ts index 6f318dcf..11c70020 100644 --- a/src/api/device/product.ts +++ b/src/api/device/product.ts @@ -42,4 +42,11 @@ export const detail = (id: string) => server.get(`/device-product/$ * 产品分类 * @param data */ -export const category = (data: any) => server.post('/device/category/_tree', data) \ No newline at end of file +export const category = (data: any) => server.post('/device/category/_tree', data) + +/** + * 保存产品 + * @param data 产品信息 + * @returns + */ +export const saveProductMetadata = (data: Record) => server.patch('/device-product', data) \ No newline at end of file diff --git a/src/components/Table/index.tsx b/src/components/Table/index.tsx index 92069199..7c43d1f7 100644 --- a/src/components/Table/index.tsx +++ b/src/components/Table/index.tsx @@ -54,7 +54,7 @@ export interface JTableProps extends TableProps{ rowSelection?: TableProps['rowSelection']; cardProps?: Record; dataSource?: Record[]; - gridColumn: number; + gridColumn?: number; /** * 用于不同分辨率 * gridColumns[0] 1366 ~ 1440 分辨率; diff --git a/src/store/instance.ts b/src/store/instance.ts index f4d6e145..eb51df72 100644 --- a/src/store/instance.ts +++ b/src/store/instance.ts @@ -1,4 +1,4 @@ -import { DeviceInstance, InstanceModel } from "@/views/device/instance/typings"; +import { DeviceInstance, InstanceModel } from "@/views/device/Instance/typings" import { defineStore } from "pinia"; export const useInstanceStore = defineStore({ @@ -7,6 +7,7 @@ export const useInstanceStore = defineStore({ actions: { setCurrent(current: Partial) { this.current = current + this.detail = current } } }) \ No newline at end of file diff --git a/src/store/metadata.ts b/src/store/metadata.ts new file mode 100644 index 00000000..c793f233 --- /dev/null +++ b/src/store/metadata.ts @@ -0,0 +1,31 @@ +import { DeviceInstance, InstanceModel } from "@/views/device/Instance/typings" +import { defineStore } from "pinia"; +import type { MetadataItem, MetadataType } from '@/views/device/Product/typings' + +type MetadataModelType = { + item: MetadataItem | unknown; + edit: boolean; + type: MetadataType; + action: 'edit' | 'add'; + import: boolean; + importMetadata: boolean; +}; + +export const useMetadataStore = defineStore({ + id: 'metadata', + state: () => ({ + model: { + item: undefined, + edit: false, + type: 'events', + action: 'add', + import: false, + importMetadata: false, + } as MetadataModelType + }), + actions: { + set(key: string, value: any) { + this.model[key] = value + } + } +}) \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/Edit/index.vue b/src/views/device/components/Metadata/Base/Edit/index.vue new file mode 100644 index 00000000..1f0f0de7 --- /dev/null +++ b/src/views/device/components/Metadata/Base/Edit/index.vue @@ -0,0 +1,119 @@ + + + \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/columns.ts b/src/views/device/components/Metadata/Base/columns.ts new file mode 100644 index 00000000..7c4f0f63 --- /dev/null +++ b/src/views/device/components/Metadata/Base/columns.ts @@ -0,0 +1,91 @@ +import { JColumnProps } from "@/components/Table"; + +const SourceMap = { + device: '设备', + manual: '手动', + rule: '规则', +}; + +const type = { + read: '读', + write: '写', + report: '上报', +}; + +const BaseColumns: JColumnProps[] = [ + { + title: '标识', + dataIndex: 'id', + ellipsis: true, + }, + { + title: '名称', + dataIndex: 'name', + ellipsis: true, + }, + { + title: '说明', + dataIndex: 'description', + ellipsis: true, + }, +]; + +const EventColumns: JColumnProps[] = BaseColumns.concat([ + { + title: '事件级别', + dataIndex: 'expands', + scopedSlots: true, + }, +]); + +const FunctionColumns: JColumnProps[] = BaseColumns.concat([ + { + title: '是否异步', + dataIndex: 'async', + scopedSlots: true, + }, + // { + // title: '读写类型', + // dataIndex: 'expands', + // render: (text: any) => (text?.type || []).map((item: string | number) => {type[item]}), + // }, +]); + +const PropertyColumns: JColumnProps[] = BaseColumns.concat([ + { + title: '数据类型', + dataIndex: 'valueType', + scopedSlots: true, + }, + { + title: '属性来源', + dataIndex: 'expands', + scopedSlots: true, + }, + { + title: '读写类型', + dataIndex: 'expands', + scopedSlots: true, + }, +]); + +const TagColumns: JColumnProps[] = BaseColumns.concat([ + { + title: '数据类型', + dataIndex: 'valueType', + scopedSlots: true, + }, + { + title: '读写类型', + dataIndex: 'expands', + scopedSlots: true, + }, +]); + +const MetadataMapping = new Map(); +MetadataMapping.set('properties', PropertyColumns); +MetadataMapping.set('events', EventColumns); +MetadataMapping.set('tags', TagColumns); +MetadataMapping.set('functions', FunctionColumns); + +export default MetadataMapping; \ No newline at end of file diff --git a/src/views/device/components/Metadata/Base/index.vue b/src/views/device/components/Metadata/Base/index.vue new file mode 100644 index 00000000..35e9dfed --- /dev/null +++ b/src/views/device/components/Metadata/Base/index.vue @@ -0,0 +1,100 @@ + + + \ No newline at end of file diff --git a/src/views/device/components/Metadata/Import/index.vue b/src/views/device/components/Metadata/Import/index.vue index eda57092..fb6028bd 100644 --- a/src/views/device/components/Metadata/Import/index.vue +++ b/src/views/device/components/Metadata/Import/index.vue @@ -47,14 +47,16 @@ import { saveMetadata } from '@/api/device/instance' import { queryNoPagingPost, convertMetadata, modify } from '@/api/device/product' import type { DefaultOptionType } from 'ant-design-vue/es/select'; import { UploadProps } from 'ant-design-vue/es'; -import type { DeviceMetadata } from '@/views/device/Product/typings' +import type { DeviceMetadata, ProductItem } from '@/views/device/Product/typings' import { message } from 'ant-design-vue/es'; import { Store } from 'jetlinks-store'; import { SystemConst } from '@/utils/consts'; import { useInstanceStore } from '@/store/instance' +import { useProductStore } from '@/store/product'; const route = useRoute() const instanceStore = useInstanceStore() +const productStore = useProductStore() interface Props { visible: boolean, @@ -191,8 +193,10 @@ const handleImport = async () => { const { id } = route.params || {} if (props?.type === 'device') { await saveMetadata(id as string, metadata) + instanceStore.setCurrent(JSON.parse(metadata || '{}')) } else { await modify(id as string, { metadata: metadata }) + productStore.setCurrent(JSON.parse(metadata || '{}')) } loading.value = false // MetadataAction.insert(JSON.parse(metadata || '{}')); @@ -231,10 +235,12 @@ const handleImport = async () => { if (props?.type === 'device') { const metadata: DeviceMetadata = JSON.parse(paramsDevice || '{}') // MetadataAction.insert(metadata); + instanceStore.setCurrent(metadata) message.success('导入成功') } else { - const metadata: DeviceMetadata = JSON.parse(params?.metadata || '{}') + const metadata: ProductItem = JSON.parse(params?.metadata || '{}') // MetadataAction.insert(metadata); + productStore.setCurrent(metadata) message.success('导入成功') } } diff --git a/src/views/device/components/Metadata/metadata.ts b/src/views/device/components/Metadata/metadata.ts new file mode 100644 index 00000000..134a67c0 --- /dev/null +++ b/src/views/device/components/Metadata/metadata.ts @@ -0,0 +1,61 @@ +import { saveProductMetadata } from "@/api/device/product"; +import { saveMetadata } from "@/api/device/instance"; +import type { DeviceInstance } from "../../Instance/typings"; +import type { DeviceMetadata, MetadataItem, MetadataType, ProductItem } from "../../Product/typings"; + +/** + * 更新物模型 + * @param type 物模型类型 events + * @param item 物模型数据 【{a},{b},{c}】 + // * @param target product、device + * @param data product 、device [{event:[1,2,3]] + * @param onEvent 数据更新回调:更新数据库、发送事件等操作 + * + */ + export const updateMetadata = ( + type: MetadataType, + item: MetadataItem[], + // target: 'product' | 'device', + data: ProductItem | DeviceInstance, + onEvent?: (item: string) => void, +): ProductItem | DeviceInstance => { + if (!data) return data; + const metadata = JSON.parse(data.metadata || '{}') as DeviceMetadata; + const config = (metadata[type] || []) as MetadataItem[]; + if (item.length > 0) { + item.forEach((i) => { + const index = config.findIndex((c) => c.id === i.id); + if (index > -1) { + config[index] = i; + // onEvent?.('update', i); + } else { + config.push(i); + // onEvent?.('add', i); + } + }); + } else { + console.warn('未触发物模型修改'); + } + // @ts-ignore + metadata[type] = config.sort((a, b) => b?.sortsIndex - a?.sortsIndex); + data.metadata = JSON.stringify(metadata); + onEvent?.(data.metadata) + return data; +}; + +/** + * 保存物模型数据到服务器 + * @param type 类型 + * @param data 数据 + */ +export const asyncUpdateMetadata = ( + type: 'product' | 'device', + data: ProductItem | DeviceInstance, +): Promise => { + switch (type) { + case 'product': + return saveProductMetadata(data); + case 'device': + return saveMetadata(data.id, JSON.parse(data.metadata || '{}')); + } +}; \ No newline at end of file