index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. <template>
  2. <div
  3. class="u-pointer"
  4. @click="open"
  5. >
  6. <i
  7. class="el-icon-upload u-color--blue u-font-size--2xl has-active"
  8. :class="{ breathe: uploading }"
  9. />
  10. <c-dialog
  11. ref="dialog"
  12. size="lg fixed"
  13. title="文件上传"
  14. append-to-body
  15. >
  16. <div class="l-flex__fill l-flex">
  17. <directory-tree
  18. class="c-sibling-item c-sidebar u-width--md"
  19. :option="directoryOption"
  20. editable
  21. @change="onDirectoryChanged"
  22. @refresh="onRefresh"
  23. />
  24. <div class="l-flex__fill l-flex--col c-sibling-item far">
  25. <div class="l-flex__none l-flex--row c-sibling-item--v">
  26. <div class="l-flex__fill" />
  27. <div class="l-flex--row c-sibling-item">
  28. <span class="c-sibling-item u-color--info">
  29. 目录
  30. </span>
  31. <div class="c-sibling-item el-input__inner u-width u-ellipsis">
  32. {{ directory }}
  33. </div>
  34. </div>
  35. <div class="l-flex--row c-sibling-item">
  36. <span class="c-sibling-item u-color--info">
  37. 类型
  38. </span>
  39. <schema-select
  40. v-model="tag"
  41. class="c-sibling-item u-width--xs"
  42. :schema="tagSelectSchema"
  43. />
  44. </div>
  45. <div class="l-flex--row c-sibling-item far">
  46. <span class="c-sibling-item u-color--info">
  47. 标签
  48. </span>
  49. <schema-select
  50. v-model="subTag"
  51. class="c-sibling-item u-width--xs"
  52. :schema="subTagSelectSchema"
  53. />
  54. </div>
  55. <div class="l-flex--row c-sibling-item far">
  56. <span class="c-sibling-item u-color--info">
  57. 转码
  58. </span>
  59. <el-switch
  60. v-model="videoTranscode"
  61. class="c-sibling-item"
  62. active-color="#13ce66"
  63. inactive-color="#ff4949"
  64. />
  65. </div>
  66. </div>
  67. <el-upload
  68. ref="upload"
  69. class="c-sibling-item--v o-upload"
  70. :class="{ 'l-flex__fill': !hasFile }"
  71. action="none"
  72. :accept="accept"
  73. :auto-upload="false"
  74. :show-file-list="false"
  75. :on-change="onChange"
  76. drag
  77. multiple
  78. >
  79. <div class="l-flex--row">
  80. <i class="c-sibling-item o-upload__icon el-icon-upload" />
  81. <span class="c-sibling-item near">
  82. 拖拽文件到此或
  83. </span>
  84. <span class="c-sibling-item near u-color--blue">
  85. 点击选择文件
  86. </span>
  87. </div>
  88. <div class="o-upload__accept">
  89. {{ accept }}
  90. </div>
  91. </el-upload>
  92. <file-progress
  93. v-if="hasFile"
  94. class="l-flex__auto c-sibling-item--v far"
  95. />
  96. </div>
  97. </div>
  98. </c-dialog>
  99. </div>
  100. </template>
  101. <script>
  102. import { mapGetters } from 'vuex'
  103. import {
  104. AssetTag,
  105. AssetTagInfo
  106. } from '@/constant'
  107. import { EventBus } from '@/utils'
  108. import {
  109. appendFile,
  110. addListener,
  111. removeListener,
  112. isUploading
  113. } from '@/utils/upload'
  114. import { getAssetSubTags } from '@/api/asset'
  115. import FileProgress from './FileProgress'
  116. export default {
  117. name: 'UploadDashboard',
  118. components: {
  119. FileProgress
  120. },
  121. data () {
  122. return {
  123. uploading: false,
  124. hasFile: false,
  125. tag: AssetTag.AD,
  126. subTag: '',
  127. videoTranscode: true,
  128. tagSelectSchema: { options: [
  129. { value: AssetTag.AD, label: AssetTagInfo[AssetTag.AD] },
  130. { value: AssetTag.PUBLICITY, label: AssetTagInfo[AssetTag.PUBLICITY] },
  131. { value: AssetTag.LOCAL_PUBLICITY, label: AssetTagInfo[AssetTag.LOCAL_PUBLICITY] },
  132. { value: AssetTag.SHIM, label: AssetTagInfo[AssetTag.SHIM] }
  133. ] },
  134. subTagSelectSchema: {
  135. remote: getAssetSubTags,
  136. placeholder: '暂不配置',
  137. value: 'id',
  138. label: 'name'
  139. },
  140. directoryOption: null,
  141. directoryInfo: null
  142. }
  143. },
  144. computed: {
  145. ...mapGetters(['org']),
  146. accept () {
  147. return '.png,.jpg,.jpeg,.gif,.mp4,audio/mpeg,.ppt,.pptx,application/pdf,.doc,.docx,.ts,.mpg,.wmv,.avi,.mov,.m4v'
  148. },
  149. directory () {
  150. return this.directoryInfo?.directory
  151. }
  152. },
  153. created () {
  154. addListener('change', this.check)
  155. EventBus.$on('upload', this.onShowByOption)
  156. },
  157. beforeDestroy () {
  158. removeListener('change', this.check)
  159. EventBus.$off('upload', this.onShowByOption)
  160. },
  161. methods: {
  162. onChange ({ raw }) {
  163. this.$refs.upload.clearFiles()
  164. const { org, directory, treeId } = this.directoryInfo
  165. appendFile(raw, {
  166. tag: this.tag,
  167. subtag: this.subTag,
  168. org,
  169. directory,
  170. treeId,
  171. videoTranscode: this.videoTranscode
  172. })
  173. },
  174. open () {
  175. this.$refs.dialog.show()
  176. },
  177. onShowByOption (option) {
  178. this.directoryOption = option
  179. this.open()
  180. },
  181. check (files) {
  182. this.uploading = isUploading()
  183. this.hasFile = files.length > 0
  184. },
  185. onDirectoryChanged (directory) {
  186. const { root, id, name, group } = directory
  187. this.directoryOption = directory
  188. this.directoryInfo = root
  189. ? { org: group.path, directory: `${group.name}-${name}` }
  190. : { org: group.path, directory: `${group.name}-${name}`, treeId: id }
  191. },
  192. onRefresh () {
  193. EventBus.$emit('directory-refresh', this.directoryOption)
  194. }
  195. }
  196. }
  197. </script>
  198. <style lang="scss" scoped>
  199. .breathe {
  200. animation: breathe 1s ease-in-out infinite alternate;
  201. }
  202. @keyframes breathe {
  203. 0% {
  204. text-shadow: 0 0 2px rgba($blue, 0.5);
  205. }
  206. 100% {
  207. text-shadow: 0 0 20px $blue;
  208. }
  209. }
  210. </style>