Column.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. <script>
  2. import { getThumbnailUrl } from '@/api/asset'
  3. import { AssetType } from '@/constant'
  4. export default {
  5. name: 'SchemaTableColumn',
  6. inject: ['table'],
  7. props: {
  8. schema: {
  9. type: Object,
  10. required: true
  11. }
  12. },
  13. methods: {
  14. renderRefreshColumn (h, props) {
  15. const { render } = this.schema
  16. return h('el-table-column', {
  17. props: {
  18. width: 50,
  19. ...props
  20. },
  21. scopedSlots: {
  22. header: this.renderRefreshColumnHeader,
  23. default: render && function ({ store, row }) {
  24. return render(row, store.$createElement)
  25. }
  26. }
  27. })
  28. },
  29. renderRefreshColumnHeader () {
  30. return this.$createElement('i', {
  31. staticClass: 'o-refresh el-icon-refresh',
  32. on: { click: $event => {
  33. $event.stopPropagation()
  34. this.table.pageTo()
  35. } }
  36. })
  37. },
  38. renderExpandColumn (h, props) {
  39. const { render } = this.schema
  40. return h('el-table-column', {
  41. props: {
  42. type: 'expand',
  43. ...props
  44. },
  45. scopedSlots: {
  46. default ({ store, row }) {
  47. return render(row, store.$createElement)
  48. }
  49. }
  50. })
  51. },
  52. renderAssetColumn (h, props) {
  53. return h('el-table-column', {
  54. props: {
  55. 'class-name': 'c-thumbnail-col',
  56. label: '文件',
  57. align: 'center',
  58. width: 100,
  59. ...props
  60. },
  61. scopedSlots: {
  62. default: this.renderAsset
  63. }
  64. })
  65. },
  66. renderAsset ({ row: data }) {
  67. const value = this.getRenderValue(data)
  68. if (value) {
  69. const { on } = this.schema
  70. if (value.thumbnail) {
  71. return this.$createElement('auto-image', {
  72. staticClass: `o-thumbnail${on ? ' u-pointer' : ''}`,
  73. props: {
  74. src: getThumbnailUrl(value.thumbnail, '64,fit'),
  75. broken: value.type === AssetType.VIDEO ? 'video-broken' : 'image-broken'
  76. },
  77. nativeOn: on && { click: $event => {
  78. $event.stopPropagation()
  79. on(value, data)
  80. } }
  81. })
  82. }
  83. switch (value.type) {
  84. case AssetType.VIDEO:
  85. case AssetType.AUDIO:
  86. return this.$createElement('SvgIcon', {
  87. staticClass: `o-thumbnail${on ? ' u-pointer' : ''}`,
  88. props: {
  89. 'icon-class': value.type === AssetType.VIDEO
  90. ? value.thumbnail === ''
  91. ? 'video-broken'
  92. : 'video-thumb'
  93. : 'audio-thumb'
  94. },
  95. on: on && { click: $event => {
  96. $event.stopPropagation()
  97. on(value, data)
  98. } }
  99. })
  100. default:
  101. break
  102. }
  103. }
  104. return '-'
  105. },
  106. renderChildren (data) {
  107. const { type, render } = this.schema
  108. let children = null
  109. switch (type) {
  110. case 'tag':
  111. children = this.renderTags(data.row)
  112. break
  113. case 'invoke':
  114. children = this.renderInvokes(data)
  115. break
  116. default:
  117. children = render && render(data.row, this.$createElement)
  118. break
  119. }
  120. if (children && !Array.isArray(children)) {
  121. children = [children]
  122. }
  123. return children && children.length ? children : null
  124. },
  125. getRenderValue (data) {
  126. const { prop, render } = this.schema
  127. return render ? render(data) : data[prop]
  128. },
  129. renderTags (data) {
  130. const tags = this.getRenderValue(data)
  131. if (tags) {
  132. if (Array.isArray(tags)) {
  133. if (tags.length > 1) {
  134. return this.$createElement('div', {
  135. staticClass: 'c-tags'
  136. }, tags.map(tag => this.renderTag(tag, data)))
  137. }
  138. return tags.map(tag => this.renderTag(tag, data))
  139. }
  140. return this.renderTag(tags, data)
  141. }
  142. return '-'
  143. },
  144. renderTag (tag, data) {
  145. if (!tag) {
  146. return '-'
  147. }
  148. const { label, ...tagProps } = tag
  149. const { on } = this.schema
  150. return this.$createElement('el-tag', {
  151. staticClass: on ? 'o-tag u-pointer' : 'o-tag u-readonly',
  152. props: {
  153. size: 'medium',
  154. ...tagProps
  155. },
  156. on: on && { click: $event => {
  157. $event.stopPropagation()
  158. on(data, tag)
  159. } }
  160. }, label)
  161. },
  162. renderInvokes (data) {
  163. const { render, use } = this.schema
  164. const h = this.$createElement
  165. const invokes = Array.isArray(render) ? render : render(data.row)
  166. return (!use || use(data.row)) && invokes.filter(({ render }) => !render || render(data.row)).map(({ label, on }) => {
  167. return h('div', {
  168. staticClass: 'c-table__btn u-pointer',
  169. on: on && {
  170. click ($event) {
  171. $event.stopPropagation()
  172. on(data.row, data.$index)
  173. }
  174. }
  175. }, label)
  176. })
  177. }
  178. },
  179. render (h) {
  180. const { type, render, ...columnProps } = this.schema
  181. let defaultProps = null
  182. switch (type) {
  183. case 'refresh':
  184. return this.renderRefreshColumn(h, columnProps)
  185. case 'expand':
  186. return this.renderExpandColumn(h, columnProps)
  187. case 'asset':
  188. return this.renderAssetColumn(h, columnProps)
  189. case 'selection':
  190. return h('el-table-column', {
  191. props: {
  192. type,
  193. width: 50
  194. }
  195. })
  196. case 'tag':
  197. defaultProps = { label: '状态' }
  198. break
  199. case 'invoke':
  200. defaultProps = { label: '操作', align: render?.length > 1 ? 'right' : 'center', width: 120 }
  201. break
  202. default:
  203. defaultProps = { 'show-overflow-tooltip': true }
  204. break
  205. }
  206. return h('el-table-column', {
  207. props: {
  208. ...defaultProps,
  209. ...columnProps
  210. },
  211. scopedSlots: {
  212. default: type || render ? this.renderChildren : null
  213. }
  214. })
  215. }
  216. }
  217. </script>