| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- <template>
- <div class="l-flex--col">
- <div class="c-sibling-item--v has-bottom-padding--sm has-bottom-border">
- <div class="c-sibling-item--v u-bold">
- <span class="c-sibling-item u-font-size--sm">上播内容</span>
- <i
- v-if="isAssets"
- class="c-sibling-item el-icon-edit u-color--blue u-pointer"
- @click="onEditAssets"
- />
- </div>
- <div
- v-if="!simple"
- class="l-flex--row c-sibling-item--v near"
- >
- <el-select
- v-model="currentTarget.type"
- class="c-sibling-item"
- @change="onChangeTargetType"
- >
- <el-option
- v-for="option in eventTypeOptions"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- <div
- v-if="isAssets"
- class="c-sibling-item o-button"
- @click="onImportDataset"
- >
- 导入
- </div>
- <div
- class="l-flex--row c-sibling-item far has-active u-ellipsis"
- @click="onViewCurrentTarget"
- >
- {{ targetInfo }}
- </div>
- </div>
- </div>
- <template v-if="isAssets">
- <draggable
- v-if="currentTarget.assets.length"
- v-model="currentTarget.assets"
- class="l-flex__fill c-sibling-item--v u-overflow-y--auto"
- handle=".mover"
- animation="300"
- >
- <draggable-item
- v-for="(asset, index) in currentTarget.assets"
- :key="asset.key"
- :item="asset"
- :hide-duration="hideDuration"
- @view="onViewAsset"
- @del="onDelAsset(index)"
- />
- </draggable>
- <el-empty
- v-else
- class="l-flex__fill l-flex--row center"
- description="请添加素材"
- />
- </template>
- <schema-table
- v-else
- :key="currentTarget.type"
- class="c-sibling-item--v"
- :schema="schema"
- row-key="id"
- :current-row-key="selectedId"
- highlight-current-row
- @row-click="onClickRow"
- />
- <confirm-dialog
- ref="assetTableDialog"
- title="上播内容"
- size="xl fixed"
- append-to-body
- @confirm="onSaveAssets"
- >
- <c-transfer
- class="l-flex__auto"
- :source-schema="assetTableSchema"
- :add="onAddAssets"
- >
- <el-empty
- v-if="!selectionAssets.length"
- class="l-flex__auto l-flex--row center"
- description="请添加素材"
- />
- <draggable
- v-else
- v-model="selectionAssets"
- class="l-flex__auto l-flex--col u-font-size--sm u-overflow-y--auto"
- handle=".mover"
- animation="300"
- >
- <draggable-item
- v-for="(asset, index) in selectionAssets"
- :key="asset.key"
- :item="asset"
- @view="onViewAsset"
- @del="onDelSelectionAsset(index)"
- />
- </draggable>
- </c-transfer>
- </confirm-dialog>
- <radio-table-dialog
- ref="datasetDialog"
- title="素材包"
- message="请选择素材包"
- :schema="datasetSchema"
- append-to-body
- @confirm="onChoosenDataset"
- />
- <table-dialog
- ref="contentDialog"
- title="素材包"
- :schema="contentSchema"
- append-to-body
- />
- <preview-dialog ref="previewDialog" />
- <material-dialog ref="materialDialog" />
- </div>
- </template>
- <script>
- import {
- State,
- ScheduleType,
- EventTarget,
- EventTargetInfo,
- AssetTagInfo,
- AssetType,
- AssetTypeInfo,
- Dataset
- } from '@/constant'
- import {
- parseDuration,
- getAssetThumb,
- getAssetDuration
- } from '@/utils'
- import { getRatios } from '@/api/device'
- import {
- getDatasets,
- getCommonDataset
- } from '@/api/asset'
- import { getSchedules } from '@/api/calendar'
- import { getPrograms } from '@/api/program'
- import { assetTableMixin } from '@/mixins/asset-table'
- import Draggable from 'vuedraggable'
- export default {
- name: 'EventTargetPicker',
- components: {
- Draggable
- },
- mixins: [assetTableMixin],
- props: {
- eventTarget: {
- type: Object,
- default: null
- },
- simple: {
- type: [Boolean, String],
- default: false
- },
- ratio: {
- type: String,
- default: ''
- }
- },
- data () {
- return {
- eventTypeOptions: [
- { value: EventTarget.PROGRAM, label: EventTargetInfo[EventTarget.PROGRAM] },
- { value: EventTarget.RECUR, label: EventTargetInfo[EventTarget.RECUR] },
- { value: EventTarget.ASSETS, label: EventTargetInfo[EventTarget.ASSETS] }
- ],
- currentTarget: null,
- selectionAssets: [],
- datasetSchema: {
- list: getDatasets,
- condition: { type: Dataset.COMMON },
- cols: [
- { prop: 'name', label: '名称', 'align': 'center' },
- { type: 'invoke', render: [
- { label: '查看', on: this.onViewDataset }
- ] }
- ]
- },
- contentSchema: {
- singlePage: true,
- list: this.getAssets,
- cols: [
- { prop: 'tagInfo', label: '类型', align: 'center', width: 80 },
- { prop: 'typeName', label: '文件', align: 'center', width: 80 },
- { prop: 'file', label: '', type: 'asset', on: this.onViewAsset },
- { prop: 'name', label: '' },
- { prop: 'duration', label: '上播时长', 'align': 'center', width: 100 },
- { type: 'invoke', render: [
- { label: '查看', on: this.onViewAsset }
- ] }
- ]
- }
- }
- },
- computed: {
- isAssets () {
- return this.currentTarget?.type === EventTarget.ASSETS
- },
- hideDuration () {
- return this.isAssets && this.currentTarget.assets.length <= 1
- },
- selectedId () {
- return this.currentTarget?.detail?.id
- },
- targetInfo () {
- if (this.isAssets) {
- return ''
- }
- return this.currentTarget?.detail
- ? this.currentTarget.detail.name || '未知'
- : ''
- },
- schema () {
- if (!this.currentTarget) {
- return {}
- }
- const { type } = this.currentTarget
- return {
- list: this.getListInvoke,
- condition: { resolutionRatio: this.ratio, name: '' },
- filters: [
- { key: 'resolutionRatio', type: 'select', placeholder: '分辨率', remote: getRatios },
- { key: 'name', type: 'search', placeholder: '名称' }
- ],
- cols: [
- { render: ({ id }, h) => h(
- 'span',
- { staticClass: `el-radio__input ${id === this.selectedId ? 'is-checked' : ''}` },
- [h('span', { staticClass: 'el-radio__inner' })]
- ), width: 60, align: 'center' },
- type === EventTarget.PROGRAM
- ? { label: '缩略图', type: 'asset', render ({ img }) {
- return img
- ? { thumb: img }
- : null
- }, on: this.onView }
- : null,
- { prop: 'name', label: '名称' },
- { prop: 'resolutionRatio', label: '分辨率' },
- { type: 'invoke', render: [
- { label: '查看', on: this.onView }
- ] }
- ]
- }
- }
- },
- watch: {
- eventTarget: {
- handler () {
- this.init()
- },
- immediate: true
- }
- },
- methods: {
- init () {
- const target = this.eventTarget
- switch (target?.type) {
- case EventTarget.PROGRAM:
- case EventTarget.RECUR:
- this.currentTarget = {
- type: target.type,
- detail: target,
- assets: []
- }
- break
- case EventTarget.ASSETS:
- this.currentTarget = {
- type: target.type,
- detail: null,
- assets: (target.sources || []).map(asset => {
- return {
- info: `${AssetTagInfo[asset.tag]} ${AssetTypeInfo[asset.type]}`,
- ...asset
- }
- })
- }
- break
- default:
- this.currentTarget = {
- type: EventTarget.PROGRAM,
- detail: null,
- assets: []
- }
- break
- }
- },
- onChangeTargetType () {
- this.currentTarget.detail = null
- this.currentTarget.assets = []
- },
- getListInvoke (params) {
- switch (this.currentTarget.type) {
- case EventTarget.RECUR:
- return getSchedules({
- type: ScheduleType.RECUR,
- status: State.AVAILABLE,
- ...params
- })
- default:
- return getPrograms({
- status: State.AVAILABLE,
- ...params
- })
- }
- },
- onView ({ id }) {
- switch (this.currentTarget.type) {
- case EventTarget.PROGRAM:
- this.$refs.materialDialog.showProgram(id)
- break
- case EventTarget.RECUR:
- this.$refs.materialDialog.showSchedule(id)
- break
- default:
- break
- }
- },
- onViewCurrentTarget () {
- this.onView(this.currentTarget.detail)
- },
- onClickRow (row) {
- this.currentTarget.detail = row
- },
- onEditAssets () {
- this.selectionAssets = this.currentTarget.assets.map(asset => {
- return {
- ...asset
- }
- })
- this.$refs.assetTableDialog.show()
- },
- onDelSelectionAsset (index) {
- this.selectionAssets.splice(index, 1)
- },
- onAddAssets (value) {
- value.forEach(item => {
- const { tag, type, keyName, originalName, size, md5, file } = item
- this.selectionAssets.push({
- key: `${Date.now()}_${Math.random().toString(16).slice(2)}`,
- tag,
- type,
- keyName,
- size,
- md5,
- info: `${AssetTagInfo[tag]} ${AssetTypeInfo[type]}`,
- name: originalName,
- duration: getAssetDuration(item),
- disabled: type === AssetType.VIDEO,
- file
- })
- })
- return Promise.resolve()
- },
- onSaveAssets (done) {
- this.currentTarget.assets = this.selectionAssets.map(asset => {
- return {
- ...asset
- }
- })
- done()
- },
- onImportDataset () {
- this.$datasetAssets = null
- this.$refs.datasetDialog.show()
- },
- onViewDataset ({ id }) {
- this.$datasetId = id
- this.$datasetAssets = null
- this.$refs.contentDialog.show()
- },
- getAssets () {
- if (this.$datasetAssets) {
- return Promise.resolve({ data: this.$datasetAssets })
- }
- return getCommonDataset(this.$datasetId).then(({ data: { mediaList } }) => {
- this.$datasetAssets = mediaList.map(this.transformDatasetAsset)
- return {
- data: this.$datasetAssets
- }
- })
- },
- transformDatasetAsset (asset) {
- asset.tagInfo = AssetTagInfo[asset.tag]
- asset.typeName = AssetTypeInfo[asset.type]
- asset.file = {
- type: asset.type,
- url: asset.keyName,
- thumb: asset.minioData ? getAssetThumb(asset.minioData) : null
- }
- asset.name = asset.minioData?.originalName || '素材已删除'
- asset.duration = parseDuration(asset.adDuration)
- return asset
- },
- onChoosenDataset ({ value, done }) {
- if (this.$datasetId !== value.id) {
- this.$datasetId = value.id
- this.$datasetAssets = null
- }
- this.getAssets().then(({ data }) => {
- data.forEach(item => {
- const { tag, type, keyName, adDuration, name, file, minioData } = item
- if (minioData) {
- this.currentTarget.assets.push({
- key: `${Date.now()}_${Math.random().toString(16).slice(2)}`,
- tag,
- type,
- keyName,
- size: minioData.size,
- md5: minioData.md5,
- info: `${AssetTagInfo[tag]} ${AssetTypeInfo[type]}`,
- name,
- duration: adDuration,
- disabled: type === AssetType.VIDEO,
- file
- })
- }
- })
- done()
- })
- },
- onDelAsset (index) {
- this.currentTarget.assets.splice(index, 1)
- },
- createEventTarget () {
- if (this.isAssets ? !this.currentTarget.assets.length : !this.selectedId) {
- this.$message({
- type: 'warning',
- message: '请选择上播内容'
- })
- return null
- }
- const { type, detail, assets } = this.currentTarget
- return type === EventTarget.PROGRAM
- ? {
- type,
- id: detail.id,
- name: detail.name,
- programUrl: `${detail.buckets}/${detail.itemConfigName}`
- }
- : type === EventTarget.RECUR
- ? {
- type,
- id: detail.id,
- name: detail.name
- }
- : {
- type,
- sources: assets.map(({ tag, type, name, keyName, duration, size, md5 }) => {
- return { tag, type, name, keyName, duration, size, md5 }
- })
- }
- },
- getSnapshot () {
- return this.currentTarget
- },
- getValue () {
- const eventTarget = this.createEventTarget()
- if (eventTarget && !this.isAssets && (!this.ratio || this.ratio !== this.currentTarget.detail.resolutionRatio)) {
- eventTarget.adaptive = 1
- }
- return eventTarget
- }
- }
- }
- </script>
|