Pārlūkot izejas kodu

feat(external): receiving card

Casper Dai 2 gadi atpakaļ
vecāks
revīzija
bdceaa36b4

+ 59 - 44
src/api/external.js

@@ -39,50 +39,6 @@ export function getThirdPartyDevices (query) {
   })
 }
 
-// 接收卡
-export function getReceivingCardManufacturers () {
-  return request({
-    url: '/device/manufacturer/list',
-    method: 'GET'
-  })
-}
-
-export function addReceivingCard (fromData, onUploadProgress) {
-  return request({
-    url: '/device/information',
-    method: 'POST',
-    timeout: 0,
-    data: fromData,
-    onUploadProgress
-  })
-}
-
-export function updateReceivingCard (fromData, onUploadProgress) {
-  return update({
-    url: '/device/information',
-    method: 'PUT',
-    timeout: 0,
-    data: fromData,
-    onUploadProgress
-  })
-}
-
-export function getReceivingCard (id, options) {
-  return request({
-    url: `/device/information/${id}`,
-    method: 'GET',
-    ...options
-  })
-}
-
-export function getReceivingCardTopology (id, options) {
-  return request({
-    url: `/device/topology/${id}`,
-    method: 'GET',
-    ...options
-  })
-}
-
 // 厂商
 export function getManufacturers (query) {
   const { pageNum: pageIndex, pageSize, ...params } = query
@@ -509,3 +465,62 @@ export function deleteRecord (id) {
     method: 'DELETE'
   })
 }
+
+// 接收卡
+export function getReceivingCardManufacturers () {
+  return request({
+    url: '/device/manufacturer/list',
+    method: 'GET'
+  })
+}
+
+export function getReceivingCard (id, options) {
+  return request({
+    url: `/device/information/${id}`,
+    method: 'GET',
+    ...options
+  })
+}
+
+export function getReceivingCardTopology (id, options) {
+  return request({
+    url: `/device/topology/${id}`,
+    method: 'GET',
+    ...options
+  })
+}
+
+export function getReceivingCards (query) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
+  return request({
+    url: '/device/thirdPartyReceiverCard/pageQuery',
+    method: 'GET',
+    params: addTenant({
+      pageIndex, pageSize,
+      ...params
+    })
+  })
+}
+
+export function addReceivingCard (data) {
+  return add({
+    url: '/device/thirdPartyReceiverCard',
+    method: 'POST',
+    data: addTenantAndOrg(data)
+  })
+}
+
+export function updateReceivingCard (data) {
+  return update({
+    url: '/device/thirdPartyReceiverCard',
+    method: 'PUT',
+    data
+  })
+}
+
+export function deleteReceivingCard ({ id }) {
+  return del({
+    url: `/device/thirdPartyReceiverCard/${id}`,
+    method: 'DELETE'
+  }, '该网关')
+}

+ 20 - 1
src/constant.js

@@ -191,13 +191,32 @@ export const CameraInfo = {
   [Camera.TRAFFIC]: ThirdPartyDeviceInfo[CameraToThirdPartyMap[Camera.TRAFFIC]]
 }
 
-export const Transmitter = {
+export const SendingCard = {
   IS_ASYNC: 1,
   SUPPORT_DETECTION: 1 << 1,
   SUPPORT_CONTENT_PROTECTION: 1 << 2,
   RECOVERY_CARD: 1 << 3
 }
 
+export const SendingCardFeatures = [
+  { key: 'IS_ASYNC', label: '异步盒' },
+  { key: 'SUPPORT_DETECTION', label: '设备监测' },
+  { key: 'SUPPORT_CONTENT_PROTECTION', label: '内容保护' },
+  { key: 'RECOVERY_CARD', label: '回采卡' }
+]
+
+export const ReceivingCard = {
+  TEMPERATURE: 1,
+  VOLTAGE: 1 << 1,
+  MONITOR: 1 << 2
+}
+
+export const ReceivingCardFeatures = [
+  { key: 'TEMPERATURE', label: '温度检测' },
+  { key: 'VOLTAGE', label: '电压检测' },
+  { key: 'MONITOR', label: '支持检测卡' }
+]
+
 export const Sensor = {
   SMOKE: 0,
   TEMPERATURE: 1,

+ 5 - 0
src/router/index.js

@@ -525,6 +525,11 @@ export const asyncRoutes = [
         component: () => import('@/views/external/sending-card/index'),
         meta: { title: '发送控制设备' }
       },
+      {
+        path: 'receiving-card',
+        component: () => import('@/views/external/receiving-card/index'),
+        meta: { title: '接收卡' }
+      },
       ...Object.keys(Camera).map(key => {
         return {
           path: `camera/${Camera[key]}`,

+ 14 - 35
src/views/device/detail/components/DeviceExternal/components/SendingCard.vue

@@ -27,32 +27,13 @@
           <div class="l-flex__none c-info__title">特性</div>
           <div class="l-flex__fill l-flex--row">
             <el-tag
+              v-for="(tag, index) in tags"
+              :key="index"
               class="c-sibling-item o-tag"
               size="medium"
-              :type="type"
+              :type="tag.type"
             >
-              异步盒
-            </el-tag>
-            <el-tag
-              class="c-sibling-item o-tag"
-              size="medium"
-              :type="supportDetection"
-            >
-              设备监测
-            </el-tag>
-            <el-tag
-              class="c-sibling-item o-tag"
-              size="medium"
-              :type="supportContentProtection"
-            >
-              内容保护
-            </el-tag>
-            <el-tag
-              class="c-sibling-item o-tag"
-              size="medium"
-              :type="recoveryCard"
-            >
-              回采卡
+              {{ tag.label }}
             </el-tag>
           </div>
         </div>
@@ -64,7 +45,8 @@
 <script>
 import {
   ThirdPartyDevice,
-  Transmitter
+  SendingCard,
+  SendingCardFeatures
 } from '@/constant'
 import { getThirdPartyDevicesByThirdPartyDevice } from '@/api/mesh'
 
@@ -84,17 +66,14 @@ export default {
     }
   },
   computed: {
-    type () {
-      return this.info && this.info.flag & Transmitter.IS_ASYNC ? 'success' : 'danger'
-    },
-    supportDetection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_DETECTION ? 'success' : 'danger'
-    },
-    supportContentProtection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? 'success' : 'danger'
-    },
-    recoveryCard () {
-      return this.info && this.info.flag & Transmitter.RECOVERY_CARD ? 'success' : 'danger'
+    tags () {
+      if (this.info) {
+        const flag = this.info.flag
+        return SendingCardFeatures.map(({ key, label }) => {
+          return { type: flag & SendingCard[key] ? 'success' : 'danger', label }
+        })
+      }
+      return []
     }
   },
   created () {

+ 45 - 0
src/views/external/box/settings/components/ReceivingCard/api.js

@@ -0,0 +1,45 @@
+import request from '@/utils/request'
+import { update } from '@/api/base'
+
+export function getReceivingCardManufacturers () {
+  return request({
+    url: '/device/manufacturer/list',
+    method: 'GET'
+  })
+}
+
+export function addReceivingCard (fromData, onUploadProgress) {
+  return request({
+    url: '/device/information',
+    method: 'POST',
+    timeout: 0,
+    data: fromData,
+    onUploadProgress
+  })
+}
+
+export function updateReceivingCard (fromData, onUploadProgress) {
+  return update({
+    url: '/device/information',
+    method: 'PUT',
+    timeout: 0,
+    data: fromData,
+    onUploadProgress
+  })
+}
+
+export function getReceivingCard (id, options) {
+  return request({
+    url: `/device/information/${id}`,
+    method: 'GET',
+    ...options
+  })
+}
+
+export function getReceivingCardTopology (id, options) {
+  return request({
+    url: `/device/topology/${id}`,
+    method: 'GET',
+    ...options
+  })
+}

+ 0 - 0
src/views/device/detail/components/DeviceExternal/components/ReceivingCard/ReceivingCardInfo.vue → src/views/external/box/settings/components/ReceivingCard/detail/ReceivingCardInfo.vue


+ 1 - 1
src/views/device/detail/components/DeviceExternal/components/ReceivingCard/ReceivingCardTopology.vue → src/views/external/box/settings/components/ReceivingCard/detail/ReceivingCardTopology.vue

@@ -26,7 +26,7 @@
 </template>
 
 <script>
-import { getReceivingCardTopology } from '@/api/external'
+import { getReceivingCardTopology } from './api'
 // import {
 //   addListener,
 //   removeListener

+ 1 - 1
src/views/device/detail/components/DeviceExternal/components/ReceivingCard/bak.vue → src/views/external/box/settings/components/ReceivingCard/detail/index.vue

@@ -26,7 +26,7 @@
 </template>
 
 <script>
-import { getReceivingCard } from '@/api/external'
+import { getReceivingCard } from './api'
 import ReceivingCardTopology from './ReceivingCardTopology'
 import ReceivingCardInfo from './ReceivingCardInfo'
 

+ 2 - 2
src/views/external/box/settings/components/ReceivingCard/index.vue

@@ -215,13 +215,13 @@
 </template>
 
 <script>
+import { validIPv4 } from '@/utils/validate'
 import {
   getReceivingCardManufacturers,
   getReceivingCard,
   addReceivingCard,
   updateReceivingCard
-} from '@/api/external'
-import { validIPv4 } from '@/utils/validate'
+} from './api'
 import ReceivingCardTopology from './ReceivingCardTopology'
 
 export default {

+ 88 - 0
src/views/external/box/settings/components/external/ReceivingCard.vue

@@ -0,0 +1,88 @@
+<template>
+  <div
+    v-if="item"
+    class="c-info"
+  >
+    <div class="c-sibling-item--v u-bold">接收卡</div>
+    <div class="c-sibling-item--v">
+      <template v-if="info">
+        <div class="l-flex--row c-info__block">
+          <div class="l-flex--row l-flex__fill c-sibling-item">
+            <div class="l-flex__none c-info__title">厂商</div>
+            <div class="l-flex__fill c-info__value">{{ info.manufacturerName }}</div>
+          </div>
+          <div class="l-flex--row l-flex__fill c-sibling-item">
+            <div class="l-flex__none c-info__title">型号</div>
+            <div class="l-flex__fill c-info__value">{{ info.model }}</div>
+          </div>
+          <div class="l-flex--row l-flex__fill c-sibling-item">
+            <div class="l-flex__none c-info__title">唯一标识</div>
+            <div class="l-flex__fill c-info__value">{{ info.identifier }}</div>
+          </div>
+        </div>
+        <div class="l-flex--row c-info__block">
+          <div class="l-flex--row l-flex__fill c-sibling-item">
+            <div class="l-flex__none c-info__title">规格</div>
+            <div class="l-flex__fill c-info__value u-color--blue">{{ info.rowCount }} x {{ info.colCount }}</div>
+          </div>
+          <div class="l-flex--row l-flex__fill c-sibling-item">
+            <div class="l-flex__none c-info__title">特性</div>
+            <div class="l-flex__fill l-flex--row">
+              <el-tag
+                v-for="(tag, index) in tags"
+                :key="index"
+                class="c-sibling-item o-tag"
+                size="medium"
+                :type="tag.type"
+              >
+                {{ tag.label }}
+              </el-tag>
+            </div>
+          </div>
+          <div class="l-flex__fill c-sibling-item" />
+        </div>
+      </template>
+      <div
+        v-else
+        class="u-color--info u-font-size--sm"
+      >
+        暂未绑定
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  ThirdPartyDevice,
+  ReceivingCard,
+  ReceivingCardFeatures
+} from '@/constant'
+
+export default {
+  name: 'ReceivingCard',
+  props: {
+    devices: {
+      type: Array,
+      required: true
+    }
+  },
+  computed: {
+    item () {
+      return this.devices.find(({ nodeType }) => nodeType === ThirdPartyDevice.RECEIVING_CARD)
+    },
+    info () {
+      return this.item?.instance
+    },
+    tags () {
+      if (this.info) {
+        const flag = this.info.flag
+        return ReceivingCardFeatures.map(({ key, label }) => {
+          return { type: flag & ReceivingCard[key] ? 'success' : 'danger', label }
+        })
+      }
+      return []
+    }
+  }
+}
+</script>

+ 14 - 35
src/views/external/box/settings/components/external/SendingCard.vue

@@ -25,32 +25,13 @@
             <div class="l-flex__none c-info__title">特性</div>
             <div class="l-flex__fill l-flex--row">
               <el-tag
+                v-for="(tag, index) in tags"
+                :key="index"
                 class="c-sibling-item o-tag"
                 size="medium"
-                :type="type"
+                :type="tag.type"
               >
-                异步盒
-              </el-tag>
-              <el-tag
-                class="c-sibling-item o-tag"
-                size="medium"
-                :type="supportDetection"
-              >
-                设备监测
-              </el-tag>
-              <el-tag
-                class="c-sibling-item o-tag"
-                size="medium"
-                :type="supportContentProtection"
-              >
-                内容保护
-              </el-tag>
-              <el-tag
-                class="c-sibling-item o-tag"
-                size="medium"
-                :type="recoveryCard"
-              >
-                回采卡
+                {{ tag.label }}
               </el-tag>
             </div>
           </div>
@@ -69,7 +50,8 @@
 <script>
 import {
   ThirdPartyDevice,
-  Transmitter
+  SendingCard,
+  SendingCardFeatures
 } from '@/constant'
 
 export default {
@@ -87,17 +69,14 @@ export default {
     info () {
       return this.item?.instance
     },
-    type () {
-      return this.info && this.info.flag & Transmitter.IS_ASYNC ? 'success' : 'danger'
-    },
-    supportDetection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_DETECTION ? 'success' : 'danger'
-    },
-    supportContentProtection () {
-      return this.info && this.info.flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? 'success' : 'danger'
-    },
-    recoveryCard () {
-      return this.info && this.info.flag & Transmitter.RECOVERY_CARD ? 'success' : 'danger'
+    tags () {
+      if (this.info) {
+        const flag = this.info.flag
+        return SendingCardFeatures.map(({ key, label }) => {
+          return { type: flag & SendingCard[key] ? 'success' : 'danger', label }
+        })
+      }
+      return []
     }
   }
 }

+ 6 - 0
src/views/external/box/settings/components/external/index.vue

@@ -45,6 +45,10 @@
             class="c-sibling-item--v far"
             :devices="thirdPartyDevices"
           />
+          <receiving-card
+            class="c-sibling-item--v far"
+            :devices="thirdPartyDevices"
+          />
           <multifunction-card
             class="c-sibling-item--v far"
             :devices="thirdPartyDevices"
@@ -79,6 +83,7 @@
 import { getMeshByBox } from '@/api/mesh'
 import Screen from './Screen.vue'
 import SendingCard from './SendingCard.vue'
+import ReceivingCard from './ReceivingCard.vue'
 import MultifunctionCard from './MultifunctionCard.vue'
 import Sensor from './Sensor.vue'
 import PLC from './PLC.vue'
@@ -90,6 +95,7 @@ export default {
   components: {
     Screen,
     SendingCard,
+    ReceivingCard,
     MultifunctionCard,
     Sensor,
     Gateway,

+ 3 - 3
src/views/external/box/settings/index.vue

@@ -53,7 +53,7 @@ import { mapGetters } from 'vuex'
 import { getDevice } from '@/api/device'
 import DeviceNormalConfig from './components/DeviceNormalConfig'
 import DeviceThirdParty from './components/external'
-import ReceivingCard from './components/ReceivingCard'
+// import ReceivingCard from './components/ReceivingCard'
 import DeviceCamera from './components/Camera.vue'
 import DeviceShadow from './components/DeviceShadow'
 
@@ -62,7 +62,7 @@ export default {
   components: {
     DeviceNormalConfig,
     DeviceThirdParty,
-    ReceivingCard,
+    // ReceivingCard,
     DeviceCamera,
     DeviceShadow
   },
@@ -85,7 +85,7 @@ export default {
       return [
         { key: 'DeviceNormalConfig', label: '基础配置' },
         { key: 'DeviceThirdParty', label: '第三方设备' },
-        this.isSuperAdmin && { key: 'ReceivingCard', label: '接收卡' },
+        // this.isSuperAdmin && { key: 'ReceivingCard', label: '接收卡' },
         { key: 'DeviceCamera', label: '摄像头' },
         this.isSuperAdmin && { key: 'DeviceShadow', label: '影子配置' }
       ].filter(Boolean)

+ 165 - 0
src/views/external/components/ReceivingCardConfigDialog.vue

@@ -0,0 +1,165 @@
+<template>
+  <confirm-dialog
+    ref="dialog"
+    title="新增接收卡"
+    @confirm="onConfirm"
+  >
+    <div class="c-grid-form u-align-self--center">
+      <span class="c-grid-form__label u-required">厂商</span>
+      <schema-select
+        ref="manufacturer"
+        v-model="item.manufacturerKey"
+        class="u-width"
+        placeholder="请选择厂商"
+        :schema="manufacturerSelectSchema"
+      />
+      <span class="c-grid-form__label u-required">型号</span>
+      <el-input
+        v-model.trim="item.model"
+        placeholder="最多50个字符"
+        maxlength="50"
+        clearable
+      />
+      <span class="c-grid-form__label">特性</span>
+      <el-checkbox-group
+        v-model="features"
+        class="l-flex--row c-grid-form__option"
+      >
+        <el-checkbox
+          v-for="feature in featureOptions"
+          :key="feature.key"
+          :label="feature.key"
+        >
+          {{ feature.label }}
+        </el-checkbox>
+      </el-checkbox-group>
+      <span class="c-grid-form__label u-required">唯一标识</span>
+      <el-input
+        v-model.trim="item.identifier"
+        placeholder="最多50个字符"
+        maxlength="50"
+        clearable
+      />
+      <span class="c-grid-form__label">行数</span>
+      <div class="l-flex--row c-grid-form__option">
+        <el-input-number
+          v-model="item.rowCount"
+          class="l-flex__auto c-sibling-item"
+          controls-position="right"
+          :min="1"
+          :max="999"
+          step-strictly
+        />
+        <span class="l-flex__none c-sibling-item far">列数</span>
+        <el-input-number
+          v-model="item.colCount"
+          class="l-flex__auto c-sibling-item"
+          controls-position="right"
+          :min="1"
+          :max="999"
+          step-strictly
+        />
+      </div>
+      <span class="c-grid-form__label">ip</span>
+      <el-input
+        v-model.trim="item.ip"
+        class="u-width--sm"
+        placeholder="192.168.0.1"
+        maxlength="15"
+        clearable
+      />
+    </div>
+  </confirm-dialog>
+</template>
+
+<script>
+import {
+  ThirdPartyDevice,
+  ReceivingCard,
+  ReceivingCardFeatures
+} from '@/constant'
+import { validIPv4 } from '@/utils/validate'
+import {
+  getManufacturersByType,
+  addReceivingCard
+} from '@/api/external'
+
+export default {
+  name: 'ReceivingCardConfigDialog',
+  data () {
+    return {
+      manufacturerSelectSchema: {
+        remote: this.getManufacturersByType,
+        value: 'manufacturerKey',
+        label: 'manufacturerName'
+      },
+      item: {},
+      features: [],
+      featureOptions: ReceivingCardFeatures.map(feature => {
+        return { ...feature }
+      })
+    }
+  },
+  methods: {
+    show () {
+      this.item = {
+        identifier: '',
+        manufacturerKey: '',
+        model: '',
+        ip: '',
+        rowCount: 1,
+        colCount: 1
+      }
+      this.features = []
+      this.$refs.dialog.show()
+    },
+    getManufacturersByType () {
+      return getManufacturersByType(ThirdPartyDevice.RECEIVING_CARD)
+    },
+    onConfirm (done) {
+      if (!this.item.manufacturerKey) {
+        this.$message({
+          type: 'warning',
+          message: '请选择厂商'
+        })
+        return
+      }
+      if (!this.item.model) {
+        this.$message({
+          type: 'warning',
+          message: '请填写型号'
+        })
+        return
+      }
+      if (!this.item.identifier) {
+        this.$message({
+          type: 'warning',
+          message: '请填写唯一标识'
+        })
+        return
+      }
+      if (this.item.ip && !validIPv4(this.item.ip)) {
+        this.$message({
+          type: 'warning',
+          message: 'IP格式错误'
+        })
+        return
+      }
+      const key = this.item.manufacturerKey
+      const flag = this.features.reduce((val, key) => val | ReceivingCard[key], 0)
+      addReceivingCard({
+        flag,
+        manufacturerName: this.$refs.manufacturer.getOptions().find(({ value }) => value === key).label,
+        ...this.item
+      }).then(() => {
+        done()
+        this.$emit('confirm', {
+          flag,
+          ...this.item
+        })
+      })
+    }
+  }
+}
+</script>
+

+ 20 - 28
src/views/external/components/SendingCardConfigDialog.vue

@@ -21,12 +21,18 @@
         clearable
       />
       <span class="c-grid-form__label">特性</span>
-      <div class="l-flex--row c-grid-form__option">
-        <el-checkbox v-model="flag.async">异步盒</el-checkbox>
-        <el-checkbox v-model="flag.detection">设备监测</el-checkbox>
-        <el-checkbox v-model="flag.contentProtection">内容保护</el-checkbox>
-        <el-checkbox v-model="flag.recoveryCard">回采卡</el-checkbox>
-      </div>
+      <el-checkbox-group
+        v-model="features"
+        class="l-flex--row c-grid-form__option"
+      >
+        <el-checkbox
+          v-for="feature in featureOptions"
+          :key="feature.key"
+          :label="feature.key"
+        >
+          {{ feature.label }}
+        </el-checkbox>
+      </el-checkbox-group>
       <span class="c-grid-form__label u-required">唯一标识</span>
       <el-input
         v-model.trim="item.identifier"
@@ -41,7 +47,8 @@
 <script>
 import {
   ThirdPartyDevice,
-  Transmitter
+  SendingCard,
+  SendingCardFeatures
 } from '@/constant'
 import {
   getManufacturersByType,
@@ -58,7 +65,10 @@ export default {
         label: 'manufacturerName'
       },
       item: {},
-      flag: {}
+      features: [],
+      featureOptions: SendingCardFeatures.map(feature => {
+        return { ...feature }
+      })
     }
   },
   methods: {
@@ -68,12 +78,7 @@ export default {
         manufacturerKey: '',
         model: ''
       }
-      this.flag = {
-        async: false,
-        detection: false,
-        contentProtection: false,
-        recoveryCard: false
-      }
+      this.features = []
       this.$refs.dialog.show()
     },
     getManufacturersByType () {
@@ -101,21 +106,8 @@ export default {
         })
         return
       }
-      const { async: isAsync, detection, contentProtection, recoveryCard } = this.flag
-      let flag = 0
-      if (isAsync) {
-        flag |= Transmitter.IS_ASYNC
-      }
-      if (detection) {
-        flag |= Transmitter.SUPPORT_DETECTION
-      }
-      if (contentProtection) {
-        flag |= Transmitter.SUPPORT_CONTENT_PROTECTION
-      }
-      if (recoveryCard) {
-        flag |= Transmitter.RECOVERY_CARD
-      }
       const key = this.item.manufacturerKey
+      const flag = this.features.reduce((val, key) => val | SendingCard[key], 0)
       addSendingCard({
         flag,
         manufacturerName: this.$refs.manufacturer.getOptions().find(({ value }) => value === key).label,

+ 35 - 9
src/views/external/mesh/index.vue

@@ -209,7 +209,10 @@
 import {
   ThirdPartyDevice,
   ThirdPartyDeviceInfo,
-  Transmitter,
+  SendingCard,
+  SendingCardFeatures,
+  ReceivingCard,
+  ReceivingCardFeatures,
   ThirdPartyToSensorMap,
   SensorToThirdPartyMap,
   ThirdPartyToCameraMap
@@ -232,6 +235,7 @@ import {
   getGateways,
   getScreens,
   getSendingCards,
+  getReceivingCards,
   getMultifunctionCards,
   getSensors,
   getPLCs,
@@ -242,6 +246,7 @@ import * as echarts from 'echarts'
 import GatewayConfigDialog from '../components/GatewayConfigDialog.vue'
 import ScreenConfigDialog from '../components/ScreenConfigDialog.vue'
 import SendingCardConfigDialog from '../components/SendingCardConfigDialog.vue'
+import ReceivingCardConfigDialog from '../components/ReceivingCardConfigDialog.vue'
 import PlcConfigDialog from '../components/PlcConfigDialog.vue'
 import MultifunctionCardConfigDialog from '../components/MultifunctionCardConfigDialog.vue'
 import SensorConfigDialog from '../components/SensorConfigDialog.vue'
@@ -346,6 +351,7 @@ export default {
     GatewayConfigDialog,
     ScreenConfigDialog,
     SendingCardConfigDialog,
+    ReceivingCardConfigDialog,
     PlcConfigDialog,
     MultifunctionCardConfigDialog,
     SensorConfigDialog,
@@ -445,6 +451,8 @@ export default {
           return 'ScreenConfigDialog'
         case ThirdPartyDevice.SENDING_CARD:
           return 'SendingCardConfigDialog'
+        case ThirdPartyDevice.RECEIVING_CARD:
+          return 'ReceivingCardConfigDialog'
         case ThirdPartyDevice.PLC:
           return 'PlcConfigDialog'
         case ThirdPartyDevice.MULTI_FUNCTION_CARD:
@@ -517,14 +525,29 @@ export default {
               { prop: 'manufacturerName', label: '厂商' },
               { prop: 'model', label: '型号' },
               { prop: 'identifier', label: '唯一标识' },
-              { label: '特性', type: 'tag', render ({ flag }) {
-                return [
-                  { type: flag & Transmitter.IS_ASYNC ? 'success' : 'danger', label: '异步盒' },
-                  { type: flag & Transmitter.SUPPORT_DETECTION ? 'success' : 'danger', label: '设备监测' },
-                  { type: flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? 'success' : 'danger', label: '内容保护' },
-                  { type: flag & Transmitter.RECOVERY_CARD ? 'success' : 'danger', label: '回采卡' }
-                ]
-              }, width: 364 }
+              { label: '特性', type: 'tag', render: ({ flag }) => SendingCardFeatures.map(({ key, label }) => {
+                return { type: flag & SendingCard[key] ? 'success' : 'danger', label }
+              }), width: 364 }
+            ]
+          }
+        case ThirdPartyDevice.RECEIVING_CARD:
+          return {
+            list: getReceivingCards,
+            condition: { boundFlag: 0 },
+            buttons: [
+              { type: 'add', on: this.onAddThirdParty }
+            ],
+            filters: [
+              { key: 'manufacturerKey', type: 'select', placeholder: '厂商', remote: this.getManufacturersByType, value: 'manufacturerKey', label: 'manufacturerName' },
+              { key: 'identifier', type: 'search', placeholder: '唯一标识' }
+            ],
+            cols: [
+              { prop: 'manufacturerName', label: '厂商' },
+              { prop: 'model', label: '型号' },
+              { prop: 'identifier', label: '唯一标识' },
+              { label: '特性', type: 'tag', render: ({ flag }) => ReceivingCardFeatures.map(({ key, label }) => {
+                return { type: flag & ReceivingCard[key] ? 'success' : 'danger', label }
+              }), width: 364 }
             ]
           }
         case ThirdPartyDevice.PLC:
@@ -815,6 +838,9 @@ export default {
           case ThirdPartyDevice.TRANSLOCATION_SENSOR:
             tooltip += `<br/>唯一标识:${instance.identifier}<br/>厂商:${instance.manufacturerName}<br/>型号:${instance.model}`
             break
+          case ThirdPartyDevice.RECEIVING_CARD:
+            tooltip += `<br/>唯一标识:${instance.identifier}<br/>厂商:${instance.manufacturerName}<br/>型号:${instance.model}<br/>规格:${instance.rowCount} x ${instance.colCount}`
+            break
           case ThirdPartyDevice.GATEWAY:
             tooltip += `<br/>唯一标识:${instance.identifier}<br/>厂商:${instance.manufacturerName}<br/>型号:${instance.model}<br/>服务器:${instance.ip}`
             break

+ 98 - 0
src/views/external/receiving-card/index.vue

@@ -0,0 +1,98 @@
+<template>
+  <wrapper
+    fill
+    margin
+    padding
+    background
+  >
+    <schema-table
+      ref="table"
+      :schema="schema"
+    />
+    <mesh-dialog ref="meshDialog" />
+    <receiving-card-config-dialog
+      ref="receivingCardConfigDialog"
+      @confirm="onConfirm"
+    />
+  </wrapper>
+</template>
+
+<script>
+import {
+  ThirdPartyDevice,
+  ReceivingCard,
+  ReceivingCardFeatures
+} from '@/constant'
+import {
+  getManufacturersByType,
+  getReceivingCards,
+  deleteReceivingCard
+} from '@/api/external'
+import MeshDialog from '../components/MeshDialog.vue'
+import ReceivingCardConfigDialog from '../components/ReceivingCardConfigDialog.vue'
+
+export default {
+  name: 'ReceivingCardList',
+  components: {
+    MeshDialog,
+    ReceivingCardConfigDialog
+  },
+  data () {
+    return {
+      schema: {
+        list: getReceivingCards,
+        buttons: [
+          { type: 'add', on: this.onAdd }
+        ],
+        filters: [
+          { key: 'manufacturerKey', type: 'select', placeholder: '厂商', remote: this.getManufacturersByType, value: 'manufacturerKey', label: 'manufacturerName' },
+          { key: 'boundFlag', type: 'select', placeholder: '使用情况', options: [
+            { value: 1, label: '已使用' },
+            { value: 0, label: '未使用' }
+          ] },
+          { key: 'identifier', type: 'search', placeholder: '唯一标识' }
+        ],
+        cols: [
+          { prop: 'manufacturerName', label: '厂商' },
+          { prop: 'model', label: '型号' },
+          { prop: 'identifier', label: '唯一标识' },
+          { label: '规格', render: ({ rowCount, colCount }) => `${rowCount} x ${colCount}`, width: 100 },
+          { label: '特性', type: 'tag', render: ({ flag }) => ReceivingCardFeatures.map(({ key, label }) => {
+            return { type: flag & ReceivingCard[key] ? 'success' : 'danger', label }
+          }), width: 280 },
+          { label: '使用情况', type: 'tag', render: ({ bound }) => bound
+            ? { type: 'success', label: '已使用' }
+            : { type: 'primary', label: '未使用' } },
+          { type: 'invoke', render: [
+            { label: '所属网点', allow: ({ bound }) => bound, on: this.onViewMesh },
+            { label: '删除', allow: ({ bound }) => !bound, on: this.onDel }
+          ] }
+        ]
+      }
+    }
+  },
+  methods: {
+    getManufacturersByType () {
+      return getManufacturersByType(ThirdPartyDevice.ReceivingingCard)
+    },
+    onAdd () {
+      this.$refs.receivingCardConfigDialog.show()
+    },
+    onConfirm ({ manufacturerKey, identifier }) {
+      this.$refs.table.resetCondition({
+        boundFlag: 0,
+        manufacturerKey,
+        identifier
+      })
+    },
+    onDel (item) {
+      deleteReceivingCard(item).then(() => {
+        this.$refs.table.decrease(1)
+      })
+    },
+    onViewMesh ({ id }) {
+      this.$refs.meshDialog.show(id)
+    }
+  }
+}
+</script>

+ 5 - 9
src/views/external/sending-card/index.vue

@@ -20,7 +20,8 @@
 <script>
 import {
   ThirdPartyDevice,
-  Transmitter
+  SendingCard,
+  SendingCardFeatures
 } from '@/constant'
 import {
   getManufacturersByType,
@@ -55,14 +56,9 @@ export default {
           { prop: 'manufacturerName', label: '厂商' },
           { prop: 'model', label: '型号' },
           { prop: 'identifier', label: '唯一标识' },
-          { label: '特性', type: 'tag', render ({ flag }) {
-            return [
-              { type: flag & Transmitter.IS_ASYNC ? 'success' : 'danger', label: '异步盒' },
-              { type: flag & Transmitter.SUPPORT_DETECTION ? 'success' : 'danger', label: '设备监测' },
-              { type: flag & Transmitter.SUPPORT_CONTENT_PROTECTION ? 'success' : 'danger', label: '内容保护' },
-              { type: flag & Transmitter.RECOVERY_CARD ? 'success' : 'danger', label: '回采卡' }
-            ]
-          }, width: 364 },
+          { label: '特性', type: 'tag', render: ({ flag }) => SendingCardFeatures.map(({ key, label }) => {
+            return { type: flag & SendingCard[key] ? 'success' : 'danger', label }
+          }), width: 364 },
           { label: '使用情况', type: 'tag', render: ({ bound }) => bound
             ? { type: 'success', label: '已使用' }
             : { type: 'primary', label: '未使用' } },