Parcourir la source

feat: the CMedia component support document (PPT, PDF, DOC)

Casper Dai il y a 3 ans
Parent
commit
b46d01cb7e

+ 10 - 0
src/components/service/EventPicker/index.vue

@@ -46,6 +46,7 @@
         popper-class="is-hide-now"
         :disabled="!eventOptions.start"
         placeholder="请选择失效时间"
+        :default-value="defaultEndDateTime"
         value-format="yyyy-MM-dd HH:mm:ss"
         :picker-options="endPickerOptions"
         @change="onDateTimeChange('until')"
@@ -232,6 +233,14 @@ export default {
         }
       }
       return null
+    },
+    defaultEndDateTime () {
+      if (this.eventOptions.start) {
+        const date = new Date(this.eventOptions.start)
+        date.setDate(date.getDate() + 1)
+        return `${parseTime(date, '{y}-{m}-{d}')} 00:00:00`
+      }
+      return null
     }
   },
   watch: {
@@ -290,6 +299,7 @@ export default {
     },
     onDateTimeChange (type) {
       const { start, until } = this.eventOptions
+      console.log(start, until)
       if (start && until && start > until) {
         if (type === 'start') {
           this.eventOptions.until = start

+ 8 - 2
src/components/table/GridTable/index.vue

@@ -31,7 +31,7 @@
           </div>
         </template>
       </div>
-      <template v-if="filters">
+      <template v-if="!custom && filters">
         <div
           v-for="filter in filters"
           :key="filter.key"
@@ -76,7 +76,7 @@
       :error="options.error"
       @click="onPagination"
     />
-    <template v-else>
+    <template v-else-if="!custom">
       <grid-table-body
         :data="tableData"
         :item-render="itemRender"
@@ -104,6 +104,12 @@ export default {
     GridTableBody
   },
   mixins: [tableMixin],
+  props: {
+    custom: {
+      type: [Boolean, String],
+      default: false
+    }
+  },
   data () {
     return {
       itemRender: null

+ 3 - 2
src/scss/bem/_component.scss

@@ -232,10 +232,11 @@
   min-height: 300px;
 
   &__header {
-    padding-bottom: $spacing;
+    margin-bottom: $spacing;
+    min-height: 40px;
 
     &:empty {
-      padding-bottom: 0;
+      margin-bottom: 0;
     }
   }
 

+ 105 - 16
src/views/bigscreen/ast/Designer.vue

@@ -303,7 +303,15 @@
         <grid-table
           ref="gridTable"
           :schema="assetSchema"
+          :custom="!!fileDir"
         >
+          <template #header>
+            <i
+              v-if="!!fileDir"
+              class="o-icon medium o-icon--back el-icon-arrow-left u-bold u-pointer"
+              @click="onDirBack"
+            />
+          </template>
           <grid-table-item v-slot="item">
             <media-card
               :source="item"
@@ -317,8 +325,33 @@
                 class="o-card__play el-icon-video-play has-active u-pointer"
                 @click.stop="onView(item)"
               />
+              <i
+                v-if="item.files"
+                class="o-card__grid el-icon-s-grid has-active u-pointer"
+                @click.stop="onChooseDir(item)"
+              />
             </media-card>
           </grid-table-item>
+          <div
+            v-if="fileDir"
+            class="l-flex__self l-grid u-overflow-y--auto"
+          >
+            <media-card
+              v-for="file in fileDir.files"
+              :key="file.keyName"
+              :source="file"
+              @click="onToggleGrid"
+            >
+              <el-checkbox
+                v-model="file.selected"
+                class="o-card__checkbox"
+              />
+              <i
+                class="o-card__play el-icon-video-play has-active u-pointer"
+                @click.stop="onView(file)"
+              />
+            </media-card>
+          </div>
         </grid-table>
       </template>
     </confirm-dialog>
@@ -382,7 +415,8 @@ export default {
       dragging: false,
       dragScale: false,
       showServerAssets: false,
-      showServerAssetsMulti: false
+      showServerAssetsMulti: false,
+      fileDir: null
     }
   },
   computed: {
@@ -438,7 +472,9 @@ export default {
         : ''
     },
     assetDialogTitle () {
-      return `请选择${this.assetDialogType}`
+      return this.fileDir
+        ? this.fileDir.name
+        : `请选择${this.assetDialogType}`
     },
     selectedWidgetId () {
       return this.widget?.id
@@ -483,6 +519,12 @@ export default {
           return '视频'
         case AssetType.AUDIO:
           return '音频'
+        case AssetType.PPT:
+          return 'PPT'
+        case AssetType.PDF:
+          return 'PDF'
+        case AssetType.DOC:
+          return 'DOC'
         default:
           return '媒资'
       }
@@ -665,7 +707,7 @@ export default {
       this.showAssets = false
       this.showServerAssets = false
     },
-    transformAsset ({ type, originalName, keyName, thumbnail, duration, size, md5 }) {
+    transformAsset ({ type, originalName, keyName, thumbnail, duration, size, md5, childrenData }) {
       const asset = {
         selected: false,
         type,
@@ -675,15 +717,33 @@ export default {
         md5,
         thumbnail
       }
-      if (type === AssetType.IMAGE) {
-        asset.duration = this.widget.interval
-      } else {
-        asset.duration = Number(duration) || 0
-      }
-      if (thumbnail) {
-        asset.thumb = getThumbnailUrl(thumbnail)
-      } else {
-        asset.icon = `${type === AssetType.VIDEO ? 'video' : 'audio'}-bg`
+      switch (type) {
+        case AssetType.IMAGE:
+          asset.duration = this.widget.interval
+          asset.thumb = getThumbnailUrl(thumbnail)
+          break
+        case AssetType.PPT:
+        case AssetType.PDF:
+        case AssetType.DOC:
+          asset.thumb = getThumbnailUrl(childrenData[0].keyName)
+          asset.files = (childrenData || []).map(({ type, keyName, size, md5 }, index) => {
+            return {
+              type, originalName, keyName, size, md5,
+              selected: false,
+              name: `第${index + 1}页`,
+              url: keyName,
+              thumb: getThumbnailUrl(keyName)
+            }
+          })
+          break
+        default:
+          asset.duration = Number(duration) || 0
+          if (thumbnail) {
+            asset.thumb = getThumbnailUrl(thumbnail)
+          } else {
+            asset.icon = `${type === AssetType.VIDEO ? 'video' : 'audio'}-bg`
+          }
+          break
       }
       return this.addTag(asset)
     },
@@ -732,26 +792,47 @@ export default {
       this.onCloseAssetsDialog()
     },
     onAddAssets () {
+      this.fileDir = null
       this.showServerAssetsMulti = true
       this.$refs.assetsDialog.show()
     },
     onToggleGrid (asset) {
       asset.selected = !asset.selected
     },
+    transformFileToAsset ({ type, originalName, name, keyName, thumb, size, md5 }) {
+      const asset = {
+        type, size, md5, keyName, thumb,
+        name: `${originalName}${name}`,
+        duration: this.widget.interval
+      }
+      this.addTag(asset)
+      return asset
+    },
     onChoosenAssets (done) {
-      const assets = this.$refs.gridTable.getData().filter(({ selected }) => selected)
+      const assets = this.fileDir
+        ? this.fileDir.files.filter(({ selected }) => selected).map(this.transformFileToAsset)
+        : this.$refs.gridTable.getData().filter(({ selected }) => selected).map(asset => asset.files?.map(this.transformFileToAsset) || asset)
       if (assets.length) {
-        this.sources = this.sources.concat(assets)
+        this.sources = this.sources.concat(...assets)
       }
       this.showServerAssetsMulti = false
       done()
     },
+    onChooseDir (fileDir) {
+      fileDir.files.forEach(file => {
+        file.selected = false
+      })
+      this.fileDir = fileDir
+    },
+    onDirBack () {
+      this.fileDir = null
+    },
     onSaveAssets () {
       this.changeAttr(this.sources.map(this.transformToData))
       this.onCloseAssetsDialog()
     },
-    onView ({ type, keyName }) {
-      this.onViewAsset({ type: type || this.widgetAttr.options.type, url: keyName })
+    onView ({ type, keyName, files }) {
+      this.onViewAsset({ type: type || this.widgetAttr.options.type, url: keyName, files })
     },
     onViewAsset (asset) {
       this.$muted = this.muted
@@ -1137,6 +1218,14 @@ $border: #242835;
     background-color: rgba(#000, 0.4);
     transform: translate(-50%, -50%);
   }
+
+  &__grid {
+    position: absolute;
+    top: 10px;
+    right: 10px;
+    font-size: 18px;
+    z-index: 9;
+  }
 }
 
 .o-scale-slider {

+ 7 - 1
src/views/bigscreen/ast/core/config-json/media.js

@@ -61,7 +61,13 @@ export default {
           label: '媒资',
           type: 'data',
           options: {
-            type: [AssetType.IMAGE, AssetType.VIDEO]
+            type: [
+              AssetType.IMAGE,
+              AssetType.VIDEO,
+              AssetType.PPT,
+              AssetType.PDF,
+              AssetType.DOC
+            ]
           }
         }
       ]