Browse Source

refactor: adjust some styles

Casper Dai 3 years ago
parent
commit
a76c36b1c8
49 changed files with 477 additions and 788 deletions
  1. 31 6
      src/components/dialog/CDialog/index.vue
  2. 7 11
      src/components/dialog/CameraDialog/index.vue
  3. 12 5
      src/components/dialog/ConfirmDialog/index.vue
  4. 0 75
      src/components/dialog/GridTableDialog/index.vue
  5. 36 34
      src/components/dialog/MaterialDialog/index.vue
  6. 14 13
      src/components/dialog/PreviewDialog/index.vue
  7. 1 1
      src/components/dialog/RadioTableDialog/index.vue
  8. 1 1
      src/components/dialog/SelectionTableDialog/index.vue
  9. 2 23
      src/components/dialog/TableDialog/index.vue
  10. 0 74
      src/components/table/CTable/index.vue
  11. 3 3
      src/components/table/Table/Column.vue
  12. 1 1
      src/components/table/mixins/table.js
  13. 2 2
      src/components/tree/DeviceGroupTree/index.vue
  14. 4 4
      src/components/tree/DeviceTree/index.vue
  15. 3 3
      src/components/tree/DeviceTreeSingle/index.vue
  16. 47 52
      src/layout/components/Navbar/UploadDashboard/index.vue
  17. 2 11
      src/mixins/dialog.js
  18. 6 56
      src/scss/bem/_component.scss
  19. 0 15
      src/scss/bem/_object.scss
  20. 8 0
      src/scss/bem/_utility.scss
  21. 1 2
      src/views/ad/review-asset/index.vue
  22. 1 2
      src/views/device/detail/components/DeviceAlarm.vue
  23. 6 3
      src/views/device/detail/components/DeviceExternal/external/Camera/led.vue
  24. 6 3
      src/views/device/detail/components/DeviceExternal/external/Camera/traffic.vue
  25. 2 2
      src/views/device/detail/components/DeviceExternal/external/ReceivingCard/ReceivingCardTopology.vue
  26. 14 15
      src/views/device/detail/components/DeviceExternal/index.vue
  27. 0 73
      src/views/device/detail/components/DeviceInvoke/DeviceSwitch.vue
  28. 24 25
      src/views/device/detail/components/DeviceInvoke/MultifunctionCardPowerSwitch.vue
  29. 7 15
      src/views/device/detail/components/DeviceInvoke/PLCSwitch.vue
  30. 16 19
      src/views/device/detail/components/DeviceInvoke/ScreenLight.vue
  31. 19 22
      src/views/device/detail/components/DeviceInvoke/ScreenSwitch.vue
  32. 16 19
      src/views/device/detail/components/DeviceInvoke/ScreenVolume.vue
  33. 1 1
      src/views/device/detail/components/DeviceInvoke/index.vue
  34. 1 1
      src/views/device/detail/components/DeviceInvoke/mixins/simple-task.js
  35. 1 1
      src/views/device/detail/components/DeviceInvoke/mixins/switch-task.js
  36. 0 4
      src/views/device/detail/components/DeviceInvoke/mixins/task.js
  37. 5 7
      src/views/device/detail/components/DeviceRuntime/Download.vue
  38. 7 8
      src/views/external/gateway/index.vue
  39. 5 7
      src/views/platform/debug/index.vue
  40. 31 30
      src/views/platform/tenant/device/settings/components/DatasetConfigDialog.vue
  41. 6 3
      src/views/platform/tenant/device/settings/components/external/Camera/index.vue
  42. 2 2
      src/views/platform/tenant/device/settings/components/external/ReceivingCard/ReceivingCardTopology.vue
  43. 26 28
      src/views/platform/tenant/device/settings/components/external/ReceivingCard/index.vue
  44. 2 3
      src/views/platform/upgrade/index.vue
  45. 2 2
      src/views/realm/assign/Device.vue
  46. 5 6
      src/views/realm/logger/index.vue
  47. 15 16
      src/views/realm/user/Account.vue
  48. 74 77
      src/views/screen/material/program/ast/Designer.vue
  49. 2 2
      src/views/screen/material/program/ast/Viewer.vue

+ 31 - 6
src/components/dialog/CDialog/index.vue

@@ -2,15 +2,22 @@
   <el-dialog
     :visible.sync="dialogVisible"
     :custom-class="className"
+    :close-on-click-modal="false"
     v-bind="$attrs"
-    v-on="$listeners"
+    v-on="dialogListeners"
     @open="onOpen"
     @closed="onClosed"
   >
-    <slot
-      v-if="contentRender"
-      :visible="contentRender"
-    />
+    <slot v-if="contentRender" />
+    <template
+      v-if="hasFooter"
+      #footer
+    >
+      <slot
+        name="footer"
+        :hide="hide"
+      />
+    </template>
   </el-dialog>
 </template>
 
@@ -19,6 +26,24 @@ import dialogMixin from '@/mixins/dialog'
 
 export default {
   name: 'CDialog',
-  mixins: [dialogMixin]
+  mixins: [dialogMixin],
+  props: {
+    size: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    className () {
+      return `c-dialog ${this.size}`
+    },
+    dialogListeners () {
+      const { open, closed, ...listeners } = this.$listeners
+      return listeners
+    },
+    hasFooter () {
+      return !!this.$scopedSlots.footer
+    }
+  }
 }
 </script>

+ 7 - 11
src/components/dialog/CameraDialog/index.vue

@@ -3,22 +3,18 @@
     :visible.sync="dialogVisible"
     custom-class="c-dialog--full"
     :close-on-click-modal="false"
-    :close-on-press-escape="false"
     fullscreen
     append-to-body
-    v-bind="$attrs"
-    v-on="$listeners"
     @open="onOpen"
     @closed="onClosed"
   >
-    <camera-detail
-      v-if="contentRender"
-      :camera="camera"
-    />
-    <i
-      class="l-flex__none c-dialog--full__close el-icon-close has-active u-bold u-pointer"
-      @click="hide"
-    />
+    <template v-if="contentRender">
+      <camera-detail :camera="camera" />
+      <i
+        class="l-flex__none c-dialog--full__close el-icon-close has-active u-bold u-pointer"
+        @click="hide"
+      />
+    </template>
   </el-dialog>
 </template>
 

+ 12 - 5
src/components/dialog/ConfirmDialog/index.vue

@@ -5,14 +5,10 @@
     :close-on-click-modal="false"
     :before-close="onCancel"
     v-bind="$attrs"
-    v-on="$listeners"
     @open="onOpen"
     @closed="onClosed"
   >
-    <slot
-      v-if="contentRender"
-      :visible="contentRender"
-    />
+    <slot v-if="contentRender" />
     <template #footer>
       <slot
         name="footer"
@@ -42,6 +38,17 @@ import dialogMixin from '@/mixins/dialog'
 export default {
   name: 'ConfirmDialog',
   mixins: [dialogMixin],
+  props: {
+    size: {
+      type: String,
+      default: ''
+    }
+  },
+  computed: {
+    className () {
+      return `c-dialog ${this.size}`
+    }
+  },
   methods: {
     hide () {
       this.onCancel()

+ 0 - 75
src/components/dialog/GridTableDialog/index.vue

@@ -1,75 +0,0 @@
-<template>
-  <el-dialog
-    :visible.sync="choosing"
-    :custom-class="customClass"
-    :close-on-click-modal="false"
-    v-bind="$attrs"
-  >
-    <grid-table
-      v-if="choosing"
-      ref="table"
-      :schema="schema"
-    >
-      <template
-        v-if="hasHeader"
-        #header="scope"
-      >
-        <slot
-          name="header"
-          v-bind="scope"
-        />
-      </template>
-      <grid-table-item v-slot="item">
-        <slot
-          name="item"
-          v-bind="item"
-        />
-      </grid-table-item>
-    </grid-table>
-    <slot />
-  </el-dialog>
-</template>
-
-<script>
-export default {
-  name: 'GridTableDialog',
-  inheritAttrs: false,
-  props: {
-    schema: {
-      type: Object,
-      default: null
-    },
-    size: {
-      type: String,
-      default: 'medium'
-    }
-  },
-  data () {
-    return {
-      choosing: false
-    }
-  },
-  computed: {
-    hasHeader () {
-      return this.$scopedSlots.header
-    },
-    customClass () {
-      return `c-dialog ${this.size}`
-    }
-  },
-  methods: {
-    show (condition) {
-      if (condition) {
-        this.schema.condition = { ...this.schema.condition, ...condition }
-      }
-      this.choosing = true
-    },
-    hide () {
-      this.choosing = false
-    },
-    getTable () {
-      return this.$refs.table
-    }
-  }
-}
-</script>

+ 36 - 34
src/components/dialog/MaterialDialog/index.vue

@@ -1,31 +1,34 @@
 <template>
   <el-dialog
-    :visible.sync="isPreviewing"
-    title="上播内容"
+    :visible.sync="dialogVisible"
     :custom-class="customClass"
+    title="上播内容"
     :close-on-click-modal="false"
     append-to-body
+    @open="onOpen"
     @closed="onClosed"
   >
-    <program
-      v-if="program"
-      :program="program"
-    />
-    <schedule
-      v-if="scheduleId"
-      class="l-flex__auto has-padding--h has-bottom-padding"
-      :schedule="scheduleId"
-    />
-    <schema-table
-      v-if="assets"
-      :schema="contentSchema"
-    >
-      <preview-dialog ref="previewDialog" />
-    </schema-table>
-    <i
-      class="l-flex__none c-dialog--preview__close el-icon-close has-active u-bold u-pointer"
-      @click="onCloseDialog"
-    />
+    <template v-if="contentRender">
+      <program
+        v-if="program"
+        :program="program"
+      />
+      <schedule
+        v-if="scheduleId"
+        class="l-flex__auto has-padding--h has-bottom-padding"
+        :schedule="scheduleId"
+      />
+      <schema-table
+        v-if="assets"
+        :schema="contentSchema"
+      >
+        <preview-dialog ref="previewDialog" />
+      </schema-table>
+      <i
+        class="l-flex__none c-dialog--preview__close el-icon-close has-active u-bold u-pointer"
+        @click="hide"
+      />
+    </template>
   </el-dialog>
 </template>
 
@@ -39,16 +42,16 @@ import {
 import { parseDuration } from '@/utils'
 import { getProgram } from '@/api/program'
 import Program from '@/views/screen/material/program/ast/Viewer'
+import dialogMixin from '@/mixins/dialog'
 
 export default {
   name: 'MaterialDialog',
   components: {
     Program
   },
-  inheritAttrs: false,
+  mixins: [dialogMixin],
   data () {
     return {
-      isPreviewing: false,
       program: null,
       scheduleId: null,
       assets: null,
@@ -75,6 +78,13 @@ export default {
     }
   },
   methods: {
+    onClosed () {
+      this.contentRender = false
+      this.program = null
+      this.scheduleId = null
+      this.assets = null
+      this.$emit('closed')
+    },
     showProgram (id) {
       const loading = this.$showLoading()
       getProgram(id).then(({ data }) => {
@@ -94,7 +104,7 @@ export default {
               ...JSON.parse(itemJsonStr)
             }
           }
-          this.isPreviewing = true
+          this.dialogVisible = true
         } catch (e) {
           this.showMessage('error', '布局解析失败')
         }
@@ -104,7 +114,7 @@ export default {
     },
     showSchedule (id) {
       this.scheduleId = id
-      this.isPreviewing = true
+      this.dialogVisible = true
     },
     showPublishTarget ({ type, detail }) {
       switch (type) {
@@ -139,7 +149,7 @@ export default {
         assets[0].adDuration = '独占'
       }
       this.assets = assets
-      this.isPreviewing = true
+      this.dialogVisible = true
     },
     getContentAssets () {
       return Promise.resolve({ data: this.assets })
@@ -157,14 +167,6 @@ export default {
     },
     onViewAsset ({ file }) {
       this.$refs.previewDialog.show(file)
-    },
-    onCloseDialog () {
-      this.isPreviewing = false
-    },
-    onClosed () {
-      this.program = null
-      this.scheduleId = null
-      this.assets = null
     }
   }
 }

+ 14 - 13
src/components/dialog/PreviewDialog/index.vue

@@ -1,13 +1,14 @@
 <template>
   <el-dialog
-    :visible.sync="isPreviewing"
+    :visible.sync="dialogVisible"
     custom-class="c-dialog--transparent"
     :close-on-click-modal="false"
     append-to-body
-    v-bind="$attrs"
-    v-on="$listeners"
+    @open="onOpen"
+    @close="onClose"
+    @closed="onClosed"
   >
-    <template v-if="isPreviewing">
+    <template v-if="contentRender">
       <auto-image
         v-if="isImage"
         class="o-preview u-font-size--3xl"
@@ -36,7 +37,7 @@
       />
       <i
         class="o-close o-icon el-icon-close has-active u-bold u-pointer"
-        @click="onCloseDialog"
+        @click="hide"
       />
       <template v-if="isMultipleFiles">
         <i
@@ -57,15 +58,16 @@
 import HlsJs from 'hls.js'
 import { AssetType } from '@/constant'
 import { getAssetUrl } from '@/api/asset'
+import dialogMixin from '@/mixins/dialog'
 
 const isSupported = HlsJs.isSupported()
 const isHttps = location.protocol === 'https:'
 
 export default {
   name: 'PreviewDialog',
+  mixins: [dialogMixin],
   data () {
     return {
-      isPreviewing: false,
       isMultipleFiles: false,
       total: 0,
       active: 0,
@@ -93,10 +95,7 @@ export default {
     }
   },
   beforeDestroy () {
-    if (this.hlsjs) {
-      this.hlsjs.destroy()
-      this.hlsjs = null
-    }
+    this.onClose()
   },
   methods: {
     show (source) {
@@ -108,15 +107,17 @@ export default {
       this.total = this.$sources.length
       this.active = 0
       this.source = this.$sources[this.active]
-      this.isPreviewing = true
+      this.dialogVisible = true
+    },
+    onOpen () {
+      this.contentRender = true
       if (this.isStreamingMedia) {
         this.$nextTick(() => {
           this.playStreamingMedia()
         })
       }
     },
-    onCloseDialog () {
-      this.isPreviewing = false
+    onClose () {
       if (this.hlsjs) {
         this.hlsjs.destroy()
         this.hlsjs = null

+ 1 - 1
src/components/dialog/RadioTableDialog/index.vue

@@ -55,7 +55,7 @@ export default {
   },
   computed: {
     hasHeader () {
-      return this.$scopedSlots.header
+      return !!this.$scopedSlots.header
     },
     selectedKey () {
       return this.selectedRow?.[this.rowKey]

+ 1 - 1
src/components/dialog/SelectionTableDialog/index.vue

@@ -43,7 +43,7 @@ export default {
   },
   computed: {
     hasHeader () {
-      return this.$scopedSlots.header
+      return !!this.$scopedSlots.header
     },
     tableSchema () {
       const { cols, ...data } = this.schema

+ 2 - 23
src/components/dialog/TableDialog/index.vue

@@ -2,13 +2,12 @@
   <c-dialog
     ref="dialog"
     :size="size"
-    :close-on-click-modal="closeOnClickModal"
     v-bind="$attrs"
   >
     <schema-table
       ref="table"
       :schema="schema"
-      v-on="tableListeners"
+      v-on="schema.listeners"
     >
       <template
         v-if="hasHeader"
@@ -40,20 +39,7 @@ export default {
   },
   computed: {
     hasHeader () {
-      return this.$scopedSlots.header
-    },
-    closeOnClickModal () {
-      return !this.$listeners.choosen
-    },
-    tableListeners () {
-      return {
-        ...(
-          this.closeOnClickModal
-            ? null
-            : { 'row-dblclick': this.onChoosen }
-        ),
-        ...this.schema.listeners
-      }
+      return !!this.$scopedSlots.header
     }
   },
   methods: {
@@ -63,13 +49,6 @@ export default {
       }
       this.$refs.dialog.show()
     },
-    onChoosen (value) {
-      this.$emit('choosen', {
-        value,
-        table: this.$refs.table,
-        done: () => { this.$refs.dialog.hide() }
-      })
-    },
     getTable () {
       return this.$refs.table
     }

+ 0 - 74
src/components/table/CTable/index.vue

@@ -1,74 +0,0 @@
-<template>
-  <div
-    v-loading="options.loading"
-    class="l-flex__auto l-flex--col c-table"
-    :class="{ 'prevent-copy': preventCopy }"
-  >
-    <div class="l-flex__none l-flex--row c-table__header">
-      <slot name="header" />
-    </div>
-    <el-table
-      ref="table"
-      class="l-flex__self l-flex--col"
-      :data="options.list"
-      v-bind="$attrs"
-      @row-click="onClick"
-      @row-dblclick="onRowClick"
-      @selection-change="onSelectionChange"
-    >
-      <slot />
-      <status-wrapper
-        slot="empty"
-        :error="options.error"
-        @click="onPagination"
-      />
-    </el-table>
-    <pagination
-      v-if="options.params"
-      :total="options.totalCount"
-      :page.sync="options.params.pageNum"
-      :limit.sync="options.params.pageSize"
-      @pagination="onPagination"
-    />
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'CTable',
-  props: {
-    options: {
-      type: Object,
-      default () {
-        return {}
-      }
-    },
-    copy: {
-      type: [Boolean, String],
-      default: false
-    }
-  },
-  computed: {
-    preventCopy () {
-      return !this.copy && !!(this.$listeners['row-click'] || this.$listeners['row-dblclick'])
-    }
-  },
-  methods: {
-    onPagination () {
-      this.$emit('pagination')
-    },
-    onClick (row) {
-      this.$emit('row-click', row)
-    },
-    onRowClick (row) {
-      this.$emit('row-dblclick', row)
-    },
-    onSelectionChange (val) {
-      this.$emit('selection-change', val)
-    },
-    getInstance () {
-      return this.$refs.table
-    }
-  }
-}
-</script>

+ 3 - 3
src/components/table/Table/Column.vue

@@ -20,7 +20,6 @@ export default {
       return h('el-table-column', {
         props: {
           width: 48,
-          'label-class-name': 'o-refresh-header',
           align: 'center',
           ...props
         },
@@ -34,7 +33,7 @@ export default {
     },
     renderRefreshColumnHeader () {
       return this.$createElement('i', {
-        staticClass: 'o-refresh el-icon-refresh',
+        staticClass: 'el-icon-refresh u-color--black light u-font-size--xl u-vertical--middle has-active u-pointer',
         on: { click: $event => {
           $event.stopPropagation()
           this.table.pageTo()
@@ -56,7 +55,7 @@ export default {
         }
       })
     },
-    renderAssetColumn (h, props) {
+    renderAssetColumn (h, { refresh, ...props }) {
       return h('el-table-column', {
         props: {
           'class-name': 'c-thumbnail-column',
@@ -66,6 +65,7 @@ export default {
           ...props
         },
         scopedSlots: {
+          header: refresh ? this.renderRefreshColumnHeader : null,
           default: this.renderAsset
         }
       })

+ 1 - 1
src/components/table/mixins/table.js

@@ -57,7 +57,7 @@ export default {
       })
     },
     hasHeader () {
-      return this.$scopedSlots.header || this.buttons?.length || this.filters?.length
+      return !!this.filters?.length || !!this.buttons?.length || !!this.$scopedSlots.header
     },
     tableData () {
       const { transformData } = this.schema

+ 2 - 2
src/components/tree/DeviceGroupTree/index.vue

@@ -58,11 +58,11 @@
             class="l-flex__none l-flex--row c-tree__title c-tree__content u-pointer"
             @click="onAllToggle"
           >
-            <span class="l-flex__auto">全部设备</span>
+            <span class="l-flex__fill c-sibling-item u-ellipisi">全部设备</span>
             <el-checkbox
               :value="isAll"
               :indeterminate="isIndeterminate"
-              class="l-flex__none u-events--none"
+              class="l-flex__none c-sibling-item u-events--none"
             />
           </div>
           <div class="l-flex__auto l-flex--col u-overflow-y--auto">

+ 4 - 4
src/components/tree/DeviceTree/index.vue

@@ -28,11 +28,11 @@
           class="l-flex__none l-flex--row c-tree__title c-tree__content u-pointer"
           @click="onAllToggle"
         >
-          <span class="l-flex__auto">全部设备</span>
+          <span class="l-flex__fill c-sibling-item u-ellipsis">全部设备</span>
           <el-checkbox
             :value="isAll"
             :indeterminate="isIndeterminate"
-            class="l-flex__none c-tree__checkbox"
+            class="l-flex__none c-sibling-item u-events--none"
           />
         </div>
         <div class="l-flex__auto l-flex--col c-tree__list u-overflow-y--auto">
@@ -42,10 +42,10 @@
             class="c-tree__content u-pointer"
             @click="onDeviceToggle(device)"
           >
-            <span class="c-tree__label">{{ device.name }} {{ showRatio ? device.resolutionRatio : '' }}</span>
+            <span class="l-flex__fill c-sibling-item u-ellipsis">{{ device.name }} {{ showRatio ? device.resolutionRatio : '' }}</span>
             <el-checkbox
               :value="device.checked"
-              class="l-flex__none c-tree__checkbox"
+              class="l-flex__none c-sibling-item u-events--none"
             />
           </div>
         </div>

+ 3 - 3
src/components/tree/DeviceTreeSingle/index.vue

@@ -45,7 +45,7 @@
                   class="c-tree__expand el-icon-arrow-right"
                   :class="{ expand: group.expand }"
                 />
-                <span class="c-tree__label">{{ group.name }}</span>
+                <span class="l-flex__fill u-ellipsis">{{ group.name }}</span>
               </div>
               <div v-show="onlyOneGroup || group.expand">
                 <div
@@ -57,11 +57,11 @@
                 <div
                   v-for="device in group.list"
                   :key="device.id"
-                  class="c-tree__content u-ellipsis u-pointer"
+                  class="c-tree__content u-pointer"
                   :class="{ sub: !onlyOneGroup, selected: device.id === deviceId }"
                   @click="onDeviceToggle(device)"
                 >
-                  <span class="l-flex__fill">{{ device.name }}</span>
+                  <span class="l-flex__fill u-ellipsis">{{ device.name }}</span>
                 </div>
               </div>
             </div>

+ 47 - 52
src/layout/components/Navbar/UploadDashboard/index.vue

@@ -7,58 +7,55 @@
       class="el-icon-upload u-color--blue u-font-size--2xl has-active"
       :class="{ breathe: uploading }"
     />
-    <el-dialog
+    <c-dialog
+      ref="dialog"
+      size="lg"
       title="文件上传"
-      :visible.sync="show"
-      custom-class="c-dialog lg"
-      :before-close="close"
       append-to-body
     >
-      <template v-if="show">
-        <div class="l-flex__none l-flex--row c-sibling-item--v">
-          <div class="l-flex__fill" />
-          <div class="l-flex--row c-sibling-item">
-            <span class="c-sibling-item u-color--info">类型</span>
-            <schema-select
-              v-model="tag"
-              class="c-sibling-item u-width--xs"
-              :schema="tagSelectSchema"
-            />
-          </div>
-          <div class="l-flex--row c-sibling-item far">
-            <span class="c-sibling-item u-color--info">标签</span>
-            <schema-select
-              v-model="subTag"
-              class="c-sibling-item u-width--xs"
-              :schema="subTagSelectSchema"
-            />
-          </div>
+      <div class="l-flex__none l-flex--row c-sibling-item--v">
+        <div class="l-flex__fill" />
+        <div class="l-flex--row c-sibling-item">
+          <span class="c-sibling-item u-color--info">类型</span>
+          <schema-select
+            v-model="tag"
+            class="c-sibling-item u-width--xs"
+            :schema="tagSelectSchema"
+          />
         </div>
-        <el-upload
-          ref="upload"
-          class="c-sibling-item--v o-upload"
-          :class="{ 'l-flex__fill': !hasFile }"
-          action="none"
-          :accept="accept"
-          :auto-upload="false"
-          :show-file-list="false"
-          :on-change="onChange"
-          drag
-          multiple
-        >
-          <div class="l-flex--row">
-            <i class="c-sibling-item o-upload__icon el-icon-upload" />
-            <span class="c-sibling-item near">拖拽文件到此或</span>
-            <span class="c-sibling-item near u-color--blue">点击选择文件</span>
-          </div>
-          <div class="o-upload__accept">{{ accept }}</div>
-        </el-upload>
-        <file-progress
-          v-if="hasFile"
-          class="l-flex__auto c-sibling-item--v far"
-        />
-      </template>
-    </el-dialog>
+        <div class="l-flex--row c-sibling-item far">
+          <span class="c-sibling-item u-color--info">标签</span>
+          <schema-select
+            v-model="subTag"
+            class="c-sibling-item u-width--xs"
+            :schema="subTagSelectSchema"
+          />
+        </div>
+      </div>
+      <el-upload
+        ref="upload"
+        class="c-sibling-item--v o-upload"
+        :class="{ 'l-flex__fill': !hasFile }"
+        action="none"
+        :accept="accept"
+        :auto-upload="false"
+        :show-file-list="false"
+        :on-change="onChange"
+        drag
+        multiple
+      >
+        <div class="l-flex--row">
+          <i class="c-sibling-item o-upload__icon el-icon-upload" />
+          <span class="c-sibling-item near">拖拽文件到此或</span>
+          <span class="c-sibling-item near u-color--blue">点击选择文件</span>
+        </div>
+        <div class="o-upload__accept">{{ accept }}</div>
+      </el-upload>
+      <file-progress
+        v-if="hasFile"
+        class="l-flex__auto c-sibling-item--v far"
+      />
+    </c-dialog>
   </div>
 </template>
 
@@ -122,12 +119,10 @@ export default {
       })
     },
     open () {
-      this.show = true
+      this.$refs.dialog.show()
     },
     close () {
-      this.show = false
-      this.tag = AssetTag.AD
-      this.subTag = ''
+      this.$refs.dialog.hide()
     },
     check (files) {
       this.uploading = isUploading()

+ 2 - 11
src/mixins/dialog.js

@@ -1,22 +1,11 @@
 export default {
   inheritAttrs: false,
-  props: {
-    size: {
-      type: String,
-      default: ''
-    }
-  },
   data () {
     return {
       dialogVisible: false,
       contentRender: false
     }
   },
-  computed: {
-    className () {
-      return `c-dialog ${this.size}`
-    }
-  },
   methods: {
     show () {
       this.dialogVisible = true
@@ -25,10 +14,12 @@ export default {
       this.dialogVisible = false
     },
     onOpen () {
+      this.$emit('open')
       this.contentRender = true
     },
     onClosed () {
       this.contentRender = false
+      this.$emit('closed')
     }
   }
 }

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

@@ -107,7 +107,7 @@
     padding: $padding--md;
     color: $black;
     font-size: $font-size--xl;
-    z-index: 8;
+    z-index: 9;
   }
 
   .el-dialog__header {
@@ -129,8 +129,7 @@
   display: flex;
   flex-direction: column;
   justify-content: center;
-  align-items: center;
-  width: 80%;
+  width: 60%;
   height: 80%;
   margin-top: 10vh !important;
   margin-bottom: 0;
@@ -142,56 +141,13 @@
   }
 
   .el-dialog__body {
-    min-height: 0;
-    padding: 0;
-  }
-}
-
-.c-dialog--detail {
-  display: flex;
-  flex-direction: column;
-  width: 960px;
-  min-height: 540px;
-  height: 88%;
-  margin-top: 6vh !important;
-  margin-bottom: 0;
-  box-shadow: none;
-
-  .el-dialog__header {
-    flex: none;
-    position: relative;
-    color: $black;
-    padding: $spacing;
-    font-size: 24px;
-    font-weight: bold;
-    line-height: 1;
-    border-bottom: 1px solid $border;
-
-    .el-dialog__headerbtn {
-      position: absolute;
-      top: 0;
-      right: 0;
-      padding: 16px;
-    }
-
-    .el-dialog__close {
-      color: $black;
-      font-size: 24px;
-      font-weight: bold;
-
-      &:hover {
-        color: $primary;
-      }
-    }
-  }
-
-  .el-dialog__body {
-    flex: 1 1 auto;
+    flex: 1 0 none;
     display: flex;
     flex-direction: column;
-    position: relative;
+    justify-content: center;
+    align-items: center;
     min-height: 0;
-    padding: $spacing;
+    padding: 0;
   }
 }
 
@@ -434,12 +390,6 @@
   }
 }
 
-.c-progress > .el-dialog {
-  top: 20%;
-  box-shadow: none;
-  background-color: transparent;
-}
-
 .c-thumbnail-column:not(.is-leaf) {
   padding: $padding--xs  !important;
 

+ 0 - 15
src/scss/bem/_object.scss

@@ -146,21 +146,6 @@
   }
 }
 
-.o-refresh-header.cell {
-  display: inline-flex !important;
-  justify-content: center;
-}
-
-.o-refresh {
-  color: $gray;
-  font-size: $font-size--xl;
-  @extend .u-pointer;
-
-  &:hover {
-    color: $blue;
-  }
-}
-
 .o-info {
   padding: 0 $spacing;
   color: $info--dark;

+ 8 - 0
src/scss/bem/_utility.scss

@@ -65,6 +65,10 @@
 
 .u-color--black {
   color: $black;
+
+  &.light {
+    color: $gray;
+  }
 }
 
 .u-color--info {
@@ -194,3 +198,7 @@
     width: 400px !important;
   }
 }
+
+.u-vertical--middle {
+  vertical-align: middle;
+}

+ 1 - 2
src/views/ad/review-asset/index.vue

@@ -71,8 +71,7 @@ export default {
         list: getAssets,
         transform: this.transform,
         cols: [
-          { type: 'refresh' },
-          { prop: 'fileType', label: '文件', align: 'center' },
+          { prop: 'fileType', type: 'refresh', width: 80 },
           { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
           { prop: 'size', label: '文件大小', align: 'right' },
           { prop: 'ratio', label: '分辨率', align: 'right' },

+ 1 - 2
src/views/device/detail/components/DeviceAlarm.vue

@@ -28,8 +28,7 @@ export default {
         condition: { deviceId: this.device.id },
         list: getDeviceAlarms,
         cols: [
-          { type: 'refresh' },
-          { prop: 'file', label: '截图', type: 'asset', on: this.onView },
+          { prop: 'file', label: '截图', type: 'asset', refresh: true, on: this.onView },
           { prop: 'type', label: '类型', 'min-width': 120 },
           { prop: 'handle', label: '处理方式' },
           { prop: 'status', label: '处理结果', type: 'tag' },

+ 6 - 3
src/views/device/detail/components/DeviceExternal/external/Camera/led.vue

@@ -18,7 +18,8 @@
     </grid-table>
     <camera-dialog
       ref="cameraDialog"
-      @close="onClose"
+      @open="onOpen"
+      @closed="onClosed"
     />
   </div>
 </template>
@@ -60,10 +61,12 @@ export default {
       })
     },
     onFullScreen (camera) {
-      this.isActivated = false
       this.$refs.cameraDialog.show(camera)
     },
-    onClose () {
+    onOpen () {
+      this.isActivated = false
+    },
+    onClosed () {
       this.isActivated = true
     }
   }

+ 6 - 3
src/views/device/detail/components/DeviceExternal/external/Camera/traffic.vue

@@ -18,7 +18,8 @@
     </grid-table>
     <camera-dialog
       ref="cameraDialog"
-      @close="onClose"
+      @open="onOpen"
+      @closed="onClosed"
     />
   </div>
 </template>
@@ -60,10 +61,12 @@ export default {
       })
     },
     onFullScreen (camera) {
-      this.isActivated = false
       this.$refs.cameraDialog.show(camera)
     },
-    onClose () {
+    onOpen () {
+      this.isActivated = false
+    },
+    onClosed () {
       this.isActivated = true
     }
   }

+ 2 - 2
src/views/device/detail/components/DeviceExternal/external/ReceivingCard/ReceivingCardTopology.vue

@@ -1,6 +1,6 @@
 <template>
   <div
-    class="c-card-grid"
+    class="c-receiving-card"
     :class="{ empty: !cards, mismatched: message }"
     :style="style"
     :message="message"
@@ -163,7 +163,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.c-card-grid {
+.c-receiving-card {
   display: grid;
   position: relative;
   overflow: auto;

+ 14 - 15
src/views/device/detail/components/DeviceExternal/index.vue

@@ -4,19 +4,19 @@
     :device="device"
     @click="onClick"
   >
-    <el-dialog
-      :visible.sync="showDetail"
-      custom-class="c-dialog--detail"
+    <c-dialog
+      ref="dialog"
+      size="lg"
       :title="title"
-      :close-on-click-modal="false"
     >
-      <component
-        :is="activeComponent"
-        v-if="showDetail"
-        class="l-flex__auto"
-        :device="device"
-      />
-    </el-dialog>
+      <template #default>
+        <component
+          :is="activeComponent"
+          class="l-flex__auto"
+          :device="device"
+        />
+      </template>
+    </c-dialog>
   </full-link>
 </template>
 
@@ -45,9 +45,8 @@ export default {
   },
   data () {
     return {
-      showDetail: false,
-      activeComponent: null,
-      title: ''
+      title: '',
+      activeComponent: null
     }
   },
   methods: {
@@ -77,7 +76,7 @@ export default {
       }
       this.title = label
       this.activeComponent = activeComponent
-      this.showDetail = true
+      this.$refs.dialog.show()
     }
   }
 }

+ 0 - 73
src/views/device/detail/components/DeviceInvoke/DeviceSwitch.vue

@@ -1,73 +0,0 @@
-<template>
-  <div class="l-flex--col center has-border radius has-padding">
-    <i
-      class="o-icon has-bg u-pointer"
-      @click="invoke"
-    />
-    <div class="has-padding u-color--black u-bold">开关设备</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog medium"
-      title="开关设备"
-      :before-close="onCloseDialog"
-    >
-      <tabbar
-        :items="tabs"
-        :active.sync="active"
-      />
-      <template v-if="show">
-        <template v-if="isImmediate">
-          <div class="l-flex__auto l-flex--col jcenter center has-bottom-padding">
-            <div>
-              <button
-                class="o-button c-sibling-item"
-                @click="onSwitch(true)"
-              >
-                即刻开机
-              </button>
-              <button
-                class="o-button c-sibling-item far"
-                @click="onSwitch(false)"
-              >
-                即刻关机
-              </button>
-            </div>
-            <div class="has-padding u-color--info">【实时控制】会立即执行</div>
-          </div>
-        </template>
-        <schema-table
-          v-else
-          ref="table"
-          :schema="schema"
-          :proxy.sync="currOptions"
-        />
-      </template>
-    </el-dialog>
-    <task-dialog
-      ref="editDialog"
-      :title="dialogTitle"
-      @confirm="onSave"
-    />
-  </div>
-</template>
-
-<script>
-import switchTaskMixin from './mixins/switch-task'
-
-export default {
-  name: 'DeviceSwitch',
-  mixins: [switchTaskMixin],
-  data () {
-    return {
-      openFunctionKey: 'bootDevice',
-      closeFunctionKey: 'shutdownDevice'
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-.o-icon {
-  background-image: url("~@/assets/icon_device_switch.png");
-}
-</style>

+ 24 - 25
src/views/device/detail/components/DeviceInvoke/MultifunctionCardPowerSwitch.vue

@@ -5,29 +5,30 @@
       @click="invoke"
     />
     <div class="has-padding u-color--black u-bold">开关电源</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog lg"
+    <c-dialog
+      ref="dialog"
+      size="lg"
       title="开关电源"
-      :before-close="onCloseDialog"
+      @close="onClose"
     >
-      <tabbar
-        :items="tabs"
-        :active="active"
-        @click="onClickTab"
-      />
-      <div
-        v-if="show"
-        v-loading="loading"
-        class="l-flex__auto l-flex--col"
-      >
-        <schema-table
-          :key="active"
-          ref="table"
-          :schema="schema"
+      <template #default>
+        <tabbar
+          :items="tabs"
+          :active="active"
+          @click="onClickTab"
         />
-      </div>
-    </el-dialog>
+        <div
+          v-loading="loading"
+          class="l-flex__auto l-flex--col"
+        >
+          <schema-table
+            :key="active"
+            ref="table"
+            :schema="schema"
+          />
+        </div>
+      </template>
+    </c-dialog>
     <task-dialog
       ref="editDialog"
       :title="dialogTitle"
@@ -138,7 +139,6 @@ export default {
   mixins: [baseMixin],
   data () {
     return {
-      show: false,
       active: GET_POWER_STATUS,
       tabs: [
         { key: GET_POWER_STATUS, name: '电源状态' }
@@ -342,7 +342,7 @@ export default {
       }
       switch (message.function) {
         case GET_POWER_STATUS:
-          this.show = true
+          this.$refs.dialog?.show()
           this.setPowerStatus(data)
           break
         case SET_POWER_STATUS:
@@ -386,8 +386,7 @@ export default {
           break
       }
     },
-    onCloseDialog () {
-      this.show = false
+    onClose () {
       this.$powers = []
       this.$taskPorts = []
       this.$tasks = []
@@ -400,7 +399,7 @@ export default {
       this.sendTopic(
         GET_POWER_STATUS,
         JSON.stringify({ sn: this.device.serialNumber }),
-        ErrorMessage[this.show ? 'TIMEOUT_RETRY' : GET_POWER_STATUS]
+        ErrorMessage[this.$refs.dialog?.dialogVisible ? 'TIMEOUT_RETRY' : GET_POWER_STATUS]
       )
     },
     setPowerStatus ({ current_status_info }) {

+ 7 - 15
src/views/device/detail/components/DeviceInvoke/PLCSwitch.vue

@@ -5,15 +5,12 @@
       @click="onInvoke"
     />
     <div class="has-padding u-color--black u-bold">开关电源(PLC)</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog medium"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       title="开关电源"
     >
-      <div
-        v-if="show"
-        class="l-flex__fill l-flex--col jcenter center has-bottom-padding"
-      >
+      <div class="l-flex__fill l-flex--col jcenter center has-bottom-padding">
         <div>
           <button
             class="o-button c-sibling-item"
@@ -29,7 +26,7 @@
           </button>
         </div>
       </div>
-    </el-dialog>
+    </c-dialog>
   </div>
 </template>
 
@@ -47,11 +44,6 @@ export default {
       required: true
     }
   },
-  data () {
-    return {
-      show: false
-    }
-  },
   methods: {
     onInvoke () {
       const loading = this.$showLoading()
@@ -59,7 +51,7 @@ export default {
         this.$closeLoading(loading)
       }).then(data => {
         if (data.length) {
-          this.show = true
+          this.$refs.dialog.show()
         } else {
           this.$message({
             type: 'warning',
@@ -83,6 +75,6 @@ export default {
 
 <style lang="scss" scoped>
 .o-icon {
-  background-image: url("~@/assets/icon_screen_switch.png");
+  background-image: url("~@/assets/icon_device_switch.png");
 }
 </style>

+ 16 - 19
src/views/device/detail/components/DeviceInvoke/ScreenLight.vue

@@ -5,20 +5,19 @@
       @click="invoke"
     />
     <div class="has-padding u-color--black u-bold">{{ type }}</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog medium"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       :title="settings"
-      :before-close="onCloseDialog"
     >
-      <tabbar
-        :items="tabs"
-        :active.sync="active"
-      />
-      <template v-if="show">
+      <template #default>
+        <tabbar
+          :items="tabs"
+          :active.sync="active"
+        />
         <template v-if="isImmediate">
           <div class="l-flex__auto l-flex--col jcenter center has-bottom-padding">
-            <div class="c-grid-form auto">
+            <div class="c-sibling-item--v c-grid-form auto">
               <span class="c-grid-form__label u-required">{{ tip }}</span>
               <div class="l-flex--row">
                 <el-input-number
@@ -29,14 +28,12 @@
                 />&nbsp;%
               </div>
             </div>
-            <div class="has-padding">
-              <button
-                class="o-button"
-                @click="onInvoke"
-              >
-                执行
-              </button>
-            </div>
+            <button
+              class="c-sibling-item--v o-button"
+              @click="onInvoke"
+            >
+              应用
+            </button>
           </div>
         </template>
         <schema-table
@@ -46,7 +43,7 @@
           :proxy.sync="options"
         />
       </template>
-    </el-dialog>
+    </c-dialog>
     <task-dialog
       ref="editDialog"
       :title="dialogTitle"

+ 19 - 22
src/views/device/detail/components/DeviceInvoke/ScreenSwitch.vue

@@ -5,31 +5,28 @@
       @click="invoke"
     />
     <div class="has-padding u-color--black u-bold">开关大屏</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog medium"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       title="开关大屏"
-      :before-close="onCloseDialog"
     >
-      <template v-if="show">
-        <div class="l-flex__fill l-flex--col jcenter center has-bottom-padding">
-          <div>
-            <button
-              class="o-button c-sibling-item"
-              @click="onSwitch(true)"
-            >
-              即刻开机
-            </button>
-            <button
-              class="o-button c-sibling-item far"
-              @click="onSwitch(false)"
-            >
-              即刻关机
-            </button>
-          </div>
+      <div class="l-flex__fill l-flex--col jcenter center has-bottom-padding">
+        <div>
+          <button
+            class="o-button c-sibling-item"
+            @click="onSwitch(true)"
+          >
+            即刻开机
+          </button>
+          <button
+            class="o-button c-sibling-item far"
+            @click="onSwitch(false)"
+          >
+            即刻关机
+          </button>
         </div>
-      </template>
-    </el-dialog>
+      </div>
+    </c-dialog>
   </div>
 </template>
 

+ 16 - 19
src/views/device/detail/components/DeviceInvoke/ScreenVolume.vue

@@ -5,20 +5,19 @@
       @click="invoke"
     />
     <div class="has-padding u-color--black u-bold">{{ type }}</div>
-    <el-dialog
-      :visible.sync="show"
-      custom-class="c-dialog medium"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       :title="settings"
-      :before-close="onCloseDialog"
     >
-      <tabbar
-        :items="tabs"
-        :active.sync="active"
-      />
-      <template v-if="show">
+      <template #default>
+        <tabbar
+          :items="tabs"
+          :active.sync="active"
+        />
         <template v-if="isImmediate">
           <div class="l-flex__auto l-flex--col jcenter center has-bottom-padding">
-            <div class="c-grid-form auto">
+            <div class="c-sibling-item--v c-grid-form auto">
               <span class="c-grid-form__label u-required">{{ tip }}</span>
               <div class="l-flex--row">
                 <el-input-number
@@ -29,14 +28,12 @@
                 />&nbsp;%
               </div>
             </div>
-            <div class="has-padding">
-              <button
-                class="o-button"
-                @click="onInvoke"
-              >
-                执行
-              </button>
-            </div>
+            <button
+              class="c-sibling-item--v o-button"
+              @click="onInvoke"
+            >
+              应用
+            </button>
           </div>
         </template>
         <schema-table
@@ -46,7 +43,7 @@
           :proxy.sync="options"
         />
       </template>
-    </el-dialog>
+    </c-dialog>
     <task-dialog
       ref="editDialog"
       :title="dialogTitle"

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

@@ -51,8 +51,8 @@ export default {
         ]
         : [
           h('DeviceNetwork', { props: this.$attrs }),
-          h('ScreenVolume', { props: this.$attrs }),
           h('MultifunctionCardPowerSwitch', { props: this.$attrs }),
+          h('ScreenVolume', { props: this.$attrs }),
           h('DeviceReboot', { props: this.$attrs })
         ]
     )

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

@@ -25,7 +25,7 @@ export default {
       this.active = 'immediate'
       this.taskValue = 50
       this.options = createListOptions({ functionKey: this.functionKey })
-      this.show = true
+      this.$refs.dialog.show()
     },
     onInvoke () {
       this.$confirm(

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

@@ -36,7 +36,7 @@ export default {
       this.active = 'immediate'
       this.delayOpenOptions = createListOptions({ functionKey: this.openFunctionKey })
       this.delayCloseOptions = createListOptions({ functionKey: this.closeFunctionKey })
-      this.show = true
+      this.$refs.dialog.show()
     },
     onSwitch (open) {
       this.$confirm(

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

@@ -17,7 +17,6 @@ export default {
   data () {
     return {
       isAdd: false,
-      show: false,
       active: 'immediate',
       options: null,
       task: {}
@@ -53,9 +52,6 @@ export default {
         ]
       }
     },
-    onCloseDialog () {
-      this.show = false
-    },
     getTasks (params) {
       return getTasks({
         deviceId: this.deviceId,

+ 5 - 7
src/views/device/detail/components/DeviceRuntime/Download.vue

@@ -21,14 +21,13 @@
     >
       正在下载文件...
     </div>
-    <el-dialog
-      :visible.sync="showProgress"
-      custom-class="c-dialog"
-      title="文件下载详情"
+    <c-dialog
+      ref="dialog"
+      title="下载详情"
       append-to-body
     >
       <download-progress @update="onUpdate" />
-    </el-dialog>
+    </c-dialog>
   </div>
 </template>
 
@@ -46,7 +45,6 @@ export default {
   },
   data () {
     return {
-      showProgress: false,
       count: 0,
       downloadCount: 0,
       loading: false
@@ -65,7 +63,7 @@ export default {
       this.loading = files.some(({ complete }) => !complete)
     },
     showDownload () {
-      this.showProgress = true
+      this.$refs.dialog.show()
     }
   }
 }

+ 7 - 8
src/views/external/gateway/index.vue

@@ -39,11 +39,10 @@
         />
       </div>
     </confirm-dialog>
-    <el-dialog
-      :visible.sync="showSubDialog"
-      custom-class="c-dialog medium"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       :title="subDialogTitle"
-      :close-on-click-modal="false"
       @closed="onCloseSubDialog"
     >
       <plc
@@ -54,7 +53,7 @@
         v-if="showSensor"
         :gateway="gateway"
       />
-    </el-dialog>
+    </c-dialog>
   </wrapper>
 </template>
 
@@ -94,7 +93,6 @@ export default {
           ] }
         ]
       },
-      showSubDialog: false,
       showPLC: false,
       showSensor: false
     }
@@ -171,14 +169,15 @@ export default {
     onEditPLC (gateway) {
       this.gateway = gateway
       this.showPLC = true
-      this.showSubDialog = true
+      this.$refs.dialog.show()
     },
     onEditSensor (gateway) {
       this.gateway = gateway
       this.showSensor = true
-      this.showSubDialog = true
+      this.$refs.dialog.show()
     },
     onCloseSubDialog () {
+      console.log('onCloseSubDialog')
       this.showPLC = false
       this.showSensor = false
     }

+ 5 - 7
src/views/platform/debug/index.vue

@@ -55,11 +55,10 @@
         <div>{{ message.desc }}</div>
       </div>
     </div>
-    <el-dialog
+    <c-dialog
+      ref="dialog"
+      size="medium"
       title="发送消息"
-      :visible.sync="mqtt.show"
-      custom-class="c-dialog medium"
-      :close-on-click-modal="false"
     >
       <div class="c-grid-form u-align-self--center">
         <span class="c-grid-form__label u-required">topic</span>
@@ -87,7 +86,7 @@
           发送
         </button>
       </template>
-    </el-dialog>
+    </c-dialog>
   </wrapper>
 </template>
 
@@ -111,7 +110,6 @@ export default {
       deviceMessage,
       device: 'all',
       mqtt: {
-        show: false,
         topic: '',
         message: '',
         encode: true
@@ -149,7 +147,6 @@ export default {
     publish () {
       const messageProxy = this.messageProxy
       this.mqtt = {
-        show: true,
         topic: messageProxy && messageProxy.productId ? `${messageProxy.productId}/${this.device}/` : '',
         message: JSON.stringify({
           messageId: `${this.device}_${Math.random().toString(16).slice(2)}`,
@@ -157,6 +154,7 @@ export default {
         }, null, 2),
         encode: true
       }
+      this.$refs.dialog.show()
     },
     send () {
       if (!this.mqtt.topic) {

+ 31 - 30
src/views/platform/tenant/device/settings/components/DatasetConfigDialog.vue

@@ -1,35 +1,37 @@
 <template>
-  <el-dialog
-    :visible.sync="dialogVisible"
-    custom-class="c-dialog medium"
+  <c-dialog
+    ref="dialog"
+    size="medium"
     :title="title"
   >
-    <div
-      v-if="isUnbound"
-      class="l-flex__fill l-flex--col center jcenter"
-    >
-      <button
-        class="o-button"
-        @click="onBind"
+    <template #default>
+      <div
+        v-if="isUnbound"
+        class="l-flex__fill l-flex--col center jcenter"
       >
-        绑定填充素材包
-      </button>
-    </div>
-    <schema-table
-      v-else
-      ref="table"
-      :schema="assetSchema"
-    />
-    <preview-dialog ref="previewDialog" />
-    <radio-table-dialog
-      ref="datasetDialog"
-      title="填充素材包"
-      message="请选择填充素材包"
-      :schema="schema"
-      append-to-body
-      @confirm="onBindDataset"
-    />
-  </el-dialog>
+        <button
+          class="o-button"
+          @click="onBind"
+        >
+          绑定填充素材包
+        </button>
+      </div>
+      <schema-table
+        v-else
+        ref="table"
+        :schema="assetSchema"
+      />
+      <preview-dialog ref="previewDialog" />
+      <radio-table-dialog
+        ref="datasetDialog"
+        title="填充素材包"
+        message="请选择填充素材包"
+        :schema="schema"
+        append-to-body
+        @confirm="onBindDataset"
+      />
+    </template>
+  </c-dialog>
 </template>
 
 <script>
@@ -51,7 +53,6 @@ export default {
   name: 'DatasetConfigDialog',
   data () {
     return {
-      dialogVisible: false,
       isUnbound: false,
       title: '绑定填充素材包',
       assetSchema: {
@@ -89,7 +90,7 @@ export default {
         this.isUnbound = !data
         this.dataset = data
         this.title = data ? data.name : '绑定填充素材包'
-        this.dialogVisible = true
+        this.$refs.dialog.show()
       }).finally(() => {
         this.$closeLoading(loading)
       })

+ 6 - 3
src/views/platform/tenant/device/settings/components/external/Camera/index.vue

@@ -58,7 +58,8 @@
     />
     <camera-dialog
       ref="cameraDialog"
-      @close="onClose"
+      @open="onOpen"
+      @closed="onClosed"
     />
   </div>
 </template>
@@ -137,10 +138,12 @@ export default {
       })
     },
     onFullScreen (camera) {
-      this.isActivated = false
       this.$refs.cameraDialog.show(camera)
     },
-    onClose () {
+    onOpen () {
+      this.isActivated = false
+    },
+    onClosed () {
       this.isActivated = true
     },
     onAdd (deviceType) {

+ 2 - 2
src/views/platform/tenant/device/settings/components/external/ReceivingCard/ReceivingCardTopology.vue

@@ -1,6 +1,6 @@
 <template>
   <div
-    class="l-card-grid"
+    class="c-receiving-card"
     :style="style"
   >
     <div
@@ -100,7 +100,7 @@ export default {
 </script>
 
 <style lang="scss" scoped>
-.l-card-grid {
+.c-receiving-card {
   display: grid;
   position: relative;
   overflow: auto;

+ 26 - 28
src/views/platform/tenant/device/settings/components/external/ReceivingCard/index.vue

@@ -98,18 +98,18 @@
             </div>
           </div>
         </div>
-        <el-dialog
-          :visible.sync="showTopology"
-          custom-class="c-dialog--detail"
+        <c-dialog
+          ref="topologyDialog"
+          size="lg"
           title="拓扑图"
-          :close-on-click-modal="false"
         >
-          <receiving-card-topology
-            v-if="showTopology"
-            class="l-flex__auto"
-            :info="info"
-          />
-        </el-dialog>
+          <template #default>
+            <receiving-card-topology
+              class="l-flex__auto"
+              :info="info"
+            />
+          </template>
+        </c-dialog>
       </template>
       <template v-else>
         <div class="l-flex__fill l-flex--row center">
@@ -195,22 +195,21 @@
             />
           </div>
         </confirm-dialog>
-        <el-dialog
-          class="c-progress"
-          :visible.sync="showProgress"
-          width="50%"
-          :close-on-click-modal="false"
-          :close-on-press-escape="false"
-          :show-close="false"
-        >
-          <el-progress
-            :percentage="progress"
-            :stroke-width="24"
-            text-inside
-            status="success"
-          />
-        </el-dialog>
       </template>
+      <el-dialog
+        :visible.sync="showProgress"
+        custom-class="c-dialog--transparent"
+        :close-on-click-modal="false"
+        :close-on-press-escape="false"
+      >
+        <el-progress
+          class="u-align-self--stretch"
+          :percentage="progress"
+          :stroke-width="24"
+          text-inside
+          status="success"
+        />
+      </el-dialog>
     </template>
   </div>
 </template>
@@ -248,8 +247,7 @@ export default {
       info: null,
       receivingCard: {},
       showProgress: false,
-      progress: 0,
-      showTopology: false
+      progress: 0
     }
   },
   created () {
@@ -412,7 +410,7 @@ export default {
       return updateReceivingCard(formData, options)
     },
     onView () {
-      this.showTopology = true
+      this.$refs.topologyDialog.show()
     }
   }
 }

+ 2 - 3
src/views/platform/upgrade/index.vue

@@ -96,14 +96,13 @@
       </div>
     </confirm-dialog>
     <el-dialog
-      class="c-progress"
       :visible.sync="showProgress"
-      width="50%"
+      custom-class="c-dialog--transparent"
       :close-on-click-modal="false"
       :close-on-press-escape="false"
-      :show-close="false"
     >
       <el-progress
+        class="u-align-self--stretch"
         :percentage="progress"
         :stroke-width="24"
         text-inside

+ 2 - 2
src/views/realm/assign/Device.vue

@@ -8,7 +8,6 @@
       size="lg"
       title="分配设备"
       :schema="deviceSchema"
-      @choosen="onChoosen"
     />
   </schema-table>
 </template>
@@ -56,6 +55,7 @@ export default {
     ...mapGetters(['tenant']),
     deviceSchema () {
       return {
+        listeners: { 'row-dblclick': this.onChoosen },
         condition: { name: '', tenant: this.tenant },
         list: getDevicesByAdmin,
         filters: [
@@ -85,7 +85,7 @@ export default {
     onAdd () {
       this.$refs.tableDialog.show()
     },
-    onChoosen ({ value: { id } }) {
+    onChoosen ({ id }) {
       bindDeviceToObject(id, this.group.path).then(() => {
         this.$message({
           type: 'success',

+ 5 - 6
src/views/realm/logger/index.vue

@@ -75,10 +75,10 @@
         </div>
       </template>
     </schema-table>
-    <el-dialog
+    <c-dialog
+      ref="dialog"
+      size="lg"
       title="操作日志详情"
-      :visible.sync="showDetail"
-      custom-class="c-dialog lg"
     >
       <div class="c-detail-grid">
         <div class="box title">操作者</div>
@@ -104,7 +104,7 @@
         <div class="box title">错误原因</div>
         <div class="box value fill">{{ log.errorMsg }}</div>
       </div>
-    </el-dialog>
+    </c-dialog>
   </wrapper>
 </template>
 
@@ -119,7 +119,6 @@ export default {
   name: 'Logger',
   data () {
     return {
-      showDetail: false,
       log: {},
       businessSelectSchema: {
         placeholder: '业务模块',
@@ -182,7 +181,7 @@ export default {
         data.status = data.status ? '成功' : '失败'
         data.requestMethod = ['GET', 'POST', 'PUT', 'DELETE'][data.requestMethod]
         this.log = data
-        this.showDetail = true
+        this.$refs.dialog.show()
       })
     },
     checkDateTime (type) {

+ 15 - 16
src/views/realm/user/Account.vue

@@ -67,19 +67,20 @@
         </div>
       </template>
     </confirm-dialog>
-    <el-dialog
-      :visible.sync="showSettings"
+    <c-dialog
+      ref="dialog"
+      size="medium"
       title="设置"
-      custom-class="c-dialog medium"
     >
-      <settings
-        v-if="showSettings"
-        :user="user"
-        :tenant="tenant"
-        @del="onDel"
-        @group="onGroupChange"
-      />
-    </el-dialog>
+      <template #default>
+        <settings
+          :user="user"
+          :tenant="tenant"
+          @del="onDel"
+          @group="onGroupChange"
+        />
+      </template>
+    </c-dialog>
   </schema-table>
 </template>
 
@@ -122,8 +123,7 @@ export default {
           ] }
         ]
       },
-      account: {},
-      showSettings: false
+      account: {}
     }
   },
   computed: {
@@ -138,7 +138,6 @@ export default {
   },
   watch: {
     group () {
-      this.showSettings = false
       this.$refs.table.pageTo(1)
     }
   },
@@ -163,14 +162,14 @@ export default {
     },
     onSettings (user) {
       this.user = user
-      this.showSettings = true
+      this.$refs.dialog.show()
     },
     onDel () {
       this.$message({
         type: 'success',
         message: '注销成功'
       })
-      this.showSettings = false
+      this.$refs.dialog.hide()
       this.$refs.table.decrease(1)
     },
     onGroupChange ({ path }) {

+ 74 - 77
src/views/screen/material/program/ast/Designer.vue

@@ -218,44 +218,44 @@
       @up="upLayer"
       @down="downLayer"
     />
-    <el-dialog
-      :visible.sync="showAssets"
+    <confirm-dialog
+      ref="sourcesDialog"
+      size="medium fixed"
       :title="assetDialogType"
-      custom-class="c-dialog medium fixed"
-      :close-on-click-modal="false"
-      @closed="onCloseAssetsDialog"
+      @confirm="onSaveAssets"
     >
-      <draggable
-        v-if="showAssets"
-        v-model="sources"
-        class="l-grid--info mini"
-        :class="{ dragging }"
-        animation="300"
-        @start="onSourceDragStart"
-        @end="onSourceDragEnd"
-      >
-        <media-card
-          v-for="(source, index) in sources"
-          :key="index"
-          class="o-card"
-          :source="source"
-          @click="onView"
+      <template #default>
+        <draggable
+          v-model="sources"
+          class="l-grid--info mini"
+          :class="{ dragging }"
+          animation="300"
+          @start="onSourceDragStart"
+          @end="onSourceDragEnd"
         >
-          <div
-            v-if="needTypeTag"
-            class="o-card__tag"
+          <media-card
+            v-for="(source, index) in sources"
+            :key="index"
+            class="o-card"
+            :source="source"
+            @click="onView"
           >
-            {{ source.typeTag }}
-          </div>
-          <i
-            class="o-card__icon el-icon-delete has-active"
-            @mousedown.stop
-            @pointerdown.stop
-            @click.stop="onDelAsset(index)"
-          />
-        </media-card>
-      </draggable>
-      <template #footer>
+            <div
+              v-if="needTypeTag"
+              class="o-card__tag"
+            >
+              {{ source.typeTag }}
+            </div>
+            <i
+              class="o-card__icon el-icon-delete has-active"
+              @mousedown.stop
+              @pointerdown.stop
+              @click.stop="onDelAsset(index)"
+            />
+          </media-card>
+        </draggable>
+      </template>
+      <template #footer="{ confirm, cancel }">
         <button
           class="c-sibling-item o-button"
           @click="onAddAssets"
@@ -264,33 +264,35 @@
         </button>
         <button
           class="c-sibling-item o-button"
-          @click="onSaveAssets"
+          @click="confirm"
         >
           确定
         </button>
         <button
           class="c-sibling-item o-button o-button--cancel"
-          @click="onCloseAssetsDialog"
+          @click="cancel"
         >
           取消
         </button>
       </template>
-    </el-dialog>
-    <el-dialog
-      :visible.sync="showServerAssets"
+    </confirm-dialog>
+    <c-dialog
+      ref="assetDialog"
+      size="lg"
       :title="assetDialogTitle"
-      custom-class="c-dialog lg"
       append-to-body
     >
-      <grid-table :schema="assetSchema">
-        <grid-table-item v-slot="item">
-          <media-card
-            :source="item"
-            @dblclick="onChoosenAsset"
-          />
-        </grid-table-item>
-      </grid-table>
-    </el-dialog>
+      <template #default>
+        <grid-table :schema="assetSchema">
+          <grid-table-item v-slot="item">
+            <media-card
+              :source="item"
+              @dblclick="onChoosenAsset"
+            />
+          </grid-table-item>
+        </grid-table>
+      </template>
+    </c-dialog>
     <confirm-dialog
       ref="assetsDialog"
       :title="assetDialogTitle"
@@ -354,7 +356,7 @@
     </confirm-dialog>
     <preview-dialog
       ref="previewDialog"
-      @closed="onClosePreview"
+      @closed="onClosedPreview"
     />
     <confirm-dialog
       ref="rich"
@@ -363,20 +365,22 @@
       append-to-body
       @confirm="onRichConfirm"
     >
-      <toolbar
-        style="border-bottom: 1px solid #ccc"
-        mode="simple"
-        :editor="editor"
-        :default-config="toolbarConfig"
-      />
-      <editor
-        v-model="richHtml"
-        mode="simple"
-        style="height: 500px; overflow: hidden;"
-        :default-config="editorConfig"
-        @onCreated="onEditorCreated"
-        @customPaste="onCustomPaste"
-      />
+      <template #default>
+        <toolbar
+          style="border-bottom: 1px solid #ccc"
+          mode="simple"
+          :editor="editor"
+          :default-config="toolbarConfig"
+        />
+        <editor
+          v-model="richHtml"
+          mode="simple"
+          style="height: 500px; overflow: hidden;"
+          :default-config="editorConfig"
+          @onCreated="onEditorCreated"
+          @customPaste="onCustomPaste"
+        />
+      </template>
     </confirm-dialog>
   </div>
 </template>
@@ -436,11 +440,9 @@ export default {
       visibleContentMenu: false,
       styleObj: null,
       widgetAttr: null,
-      showAssets: false,
       sources: null,
       dragging: false,
       dragScale: false,
-      showServerAssets: false,
       fileDir: null,
       editor: null,
       richHtml: '',
@@ -750,10 +752,10 @@ export default {
       switch (attr.type) {
         case 'data':
           if (attr.options && attr.options.solo) {
-            this.showServerAssets = true
+            this.$refs.assetDialog.show()
           } else {
             this.sources = this.widget[attr.key].map(this.transformDataToSource)
-            this.showAssets = true
+            this.$refs.sourcesDialog.show()
           }
           break
         case 'rich':
@@ -764,11 +766,6 @@ export default {
           break
       }
     },
-    onCloseAssetsDialog () {
-      this.widgetAttr = null
-      this.showAssets = false
-      this.showServerAssets = false
-    },
     transformAsset ({ tag, type, originalName, keyName, file, duration, size, md5 }) {
       const asset = {
         selected: false,
@@ -830,7 +827,7 @@ export default {
     },
     onChoosenAsset (asset) {
       this.changeAttr([this.transformToData(asset)])
-      this.onCloseAssetsDialog()
+      this.$refs.assetDialog.hide()
     },
     onAddAssets () {
       this.fileDir = null
@@ -869,9 +866,9 @@ export default {
     onDirBack () {
       this.fileDir = null
     },
-    onSaveAssets () {
+    onSaveAssets (done) {
+      done()
       this.changeAttr(this.sources.map(this.transformToData))
-      this.onCloseAssetsDialog()
     },
     onView ({ type, keyName, files }) {
       this.onViewAsset({ type: type || this.widgetAttr.options.type, url: keyName, files })
@@ -883,7 +880,7 @@ export default {
       }
       this.$refs.previewDialog.show(asset)
     },
-    onClosePreview () {
+    onClosedPreview () {
       this.muted = this.$muted
     },
     onDelAsset (index) {

+ 2 - 2
src/views/screen/material/program/ast/Viewer.vue

@@ -95,7 +95,7 @@
     </div>
     <preview-dialog
       ref="previewDialog"
-      @close="onClose"
+      @closed="onClosed"
     />
   </div>
 </template>
@@ -186,7 +186,7 @@ export default {
       }
       this.$refs.previewDialog.show(source)
     },
-    onClose () {
+    onClosed () {
       this.muted = this.$muted
     },
     checkRatio () {