From 80aa27a14eb917cdccb1c7a4b3f42e7528c90d7b Mon Sep 17 00:00:00 2001 From: XieYongHong <18010623010@163.com> Date: Tue, 25 Jul 2023 14:18:38 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E4=BF=AE=E6=94=B9=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E6=8E=A5=E5=85=A5=E7=BD=91=E5=85=B3Modbus=E3=80=81opc?= =?UTF-8?q?ua=E4=B8=BA=E6=95=B0=E9=87=87=E8=AE=BE=E5=A4=87=E6=8E=A5?= =?UTF-8?q?=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/utils/consts.ts | 1 + .../Channel/Save/GateWayDeviceModal.vue | 190 ++++++++++++++++++ .../Channel/Save/GateWayFormItem.vue | 71 +++++++ src/views/DataCollect/Channel/Save/index.vue | 26 ++- src/views/DataCollect/Channel/data.ts | 2 + src/views/DataCollect/Channel/type.d.ts | 5 +- .../DataCollect/Collector/Point/index.vue | 2 +- .../DataCollect/Collector/Tree/Save/index.vue | 153 ++++++++++---- .../device/Instance/Detail/GateWay/index.vue | 7 + .../Detail/components/EditTable/index.vue | 26 +-- src/views/device/Instance/Detail/index.vue | 17 +- src/views/link/AccessConfig/Detail/index.vue | 36 ++-- .../AccessConfig/components/Edge/geteway.vue | 145 +++++++++++++ .../AccessConfig/components/Media/GB28181.vue | 29 ++- src/views/link/AccessConfig/data.ts | 1 + yarn.lock | 17 +- 17 files changed, 635 insertions(+), 95 deletions(-) create mode 100644 src/views/DataCollect/Channel/Save/GateWayDeviceModal.vue create mode 100644 src/views/DataCollect/Channel/Save/GateWayFormItem.vue create mode 100644 src/views/device/Instance/Detail/GateWay/index.vue create mode 100644 src/views/link/AccessConfig/components/Edge/geteway.vue diff --git a/package.json b/package.json index 971fdf85..36392bc2 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,7 @@ "event-source-polyfill": "^1.0.31", "global": "^4.4.0", "jetlinks-store": "^0.0.3", - "jetlinks-ui-components": "^1.0.26", + "jetlinks-ui-components": "^1.0.27", "js-cookie": "^3.0.1", "jsencrypt": "^3.3.2", "less": "^4.1.3", diff --git a/src/utils/consts.ts b/src/utils/consts.ts index 0ea4e3de..d4404334 100644 --- a/src/utils/consts.ts +++ b/src/utils/consts.ts @@ -55,4 +55,5 @@ export const USER_CENTER_MENU_BUTTON_CODE = 'user-center-passwd-update' export const protocolList = [ { label: 'OPC-UA', value: 'OPC_UA', alias: 'opc-ua' }, { label: 'Modbus/TCP', value: 'MODBUS_TCP', alias: 'modbus-tcp' }, + { label: 'GATEWAY', value: 'GATEWAY', alias: 'collector-gateway' }, ] diff --git a/src/views/DataCollect/Channel/Save/GateWayDeviceModal.vue b/src/views/DataCollect/Channel/Save/GateWayDeviceModal.vue new file mode 100644 index 00000000..68b956c9 --- /dev/null +++ b/src/views/DataCollect/Channel/Save/GateWayDeviceModal.vue @@ -0,0 +1,190 @@ + + + + + \ No newline at end of file diff --git a/src/views/DataCollect/Channel/Save/GateWayFormItem.vue b/src/views/DataCollect/Channel/Save/GateWayFormItem.vue new file mode 100644 index 00000000..5427a373 --- /dev/null +++ b/src/views/DataCollect/Channel/Save/GateWayFormItem.vue @@ -0,0 +1,71 @@ + + + + + \ No newline at end of file diff --git a/src/views/DataCollect/Channel/Save/index.vue b/src/views/DataCollect/Channel/Save/index.vue index c416f5f3..545281c8 100644 --- a/src/views/DataCollect/Channel/Save/index.vue +++ b/src/views/DataCollect/Channel/Save/index.vue @@ -92,6 +92,17 @@ :filter-option="filterOption" /> + + + (cloneDeep(FormState)); const handleOk = async () => { - const params = await formRef.value?.validate(); + const params: any = await formRef.value?.validate(); + if (params?.provider === 'GATEWAY') { + params.configuration.deviceName = formData.value.configuration.deviceName + } + + + loading.value = true; const response = !id ? await save(params).catch(() => {}) @@ -284,7 +302,7 @@ const getProvidersList = async () => { if (resp.status === 200) { const arr = resp.result .filter( - (item: any) => item.id === 'modbus-tcp' || item.id === 'opc-ua', + (item: any) => ['collector-gateway', 'modbus-tcp', 'opc-ua'].includes(item.id), ) .map((it: any) => it.id); const providers: any = protocolList.filter((item: any) => @@ -302,7 +320,9 @@ getCertificateList(); watch( () => props.data, (value) => { - if (value.id) formData.value = value as FormDataType; + if (value.id) { + formData.value = value as FormDataType; + } }, { immediate: true, deep: true }, ); diff --git a/src/views/DataCollect/Channel/data.ts b/src/views/DataCollect/Channel/data.ts index c95583fa..68a8fe0c 100644 --- a/src/views/DataCollect/Channel/data.ts +++ b/src/views/DataCollect/Channel/data.ts @@ -15,6 +15,8 @@ export const FormState: FormDataType = { authType: 'anonymous', username: '', password: '', + deviceId: undefined, + deviceName: undefined, }, description: '', }; diff --git a/src/views/DataCollect/Channel/type.d.ts b/src/views/DataCollect/Channel/type.d.ts index 9a2c7b34..7d683f08 100644 --- a/src/views/DataCollect/Channel/type.d.ts +++ b/src/views/DataCollect/Channel/type.d.ts @@ -1,6 +1,6 @@ export interface ConfigurationType { port: string | undefined; - host: string | undefined;; + host: string | undefined; username: string; password: string; endpoint: string, @@ -8,7 +8,8 @@ export interface ConfigurationType { securityMode: string | undefined, certId: string | undefined, authType: string | undefined, - + deviceId: string | undefined, + deviceName: string | undefined, } export interface FormDataType { diff --git a/src/views/DataCollect/Collector/Point/index.vue b/src/views/DataCollect/Collector/Point/index.vue index d207af99..e05c3d0a 100644 --- a/src/views/DataCollect/Collector/Point/index.vue +++ b/src/views/DataCollect/Collector/Point/index.vue @@ -20,7 +20,7 @@ + - diff --git a/src/views/link/AccessConfig/components/Media/GB28181.vue b/src/views/link/AccessConfig/components/Media/GB28181.vue index bbf277c2..f7c2730b 100644 --- a/src/views/link/AccessConfig/components/Media/GB28181.vue +++ b/src/views/link/AccessConfig/components/Media/GB28181.vue @@ -151,17 +151,11 @@ /^([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.([0-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$/, message: '请输入正确的IP地址', }, - { - max: 65535, - message: '请输入1~65535之间的正整数' - }, - { - min: 1, - message: '请输入1~65535之间的正整数' - }, + ]" + :validateFirst="true" > -
@@ -598,6 +588,15 @@ const dynamicValidateForm = reactive<{ cluster: Form2[] }>({ cluster: [], }); +const rules = { + publicPort: [ + { + required: true, + message: '输入端口', + } + ] +} + const removeCluster = (item: Form2) => { let index = dynamicValidateForm.cluster.indexOf(item); if (index !== -1) { diff --git a/src/views/link/AccessConfig/data.ts b/src/views/link/AccessConfig/data.ts index 9753405e..ba4f72fa 100644 --- a/src/views/link/AccessConfig/data.ts +++ b/src/views/link/AccessConfig/data.ts @@ -14,6 +14,7 @@ ProtocolMapping.set('Ctwing', 'HTTP'); ProtocolMapping.set('modbus-tcp', 'MODBUS_TCP'); ProtocolMapping.set('opc-ua', 'OPC_UA'); ProtocolMapping.set('edge-child-device', 'EdgeGateway'); +ProtocolMapping.set('collector-gateway', 'collector-gateway'); ProtocolMapping.set('official-edge-gateway', 'MQTT'); const NetworkTypeMapping = new Map(); diff --git a/yarn.lock b/yarn.lock index 5a0e275e..43fe36d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3738,7 +3738,7 @@ jetlinks-store@^0.0.3: resolved "https://registry.npmjs.org/jetlinks-store/-/jetlinks-store-0.0.3.tgz" integrity sha512-AZf/soh1hmmwjBZ00fr1emuMEydeReaI6IBTGByQYhTmK1Zd5pQAxC7WLek2snRAn/HHDgJfVz2hjditKThl6Q== -jetlinks-ui-components@^1.0.23, jetlinks-ui-components@^1.0.26: +jetlinks-ui-components@^1.0.23: version "1.0.26" resolved "http://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.26.tgz#26896c578396b09d49649ac87c3943491af3a9ae" integrity sha512-HkLk52C6pDKe/Ca9O4w34h1/PrC7GdBUheiicPOX2V/Lc49N+WzI9wmrCd82XBm8MocPM4gAOJxNaTxY20EO9w== @@ -3753,6 +3753,21 @@ jetlinks-ui-components@^1.0.23, jetlinks-ui-components@^1.0.26: sortablejs "^1.15.0" vuedraggable "^4.1.0" +jetlinks-ui-components@^1.0.27: + version "1.0.27" + resolved "http://registry.jetlinks.cn/jetlinks-ui-components/-/jetlinks-ui-components-1.0.27.tgz#97f04cb18906ad603de2bcbc62fa4b6673a7a3d0" + integrity sha512-R9dPrRMwV5imqV0JTkHeTMT8LeCnv7+Vb1IqKNIqc9I7joFZ9hLtEAE0EXO5GxTthPUiMZlQ+BDsd9ehCArO3Q== + dependencies: + "@vueuse/core" "^9.12.0" + "@vueuse/router" "^9.13.0" + ant-design-vue "^3.2.15" + colorpicker-v3 "^2.10.2" + jetlinks-ui-components "^1.0.23" + lodash-es "^4.17.21" + monaco-editor "^0.40.0" + sortablejs "^1.15.0" + vuedraggable "^4.1.0" + js-cookie@^3.0.1: version "3.0.1" resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.1.tgz" From ccbdef9f3cffa8ad4047744d0ba788fff578ff42 Mon Sep 17 00:00:00 2001 From: XieYongHong <18010623010@163.com> Date: Tue, 25 Jul 2023 14:27:47 +0800 Subject: [PATCH 2/8] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E8=8F=9C=E5=8D=95?= =?UTF-8?q?=E9=A2=9D=E5=A4=96=E8=B7=AF=E7=94=B1=E6=97=A0=E6=B3=95=E8=AE=BF?= =?UTF-8?q?=E9=97=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/menu.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/utils/menu.ts b/src/utils/menu.ts index 2f7de939..c973554d 100644 --- a/src/utils/menu.ts +++ b/src/utils/menu.ts @@ -384,7 +384,8 @@ const hasExtraChildren = (item: MenuItem, extraMenus: any ) => { if (extraItem) { return extraItem.children.map(e => ({ ...e, - url: `${item.url}${e.url}`, + code: `${item.code}/${e.code}`, + url: `${item.url}/${e.code}`, isShow: false })) } @@ -416,6 +417,21 @@ const findDetailRouteItem = (item: any, components: any) => { return [] } +const findSaveRouteItem = (item: any, components: any) => { + const { code, url } = item + const Component = components[`${item.code}/Save`] + if (Component) { + return [{ + url: `${url}/detail/:id`, + code: `${code}/Save`, + component: Component, + name: '详情信息', + isShow: false + }] + } + return [] +} + export const handleMenus = (menuData: any[], components: any, level: number = 1) => { if (menuData && menuData.length) { return menuData.map(item => { @@ -433,8 +449,8 @@ export const handleMenus = (menuData: any[], components: any, level: number = 1) const extraRoute = hasExtraChildren(item, extraRouteObj) const detail_components = findDetailRouteItem(item, components) - if (extraRoute && !isApp) { // 包含额外的子路由 + console.log(extraRoute) route.children = route.children ? [...route.children, ...extraRoute] : extraRoute } From 992e9a0aabbd4621501d8b03bc5fa603a40973f6 Mon Sep 17 00:00:00 2001 From: XieYongHong <18010623010@163.com> Date: Tue, 25 Jul 2023 19:50:58 +0800 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96gateway=E7=9A=84?= =?UTF-8?q?=E9=87=87=E9=9B=86=E5=99=A8=E6=96=B0=E5=A2=9E=EF=BC=8C=E7=82=B9?= =?UTF-8?q?=E4=BD=8D=E6=96=B0=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/data-collect/collector.ts | 1 + .../Collector/Point/Save/SaveModBus.vue | 49 ++- .../DataCollect/Collector/Tree/Save/index.vue | 291 +++++++++--------- .../Detail/components/EditTable/index.vue | 10 +- src/views/link/AccessConfig/Detail/index.vue | 2 +- src/views/link/AccessConfig/data.ts | 1 + vite.config.ts | 2 +- 7 files changed, 192 insertions(+), 164 deletions(-) diff --git a/src/api/data-collect/collector.ts b/src/api/data-collect/collector.ts index 53304ef6..ce1c8e5f 100644 --- a/src/api/data-collect/collector.ts +++ b/src/api/data-collect/collector.ts @@ -61,3 +61,4 @@ export const scanOpcUAList = (data: any) => export const queryTypeList = () => server.get(`/data-collect/opc/data-types`); +export const getProviders = () => server.get('/data-collect/channel/gateway/codec/providers') \ No newline at end of file diff --git a/src/views/DataCollect/Collector/Point/Save/SaveModBus.vue b/src/views/DataCollect/Collector/Point/Save/SaveModBus.vue index 5ddbdfd5..9d40ba15 100644 --- a/src/views/DataCollect/Collector/Point/Save/SaveModBus.vue +++ b/src/views/DataCollect/Collector/Point/Save/SaveModBus.vue @@ -271,7 +271,7 @@ import { import { ModBusRules, checkProviderData } from '../../data.ts'; import type { FormInstance } from 'ant-design-vue'; import type { Rule } from 'ant-design-vue/lib/form'; -import { cloneDeep } from 'lodash-es'; +import {cloneDeep, omit} from 'lodash-es'; const props = defineProps({ data: { @@ -343,10 +343,18 @@ const handleOk = async () => { // address是多余字段,但是react版本上使用到了这个字段 params.configuration.parameter = { - ...params.configuration.parameter, - address: data?.pointKey, + ...params.configuration.parameter, + address: data?.pointKey, }; + if (props.data.provider === 'GATEWAY') { + const configuration = cloneDeep(params.configuration) + params.configuration = { + configuration: configuration, + interval: params.interval + } + } + loading.value = true; const response = !id ? await savePointBatch(params).catch(() => {}) @@ -439,22 +447,31 @@ watch( watch( () => props.data, (value) => { - if (value.id && value.provider === 'MODBUS_TCP') { + if (value.id && ['MODBUS_TCP', 'GATEWAY'].includes(value.provider)) { const _value: any = cloneDeep(value); const { writeByteCount, byteCount } = - _value.configuration.parameter; + props.data.provider === 'GATEWAY' ? _value.configuration.configuration.parameter: _value.configuration.parameter; + + if (props.data.provider === 'GATEWAY') { + formData.value = { + ...omit(_value, ['configuration']), + ..._value.configuration, + } + } else { formData.value = _value; - if (!!_value.accessModes[0]?.value) { - formData.value.accessModes = value.accessModes.map( - (i: any) => i.value, - ); - } - if (!!_value.features[0]?.value) { - formData.value.features = value.features.map( - (i: any) => i.value, - ); - } - formData.value.nspwc = !!writeByteCount || !!byteCount; + } + + if (!!_value.accessModes[0]?.value) { + formData.value.accessModes = value.accessModes.map( + (i: any) => i.value, + ); + } + if (!!_value.features[0]?.value) { + formData.value.features = value.features.map( + (i: any) => i.value, + ); + } + formData.value.nspwc = !!writeByteCount || !!byteCount; } }, { immediate: true, deep: true }, diff --git a/src/views/DataCollect/Collector/Tree/Save/index.vue b/src/views/DataCollect/Collector/Tree/Save/index.vue index c4c9f1a6..f869e77f 100644 --- a/src/views/DataCollect/Collector/Tree/Save/index.vue +++ b/src/views/DataCollect/Collector/Tree/Save/index.vue @@ -40,114 +40,111 @@ v-model:value="formData.name" />
- - -