feat(bgpartymatter): 下载模板校验导入合并为导入弹窗

This commit is contained in:
wsm
2026-08-18 11:16:11 +08:00
parent 2b939ed260
commit f6005b2799
@@ -68,15 +68,7 @@
<template #tableTitle>
<a-button type="primary" v-auth="actionAuth.add" @click="handleAdd" preIcon="ant-design:plus-outlined"> 新增</a-button>
<a-button type="primary" v-auth="actionAuth.exportXls" preIcon="ant-design:export-outlined" @click="onExportXls"> 导出</a-button>
<a-button type="primary" v-auth="actionAuth.exportXls" preIcon="ant-design:download-outlined" @click="handleDownloadTemplate"
>下载模板</a-button
>
<j-upload-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:check-outlined" @click="handleCheckExcel"
>模板校验</j-upload-button
>
<j-upload-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:import-outlined" @click="handleImportByTemplate"
>模板导入</j-upload-button
>
<a-button type="primary" v-auth="actionAuth.importExcel" preIcon="ant-design:import-outlined" @click="openImportModal">导入</a-button>
<a-button
v-if="selectedRowKeys.length > 0"
v-auth="actionAuth.deleteBatch"
@@ -164,6 +156,33 @@
<BpmPictureModal @register="registerBpmModal" />
<FlowScheduleStartModalForBG ref="flowScheduleModalRef" @confirm="handleFlowScheduleConfirm" />
<BusinessProcessListModal ref="businessProcessListModalRef" />
<!-- 导入弹窗下载模板 / 模板校验 / 模板导入 -->
<a-modal v-model:open="importModalVisible" title="导入数据" :footer="null" :width="460" centered destroyOnClose>
<div class="import-action-list">
<div v-auth="actionAuth.exportXls" class="import-action-card" @click="handleDownloadTemplateFromModal">
<Icon icon="ant-design:download-outlined" class="import-action-icon" />
<div class="import-action-body">
<div class="import-action-title">下载模板</div>
<div class="import-action-desc">下载标准导入模板按模板格式填写数据</div>
</div>
</div>
<div v-auth="actionAuth.importExcel" class="import-action-card" @click="chooseFile('check')">
<Icon icon="ant-design:check-outlined" class="import-action-icon" />
<div class="import-action-body">
<div class="import-action-title">模板校验</div>
<div class="import-action-desc">校验所选文件是否符合导入规范提前发现错误</div>
</div>
</div>
<div v-auth="actionAuth.importExcel" class="import-action-card" @click="chooseFile('import')">
<Icon icon="ant-design:import-outlined" class="import-action-icon" />
<div class="import-action-body">
<div class="import-action-title">模板导入</div>
<div class="import-action-desc">导入校验通过的模板数据到当前台账</div>
</div>
</div>
</div>
<input ref="fileInputRef" type="file" accept=".xls,.xlsx" style="display: none" @change="onFileSelected" />
</a-modal>
</div>
</template>
@@ -723,6 +742,43 @@
sm: 20,
});
// ================= 导入弹窗(下载模板 / 模板校验 / 模板导入) =================
const importModalVisible = ref(false);
const fileInputRef = ref();
const pendingAction = ref<'check' | 'import' | null>(null);
function openImportModal() {
importModalVisible.value = true;
}
function handleDownloadTemplateFromModal() {
importModalVisible.value = false;
handleDownloadTemplate();
}
/** 触发隐藏文件选择框,记录当前动作(校验 or 导入) */
function chooseFile(action: 'check' | 'import') {
pendingAction.value = action;
fileInputRef.value?.click();
}
/** 文件选择后按动作分发到原校验/导入逻辑 */
function onFileSelected(e) {
const file = e.target.files?.[0];
e.target.value = '';
if (!file) {
return;
}
const action = pendingAction.value;
pendingAction.value = null;
importModalVisible.value = false;
if (action === 'check') {
void handleCheckExcel({ file });
} else if (action === 'import') {
void handleImportByTemplate({ file });
}
}
async function handleDownloadTemplate() {
const data = await defHttp.get({ url: getExportXlsHeadersUrl, params: { meetingType: props.meetingType }, responseType: 'blob', timeout: 60000 }, { isTransformResponse: false });
if (!data) {
@@ -961,4 +1017,48 @@
.status-row-3 td {
background: #f6ffed !important;
}
/* 导入弹窗操作卡片 */
.import-action-list {
display: flex;
flex-direction: column;
gap: 12px;
padding: 4px 8px 8px;
}
.import-action-card {
display: flex;
align-items: center;
gap: 14px;
padding: 14px 16px;
border: 1px solid #e5e6eb;
border-radius: 8px;
background: #fff;
cursor: pointer;
transition: all 0.2s ease;
}
.import-action-card:hover {
border-color: #1677ff;
background: #f0f7ff;
box-shadow: 0 2px 8px rgba(22, 119, 255, 0.15);
transform: translateY(-1px);
}
.import-action-icon {
font-size: 26px;
color: #1677ff;
flex-shrink: 0;
}
.import-action-body {
min-width: 0;
}
.import-action-title {
font-size: 15px;
font-weight: 600;
color: #1f2329;
line-height: 1.4;
}
.import-action-desc {
margin-top: 4px;
font-size: 12px;
color: #8a919f;
line-height: 1.5;
}
</style>