diff --git a/package.json b/package.json index 7673d65dc92f85020507c5cbba98bc2d4615a7ac..0bb3f91174724cd6ea4bd357f5ed898a19d2bdf8 100644 --- a/package.json +++ b/package.json @@ -51,6 +51,7 @@ "fast-xml-parser": "^4.3.2", "highlight.js": "^11.9.0", "jsencrypt": "^3.3.2", + "jsoneditor": "^10.1.3", "lodash-es": "^4.17.21", "markdown-it": "^14.1.0", "markmap-common": "^0.16.0", @@ -67,7 +68,6 @@ "sortablejs": "^1.15.3", "steady-xml": "^0.1.0", "url": "^0.11.3", - "v3-jsoneditor": "^0.0.6", "video.js": "^7.21.5", "vue": "3.5.12", "vue-dompurify-html": "^4.1.4", @@ -85,6 +85,7 @@ "@iconify/json": "^2.2.187", "@intlify/unplugin-vue-i18n": "^2.0.0", "@purge-icons/generated": "^0.9.0", + "@types/jsoneditor": "^9.9.5", "@types/lodash-es": "^4.17.12", "@types/node": "^20.11.21", "@types/nprogress": "^0.2.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c57c02f52dcf6601c71513f080a78216fb01add7..c7ace92dc7ca3df0946b4242990773b6e645d4da 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -86,6 +86,9 @@ importers: jsencrypt: specifier: ^3.3.2 version: 3.3.2 + jsoneditor: + specifier: ^10.1.3 + version: 10.1.3 lodash-es: specifier: ^4.17.21 version: 4.17.21 @@ -134,9 +137,6 @@ importers: url: specifier: ^0.11.3 version: 0.11.4 - v3-jsoneditor: - specifier: ^0.0.6 - version: 0.0.6 video.js: specifier: ^7.21.5 version: 7.21.6 @@ -183,6 +183,9 @@ importers: '@purge-icons/generated': specifier: ^0.9.0 version: 0.9.0 + '@types/jsoneditor': + specifier: ^9.9.5 + version: 9.9.5 '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -1693,6 +1696,9 @@ packages: resolution: {integrity: sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==} engines: {node: '>=10.13.0'} + '@types/ace@0.0.52': + resolution: {integrity: sha512-YPF9S7fzpuyrxru+sG/rrTpZkC6gpHBPF14W3x70kqVOD+ks6jkYLapk4yceh36xej7K4HYxcyz9ZDQ2lTvwgQ==} + '@types/conventional-commits-parser@5.0.1': resolution: {integrity: sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==} @@ -1804,6 +1810,9 @@ packages: '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/jsoneditor@9.9.5': + resolution: {integrity: sha512-+Wex7QCirPcG90WA8/CmvDO21KUjz63/G7Yk52Yx/NhWHw5DyeET/L+wjZHAeNeNCCnMOTEtVX5gc3F4UXwXMQ==} + '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} @@ -2336,8 +2345,8 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - ace-builds@1.39.0: - resolution: {integrity: sha512-MqoZojv4gpc5QyTMor/dS6kmruDV9db9LVZbCiT4qYz6WsDiv4qyG5f7ZPc+wjUl6oLMqgCAsBjo1whdSVyMlQ==} + ace-builds@1.39.1: + resolution: {integrity: sha512-HcJbBzx8qY66t9gZo/sQu7pi0wO/CFLdYn1LxQO1WQTfIkMfyc7LRnBpsp/oNCSSU/LL83jXHN1fqyOTuIhUjg==} acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} @@ -4069,8 +4078,8 @@ packages: resolution: {integrity: sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - jsoneditor@9.10.5: - resolution: {integrity: sha512-fVZ0NMt+zm4rqTKBv2x7zPdLeaRyKo1EjJkaR1QjK4gEM1rMwICILYSW1OPxSc1qqyAoDaA/eeNrluKoxOocCA==} + jsoneditor@10.1.3: + resolution: {integrity: sha512-zvbkiduFR19vLMJN1sSvBs9baGDdQRJGmKy6+/vQzDFhx//oEd6WAkrmmTeU4NNk9MAo+ZirENuwbtJXvS9M5g==} jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -4079,8 +4088,8 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} - jsonrepair@3.1.0: - resolution: {integrity: sha512-idqReg23J0PVRAADmZMc5xQM3xeOX5bTB6OTyMnzq33IXJXmn9iJuWIEvGmrN80rQf4d7uLTMEDwpzujNcI0Rg==} + jsonrepair@3.12.0: + resolution: {integrity: sha512-SWfjz8SuQ0wZjwsxtSJ3Zy8vvLg6aO/kxcp9TWNPGwJKgTZVfhNEQBMk/vPOpYCDFWRxD6QWuI6IHR1t615f0w==} hasBin: true katex@0.16.11: @@ -4402,9 +4411,6 @@ packages: mlly@1.7.3: resolution: {integrity: sha512-xUsx5n/mN0uQf4V548PKQ+YShA4/IW0KI1dZhrNrPCLG+xizETbHTkOa1f8/xut9JRPp8kQuMnz0oqwkTiLo/A==} - mobius1-selectr@2.4.13: - resolution: {integrity: sha512-Mk9qDrvU44UUL0EBhbAA1phfQZ7aMZPjwtL7wkpiBzGh8dETGqfsh50mWoX9EkjDlkONlErWXArHCKfoxVg0Bw==} - moddle-xml@10.1.0: resolution: {integrity: sha512-erWckwLt+dYskewKXJso9u+aAZ5172lOiYxSOqKCPTy7L/xmqH1PoeoA7eVC7oJTt3PqF5TkZzUmbjGH6soQBg==} @@ -5561,9 +5567,6 @@ packages: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} hasBin: true - v3-jsoneditor@0.0.6: - resolution: {integrity: sha512-9G0sXWXUn67SBkn46ycWfwPwjuJu/lcsQaNzMtXAR2/95hMV21WfcRNsqJ+vVVrSHQehohB/9fVLwYEXz0u/KA==} - vanilla-picker@2.12.3: resolution: {integrity: sha512-qVkT1E7yMbUsB2mmJNFmaXMWE2hF8ffqzMMwe9zdAikd8u2VfnsVY2HQcOUi2F38bgbxzlJBEdS1UUhOXdF9GQ==} @@ -7334,6 +7337,8 @@ snapshots: '@trysound/sax@0.2.0': {} + '@types/ace@0.0.52': {} + '@types/conventional-commits-parser@5.0.1': dependencies: '@types/node': 20.17.9 @@ -7468,6 +7473,11 @@ snapshots: '@types/json-schema@7.0.15': {} + '@types/jsoneditor@9.9.5': + dependencies: + '@types/ace': 0.0.52 + ajv: 6.12.6 + '@types/lodash-es@4.17.12': dependencies: '@types/lodash': 4.17.13 @@ -7830,7 +7840,7 @@ snapshots: '@unocss/rule-utils@0.58.9': dependencies: '@unocss/core': 0.58.9 - magic-string: 0.30.14 + magic-string: 0.30.17 '@unocss/rule-utils@66.1.0-beta.5': dependencies: @@ -8272,7 +8282,7 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - ace-builds@1.39.0: {} + ace-builds@1.39.1: {} acorn-jsx@5.3.2(acorn@8.14.0): dependencies: @@ -10179,15 +10189,14 @@ snapshots: espree: 9.6.1 semver: 7.6.3 - jsoneditor@9.10.5: + jsoneditor@10.1.3: dependencies: - ace-builds: 1.39.0 + ace-builds: 1.39.1 ajv: 6.12.6 javascript-natural-sort: 0.7.1 jmespath: 0.16.0 json-source-map: 0.6.1 - jsonrepair: 3.1.0 - mobius1-selectr: 2.4.13 + jsonrepair: 3.12.0 picomodal: 3.0.0 vanilla-picker: 2.12.3 @@ -10199,7 +10208,7 @@ snapshots: jsonparse@1.3.1: {} - jsonrepair@3.1.0: {} + jsonrepair@3.12.0: {} katex@0.16.11: dependencies: @@ -10550,8 +10559,6 @@ snapshots: pkg-types: 1.2.1 ufo: 1.5.4 - mobius1-selectr@2.4.13: {} - moddle-xml@10.1.0: dependencies: min-dash: 4.2.2 @@ -11811,10 +11818,6 @@ snapshots: uuid@10.0.0: {} - v3-jsoneditor@0.0.6: - dependencies: - jsoneditor: 9.10.5 - vanilla-picker@2.12.3: dependencies: '@sphinxxxx/color-conversion': 2.2.2 diff --git a/src/api/iot/device/device/index.ts b/src/api/iot/device/device/index.ts index 252ea433c7ac1f97a3c590fefa6ce8790f3111f7..6b5fa156437a5d39217fb9f85c8ef0ab70f648f7 100644 --- a/src/api/iot/device/device/index.ts +++ b/src/api/iot/device/device/index.ts @@ -165,5 +165,16 @@ export const DeviceApi = { // 获取设备MQTT连接参数 getMqttConnectionParams: async (deviceId: number) => { return await request.get({ url: `/iot/device/mqtt-connection-params`, params: { deviceId } }) + }, + + // 根据ProductKey和DeviceNames获取设备列表 + getDevicesByProductKeyAndNames: async (productKey: string, deviceNames: string[]) => { + return await request.get({ + url: `/iot/device/list-by-product-key-and-names`, + params: { + productKey, + deviceNames: deviceNames.join(',') + } + }) } } diff --git a/src/api/iot/product/product/index.ts b/src/api/iot/product/product/index.ts index 496fb049b5e055879fdc6573e5948655e60ac446..f03339d1a23aabe00e270117994e6603f908c6a2 100644 --- a/src/api/iot/product/product/index.ts +++ b/src/api/iot/product/product/index.ts @@ -78,5 +78,10 @@ export const ProductApi = { // 查询产品(精简)列表 getSimpleProductList() { return request.get({ url: '/iot/product/simple-list' }) + }, + + // 根据ProductKey获取产品信息 + getProductByKey: async (productKey: string) => { + return await request.get({ url: `/iot/product/get-by-key`, params: { productKey } }) } } diff --git a/src/api/iot/rule/databridge/index.ts b/src/api/iot/rule/databridge/index.ts index b19b8e8cfa89fdf6496f80fac32f1f16b8a81fdf..02568ccfed4e476da06939e08399730ac1e78b00 100644 --- a/src/api/iot/rule/databridge/index.ts +++ b/src/api/iot/rule/databridge/index.ts @@ -124,8 +124,8 @@ export const DataBridgeApi = { return await request.delete({ url: `/iot/data-bridge/delete?id=` + id }) }, - // 导出数据桥梁 Excel - exportDataBridge: async (params) => { - return await request.download({ url: `/iot/data-bridge/export-excel`, params }) + // 查询数据桥梁(精简)列表 + getSimpleDataBridgeList() { + return request.get({ url: '/iot/data-bridge/simple-list' }) } } diff --git a/src/api/iot/rule/scene/scene.types.ts b/src/api/iot/rule/scene/scene.types.ts index 990822b9f1d6794bd44aac0d8e11ac2194a93cb6..76cdf9a3d4c41a35d4d3d57e30397b8e6d18a28b 100644 --- a/src/api/iot/rule/scene/scene.types.ts +++ b/src/api/iot/rule/scene/scene.types.ts @@ -58,7 +58,8 @@ interface TenantBaseDO { // 触发条件参数 interface TriggerConditionParameter { - identifier: string // 标识符(属性、事件、服务) + identifier0: string // 标识符(事件、服务) + identifier: string // 标识符(属性) operator: string // 操作符 value: string // 比较值 } @@ -72,6 +73,7 @@ interface TriggerCondition { // 触发器配置 interface TriggerConfig { + key: any // 解决组件索引重用 type: number // 触发类型 productKey: string // 产品标识 deviceNames: string[] // 设备名称数组 @@ -98,6 +100,7 @@ interface ActionAlert { // 执行器配置 interface ActionConfig { + key: any // 解决组件索引重用 type: number // 执行类型 deviceControl?: ActionDeviceControl // 设备控制 alert?: ActionAlert // 告警执行 diff --git a/src/components/JsonEditor/index.ts b/src/components/JsonEditor/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..037b4496f3f71f679a291b78d66c689e2a05deb6 --- /dev/null +++ b/src/components/JsonEditor/index.ts @@ -0,0 +1,3 @@ +import JsonEditor from './src/JsonEditor.vue' + +export { JsonEditor } diff --git a/src/components/JsonEditor/src/JsonEditor.vue b/src/components/JsonEditor/src/JsonEditor.vue new file mode 100644 index 0000000000000000000000000000000000000000..f3789ee1f2c1dba2032b421bf883850d15f438c5 --- /dev/null +++ b/src/components/JsonEditor/src/JsonEditor.vue @@ -0,0 +1,126 @@ + + + + diff --git a/src/components/JsonEditor/types/index.ts b/src/components/JsonEditor/types/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..b7dadd77dc2a9c0157884cc525a169bf2cfc2eee --- /dev/null +++ b/src/components/JsonEditor/types/index.ts @@ -0,0 +1,80 @@ +import { JSONEditorOptions, JSONEditorMode } from 'jsoneditor' + +export interface JsonEditorProps { + /** + * JSON数据,支持双向绑定 + */ + modelValue: any + + /** + * 编辑器模式 + * @default 'tree' + */ + mode?: JSONEditorMode + + /** + * 编辑器高度 + * @default '400px' + */ + height?: string + + /** + * 是否显示模式选择下拉菜单 + * @default false + */ + showModeSelection?: boolean + + /** + * 是否显示导航栏 + * @default false + */ + showNavigationBar?: boolean + + /** + * 是否显示状态栏 + * @default true + */ + showStatusBar?: boolean + + /** + * 是否显示主菜单栏 + * @default true + */ + showMainMenuBar?: boolean + + /** + * JSONEditor配置选项 + * @see https://github.com/josdejong/jsoneditor/blob/develop/docs/api.md + */ + options?: Partial +} + +/** + * JsonEditor组件触发的事件 + */ +export interface JsonEditorEmits { + /** + * 数据更新时触发 + */ + (e: 'update:modelValue', value: any): void + + /** + * 数据变化时触发 + */ + (e: 'change', value: any): void + + /** + * 验证错误时触发 + */ + (e: 'error', errors: any): void +} + +/** + * JsonEditor组件暴露的方法 + */ +export interface JsonEditorExpose { + /** + * 获取原始的JSONEditor实例 + */ + getEditor: () => any +} diff --git a/src/utils/dict.ts b/src/utils/dict.ts index e6c1babd0feb35d1c89aad8591be7df5969386be..653160bfe4c409444e699fe456d0332cfd7c63be 100644 --- a/src/utils/dict.ts +++ b/src/utils/dict.ts @@ -247,5 +247,6 @@ export enum DICT_TYPE { IOT_DATA_BRIDGE_DIRECTION_ENUM = 'iot_data_bridge_direction_enum', // 桥梁方向 IOT_DATA_BRIDGE_TYPE_ENUM = 'iot_data_bridge_type_enum', // 桥梁类型 IOT_DEVICE_MESSAGE_TYPE_ENUM = 'iot_device_message_type_enum', // IoT 设备消息类型枚举 - IOT_RULE_SCENE_TRIGGER_TYPE_ENUM = 'iot_rule_scene_trigger_type_enum' // IoT 场景流转的触发类型枚举 + IOT_RULE_SCENE_TRIGGER_TYPE_ENUM = 'iot_rule_scene_trigger_type_enum', // IoT 场景流转的触发类型枚举 + IOT_RULE_SCENE_ACTION_TYPE_ENUM = 'iot_rule_scene_action_type_enum' // IoT 规则场景的触发类型枚举 } diff --git a/src/views/iot/device/device/components/DeviceTableSelect.vue b/src/views/iot/device/device/components/DeviceTableSelect.vue index f681940290b15d21c78b01c754fe213b87fee503..73c252da5813849490df57435dabd9a2b335b3f8 100644 --- a/src/views/iot/device/device/components/DeviceTableSelect.vue +++ b/src/views/iot/device/device/components/DeviceTableSelect.vue @@ -117,7 +117,7 @@ diff --git a/src/views/iot/product/product/components/ProductTableSelect.vue b/src/views/iot/product/product/components/ProductTableSelect.vue index f43d67786d8cdc53b935580aac4cf2ddbf83b41e..a1ab0f2baa9a95f229cc7f80fe24310f08eb10f4 100644 --- a/src/views/iot/product/product/components/ProductTableSelect.vue +++ b/src/views/iot/product/product/components/ProductTableSelect.vue @@ -57,7 +57,7 @@ @@ -19,6 +27,7 @@ defineOptions({ name: 'ThingModelTSL' }) const dialogVisible = ref(false) // 弹窗的是否展示 const dialogTitle = ref('物模型 TSL') // 弹窗的标题 const product = inject>(IOT_PROVIDE_KEY.PRODUCT) // 注入产品信息 +const viewMode = ref('code') // 查看模式:code-代码视图,editor-编辑器视图 /** 打开弹窗 */ const open = () => { @@ -27,17 +36,9 @@ const open = () => { defineExpose({ open }) /** 获取 TSL */ -const thingModelTSL = ref('') +const thingModelTSL = ref({}) const getTsl = async () => { - const res = await ThingModelApi.getThingModelTSLByProductId(product?.value?.id || 0) - thingModelTSL.value = JSON.stringify(res, null, 2) -} - -/** 代码高亮 */ -const highlightedCode = () => { - // TODO @puhui999:可以考虑 highlight 的告警解决下;另外,可以考虑配置设置里面,有个 json editor 预览 - const result = hljs.highlight('json', thingModelTSL.value, true) - return result.value || ' ' + thingModelTSL.value = await ThingModelApi.getThingModelTSLByProductId(product?.value?.id || 0) } /** 初始化 **/ diff --git a/src/views/iot/thingmodel/index.vue b/src/views/iot/thingmodel/index.vue index 74aec6fecba1f289387391fc6aa1023a0aaf0353..1766f73960b357fbe699acb29dccc0d92c3f2506 100644 --- a/src/views/iot/thingmodel/index.vue +++ b/src/views/iot/thingmodel/index.vue @@ -108,6 +108,7 @@ import { ThingModelApi, ThingModelData } from '@/api/iot/thingmodel' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import ThingModelForm from './ThingModelForm.vue' +import ThingModelTSL from './ThingModelTSL.vue' import { ProductVO } from '@/api/iot/product/product' import { IOT_PROVIDE_KEY } from '@/views/iot/utils/constants' import { getDataTypeOptionsLabel } from './config'