🐞 fix: 部分bug修复

This commit is contained in:
2025-03-13 11:12:01 +08:00
parent 0ce49d1504
commit 6b5ceef475
7 changed files with 391 additions and 205 deletions

View File

@@ -0,0 +1,244 @@
<!-- components/SalaryUploadDialog.vue -->
<template>
<el-dialog
title="薪资计算"
:visible.sync="localVisible"
width="30%"
@closed="handleClose"
:close-on-click-modal="false">
<!-- 全局加载状态 -->
<div v-if="globalLoading" class="global-loading">
<div class="loading-content">
<i class="el-icon-loading"></i>
<p>{{ loadingText }}</p>
</div>
</div>
<el-form ref="calcForm">
<el-form-item label="计算月份" required>
<el-date-picker
v-model="month"
type="month"
value-format="yyyyMM"
placeholder="选择月份"
style="width: 100%"
:disabled="isProcessing">
</el-date-picker>
</el-form-item>
<el-form-item label="薪资文件" required>
<el-upload
class="upload-demo"
drag
:auto-upload="false"
:on-change="handleFileChange"
:file-list="fileList"
action=""
:disabled="isProcessing">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">仅支持xlsx格式文件</div>
</el-upload>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button
@click="localVisible = false"
:disabled="isProcessing">
取消
</el-button>
<el-button
@click="handleUpload"
:disabled="!canUpload"
:loading="uploading">
{{ uploadButtonText }}
</el-button>
<el-button
type="primary"
@click="handleSubmit"
:disabled="!canSubmit"
:loading="calculating">
开始计算
</el-button>
</span>
</el-dialog>
</template>
<script>
import { uploadOssFile } from '@/api/oa/salary'
export default {
name: 'SalaryUploadDialog',
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
localVisible: this.visible,
isProcessing: false, // 整体处理状态
uploading: false, // 上传中状态
calculating: false, // 计算中状态
month: '',
fileList: [],
filePath: '',
currentFileKey: null, // 文件唯一标识
globalLoading: false,
loadingText: ''
}
},
computed: {
// 是否可以上传(有文件且未处理)
canUpload() {
return this.fileList.length > 0 && !this.uploading && !this.currentFileKey
},
// 是否可以提交计算
canSubmit() {
return Boolean(this.filePath) && !this.calculating
},
uploadButtonText() {
return this.uploading ? '上传中...' : '确认上传'
},
// 生成文件唯一标识
fileIdentifier() {
if (!this.fileList.length) return null
const file = this.fileList[0].raw
return `${file.name}-${file.lastModified}-${file.size}`
}
},
watch: {
visible(newVal) {
this.localVisible = newVal
},
localVisible(newVal) {
this.$emit('update:visible', newVal)
}
},
methods: {
handleFileChange(file, fileList) {
this.fileList = [fileList[fileList.length - 1]]
// 检测到文件变化时重置状态
if (this.fileIdentifier !== this.currentFileKey) {
this.currentFileKey = null
this.filePath = ''
}
},
async handleUpload() {
try {
this.uploading = true
this.isProcessing = true
this.showGlobalLoading('文件上传中...')
const formData = new FormData()
formData.append('file', this.fileList[0].raw)
const { data } = await uploadOssFile(formData)
this.filePath = '/data' + data.url.split('/data')[1]
this.currentFileKey = this.fileIdentifier
this.$message.success('文件上传成功')
} catch (error) {
this.$message.error('文件上传失败')
} finally {
this.uploading = false
this.isProcessing = false
this.hideGlobalLoading()
}
},
async handleSubmit() {
if (!this.validateForm()) return
try {
this.calculating = true
this.isProcessing = true
this.showGlobalLoading('薪资计算中...')
// 触发父组件计算
this.$emit('submit', {
monthStr: this.month,
filePath: this.filePath
})
} catch (error) {
this.$message.error(error.message || '计算失败')
} finally {
this.calculating = false
this.isProcessing = false
this.hideGlobalLoading()
}
},
validateForm() {
if (!this.month) {
this.$message.warning('请选择计算月份')
return false
}
if (!this.filePath) {
this.$message.warning('请先上传薪资文件')
return false
}
return true
},
showGlobalLoading(text) {
this.globalLoading = true
this.loadingText = text
},
hideGlobalLoading() {
this.globalLoading = false
this.loadingText = ''
},
handleClose() {
this.resetForm()
this.$emit('closed')
},
resetForm() {
this.fileList = []
this.month = ''
this.filePath = ''
this.currentFileKey = null
this.isProcessing = false
this.uploading = false
this.calculating = false
}
}
}
</script>
<style scoped>
/* 全局加载样式 */
.global-loading {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.8);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-content {
text-align: center;
padding: 20px;
background: rgba(0, 0, 0, 0.7);
border-radius: 4px;
color: #fff;
}
.loading-content i {
font-size: 40px;
margin-bottom: 10px;
}
.upload-demo {
text-align: center;
}
</style>