Files
fad_oa/ruoyi-ui/src/views/oa/peoples/salary/components/SalaryUploadDialog.vue
2025-03-13 11:12:01 +08:00

244 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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