新增批次下载对话框,支持导出生成的兑换码Excel文件,优化用户体验

This commit is contained in:
zyh
2025-08-29 23:55:18 +08:00
parent ccbb1a3eb4
commit 28fa2099ad

View File

@@ -432,6 +432,42 @@
</div> </div>
</el-card> </el-card>
<!-- 批次下载对话框 -->
<el-dialog
v-model="batchDownloadDialog.visible"
title="下载本次生成的兑换码"
width="400px"
:close-on-click-modal="false"
:close-on-press-escape="false"
class="batch-download-dialog"
>
<div class="download-content">
<div class="download-info">
<el-icon class="info-icon"><Download /></el-icon>
<div class="info-text">
<h4>生成成功</h4>
<p>批次ID: <strong>{{ batchDownloadDialog.batchId }}</strong></p>
<p>共生成 <strong>{{ batchDownloadDialog.count }}</strong> 个兑换码</p>
<p>是否立即下载本次生成的兑换码Excel文件</p>
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="closeBatchDownloadDialog">取消</el-button>
<el-button
type="primary"
@click="downloadCurrentBatch"
:loading="batchDownloadDialog.downloading"
>
<el-icon><Download /></el-icon>
立即下载
</el-button>
</div>
</template>
</el-dialog>
<!-- 按状态批量删除对话框 --> <!-- 按状态批量删除对话框 -->
<el-dialog <el-dialog
v-model="batchDeleteByStatusDialog.visible" v-model="batchDeleteByStatusDialog.visible"
@@ -543,6 +579,14 @@ const batchDeleteByStatusDialog = reactive({
} }
}) })
// 批次下载对话框状态
const batchDownloadDialog = reactive({
visible: false,
downloading: false,
batchId: '',
count: 0
})
// 状态选项 // 状态选项
const statusOptions = [ const statusOptions = [
{ value: 'NEW', label: '新建' }, { value: 'NEW', label: '新建' },
@@ -597,6 +641,11 @@ const handleGenerate = async () => {
// 刷新列表 // 刷新列表
await refreshList() await refreshList()
// 弹出批次下载对话框
if (result && result.batchId && result.codeNos && result.codeNos.length > 0) {
showBatchDownloadDialog(result.batchId, result.codeNos.length)
}
// 重置表单 // 重置表单
resetForm() resetForm()
@@ -938,6 +987,76 @@ const closeBatchDeleteByStatusDialog = () => {
batchDeleteFormRef.value?.resetFields() batchDeleteFormRef.value?.resetFields()
} }
// 批次下载对话框相关方法
const showBatchDownloadDialog = (batchId, count) => {
batchDownloadDialog.visible = true
batchDownloadDialog.batchId = batchId
batchDownloadDialog.count = count
batchDownloadDialog.downloading = false
}
const closeBatchDownloadDialog = () => {
batchDownloadDialog.visible = false
batchDownloadDialog.batchId = ''
batchDownloadDialog.count = 0
batchDownloadDialog.downloading = false
}
const downloadCurrentBatch = async () => {
try {
batchDownloadDialog.downloading = true
// 根据批次ID筛选当前批次的数据
const currentBatchData = linkList.value.filter(item =>
item.batchId === batchDownloadDialog.batchId
)
if (currentBatchData.length === 0) {
ElMessage.warning('未找到当前批次的数据,请刷新列表后重试')
return
}
// 准备导出数据
const headers = [
{ key: 'codeNo', label: '兑换码' },
{ key: 'batchId', label: '批次ID' },
{ key: 'quantity', label: '数量' },
{ key: 'times', label: '次数' },
{ key: 'totalPoints', label: '总积分' },
{ key: 'statusDesc', label: '状态' },
{ key: 'remainingTime', label: '剩余时间' },
{ key: 'linkUrl', label: '链接地址' },
{ key: 'expireAt', label: '过期时间' },
{ key: 'createdAt', label: '创建时间' }
]
const data = currentBatchData.map(item => ({
...item,
remainingTime: item.isExpired ? '已过期' : (item.remainingSeconds > 0 ? formatRemainingTime(item.remainingSeconds) : '-'),
linkUrl: generateLinkUrl(item.codeNo),
expireAt: formatDateTime(item.expireAt),
createdAt: formatDateTime(item.createdAt)
}))
// 生成文件名
const filename = `批次${batchDownloadDialog.batchId}_兑换码_${currentBatchData.length}个_${new Date().toISOString().split('T')[0]}.xlsx`
// 导出Excel
exportExcelUtil(data, headers, filename)
ElMessage.success(`成功导出批次 ${batchDownloadDialog.batchId}${currentBatchData.length} 个兑换码`)
// 关闭对话框
closeBatchDownloadDialog()
} catch (error) {
console.error('批次下载失败:', error)
ElMessage.error('下载失败,请重试')
} finally {
batchDownloadDialog.downloading = false
}
}
const handleBatchDeleteByStatus = async () => { const handleBatchDeleteByStatus = async () => {
try { try {
// 表单验证 // 表单验证
@@ -1465,6 +1584,69 @@ onUnmounted(() => {
} }
} }
/* 批次下载对话框样式 */
.batch-download-dialog {
text-align: center;
}
.download-content {
padding: 20px 0;
}
.download-info {
display: flex;
flex-direction: column;
align-items: center;
gap: 16px;
}
.info-icon {
font-size: 48px;
color: #409eff;
}
.info-text {
text-align: center;
}
.info-text h4 {
margin: 0 0 16px 0;
font-size: 18px;
color: #303133;
font-weight: 600;
}
.info-text p {
margin: 8px 0;
font-size: 14px;
color: #606266;
line-height: 1.5;
}
.info-text strong {
color: #409eff;
font-weight: 600;
}
@media (max-width: 768px) {
.batch-download-dialog :deep(.el-dialog) {
width: 90% !important;
margin: 0 auto !important;
}
.info-icon {
font-size: 40px;
}
.info-text h4 {
font-size: 16px;
}
.info-text p {
font-size: 13px;
}
}
@media (max-width: 480px) { @media (max-width: 480px) {
.link-generate { .link-generate {
padding: 8px; padding: 8px;