import-panel.ts 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. import { CreateElement } from 'vue'
  2. import { VxeUI } from '../../../ui'
  3. import XEUtils from 'xe-utils'
  4. import { parseFile } from '../../../ui/src/utils'
  5. import { errLog } from '../../../ui/src/log'
  6. import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../../types'
  7. const { getI18n, getIcon, globalMixins, renderEmptyElement } = VxeUI
  8. export default {
  9. name: 'VxeTableImportPanel',
  10. mixins: [
  11. globalMixins.sizeMixin
  12. ],
  13. props: {
  14. defaultOptions: Object,
  15. storeData: Object
  16. },
  17. components: {
  18. // VxeModal,
  19. // VxeRadio
  20. },
  21. inject: {
  22. $xeTable: {
  23. default: null
  24. }
  25. },
  26. data () {
  27. return {
  28. loading: false
  29. }
  30. },
  31. computed: {
  32. selectName () {
  33. return `${this.storeData.filename}.${this.storeData.type}`
  34. },
  35. hasFile () {
  36. return this.storeData.file && this.storeData.type
  37. },
  38. parseTypeLabel () {
  39. const { storeData } = this
  40. const { type, typeList } = storeData
  41. if (type) {
  42. const selectItem = XEUtils.find(typeList, item => type === item.value)
  43. return selectItem ? selectItem.label : '*.*'
  44. }
  45. return `*.${typeList.map((item: any) => item.value).join(', *.')}`
  46. }
  47. } as any,
  48. created (this: any) {
  49. const $xeTableImportPanel = this
  50. const VxeUIModalComponent = VxeUI.getComponent('VxeModal')
  51. const VxeUIButtonComponent = VxeUI.getComponent('VxeButton')
  52. const VxeUISelectComponent = VxeUI.getComponent('VxeSelect')
  53. $xeTableImportPanel.$nextTick(() => {
  54. if (!VxeUIModalComponent) {
  55. errLog('vxe.error.reqComp', ['vxe-modal'])
  56. }
  57. if (!VxeUIButtonComponent) {
  58. errLog('vxe.error.reqComp', ['vxe-button'])
  59. }
  60. if (!VxeUISelectComponent) {
  61. errLog('vxe.error.reqComp', ['vxe-select'])
  62. }
  63. })
  64. },
  65. render (this: any, h: CreateElement) {
  66. const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
  67. const $xeGrid = $xeTable.$xeGrid
  68. const $xeGantt = $xeTable.$xeGantt
  69. const { hasFile, loading, parseTypeLabel, defaultOptions, storeData, selectName } = this
  70. const slots = defaultOptions.slots || {}
  71. const topSlot = slots.top
  72. const bottomSlot = slots.bottom
  73. const defaultSlot = slots.default
  74. const footerSlot = slots.footer
  75. return h('vxe-modal', {
  76. ref: 'modal',
  77. props: {
  78. id: 'VXE_IMPORT_MODAL',
  79. value: storeData.visible,
  80. title: getI18n('vxe.import.impTitle'),
  81. width: 540,
  82. minWidth: 360,
  83. minHeight: 240,
  84. mask: true,
  85. lockView: true,
  86. showFooter: true,
  87. escClosable: true,
  88. maskClosable: true,
  89. showMaximize: true,
  90. resize: true,
  91. loading
  92. },
  93. on: {
  94. input (value: any) {
  95. storeData.visible = value
  96. },
  97. show: this.showEvent
  98. },
  99. scopedSlots: {
  100. default: () => {
  101. const params = {
  102. $table: $xeTable,
  103. $grid: $xeGrid,
  104. $gantt: $xeGantt,
  105. options: defaultOptions,
  106. params: defaultOptions.params as any
  107. }
  108. return h('div', {
  109. class: 'vxe-table-export--panel'
  110. }, [
  111. topSlot
  112. ? h('div', {
  113. class: 'vxe-table-export--panel-top'
  114. }, $xeTable.callSlot(topSlot, params, h))
  115. : renderEmptyElement(this),
  116. h('div', {
  117. class: 'vxe-table-export--panel-body'
  118. }, defaultSlot
  119. ? $xeTable.callSlot(defaultSlot, params, h)
  120. : [
  121. h('table', {
  122. class: 'vxe-table-export--panel-table',
  123. attrs: {
  124. cellspacing: 0,
  125. cellpadding: 0,
  126. border: 0
  127. }
  128. }, [
  129. h('tbody', [
  130. h('tr', [
  131. h('td', getI18n('vxe.import.impFile')),
  132. h('td', [
  133. hasFile
  134. ? h('div', {
  135. class: 'vxe-table-export--selected--file',
  136. attrs: {
  137. title: selectName
  138. }
  139. }, [
  140. h('span', selectName),
  141. h('i', {
  142. class: getIcon().INPUT_CLEAR,
  143. on: {
  144. click: this.clearFileEvent
  145. }
  146. })
  147. ])
  148. : h('button', {
  149. ref: 'fileBtn',
  150. class: 'vxe-table-export--select--file',
  151. attrs: {
  152. type: 'button'
  153. },
  154. on: {
  155. click: this.selectFileEvent
  156. }
  157. }, getI18n('vxe.import.impSelect'))
  158. ])
  159. ]),
  160. h('tr', [
  161. h('td', getI18n('vxe.import.impType')),
  162. h('td', parseTypeLabel)
  163. ]),
  164. h('tr', [
  165. h('td', getI18n('vxe.import.impMode')),
  166. h('td', [
  167. h('vxe-select', {
  168. props: {
  169. value: defaultOptions.mode,
  170. options: storeData.modeList
  171. },
  172. on: {
  173. modelValue (value: any) {
  174. defaultOptions.mode = value
  175. }
  176. }
  177. })
  178. ])
  179. ])
  180. ])
  181. ])
  182. ]
  183. ),
  184. bottomSlot
  185. ? h('div', {
  186. class: 'vxe-table-export--panel-bottom'
  187. }, $xeTable.callSlot(bottomSlot, params, h))
  188. : renderEmptyElement(this)
  189. ])
  190. },
  191. footer: () => {
  192. const params = {
  193. $table: $xeTable,
  194. $grid: $xeGrid,
  195. $gantt: $xeGantt,
  196. options: defaultOptions,
  197. params: defaultOptions.params as any
  198. }
  199. return h('div', {
  200. class: 'vxe-table-export--panel-footer'
  201. }, footerSlot
  202. ? $xeTable.callSlot(footerSlot, params, h)
  203. : [
  204. h('div', {
  205. class: 'vxe-table-export--panel-btns'
  206. }, [
  207. h('vxe-button', {
  208. on: {
  209. click: this.cancelEvent
  210. }
  211. }, getI18n('vxe.import.impCancel')),
  212. h('vxe-button', {
  213. props: {
  214. status: 'primary',
  215. disabled: !hasFile || loading
  216. },
  217. on: {
  218. click: this.importEvent
  219. }
  220. }, getI18n('vxe.import.impConfirm'))
  221. ])
  222. ]
  223. )
  224. }
  225. }
  226. })
  227. },
  228. methods: {
  229. clearFileEvent () {
  230. Object.assign(this.storeData, {
  231. filename: '',
  232. sheetName: '',
  233. type: ''
  234. })
  235. },
  236. selectFileEvent () {
  237. const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
  238. $xeTable.readFile(this.defaultOptions).then((params: any) => {
  239. const { file } = params
  240. Object.assign(this.storeData, parseFile(file), { file })
  241. }).catch((e: any) => e)
  242. },
  243. showEvent () {
  244. this.$nextTick(() => {
  245. const { $refs } = this
  246. const targetElem = $refs.fileBtn
  247. if (targetElem) {
  248. targetElem.focus()
  249. }
  250. })
  251. },
  252. cancelEvent () {
  253. this.storeData.visible = false
  254. },
  255. importEvent () {
  256. const $xeTable = this.$parent as VxeTableConstructor & VxeTablePrivateMethods
  257. this.loading = true
  258. $xeTable.importByFile(this.storeData.file, Object.assign({}, $xeTable.importOpts, this.defaultOptions)).then(() => {
  259. this.loading = false
  260. this.storeData.visible = false
  261. }).catch(() => {
  262. this.loading = false
  263. })
  264. }
  265. } as any
  266. }