Jelajahi Sumber

refactor(network): device network settings

Casper Dai 3 tahun lalu
induk
melakukan
8e27537686

+ 34 - 6
src/views/device/detail/components/DeviceInvoke/ScreenNetwork/Wired.vue → src/views/device/detail/components/DeviceInvoke/DeviceNetwork/Wired.vue

@@ -1,5 +1,11 @@
 <template>
   <div class="c-grid-form">
+    <span class="c-grid-form__label u-bold">网口:</span>
+    <schema-select
+      :value="eth"
+      :schema="ethSchema"
+      @change="onChange"
+    />
     <span class="c-grid-form__label u-bold">IP配置方式:</span>
     <schema-select
       v-model="wired.mode"
@@ -27,13 +33,13 @@
           placeholder="255.255.255.0"
           maxlength="15"
         />
-        <span class="c-grid-form__label required">网关:</span>
+        <span class="c-grid-form__label">网关:</span>
         <el-input
           v-model.trim="wired.ip4.gateway"
           placeholder="192.168.0.1"
           maxlength="15"
         />
-        <span class="c-grid-form__label required">主DNS:</span>
+        <span class="c-grid-form__label">主DNS:</span>
         <el-input
           v-model.trim="wired.ip4.dns1"
           placeholder="192.168.0.10"
@@ -68,13 +74,13 @@
           :max="32"
           step-strictly
         />
-        <span class="c-grid-form__label required">网关:</span>
+        <span class="c-grid-form__label">网关:</span>
         <el-input
           v-model.trim="wired.ip6.gateway"
           placeholder="ffff:0000:0000:0000:0000:0000:0000:0000"
           maxlength="39"
         />
-        <span class="c-grid-form__label required">主DNS:</span>
+        <span class="c-grid-form__label">主DNS:</span>
         <el-input
           v-model.trim="wired.ip6.dns1"
           placeholder="ffff:0000:0000:0000:0000:0000:0000:0000"
@@ -95,8 +101,12 @@
 export default {
   name: 'Wired',
   props: {
-    wired: {
-      type: Object,
+    eth: {
+      type: String,
+      required: true
+    },
+    eths: {
+      type: Array,
       required: true
     }
   },
@@ -111,9 +121,27 @@ export default {
     }
   },
   computed: {
+    ethSchema () {
+      return {
+        options: this.eths.map(({ name }, index) => {
+          return {
+            value: `${index}`,
+            label: name
+          }
+        })
+      }
+    },
+    wired () {
+      return this.eths[this.eth]
+    },
     isMaunal () {
       return this.wired.mode === 'manual'
     }
+  },
+  methods: {
+    onChange (val) {
+      this.$emit('update:eth', val)
+    }
   }
 }
 </script>

+ 0 - 0
src/views/device/detail/components/DeviceInvoke/ScreenNetwork/Wireless.vue → src/views/device/detail/components/DeviceInvoke/DeviceNetwork/Wireless.vue


+ 141 - 39
src/views/device/detail/components/DeviceInvoke/ScreenNetwork/index.vue → src/views/device/detail/components/DeviceInvoke/DeviceNetwork/index.vue

@@ -14,11 +14,12 @@
         :items="tabs"
         :active.sync="active"
       />
-      <div class="l-flex__auto has-bottom-padding u-overflow-y--auto">
+      <div class="l-flex__auto has-bottom-padding u-align-self--center u-overflow-y--auto">
         <wired
           v-if="isWired"
           key="wired"
-          :wired="wired"
+          :eth.sync="eth"
+          :eths="eths"
         />
         <wireless
           v-if="isWireless"
@@ -31,6 +32,11 @@
 </template>
 
 <script>
+import {
+  publish,
+  subscribe,
+  unsubscribe
+} from '@/utils/mqtt'
 import {
   validIP4,
   validIP6
@@ -41,7 +47,7 @@ import Wired from './Wired'
 import Wireless from './Wireless'
 
 export default {
-  name: 'ScreenNetwork',
+  name: 'DeviceNetwork',
   components: {
     Tabs,
     Wired,
@@ -51,30 +57,121 @@ export default {
   data () {
     return {
       tabs: [
-        { key: 'wired', name: '有线网络' },
-        { key: 'wireless', name: '无线网络' }
+        { key: 'wired', name: '有线网络' }/* ,
+        { key: 'wireless', name: '无线网络' } */
       ],
       active: null,
-      wired: null,
+      eth: '0',
+      eths: null,
       wireless: null
     }
   },
   computed: {
+    topic () {
+      return `${this.device.productId}/${this.deviceId}/function/invoke/reply`
+    },
     isWired () {
       return this.active === 'wired'
     },
+    wired () {
+      return this.eths?.[this.eth]
+    },
     isWireless () {
       return this.active === 'wireless'
     }
   },
+  watch: {
+    online () {
+      if (this.online) {
+        subscribe([this.topic], this.onMessage)
+      } else {
+        clearTimeout(this.$timer)
+        unsubscribe([this.topic], this.onMessage)
+      }
+    }
+  },
+  created () {
+    this.$timer = -1
+    this.online && subscribe([this.topic], this.onMessage)
+  },
+  beforeDestroy () {
+    clearTimeout(this.$timer)
+    this.online && unsubscribe([this.topic], this.onMessage)
+  },
   methods: {
+    onMessage (topic, message) {
+      if (topic === this.topic) {
+        message = JSON.parse(message)
+        if (message.messageId === this.$messageId) {
+          this.closeLoading()
+          try {
+            const eths = JSON.parse(message.output)
+            if (eths?.length) {
+              this.showNetwork(eths)
+              return
+            }
+          } catch (e) {
+            console.log(e)
+          }
+          this.$message({
+            type: 'warning',
+            message: '未发现设备网口,请稍后再试'
+          })
+        }
+      }
+    },
     invoke () {
-      this.active = 'wired'
-      this.wired = {
-        mode: 'dhcp',
-        ip4: this.createIPSetting(),
-        ip6: this.createIPSetting(true)
+      if (!this.online) {
+        this.$message({
+          type: 'warning',
+          message: '设备未上线,请稍后再试'
+        })
+        return
       }
+      this.fetchNetwork()
+    },
+    fetchNetwork () {
+      this.$loadingDialog = this.$showLoading()
+      clearTimeout(this.$timer)
+      this.$messageId = `${Date.now()}`
+      publish(
+        `${this.device.productId}/${this.deviceId}/function/invoke`,
+        JSON.stringify({
+          messageId: this.$messageId,
+          timestamp: Date.now(),
+          'function': 'network',
+          inputs: []
+        }),
+        true
+      ).then(
+        () => {
+          this.$timer = setTimeout(() => {
+            this.closeLoading()
+            this.$message({
+              type: 'warning',
+              message: '未获取到设备网络状态,请稍后再试'
+            })
+          }, 5000)
+        },
+        () => {
+          this.closeLoading()
+          this.$message({
+            type: 'warning',
+            message: '正在连接,请稍后再试'
+          })
+        }
+      )
+    },
+    closeLoading () {
+      clearTimeout(this.$timer)
+      this.$messageId = null
+      this.$closeLoading(this.$loadingDialog)
+      this.$loadingDialog = null
+    },
+    showNetwork (eths) {
+      this.active = 'wired'
+      this.eth = '0'
+      this.eths = eths.map(eth => this.createEth(eth))
       this.wireless = {
         enable: true,
         name: '',
@@ -83,11 +180,27 @@ export default {
       }
       this.$refs.networkDialg.show()
     },
-    createIPSetting (ip6) {
+    createEth (eth) {
+      const { name, setting, address, subnetMask, defaultGateway, preferredDNS, alternativeDNS } = eth
+      return {
+        name,
+        mode: setting === 'manual' ? 'manual' : 'dhcp',
+        ip4: {
+          enable: true,
+          address: address || '',
+          mask: subnetMask || '',
+          gateway: defaultGateway || '',
+          dns1: preferredDNS || '',
+          dns2: alternativeDNS || ''
+        },
+        ip6: this.createIPv6Setting()
+      }
+    },
+    createIPv6Setting (ip6) {
       return {
         enable: false,
         address: '',
-        mask: ip6 ? 32 : '',
+        mask: 32,
         gateway: '',
         dns1: '',
         dns2: ''
@@ -101,25 +214,24 @@ export default {
       if (!this.validWired()) {
         return
       }
-      const { mode, ip4, ip6 } = this.wired
+      const { name, mode, ip4, ip6 } = this.wired
       const inputs = []
       if (mode === 'dhcp') {
         inputs.push({
-          name: 'ip4',
+          name,
           value: JSON.stringify({ setting: mode })
         })
         inputs.push({
-          name: 'ip6',
+          name: `${name}-ipv6`,
           value: JSON.stringify({ setting: mode })
         })
       } else {
         if (ip4.enable) {
           const { address, mask, gateway, dns1, dns2 } = ip4
           inputs.push({
-            name: 'ip4',
+            name,
             value: JSON.stringify({
               setting: mode,
-              enable: 1,
               address,
               subnetMask: mask,
               defaultGateway: gateway,
@@ -127,19 +239,14 @@ export default {
               alternativeDNS: dns2
             })
           })
-        } else {
-          inputs.push({
-            name: 'ip4',
-            value: JSON.stringify({ setting: mode, enable: 0 })
-          })
         }
         if (ip6.enable) {
           const { address, mask, gateway, dns1, dns2 } = ip6
           inputs.push({
-            name: 'ip6',
+            name: `${name}-ipv6`,
             value: JSON.stringify({
+              name,
               setting: mode,
-              enable: 1,
               address,
               subnetPrefixLegth: mask,
               defaultGateway: gateway,
@@ -147,15 +254,10 @@ export default {
               alternativeDNS: dns2
             })
           })
-        } else {
-          inputs.push({
-            name: 'ip6',
-            value: JSON.stringify({ setting: mode, enable: 0 })
-          })
         }
       }
       this.$confirm(
-        '将有线网络设置为配置内容?',
+        `将${name}有线网络设置为配置内容?`,
         { type: 'warning' }
       ).then(() => {
         done()
@@ -223,11 +325,11 @@ export default {
       if (!this.isValid(mask, validIP4, type, '子网掩码')) {
         return false
       }
-      if (!this.isValid(gateway, validIP4, type, '网关')) {
-        return false
+      if (gateway && !validIP4(gateway)) {
+        return this.onError('IPv4的网关格式错误')
       }
-      if (!this.isValid(dns1, validIP4, type, '主DNS')) {
-        return false
+      if (dns1 && !validIP4(dns1)) {
+        return this.onError('IPv4的主DNS格式错误')
       }
       if (dns2 && !validIP4(dns2)) {
         return this.onError('IPv4的备DNS格式错误')
@@ -240,11 +342,11 @@ export default {
       if (!this.isValid(address, validIP6, type, 'IP地址')) {
         return false
       }
-      if (!this.isValid(gateway, validIP6, type, '网关')) {
-        return false
+      if (gateway && !validIP6(gateway)) {
+        return this.onError('IPv6的网关格式错误')
       }
-      if (!this.isValid(dns1, validIP6, type, '主DNS')) {
-        return false
+      if (dns1 && !validIP6(dns1)) {
+        return this.onError('IPv6的主DNS格式错误')
       }
       if (dns2 && !validIP6(dns2)) {
         return this.onError('IPv6的备DNS格式错误')

+ 3 - 3
src/views/device/detail/components/DeviceInvoke/index.vue

@@ -1,8 +1,8 @@
 <script>
-import ScreenNetwork from './ScreenNetwork'
 import ScreenSwitch from './ScreenSwitch'
 import ScreenLight from './ScreenLight'
 import ScreenVolume from './ScreenVolume'
+import DeviceNetwork from './DeviceNetwork'
 import DeviceSwitch from './DeviceSwitch'
 import DeviceReboot from './DeviceReboot'
 // import DeviceTime from './DeviceTime'
@@ -11,10 +11,10 @@ import DeviceReboot from './DeviceReboot'
 export default {
   name: 'DeviceInvoke',
   components: {
-    ScreenNetwork,
     ScreenSwitch,
     ScreenLight,
     ScreenVolume,
+    DeviceNetwork,
     DeviceSwitch,
     DeviceReboot/* ,
     DeviceTime,
@@ -26,7 +26,7 @@ export default {
       { staticClass: 'c-info-grid small' },
       __STAGING__
         ? [
-          h('ScreenNetwork', { props: this.$attrs }),
+          h('DeviceNetwork', { props: this.$attrs }),
           h('DeviceSwitch', { props: this.$attrs }),
           h('ScreenSwitch', { props: this.$attrs }),
           h('DeviceReboot', { props: this.$attrs }),

+ 7 - 0
src/views/device/detail/components/DeviceInvoke/mixins/simple-task.js

@@ -28,6 +28,13 @@ export default {
       this.show = true
     },
     onInvoke () {
+      if (!this.online) {
+        this.$message({
+          type: 'warning',
+          message: '设备未上线,请稍后再试'
+        })
+        return
+      }
       this.$confirm(
         `将${this.type}设置为${this.taskValue}%?`,
         { type: 'warning' }

+ 7 - 0
src/views/device/detail/components/DeviceInvoke/mixins/switch-task.js

@@ -39,6 +39,13 @@ export default {
       this.show = true
     },
     onSwitch (open) {
+      if (!this.online) {
+        this.$message({
+          type: 'warning',
+          message: '设备未上线,请稍后再试'
+        })
+        return
+      }
       this.$confirm(
         `立即${open ? '开机' : '关机'}?`,
         { type: 'warning' }

+ 1 - 1
src/views/device/detail/components/external/Sensors/Sensor.vue

@@ -122,7 +122,7 @@ export default {
   methods: {
     onUpdate (list) {
       this.list = list
-      this.$refs.table.pageTo()
+      this.$refs.table?.pageTo()
     },
     getSensors () {
       return Promise.resolve({ data: this.list })