Browse Source

上传fix

bzkf3 2 years ago
parent
commit
8281c1fbd1
2 changed files with 208 additions and 2 deletions
  1. 181 1
      src/components/FileUpload/index.vue
  2. 27 1
      src/utils/request.ts

+ 181 - 1
src/components/FileUpload/index.vue

@@ -1,4 +1,4 @@
-<script setup lang="ts">
+<!-- <script setup lang="ts">
 import { ElMessage } from 'element-plus';
 import { ref, useAttrs, watch } from 'vue';
 import request from '~/utils/request';
@@ -157,5 +157,185 @@ watch(() => List_part.value, () => {
             <slot name="tip"></slot>
         </template>
     </el-upload>
+</template> -->
+
+<script setup>
+import { ElMessage } from 'element-plus';
+import { ref, useAttrs, watch } from 'vue';
+import { REQUEST } from '~/utils/request';
+
+const emit = defineEmits(['update:part', 'update:full', 'update:size', 'update:time', 'compile'])
+
+const props = defineProps({
+  part: String,
+  full: String,
+  // kb
+  sizeLimit: Number,
+  size: String,
+  time: String,
+})
+
+const attrs = useAttrs()
+
+const List_part = ref(props.part)
+const List_full = ref(props.full)
+// const List_size = ref(props.size ? parseFloat(props.size) : 0)
+const List_size = ref(0)
+const List_time = ref(props.time ?? (new Date().toLocaleString()))
+
+const FILE_LIST = ref([])
+
+if (List_part.value !== undefined && List_part.value !== '' && List_part.value !== null) {
+  FILE_LIST.value = List_part.value.split(';').map((part_url, idx) => ({
+    part_url,
+    url: window.GLOBAL_CONFIG.oss + part_url,
+    _status: 1,
+    uid: Date.now() - idx,
+    name: part_url.split('/').pop()
+  }))
+}
+if (List_full.value !== undefined && List_full.value !== '' && List_full.value !== null) {
+  FILE_LIST.value = List_full.value.split(';').map((item, idx) => {
+    const [part_url, name] = item.split('|')
+    return ({
+      part_url,
+      url: window.GLOBAL_CONFIG.oss + part_url,
+      _status: 1,
+      name,
+      uid: Date.now() - idx
+    })
+  })
+}
+// console.log('FILE_LIST :>> ', FILE_LIST.value);
+/**
+    * const STATUS_MAP = {
+    *   0: 'READY',
+    *   1: 'SUCCESS',
+    *   2: 'FAIL'
+    * }
+*/
+
+function beforeUpload(file) {
+  if (props.sizeLimit) {
+    const isLtSize = file.size / 1024 < props.sizeLimit;
+    if (!isLtSize) {
+      ElMessage.warning(`上传文件大小不能超过 ${props.sizeLimit}KB!`);
+    }
+    return isLtSize;
+  }
+}
+
+const percentage = ref(0)
+const httpRequest = ({ file }) => {
+  return REQUEST['upload']({
+    url: 'upload/main/file',
+    data: {
+      filedata: file
+    },
+    timeout: 1000 * 60,
+    onUploadProgress(progressEvent) {
+      percentage.value = ~~(progressEvent.loaded / progressEvent.total * 100 | 0)
+    },
+  })
+    .then(({ code, data }) => {
+      if (code === '1') {
+        const { url: part_url, file_name } = data
+        // console.log('file :>> ', file);
+        // console.log('FILE_LIST :>> ', FILE_LIST.value);
+        const target = FILE_LIST.value.find(({ uid }) => uid === file.uid);
+        if (target === undefined) {
+          throw new Error("file is not exist");
+        } else {
+          target._status = 1
+          target.url = window.GLOBAL_CONFIG.oss + part_url
+          target.part_url = part_url
+          target.name = file_name
+          handleSuccess()
+        }
+      } else {
+        return Promise.reject()
+      }
+    })
+}
+
+function handleSuccess() {
+  if (FILE_LIST.value.every(item => item._status === 1)) {
+    let part = [];
+    let full = [];
+    FILE_LIST.value.forEach(item => {
+      part.push(item.part_url);
+      full.push(`${item.part_url}|${item.name}`);
+      List_size.value += item.size ?? 0
+    })
+    List_full.value = full.join(';')
+    List_part.value = part.join(';')
+    List_time.value = (new Date().toLocaleString())
+  }
+}
+
+function onRemove(file, fileList) {
+  FILE_LIST.value = fileList
+  handleSuccess()
+}
+function onExceed() {
+  ElMessage.warning(`最多允许上传${attrs.limit}个文件`)
+}
+
+const dialogImageUrl = ref('')
+const dialogVisible = ref(false)
+const handlePictureCardPreview = (uploadFile) => {
+  if (['png', 'jpg', 'jpeg'].includes(uploadFile.url?.split('.').at(-1))) {
+    dialogImageUrl.value = uploadFile.url
+    dialogVisible.value = true
+  }
+}
+
+
+/// <summary>
+/// 格式化文件大小的JS方法
+/// </summary>
+/// <param name="filesize">文件的大小,传入的是一个bytes为单位的参数</param>
+/// <returns>格式化后的值</returns>
+function renderSize(filesize) {
+  // const unitArr = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
+  // const index = Math.floor(Math.log(filesize) / Math.log(1024));
+  // const size = (filesize / Math.pow(1024, index)).toFixed(2);
+  // return size + unitArr[index];
+  return (filesize / 1024).toString()
+}
+
+watch(() => List_part.value, () => {
+  emit('update:part', List_part.value)
+  emit('update:full', List_full.value)
+  emit('update:size', renderSize(List_size.value))
+  emit('update:time', List_time.value)
+  emit('compile')
+})
+</script>
+
+
+<template>
+  <!-- 这曾经是一个bug,要记住了 -->
+  <!-- :on-preview="handlePictureCardPreview" -->
+  <el-upload action="#" :http-request="httpRequest" :on-remove="onRemove" :on-exceed="onExceed"
+    :before-upload="beforeUpload" v-model:file-list="FILE_LIST" :on-preview="handlePictureCardPreview" v-bind="attrs"
+    class="w-full">
+    <template #default>
+      <slot>
+        <el-button type="primary">点击上传</el-button>
+      </slot>
+    </template>
+    <template #tip>
+      <slot name="tip"></slot>
+    </template>
+    <template #file>
+      <slot name="file"></slot>
+    </template>
+  </el-upload>
+
+  <el-dialog v-model="dialogVisible">
+    <img w-full :src="dialogImageUrl" alt="Preview Image" />
+  </el-dialog>
 </template>
 
+

+ 27 - 1
src/utils/request.ts

@@ -41,7 +41,7 @@ Request.interceptors.request.use(
       )
     } else {
       if (config.data instanceof FormData) {
-        // 
+        //
       } else {
         config.data = Object.assign(
           {
@@ -108,3 +108,29 @@ export function download(url: string, data?: object | null) {
 
 export default Request
 
+const obj2form = (data) => {
+  const formData = new FormData()
+  Object.keys(data).forEach(key => formData.append(key, data[key]))
+  return formData;
+}
+
+const _request = Request
+export const REQUEST = {
+  empty: axios,
+  default: _request,
+  import: (c) => _request({
+    timeout: 10 * 60 * 1000,
+    transformRequest: [obj2form],
+    ...c
+  }),
+  upload: (c) => _request({
+    timeout: 3 * 60 * 1000,
+    transformRequest: [obj2form],
+    ...c
+  }),
+  download: (c) => _request({
+    timeout: 1 * 60 * 1000,
+    method: 'get',
+    params: { token, limit: 10000, page: 1, api: 'xls', ...c }
+  })
+}