补贴批量 功能开发

This commit is contained in:
lizhenhua 2025-12-09 15:52:58 +08:00
parent 6889f80321
commit 7f335c8610
1 changed files with 1232 additions and 892 deletions

View File

@ -28,6 +28,12 @@
@click="handleBatchEdit" @click="handleBatchEdit"
>批量补贴</el-button> >批量补贴</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
size="mini" type="primary"
@click="handleImportRecharge"
>导入充值</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
size="mini" type="danger" size="mini" type="danger"
@ -539,16 +545,114 @@
</div> </div>
</el-dialog> </el-dialog>
<!-- 导入充值对话框 -->
<el-dialog title="导入充值" :visible.sync="openImport" width="600px" append-to-body>
<div style="padding: 20px;">
<!-- 下载模板区域 -->
<div style="margin-bottom: 30px; padding: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px; text-align: center;">
<i class="el-icon-download" style="font-size: 48px; color: #fff; margin-bottom: 10px;"></i>
<div style="color: #fff; font-size: 16px; margin-bottom: 15px;">下载补贴充值导入模板</div>
<el-button type="primary" size="mini" @click="downloadTemplate" style="background: #fff; color: #667eea; border: none;">
<i class="el-icon-download"></i> 下载模板
</el-button>
</div>
<!-- 文件上传区域 -->
<div style="margin-bottom: 20px;">
<div style="font-size: 14px; color: #606266; margin-bottom: 10px; font-weight: 500;">
<i class="el-icon-upload2"></i> 上传文件
</div>
<el-upload
ref="upload"
:on-change="handleFileChange"
:file-list="fileList"
:auto-upload="false"
:limit="1"
:disabled="fileList.length > 0"
accept=".xlsx,.xls"
drag
style="width: 100%;"
>
<i class="el-icon-upload" style="font-size: 67px; color: #C0C4CC; margin: 40px 0 16px;"></i>
<div class="el-upload__text" style="color: #606266;">
将文件拖到此处<em>点击上传</em>
</div>
<div class="el-upload__tip" slot="tip" style="color: #909399; font-size: 12px; margin-top: 10px;">
只能上传 Excel 文件.xlsx/.xls且不超过 10MB
</div>
</el-upload>
</div>
<!-- 上传进度 -->
<div v-if="uploadProgress > 0 && uploadProgress < 100" style="margin-bottom: 20px;">
<el-progress :percentage="uploadProgress" :status="uploadProgress === 100 ? 'success' : ''"></el-progress>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button @click="handleImportCancel"> </el-button>
<el-button type="primary" @click="submitUpload" :loading="uploading">开始上传</el-button>
</div>
</el-dialog>
<!-- 补贴充值预览对话框 -->
<el-dialog title="补贴充值预览" :visible.sync="openImportPreview" width="800px" append-to-body>
<div style="margin-bottom: 10px; text-align: center;">
总记录数{{ importPreviewData.totalCount || '--' }}
有效记录数{{ importPreviewData.validCount || '--' }}
充值总额{{ importPreviewData.validTotalAmount ? (importPreviewData.validTotalAmount/100).toFixed(2) : '--' }}
无效记录数{{ importPreviewData.invalidCount || '--' }}
</div>
<div v-if="importPreviewData.invalidList && importPreviewData.invalidList.length > 0" style="margin-bottom: 20px;">
<div style="font-weight: 600; margin-bottom: 10px;">无效记录</div>
<el-table :data="importPreviewData.invalidList" max-height="250">
<!-- <el-table-column label="行号" align="center" prop="row" width="80" :show-overflow-tooltip="true" /> -->
<el-table-column label="用户编号" align="center" prop="userId" :show-overflow-tooltip="true" />
<el-table-column label="用户姓名" align="center" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="用户手机号" align="center" prop="phoneNumber" :show-overflow-tooltip="true" />
<el-table-column label="所属组织" align="center" prop="deptFullName" :show-overflow-tooltip="true" />
<el-table-column label="充值金额" align="center" prop="amount" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{ scope.row.amount ? (scope.row.amount/100).toFixed(2) : '--' }}</span>
</template>
</el-table-column>
<el-table-column label="失败原因" align="center" prop="errorMessage" :show-overflow-tooltip="true"/>
</el-table>
</div>
<div v-if="importPreviewData.successVoList && importPreviewData.successVoList.length > 0">
<div style="font-weight: 600; margin-bottom: 10px;">有效记录</div>
<el-table :data="importPreviewData.successVoList" max-height="250">
<el-table-column label="用户编号" align="center" prop="userId" :show-overflow-tooltip="true" />
<el-table-column label="用户姓名" align="center" prop="nickName" :show-overflow-tooltip="true" />
<el-table-column label="用户手机号" align="center" prop="phoneNumber" :show-overflow-tooltip="true" />
<el-table-column label="所属组织" align="center" prop="deptFullName" :show-overflow-tooltip="true" />
<el-table-column label="充值金额" align="center" prop="amount" :show-overflow-tooltip="true">
<template slot-scope="scope">
<span>{{ scope.row.amount ? (scope.row.amount/100).toFixed(2) : '--' }}</span>
</template>
</el-table-column>
</el-table>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmImportSubmit" v-if="importPreviewData.validUserIdList && importPreviewData.validUserIdList.length > 0">继续</el-button>
<el-button type="primary" @click="openImportPreview=false" v-else>确定</el-button>
<el-button @click="openImportPreview=false">取消</el-button>
</div>
</el-dialog>
</div> </div>
</template> </template>
<script> <script>
import { deptTreeSelect } from '@/api/system/user' import { deptTreeSelect } from '@/api/system/user'
import { accInfoPageApi, accInfoSumPageApi } from "@/api/accountCenter/manager"; import { accInfoPageApi, accInfoSumPageApi } from "@/api/accountCenter/manager";
import { updateAccRechargeSingleApi,checkAccRechargeBatchApi,updateAccRechargeBatchApi,clearAccRechargeSingleApi,checkClearAccRechargeBatchApi,clearAccRechargeBatchApi } from "@/api/accountCenter/butie"; import { updateAccRechargeSingleApi,checkAccRechargeBatchApi,updateAccRechargeBatchApi,clearAccRechargeSingleApi,checkClearAccRechargeBatchApi,clearAccRechargeBatchApi } from "@/api/accountCenter/butie";
import { decryptWithSM4,encryptWithSM4 } from '@/utils/sm'; import { decryptWithSM4,encryptWithSM4 } from '@/utils/sm';
export default { import { getToken } from '@/utils/auth';
import { downloadFileByUrl } from '@/utils/download'
import { download } from '@/utils/request';
import request from '@/utils/request';
export default {
name: "", name: "",
dicts: ['sys_user_type'], dicts: ['sys_user_type'],
data() { data() {
@ -626,7 +730,15 @@
openResult:false, openResult:false,
resultData:{}, resultData:{},
openResult2:false, openResult2:false,
resultData2:{} resultData2:{},
//
openImport: false,
fileList: [],
uploadProgress: 0,
uploading: false,
//
openImportPreview: false,
importPreviewData: {}
}; };
}, },
created() { created() {
@ -925,7 +1037,235 @@
},800) },800)
}); });
}, },
//
handleImportRecharge() {
this.openImport = true;
this.fileList = [];
this.uploadProgress = 0;
this.uploading = false;
this.importPreviewData = {};
if (this.$refs.upload) {
this.$refs.upload.clearFiles();
} }
}; },
</script> //
handleFileChange(file, fileList) {
//
if (fileList.length > 1) {
this.fileList = [fileList[fileList.length - 1]];
this.$refs.upload.fileList = [fileList[fileList.length - 1]];
} else {
this.fileList = fileList;
}
},
//
downloadTemplate() {
let url = window.location.origin + '/template/批量补贴导入.xlsx';
console.log(url)
downloadFileByUrl(url)
},
//
beforeUpload(file) {
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.type === 'application/vnd.ms-excel' ||
file.name.endsWith('.xlsx') ||
file.name.endsWith('.xls');
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isExcel) {
this.$modal.msgError('只能上传 Excel 文件!');
return false;
}
if (!isLt10M) {
this.$modal.msgError('上传文件大小不能超过 10MB');
return false;
}
return true;
},
//
handleUploadProgress(event, file, fileList) {
this.uploadProgress = Math.round(event.percent);
},
//
handleUploadSuccess(response, file, fileList) {
this.uploading = false;
this.uploadProgress = 100;
//
const result = response.data || response;
if (response.code === 200 || response.code === 0 || !response.code) {
this.uploadResult = {
success: true,
data: result,
message: response.msg || response.message || '导入成功'
};
this.$modal.msgSuccess('导入成功!');
//
setTimeout(() => {
this.getList();
}, 500);
} else {
this.uploadResult = {
success: false,
data: result,
message: response.msg || response.message || '导入失败'
};
this.$modal.msgError(response.msg || response.message || '导入失败');
}
},
//
handleUploadError(err, file, fileList) {
this.uploading = false;
this.uploadProgress = 0;
this.uploadResult = {
success: false,
message: err.message || '上传失败,请重试'
};
this.$modal.msgError('上传失败,请重试');
},
//
submitUpload() {
if (this.fileList.length === 0) {
this.$modal.msgError('请先选择要上传的文件!');
return;
}
const file = this.fileList[0].raw || this.fileList[0];
if (!file) {
this.$modal.msgError('文件不存在,请重新选择!');
return;
}
//
const isExcel = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
file.type === 'application/vnd.ms-excel' ||
file.name.endsWith('.xlsx') ||
file.name.endsWith('.xls');
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isExcel) {
this.$modal.msgError('只能上传 Excel 文件!');
return;
}
if (!isLt10M) {
this.$modal.msgError('上传文件大小不能超过 10MB');
return;
}
this.uploading = true;
this.uploadProgress = 0;
// 使FormData
const formData = new FormData();
formData.append('file', file);
//
request({
url: '/smart-canteen/acc/subsidy/import/add/check',
method: 'post',
data: formData,
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': 'Bearer ' + getToken()
},
onUploadProgress: (progressEvent) => {
if (progressEvent.total) {
this.uploadProgress = Math.round((progressEvent.loaded * 100) / progressEvent.total);
}
}
}).then(response => {
this.uploading = false;
this.uploadProgress = 100;
//
const result = response.data || response;
if (response.code === 200 || response.code === 0) {
//
const amountMap = {};
(result.sucVoListMap || []).forEach(item => {
const key = Object.keys(item || {})[0];
if (key) {
amountMap[key] = item[key];
}
});
const successVoList = (result.accInfoVOList || []).map(item => {
const phoneNumber = item.phoneNumber ? decryptWithSM4(item.phoneNumber) : item.phoneNumber;
return {
...item,
phoneNumber,
amount: amountMap[item.userId] || amountMap[item.userId + ''] || item.amount
};
});
const invalidList = [
...(result.errVOList || []),
...(result.invalidVOList || [])
].map(item => ({
...item,
phoneNumber: item.phoneNumber ? decryptWithSM4(item.phoneNumber) : item.phoneNumber
}));
this.importPreviewData = {
...result,
totalCount: result.totalUserSum,
successVoList,
invalidList
};
//
this.openImport = false;
this.openImportPreview = true;
} else {
this.$modal.msgError(response.msg || response.message || '校验失败');
}
}).catch(error => {
this.uploading = false;
this.uploadProgress = 0;
this.$modal.msgError(error.message || '上传失败,请重试');
});
},
//
confirmImportSubmit() {
if (!this.importPreviewData.validUserIdList || this.importPreviewData.validUserIdList.length === 0) {
this.$modal.msgError('没有有效的记录可以提交!');
return;
}
//
const userIdAmountMap = (this.importPreviewData.successVoList || [])
.filter(item => this.importPreviewData.validUserIdList.includes(String(item.userId)))
.map(item => ({ [item.userId]: item.amount }));
const param = {
userIds: this.importPreviewData.validUserIdList,
userIdAmountMap
};
//
request({
url: '/smart-canteen/acc/subsidy/batch/import/add',
method: 'post',
data: param,
headers: {
'Authorization': 'Bearer ' + getToken()
}
}).then(response => {
if (response.code === 200 || response.code === 0) {
this.$modal.msgSuccess("操作成功");
this.openImportPreview = false;
this.getList();
} else {
this.$modal.msgError(response.msg || response.message || '提交失败');
}
}).catch(error => {
this.$modal.msgError(error.message || '提交失败,请重试');
});
},
//
handleImportCancel() {
this.openImport = false;
this.fileList = [];
this.uploadProgress = 0;
this.uploading = false;
this.importPreviewData = {};
if (this.$refs.upload) {
this.$refs.upload.clearFiles();
}
},
}
};
</script>