index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <script setup>
  2. import { ElMessage } from 'element-plus';
  3. import { ref, useAttrs, watch } from 'vue';
  4. // import { REQUEST } from '~/utils/request';
  5. import { getFullUrl, getPartUrl } from '~/utils/helper';
  6. import user from '~/store/user';
  7. const token = user.token
  8. const action = window.GLOBAL_CONFIG.api + '/upload/main/file'
  9. const data = { token, client: 'web', api: 'json', issubmit: '1', site: 'tyyx' }
  10. const emit = defineEmits(['update:part', 'update:full', 'update:size', 'update:time', 'compile', 'update:list'])
  11. const props = defineProps({
  12. part: String,
  13. full: String,
  14. list: Array,
  15. // kb
  16. sizeLimit: Number,
  17. size: String,
  18. time: String,
  19. sizeLimitMsg: String
  20. })
  21. const attrs = useAttrs()
  22. const List_part = ref(props.part)
  23. const List_full = ref(props.full)
  24. // const List_size = ref(props.size ? parseFloat(props.size) : 0)
  25. const List_size = ref(0)
  26. const List_time = ref(props.time ?? (new Date().toLocaleString()))
  27. const FILE_LIST = ref([])
  28. function init() {
  29. if (List_part.value !== undefined && List_part.value !== '' && List_part.value !== null) {
  30. FILE_LIST.value = List_part.value.split(';').map((part_url, idx) => ({
  31. part_url: getPartUrl(part_url),
  32. url: getFullUrl(part_url),
  33. // _status: 1,
  34. // uid: Date.now() - idx,
  35. name: part_url.split('/').pop()
  36. }))
  37. }
  38. if (List_full.value !== undefined && List_full.value !== '' && List_full.value !== null) {
  39. FILE_LIST.value = List_full.value.split(';').map((item, idx) => {
  40. const [part_url, name] = item.split('|')
  41. return ({
  42. part_url: getPartUrl(part_url),
  43. url: getFullUrl(part_url),
  44. // _status: 1,
  45. name,
  46. // uid: Date.now() - idx
  47. })
  48. })
  49. }
  50. console.log('* init :>> ', FILE_LIST.value);
  51. }
  52. init()
  53. watch(() => [props.part, props.full], (n, o) => {
  54. List_part.value = (props.part)
  55. List_full.value = (props.full)
  56. init()
  57. })
  58. /**
  59. * const STATUS_MAP = {
  60. * 0: 'READY',
  61. * 1: 'SUCCESS',
  62. * 2: 'FAIL'
  63. * }
  64. */
  65. function beforeUpload(file) {
  66. console.log('file : ', file)
  67. if (props.sizeLimit) {
  68. const isLtSize = file.size / 1024 < props.sizeLimit;
  69. // console.log('isLtSize : ', isLtSize, !isLtSize)
  70. if (!isLtSize) {
  71. console.log('1 : ')
  72. const msg = (props.sizeLimitMsg ? `上传文件大小不能超过 ${props.sizeLimitMsg}!` : `上传文件大小不能超过 ${props.sizeLimit}'KB'!`)
  73. ElMessage.warning(msg);
  74. }
  75. return isLtSize;
  76. }
  77. }
  78. function handleSuccess() {
  79. console.log('handleSuccess :>> ', FILE_LIST.value.map(e => e.status), FILE_LIST.value);
  80. if (FILE_LIST.value.every(item => item.status === "success")) {
  81. let part = [];
  82. let full = [];
  83. FILE_LIST.value.forEach(item => {
  84. if (item.percentage === 100) {
  85. const { url: part_url, file_name } = item.response.data
  86. part.push(part_url);
  87. full.push(`${part_url}|${file_name}`);
  88. List_size.value += item.size ?? 0
  89. } else {
  90. part.push(item.part_url);
  91. full.push(`${item.part_url}|${item.name}`);
  92. List_size.value += item.size ?? 0
  93. }
  94. })
  95. emit('update:list', part)
  96. List_full.value = full.join(';')
  97. List_part.value = part.join(';')
  98. List_time.value = (new Date().toLocaleString())
  99. }
  100. }
  101. function onRemove(file, fileList) {
  102. FILE_LIST.value = fileList
  103. handleSuccess()
  104. }
  105. function onExceed() {
  106. ElMessage.warning(`最多允许上传${attrs.limit}个文件`)
  107. }
  108. const dialogImageUrl = ref('')
  109. const dialogVisible = ref(false)
  110. const handlePictureCardPreview = (uploadFile) => {
  111. if (['png', 'jpg', 'jpeg'].includes(uploadFile.url?.split('.').at(-1))) {
  112. dialogImageUrl.value = uploadFile.url
  113. dialogVisible.value = true
  114. }
  115. }
  116. /// <summary>
  117. /// 格式化文件大小的JS方法
  118. /// </summary>
  119. /// <param name="filesize">文件的大小,传入的是一个bytes为单位的参数</param>
  120. /// <returns>格式化后的值</returns>
  121. function renderSize(filesize) {
  122. // const unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
  123. // const index = Math.floor(Math.log(filesize) / Math.log(1024));
  124. // const size = (filesize / Math.pow(1024, index)).toFixed(2);
  125. // return size + unitArr[index];
  126. return (filesize / 1024).toString()
  127. }
  128. watch(() => List_part.value, () => {
  129. emit('update:part', List_part.value)
  130. emit('update:full', List_full.value)
  131. emit('update:size', renderSize(List_size.value))
  132. emit('update:time', List_time.value)
  133. emit('compile', FILE_LIST.value)
  134. console.log('compile');
  135. })
  136. function handleRequest(args) {
  137. // console.log('handleRequest', args)
  138. REQUEST.upload({
  139. url: args.action,
  140. data: {
  141. ...args.data,
  142. [args.filename]: args.file,
  143. },
  144. // onUploadProgress: () => {
  145. // // console.log('progressEvent : ', progressEvent)
  146. // // const percentage = (progressEvent.loaded / progressEvent.total) * 100
  147. // // args.onProgress({ percentage }, args.file, args.fileList)
  148. // },
  149. }).then((res) => {
  150. console.log('res', res)
  151. if (res.code === '1')
  152. args?.onSuccess(res, args.file, args.fileList)
  153. else
  154. args?.onError(res, args.file, args.fileList)
  155. })
  156. }
  157. </script>
  158. <template>
  159. <!-- :on-preview="handlePictureCardPreview" -->
  160. <el-upload :action="action" :data="data" name="filedata" :on-success="handleSuccess" :on-remove="onRemove"
  161. :on-exceed="onExceed" :before-upload="beforeUpload" v-model:file-list="FILE_LIST"
  162. :on-preview="handlePictureCardPreview" v-bind="attrs" class="w-full" :http-request="handleRequest" >
  163. <template #default>
  164. <slot>
  165. <el-button type="primary">点击上传</el-button>
  166. </slot>
  167. </template>
  168. <template #tip>
  169. <slot name="tip"></slot>
  170. </template>
  171. <template #file>
  172. <slot name="file"></slot>
  173. </template>
  174. </el-upload>
  175. <el-dialog v-model="dialogVisible">
  176. <img w-full :src="dialogImageUrl" alt="Preview Image" />
  177. </el-dialog>
  178. </template>