Ver Fonte

refactor: receiving card and sending card

Casper Dai há 3 anos atrás
pai
commit
a97b145beb

+ 0 - 6
src/scss/bem/_component.scss

@@ -367,12 +367,6 @@
   color: $black;
   line-height: 1;
 
-  &.large {
-    .c-info__title {
-      width: 180px;
-    }
-  }
-
   &__block {
     padding: 20px 32px;
     background-color: #f5f7f9;

+ 2 - 2
src/utils/validate.js

@@ -14,11 +14,11 @@ export function validMAC (mac) {
   return /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/.test(mac)
 }
 
-export function validIP4 (ip) {
+export function validIPv4 (ip) {
   return /^((25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d))).){3}(25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$/.test(ip)
 }
 
-export function validIP6 (ip) {
+export function validIPv6 (ip) {
   if (ip === '::') {
     return true
   }

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

@@ -38,8 +38,8 @@ import {
   unsubscribe
 } from '@/utils/mqtt'
 import {
-  validIP4,
-  validIP6
+  validIPv4,
+  validIPv6
 } from '@/utils/validate'
 import baseMixin from '../mixins/base'
 import Tabs from '../../Tabs'
@@ -319,19 +319,19 @@ export default {
     validIPv4 (ip4) {
       const { address, mask, gateway, dns1, dns2 } = ip4
       const type = 'IPv4'
-      if (!this.isValid(address, validIP4, type, 'IP地址')) {
+      if (!this.isValid(address, validIPv4, type, 'IP地址')) {
         return false
       }
-      if (!this.isValid(mask, validIP4, type, '子网掩码')) {
+      if (!this.isValid(mask, validIPv4, type, '子网掩码')) {
         return false
       }
-      if (gateway && !validIP4(gateway)) {
+      if (gateway && !validIPv4(gateway)) {
         return this.onError('IPv4的网关格式错误')
       }
-      if (dns1 && !validIP4(dns1)) {
+      if (dns1 && !validIPv4(dns1)) {
         return this.onError('IPv4的主DNS格式错误')
       }
-      if (dns2 && !validIP4(dns2)) {
+      if (dns2 && !validIPv4(dns2)) {
         return this.onError('IPv4的备DNS格式错误')
       }
       return true
@@ -339,16 +339,16 @@ export default {
     validIPv6 (ip6) {
       const { address, gateway, dns1, dns2 } = ip6
       const type = 'IPv6'
-      if (!this.isValid(address, validIP6, type, 'IP地址')) {
+      if (!this.isValid(address, validIPv6, type, 'IP地址')) {
         return false
       }
-      if (gateway && !validIP6(gateway)) {
+      if (gateway && !validIPv6(gateway)) {
         return this.onError('IPv6的网关格式错误')
       }
-      if (dns1 && !validIP6(dns1)) {
+      if (dns1 && !validIPv6(dns1)) {
         return this.onError('IPv6的主DNS格式错误')
       }
-      if (dns2 && !validIP6(dns2)) {
+      if (dns2 && !validIPv6(dns2)) {
         return this.onError('IPv6的备DNS格式错误')
       }
       return true

+ 18 - 8
src/views/device/detail/components/external/ReceivingCard/ReceivingCardInfo.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="c-info large">
+  <div class="c-info">
     <div class="l-flex--row c-info__block">
       <div class="l-flex--row l-flex__fill c-info__item">
         <div class="l-flex__none c-info__title">厂家名称</div>
@@ -33,6 +33,13 @@
         <div class="l-flex__fill c-info__value">{{ voltage }}</div>
       </div>
     </div>
+    <div class="l-flex--row c-info__block">
+      <div class="l-flex--row l-flex__fill c-info__item">
+        <div class="l-flex__none c-info__title">设备IP</div>
+        <div class="l-flex__fill c-info__value">{{ ip }}</div>
+      </div>
+      <div class="l-flex__fill c-info__item" />
+    </div>
   </div>
 </template>
 
@@ -42,27 +49,30 @@ export default {
   props: {
     info: {
       type: Object,
-      default: null
+      required: true
     }
   },
   computed: {
     manufacturer () {
-      return this.info?.manufacturerName
+      return this.info.manufacturerName
     },
     topology () {
-      return this.info?.topology?.version ?? '未上传'
+      return this.info.topology ? '已上传' : '未上传'
     },
     screen () {
-      return this.info?.screen
+      return this.info.screen
     },
     type () {
-      return this.info ? this.info.async ? '异步盒' : '非异步盒' : ''
+      return this.info.async ? '异步盒' : '非异步盒'
     },
     temperature () {
-      return this.info ? this.info.temperature ? '是' : '否' : ''
+      return this.info.temperature ? '是' : '否'
     },
     voltage () {
-      return this.info ? this.info.voltage ? '是' : '否' : ''
+      return this.info.voltage ? '是' : '否'
+    },
+    ip () {
+      return this.info.ip
     }
   }
 }

+ 78 - 8
src/views/device/detail/components/external/ReceivingCard/ReceivingCardInfoEdit.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="c-info large">
+  <div class="c-info">
     <template v-if="info">
       <div class="l-flex--row c-info__block">
         <div class="l-flex--row l-flex__fill c-info__item">
@@ -82,6 +82,17 @@
           </div>
         </div>
       </div>
+      <div class="l-flex--row c-info__block">
+        <div class="l-flex--row l-flex__fill c-info__item">
+          <div class="l-flex__none c-info__title">设备IP</div>
+          <edit-input
+            v-model.trim="defaults.ip"
+            class="l-flex__fill c-info__value"
+            @edit="onChangeProp('ip')"
+          />
+        </div>
+        <div class="l-flex__fill c-info__item" />
+      </div>
     </template>
     <template v-else>
       <button
@@ -137,7 +148,7 @@
             show-word-limit
           />
           <span class="c-grid-form__label">异步盒:</span>
-          <div class="l-flex--row">
+          <div class="l-flex--row c-grid-form__option">
             <el-switch
               v-model="receivingCard.async"
               class="c-sibling-item"
@@ -159,6 +170,13 @@
               inactive-color="#ff4949"
             />
           </div>
+          <span class="c-grid-form__label required">设备IP:</span>
+          <el-input
+            v-model.trim="receivingCard.ip"
+            placeholder="192.168.0.1"
+            maxlength="15"
+            show-word-limit
+          />
         </div>
       </confirm-dialog>
     </template>
@@ -186,6 +204,7 @@ import {
   addReceivingCard,
   updateReceivingCard
 } from '@/api/external'
+import { validIPv4 } from '@/utils/validate'
 
 export default {
   name: 'ReceivingCardInfoEdit',
@@ -226,7 +245,8 @@ export default {
           async: this.info.async,
           temperature: this.info.temperature,
           voltage: this.info.voltage,
-          topology: this.info.topology?.version ?? '未上传'
+          topology: this.info.topology ? '已上传' : '未上传',
+          ip: this.info.ip
         }
         if (!this.manufacturers.loaded) {
           this.manufacturers.list = [{ value: this.info.manufacturerKey, label: this.info.manufacturerName }]
@@ -254,7 +274,8 @@ export default {
         screen: '',
         async: false,
         temperature: false,
-        voltage: false
+        voltage: false,
+        ip: ''
       }
       this.$refs.addDialog.show()
     },
@@ -280,6 +301,20 @@ export default {
         })
         return
       }
+      if (!this.receivingCard.ip) {
+        this.$message({
+          type: 'warning',
+          message: '请填写设备IP'
+        })
+        return
+      }
+      if (!validIPv4(this.receivingCard.ip)) {
+        this.$message({
+          type: 'warning',
+          message: '设备IP格式错误'
+        })
+        return
+      }
       const formData = new FormData()
       formData.append('deviceId', this.$route.params.id)
       formData.append('manufacturerKey', this.receivingCard.manufacturerKey)
@@ -288,6 +323,7 @@ export default {
       formData.append('temperature', this.receivingCard.temperature)
       formData.append('voltage', this.receivingCard.voltage)
       formData.append('async', this.receivingCard.async)
+      formData.append('ip', this.receivingCard.ip)
       this.progress = 0
       this.showProgress = true
       addReceivingCard(formData, ({ loaded, total }) => {
@@ -300,9 +336,6 @@ export default {
         this.emitChange('all')
       })
     },
-    updateReceivingCard () {
-      updateReceivingCard()
-    },
     onChange ({ raw }) {
       this.$refs.upload.clearFiles()
       this.receivingCard.topologyFile = raw
@@ -318,10 +351,47 @@ export default {
         this.showProgress = false
       })
     },
+    checkProp (key) {
+      const val = this.defaults[key]
+      switch (key) {
+        case 'type':
+          if (!val) {
+            this.$message({
+              type: 'warning',
+              message: '请填写设备型号'
+            })
+            return false
+          }
+          break
+        case 'ip':
+          if (!val) {
+            this.$message({
+              type: 'warning',
+              message: '请填写设备IP'
+            })
+            return false
+          }
+          if (!validIPv4(val)) {
+            this.$message({
+              type: 'warning',
+              message: '设备IP格式错误'
+            })
+            return false
+          }
+          break
+        default:
+          break
+      }
+      return true
+    },
     onChangeProp (key) {
       if (this.defaults[key] === this.info[key]) {
         return
       }
+      if (!this.checkProp(key)) {
+        this.defaults[key] = this.info[key]
+        return
+      }
       this.updateProp(key, this.defaults[key]).catch(() => {
         this.defaults[key] = this.info[key]
       })
@@ -336,7 +406,7 @@ export default {
     },
     emitChange (key) {
       console.log('receiving card', key, 'changed')
-      this.$parent.getDefaults()
+      this.$emit('change')
     }
   }
 }

+ 75 - 80
src/views/device/detail/components/external/ReceivingCard/ReceivingCardTopology.vue

@@ -28,8 +28,8 @@
 <script>
 import { getReceivingCardTopology } from '@/api/external'
 import {
-  addListener,
-  removeListener
+  addListener/* ,
+  removeListener */
 } from '@/views/device/detail/monitor'
 
 export default {
@@ -47,70 +47,71 @@ export default {
       message: ''
     }
   },
-  computed: {
-    topology () {
-      return this.info?.topology
-    },
-    version () {
-      return this.topology?.version
-    }
-  },
   watch: {
     info: {
       handler () {
-        this.setDefaults(this.topology?.rxcList)
+        this.setDefaults(this.info?.topology?.screenList)
       },
       immediate: true
     }
   },
-  activated () {
-    this.check()
-  },
-  deactivated () {
-    removeListener('topology', this.onUpdate)
-  },
+  // activated () {
+  //   this.check()
+  // },
+  // deactivated () {
+  //   removeListener('topology', this.onUpdate)
+  // },
   methods: {
-    setDefaults (cards) {
+    setDefaults (screenList) {
       let maxRow = 0
       let maxCol = 0
-      if (cards) {
-        this.cards = cards.sort((a, b) => {
-          if (a.port === b.port) {
-            return a.sub - b.sub
-          }
-          return a.port - b.port
-        }).map(({ version, port, sub, row_index, col_index }, index) => {
-          maxRow = Math.max(maxRow, row_index)
-          maxCol = Math.max(maxCol, col_index)
-          let dirc = ''
-          let tip = sub === 1 ? 'S' : ''
-          const next = cards[index + 1]
-          if (next) {
-            if (port === next.port) {
-              if (row_index > next.row_index) {
-                dirc = 'bottom'
-              } else if (row_index < next.row_index) {
-                dirc = 'top'
-              } else {
-                dirc = col_index < next.col_index ? 'right' : 'left'
-              }
-            } else {
-              tip = 'E'
-            }
-          } else {
-            tip = 'E'
-          }
-          return {
-            key: `${port}-${sub}`,
-            style: {
-              gridRow: row_index,
-              gridColumn: col_index
-            },
-            status: 'unknown',
-            text: '未知',
-            version, tip, dirc
-          }
+      if (screenList) {
+        const cards = []
+        const status = this.info.status
+        screenList.forEach(({ outCardList }) => {
+          outCardList.forEach(({ sendCardList }) => {
+            sendCardList.forEach(({ rxcList }) => {
+              rxcList && rxcList.sort((a, b) => {
+                if (a.port === b.port) {
+                  return a.sub - b.sub
+                }
+                return a.port - b.port
+              }).map(({ port, sub, row_index, col_index }, index) => {
+                maxRow = Math.max(maxRow, row_index)
+                maxCol = Math.max(maxCol, col_index)
+                let tip = sub === 1 ? 'S' : ''
+                let dirc = ''
+                const next = rxcList[index + 1]
+                if (next) {
+                  if (port === next.port) {
+                    if (row_index > next.row_index) {
+                      dirc = 'top'
+                    } else if (row_index < next.row_index) {
+                      dirc = 'bottom'
+                    } else {
+                      dirc = col_index < next.col_index ? 'right' : 'left'
+                    }
+                  } else {
+                    tip = 'E'
+                  }
+                } else if (!tip) {
+                  tip = 'E'
+                }
+                const card = {
+                  key: `${port}-${sub}`,
+                  style: {
+                    gridRow: row_index,
+                    gridColumn: col_index
+                  },
+                  tip, dirc
+                }
+                this.setStatus(card, status)
+                cards.push(card)
+              })
+            })
+          })
         })
+        this.cards = cards
       } else {
         this.cards = null
       }
@@ -120,7 +121,7 @@ export default {
         gridTemplateRows: `repeat(${maxRow}, 96px)`,
         gridTemplateColumns: `repeat(${maxCol}, 96px)`
       }
-      this.check()
+      // this.check()
     },
     check () {
       if (!this._inactive && this.cards?.length) {
@@ -129,24 +130,20 @@ export default {
     },
     onUpdate (data) {
       if (data) {
-        const { version, rxcList } = data
-        if (version === this.version) {
-          this.message = null
-          if (rxcList) {
-            const map = {}
-            rxcList.forEach(({ port, sub, version }) => {
-              map[`${port}-${sub}`] = version
-            })
-            this.cards.forEach(card => {
-              this.setStatus(card, card.version === map[card.key] ? 1 : map[card.key] ? 3 : 2)
+        const map = {}
+        data.screenList.forEach(({ outCardList }) => {
+          outCardList.forEach(({ sendCardList }) => {
+            sendCardList.forEach(({ rxcList }) => {
+              rxcList.forEach(({ port, sub }) => {
+                map[`${port}-${sub}`] = 1
+              })
             })
-          }
-        } else {
-          this.message = `${this.version} -> ${version}`
-          this.cards.forEach(card => {
-            this.setStatus(card, 0)
           })
-        }
+        })
+        this.cards.forEach(card => {
+          this.setStatus(card, map[card.key] ? 1 : 0)
+        })
+        this.message = null
       } else if (!this.$runtime) {
         this.getRuntime()
       }
@@ -154,14 +151,12 @@ export default {
     getRuntime () {
       getReceivingCardTopology(this.$route.params.id, { custom: true }).then(({ data }) => {
         this.$runtime = true
-        if (data?.version === this.version) {
-          this.onUpdate(data)
-        }
+        this.onUpdate(data)
       })
     },
     setStatus (card, status) {
-      card.status = ['unknown', 'normal', 'error', 'error'][status]
-      card.text = ['未知', '正常', '异常', '版本不匹配'][status]
+      card.status = this.online ? ['error', 'online', 'error'][status] : 'unknown'
+      card.text = this.online ? ['离线', '在线', '异常'][status] : '未知'
     }
   }
 }
@@ -215,7 +210,7 @@ export default {
   color: $info;
   background: url("~@/assets/screen.png") 0 0 / 100% 100% no-repeat;
 
-  &.normal,
+  &.online,
   &.error {
     color: $success--dark;
   }
@@ -236,7 +231,7 @@ export default {
     transform: scale(0.8);
   }
 
-  &.normal::after {
+  &.online::after {
     background-color: $black;
   }
 
@@ -257,7 +252,7 @@ export default {
     background: url("~@/assets/icon_card_unknown.png") 0 0 / 100% 100% no-repeat;
   }
 
-  &.normal {
+  &.online {
     .o-receiving-card__status {
       color: $error;
       background-image: url("~@/assets/icon_card_normal.png");

+ 26 - 18
src/views/device/detail/components/external/ReceivingCard/index.vue

@@ -8,25 +8,28 @@
         v-if="error"
         @click="getDefaults"
       />
-      <template v-if="info">
-        <tabs
-          :items="tabs"
-          :active.sync="active"
-        />
-        <keep-alive>
-          <component
-            :is="activeComponent"
-            class="l-flex__fill"
-            :info="info"
-          />
-        </keep-alive>
-      </template>
       <template v-else>
-        <div class="l-flex__fill l-flex--row center u-color--info">
-          <div class="l-flex--col center">
-            <div class="has-padding">未绑定接收卡,请联系管理员</div>
+        <template v-if="isSuperAdmin || info">
+          <tabs
+            :items="tabs"
+            :active.sync="active"
+          />
+          <keep-alive>
+            <component
+              :is="activeComponent"
+              class="l-flex__fill"
+              :info="info"
+              @change="getDefaults"
+            />
+          </keep-alive>
+        </template>
+        <template v-else>
+          <div class="l-flex__fill l-flex--row center u-color--info">
+            <div class="l-flex--col center">
+              <div class="has-padding">未绑定接收卡,请联系管理员</div>
+            </div>
           </div>
-        </div>
+        </template>
       </template>
     </template>
   </div>
@@ -85,8 +88,13 @@ export default {
       }
     }
   },
+  watch: {
+    online () {
+      this.getDefaults()
+    }
+  },
   activated () {
-    !this.info && this.getDefaults()
+    this.getDefaults()
   },
   methods: {
     getDefaults () {

+ 71 - 61
src/views/device/detail/components/external/Transmitter/index.vue

@@ -8,70 +8,72 @@
         v-if="error"
         @click="getDefaults"
       />
-      <template v-if="info">
-        <div class="c-info large">
-          <div class="l-flex--row has-bottom-padding u-bold">
-            <span class="c-sibling-item">发送控制设备信息</span>
-            <span
-              v-if="isSuperAdmin"
-              class="c-sibling-item c-info__edit u-pointer"
-              @click="onUnbind"
-            >
-              <i class="el-icon-edit" />
-              解绑
-            </span>
-          </div>
-          <div class="l-flex--row c-info__block">
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">设备名称</div>
-              <auto-text
-                class="l-flex__fill c-info__value"
-                :text="info.name"
-              />
+      <template v-else>
+        <template v-if="info">
+          <div class="c-info">
+            <div class="l-flex--row has-bottom-padding u-bold">
+              <span class="c-sibling-item">发送控制设备信息</span>
+              <span
+                v-if="isSuperAdmin"
+                class="c-sibling-item c-info__edit u-pointer"
+                @click="onUnbind"
+              >
+                <i class="el-icon-edit" />
+                解绑
+              </span>
             </div>
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">厂家名称</div>
-              <div class="l-flex__fill c-info__value">{{ info.manufacturerName }}</div>
+            <div class="l-flex--row c-info__block">
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">设备名称</div>
+                <auto-text
+                  class="l-flex__fill c-info__value"
+                  :text="transmitter.name"
+                />
+              </div>
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">厂家名称</div>
+                <div class="l-flex__fill c-info__value">{{ transmitter.manufacturerName }}</div>
+              </div>
             </div>
-          </div>
-          <div class="l-flex--row c-info__block">
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">设备型号</div>
-              <auto-text
-                class="l-flex__fill c-info__value"
-                :text="info.type"
-              />
+            <div class="l-flex--row c-info__block">
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">设备型号</div>
+                <auto-text
+                  class="l-flex__fill c-info__value"
+                  :text="transmitter.type"
+                />
+              </div>
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">设备类型</div>
+                <div class="l-flex__fill c-info__value">{{ type }}</div>
+              </div>
             </div>
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">设备类型</div>
-              <div class="l-flex__fill c-info__value">{{ type }}</div>
+            <div class="l-flex--row c-info__block">
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">支持设备监测</div>
+                <div class="l-flex__fill c-info__value">{{ supportDetection }}</div>
+              </div>
+              <div class="l-flex--row l-flex__fill c-info__item">
+                <div class="l-flex__none c-info__title">支持内容保护</div>
+                <div class="l-flex__fill c-info__value">{{ supportContentProtection }}</div>
+              </div>
             </div>
           </div>
-          <div class="l-flex--row c-info__block">
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">支持设备监测</div>
-              <div class="l-flex__fill c-info__value">{{ supportDetection }}</div>
-            </div>
-            <div class="l-flex--row l-flex__fill c-info__item">
-              <div class="l-flex__none c-info__title">支持内容保护</div>
-              <div class="l-flex__fill c-info__value">{{ supportContentProtection }}</div>
+        </template>
+        <template v-else>
+          <div class="l-flex__fill l-flex--row center u-color--info">
+            <div class="l-flex--col center">
+              <div class="has-padding">未绑定发送控制设备,请联系管理员</div>
+              <button
+                v-if="isSuperAdmin"
+                class="o-button"
+                @click="onBind"
+              >
+                绑定设备
+              </button>
             </div>
           </div>
-        </div>
-      </template>
-      <template v-else>
-        <div class="l-flex__fill l-flex--row center u-color--info">
-          <div class="l-flex--col center">
-            <div class="has-padding">未绑定发送控制设备,请联系管理员</div>
-            <button
-              v-if="isSuperAdmin"
-              class="o-button"
-              @click="onBind"
-            >
-              绑定设备
-            </button>
-          </div>
-        </div>
+        </template>
       </template>
     </template>
     <table-dialog
@@ -127,14 +129,17 @@ export default {
   },
   computed: {
     ...mapGetters(['isSuperAdmin']),
+    transmitter () {
+      return this.info?.thirdPartyDevice
+    },
     type () {
-      return this.info && this.info.flag & Transmitter.IS_ASYNC ? '异步盒' : '非异步盒'
+      return this.transmitter && this.transmitter.flag & Transmitter.IS_ASYNC ? '异步盒' : '非异步盒'
     },
     supportDetection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_DETECTION ? '是' : '否'
+      return this.transmitter && this.transmitter.flag & Transmitter.SUPPORT_DETECTION ? '是' : '否'
     },
     supportContentProtection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? '是' : '否'
+      return this.transmitter && this.transmitter.flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? '是' : '否'
     }
   },
   activated () {
@@ -169,7 +174,12 @@ export default {
       })
     },
     onUnbind () {
-      unbind(this.info.id).then(this.getDeviceSendingCard)
+      this.$confirm(
+        '解绑发送控制设备?',
+        { type: 'warning' }
+      ).then(() => {
+        unbind(this.info.id).then(this.getDeviceSendingCard)
+      })
     }
   }
 }