|
@@ -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>
|