Quellcode durchsuchen

文件上传,进度

zhengnaiwen_citu vor 6 Monaten
Ursprung
Commit
cca7331137

+ 4 - 4
src/api/salary.js

@@ -102,13 +102,13 @@ export function saveSolution (data) {
 }
 
 // 绩效计算 模板
-export function getSalaryCalculateTemplate () {
-  return http.get('/performance/file/tmplate/lists')
+export function getSalaryCalculateTemplate (data) {
+  return http.get('/performance/file/tmplate/lists', data)
 }
 
 // 绩效计算 绩效文件上传(批量)
-export function uploadSalaryCalculateFiles (data) {
-  return http.upload('/performance/file/upload', data)
+export function uploadSalaryCalculateFiles (data, options) {
+  return http.upload('/performance/file/upload', data, options)
 }
 
 // 绩效计算 绩效文件上传历史

+ 258 - 0
src/components/DataUpload/index.vue

@@ -0,0 +1,258 @@
+<template>
+  <div>
+    <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch"></m-search>
+    <m-table
+      :card-title="$attrs.label"
+      :headers="headers"
+      :items="items"
+      v-loading="loading"
+    >
+      <template #card-tools>
+        <m-button size="small" type="orange" icon="el-icon-finished" :loading="submitLoading" @click="onSave">提交待上传文件</m-button>
+      </template>
+      <template #month>
+        {{ queryValues.month }}
+      </template>
+      <template #file="{ row }">
+        {{ filesValues[row.fileType]?.name }}
+        <el-progress
+          v-if="uploadProgress[row.fileType] !== undefined"
+          :percentage="uploadProgress[row.fileType]"
+          :status="uploadProgress[row.fileType] === 100 ? 'success' : undefined"
+          :stroke-width="12"
+          style="width: 150px; margin-top: 5px;"
+        />
+      </template>
+      <template #actions="{ row, $index }">
+        <div class="d-flex">
+          <el-upload
+            class="mr-3"
+            action="#"
+            :limit="1"
+            accept=".xlsx,.xls"
+            :ref="`upload-${$index}`"
+            :on-progress="(event, file) => onProgress(event, file, row.fileType)"
+            :show-file-list="false"
+            :on-exceed="(files, fileList) => onExceed(files, fileList, row.fileType)"
+            :http-request="e => onImport(e, row.fileType)"
+            :on-remove="() => onRemove(row.fileType)"
+          >
+            <m-button slot="trigger" text type="primary">导入文件</m-button>
+          </el-upload>
+          <m-button text type="danger" v-show="filesValues[row.fileType]" @click="onDelete(row)">移除临时文件</m-button>
+        </div>
+      </template>
+    </m-table>
+  </div>
+</template>
+
+<script>
+import {
+  getSalaryCalculateTemplate,
+  uploadSalaryCalculateFiles,
+  getSalaryCalculateFiles
+} from '@/api/salary'
+import { dateFormat } from '@/utils/date'
+export default {
+  name: 'DataUpload',
+  props: {
+    category: String
+  },
+  data () {
+    return {
+      searchValues: {
+        month: dateFormat('YYYY-mm', new Date())
+      },
+      queryValues: {},
+      filesValues: {},
+      uploadProgress: {}, // 存储每个文件的上传进度
+      categoryItems: [],
+      historyItems: [],
+      formItems: [],
+      headers: [
+        { label: '月份', prop: 'month', width: 100 },
+        { label: '文件类型', prop: 'fileName' },
+        { label: '已上传文件', prop: 'history' },
+        { label: '待上传文件', prop: 'file' },
+        { label: '操作', prop: 'actions' }
+      ],
+      loading: false,
+      submitLoading: false,
+      runLoading: false
+      // categoryType: null
+    }
+  },
+  computed: {
+    items () {
+      const items = this.categoryItems.reduce((res, v) => {
+        return res.concat(v.files)
+      }, [])
+      if (!items) {
+        return []
+      }
+      return items.map(e => {
+        return {
+          ...e,
+          history: this.historyItems.find(h => h.fileType === e.fileType)?.fileOriginalFilename
+        }
+      })
+    },
+    searchItems () {
+      return [
+        {
+          label: '月份',
+          prop: 'month',
+          type: 'datePicker',
+          options: {
+            clearable: false,
+            type: 'month',
+            format: 'yyyy-MM',
+            valueFormat: 'yyyy-MM',
+            placeholder: '选择更新月份'
+          }
+        }
+      ]
+    }
+  },
+  created () {
+    this.onInit()
+  },
+  methods: {
+    async onInit () {
+      try {
+        const { data } = await getSalaryCalculateTemplate({
+          category: this.category
+        })
+        this.categoryItems = data
+        if (!data.length) {
+          return
+        }
+        // this.categoryType = data[0].category
+        this.queryValues = { ...this.searchValues }
+        this.filesValues = {
+          ...this.items.reduce((res, v) => {
+            res[v.fileType] = null
+            return res
+          }, {})
+        }
+        this.uploadProgress = {}
+        this.onGetHistory()
+      } catch (error) {
+        this.$message.error(error)
+      }
+    },
+    async onGetHistory () {
+      try {
+        this.loading = true
+        const { data } = await getSalaryCalculateFiles({
+          ...this.queryValues,
+          category: this.category
+        })
+        this.historyItems = data
+      } catch (error) {
+        this.$message.error(error)
+      } finally {
+        this.loading = false
+      }
+    },
+    onSearch (query) {
+      this.queryValues = { ...this.searchValues }
+      this.onInit()
+    },
+    onExceed (files, fileList, key) {
+      this.filesValues[key] = files[0]
+    },
+    onImport (e, key) {
+      console.log(e, key)
+      this.filesValues[key] = e.file
+      this.$set(this.uploadProgress, key, 0) // 初始化进度
+    },
+    onRemove (key) {
+      this.filesValues[key] = null
+      this.$set(this.uploadProgress, key, undefined)
+    },
+    onDelete (row) {
+      this.onRemove(row.fileType)
+    },
+    onProgress (event, file, fileType) {
+      const percent = Math.floor(event.percent)
+      this.$set(this.uploadProgress, fileType, percent)
+    },
+    async onSave () {
+      if (Object.values(this.filesValues).every(e => e === null)) {
+        this.$message.warning('请先上传文件')
+        return
+      }
+
+      const h = this.$createElement
+      this.$confirm(h('div', [
+        h('p', undefined, '确定要更新文件吗?'),
+        h('p', undefined, `更新月份:${this.queryValues.month}`),
+        h('p', { style: 'color: red' }, '上传文件后,将覆盖之前的文件,请谨慎操作!')
+      ]), '提示').then(async () => {
+        this.submitLoading = true
+        try {
+          const formData = new FormData()
+          Object.keys(this.filesValues).forEach(key => {
+            if (!this.filesValues[key]) {
+              return
+            }
+            formData.append('files', this.filesValues[key])
+            formData.append('fileTypes', key)
+            // this.items.find()
+          })
+          formData.append('month', this.queryValues.month)
+          formData.append('category', this.category)
+          await uploadSalaryCalculateFiles(formData, {
+            onUploadProgress: progressEvent => {
+              const percent = Math.floor((progressEvent.loaded / progressEvent.total) * 100)
+              // 更新所有文件的总进度
+              Object.keys(this.uploadProgress).forEach(key => {
+                if (this.uploadProgress[key] !== undefined) {
+                  this.$set(this.uploadProgress, key, percent)
+                }
+              })
+            }
+          })
+          this.items.forEach((e, i) => {
+            this.$refs[`upload-${i}`].clearFiles()
+          })
+          this.$message.success('保存成功')
+          this.onInit()
+        } catch (error) {
+          this.$message.error(error)
+        } finally {
+          this.submitLoading = false
+        }
+      }).catch(_ => {})
+    }
+    // onRun () {}
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.d-flex {
+  display: flex;
+}
+.content {
+  width: 50%;
+  min-width: 500px;
+  margin: 0 auto;
+}
+.buttons {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+::v-deep .el-upload-list__item .el-icon-close {
+    display: inline-block;
+    &::after {
+      content: '移除';
+    }
+}
+.header {
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 3 - 2
src/utils/request.js

@@ -151,12 +151,13 @@ const http = {
       }
     })
   },
-  upload (url, params) {
+  upload (url, params, options = {}) {
     return service.post(url, params, {
       timeout: 600000,
       headers: {
         'Content-Type': 'multipart/form-data'
-      }
+      },
+      ...options
     })
   },
   download (url, params) {

+ 17 - 0
src/views/accumulatePoints/accumulatePointsDataUpload/index.vue

@@ -0,0 +1,17 @@
+<template>
+  <data-upload class="pa-3 white" category="积分类"></data-upload>
+</template>
+
+<script>
+import DataUpload from '@/components/DataUpload'
+export default {
+  name: 'accumulatePointsDataUpload',
+  components: {
+    DataUpload
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 5 - 213
src/views/salary/upload/index.vue

@@ -1,225 +1,17 @@
 <template>
-  <div class="white pa-3">
-    <m-search :items="searchItems" v-model="searchValues" class="mb-3" @search="onSearch"></m-search>
-    <m-table
-      :card-title="$attrs.label"
-      :headers="headers"
-      :items="items"
-      v-loading="loading"
-    >
-      <template #card-tools>
-        <m-button size="small" type="orange" icon="el-icon-finished" :loading="submitLoading" @click="onSave">提交待上传文件</m-button>
-        <!-- <m-button size="small" type="orange" icon="el-icon-s-promotion" :loading="runLoading" @click="onRun">执行计算</m-button> -->
-      </template>
-      <!-- <template #header>
-        <div class="header">
-          <m-button size="small" type="primary" icon="el-icon-finished" :loading="submitLoading" @click="onSave">提交当前临时文件</m-button>
-        </div>
-      </template> -->
-      <template #month>
-        {{ queryValues.month }}
-      </template>
-      <template #file="{ row }">
-        {{ filesValues[row.fileType]?.name }}
-      </template>
-      <template #actions="{ row }">
-        <div class="d-flex">
-          <el-upload
-            class="mr-3"
-            action="#"
-            :limit="1"
-            accept=".xlsx,.xls"
-            :show-file-list="false"
-            :on-exceed="(files, fileList) => onExceed(files, fileList, row.fileType)"
-            :http-request="e => onImport(e, row.fileType)"
-            :on-remove="() => onRemove(row.fileType)"
-          >
-            <m-button slot="trigger" text type="primary">导入文件</m-button>
-          </el-upload>
-          <m-button text type="danger" v-show="filesValues[row.fileType]" @click="onDelete(row)">移除临时文件</m-button>
-        </div>
-      </template>
-    </m-table>
-  </div>
+  <data-upload class="pa-3 white" category="绩效类"></data-upload>
 </template>
 
 <script>
-import {
-  getSalaryCalculateTemplate,
-  uploadSalaryCalculateFiles,
-  getSalaryCalculateFiles
-} from '@/api/salary'
-import { dateFormat } from '@/utils/date'
+import DataUpload from '@/components/DataUpload'
 export default {
   name: 'salaryUpload',
-  data () {
-    return {
-      searchValues: {
-        month: dateFormat('YYYY-mm', new Date())
-      },
-      queryValues: {},
-      filesValues: {},
-      categoryItems: [],
-      historyItems: [],
-      formItems: [],
-      headers: [
-        { label: '月份', prop: 'month', width: 100 },
-        { label: '文件类型', prop: 'fileName' },
-        { label: '已上传文件', prop: 'history' },
-        { label: '待上传文件', prop: 'file' },
-        { label: '操作', prop: 'actions' }
-      ],
-      loading: false,
-      submitLoading: false,
-      runLoading: false,
-      categoryType: null
-    }
-  },
-  computed: {
-    items () {
-      const items = this.categoryItems.reduce((res, v) => {
-        return res.concat(v.files)
-      }, [])
-      if (!items) {
-        return []
-      }
-      return items.map(e => {
-        return {
-          ...e,
-          history: this.historyItems.find(h => h.fileType === e.fileType)?.fileOriginalFilename
-        }
-      })
-    },
-    searchItems () {
-      return [
-        {
-          label: '月份',
-          prop: 'month',
-          type: 'datePicker',
-          options: {
-            clearable: false,
-            type: 'month',
-            format: 'yyyy-MM',
-            valueFormat: 'yyyy-MM',
-            placeholder: '选择更新月份'
-          }
-        }
-      ]
-    }
-  },
-  created () {
-    this.onInit()
-  },
-  methods: {
-    async onInit () {
-      try {
-        const { data } = await getSalaryCalculateTemplate()
-        this.categoryItems = data
-        if (!data.length) {
-          return
-        }
-        this.categoryType = data[0].category
-        this.queryValues = { ...this.searchValues }
-        this.filesValues = {
-          ...this.items.reduce((res, v) => {
-            res[v.fileType] = null
-            return res
-          }, {})
-        }
-        this.onGetHistory()
-      } catch (error) {
-        this.$message.error(error)
-      }
-    },
-    async onGetHistory () {
-      try {
-        this.loading = true
-        const { data } = await getSalaryCalculateFiles(this.queryValues)
-        this.historyItems = data
-      } catch (error) {
-        this.$message.error(error)
-      } finally {
-        this.loading = false
-      }
-    },
-    onSearch (query) {
-      this.queryValues = { ...this.searchValues }
-      this.onInit()
-    },
-    onExceed (files, fileList, key) {
-      this.filesValues[key] = files[0]
-    },
-    onImport (e, key) {
-      this.filesValues[key] = e.file
-    },
-    onRemove (key) {
-      this.filesValues[key] = null
-    },
-    onDelete (row) {
-      this.filesValues[row.fileType] = null
-    },
-    async onSave () {
-      if (Object.values(this.filesValues).every(e => e === null)) {
-        this.$message.warning('请先上传文件')
-        return
-      }
-
-      const h = this.$createElement
-      this.$confirm(h('div', [
-        h('p', undefined, '确定要更新文件吗?'),
-        h('p', undefined, `更新月份:${this.queryValues.month}`),
-        h('p', { style: 'color: red' }, '上传文件后,将覆盖之前的文件,请谨慎操作!')
-      ]), '提示').then(async () => {
-        this.submitLoading = true
-        try {
-          const formData = new FormData()
-          Object.keys(this.filesValues).forEach(key => {
-            if (!this.filesValues[key]) {
-              return
-            }
-            formData.append('files', this.filesValues[key])
-            formData.append('fileTypes', key)
-            // this.items.find()
-          })
-          formData.append('month', this.queryValues.month)
-          formData.append('category', this.categoryType)
-          await uploadSalaryCalculateFiles(formData)
-          this.$message.success('保存成功')
-          this.onInit()
-        } catch (error) {
-          this.$message.error(error)
-        } finally {
-          this.submitLoading = false
-        }
-      }).catch(_ => {})
-    }
-    // onRun () {}
+  components: {
+    DataUpload
   }
 }
 </script>
 
 <style lang="scss" scoped>
-.d-flex {
-  display: flex;
-}
-.content {
-  width: 50%;
-  min-width: 500px;
-  margin: 0 auto;
-}
-.buttons {
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-::v-deep .el-upload-list__item .el-icon-close {
-    display: inline-block;
-    &::after {
-      content: '移除';
-    }
-}
-.header {
-  display: flex;
-  justify-content: flex-end;
-}
+
 </style>

+ 17 - 0
src/views/salaryOther/salaryOtherDataUpload/index.vue

@@ -0,0 +1,17 @@
+<template>
+  <data-upload class="pa-3 white" category="其它工资"></data-upload>
+</template>
+
+<script>
+import DataUpload from '@/components/DataUpload'
+export default {
+  name: 'SalaryOtherDataUpload',
+  components: {
+    DataUpload
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>