重构学员证书签发与批量导入流程
This commit is contained in:
@@ -5,25 +5,26 @@
|
||||
<h2>Excel 导入</h2>
|
||||
<p>上传后先校验,确认导入后才会正式写入学员和证书数据。</p>
|
||||
</div>
|
||||
<el-button @click="downloadTemplate">下载模板</el-button>
|
||||
<el-button :disabled="!selectedTemplate" @click="downloadTemplate">下载所选模板</el-button>
|
||||
</header>
|
||||
|
||||
<el-alert
|
||||
class="import-tip"
|
||||
type="info"
|
||||
:closable="false"
|
||||
title="课程开始日期、课程结束日期和发证日期均为必填项,请统一使用 YYYY-MM-DD 格式,例如 2026-06-01。"
|
||||
title="请先选择证书模板,再下载对应 Excel。不同证书模板的列和必填项不同,不要混用文件。"
|
||||
/>
|
||||
|
||||
<div class="batch-template">
|
||||
<div>
|
||||
<strong>本批次证书模板</strong>
|
||||
<span>确认导入后,整批证书都会固化为所选模板。</span>
|
||||
<span>下载、校验和正式签发都以本次选择为准。</span>
|
||||
</div>
|
||||
<el-select v-model="templateCode" placeholder="选择证书模板">
|
||||
<el-option v-for="item in templates" :key="item.code" :label="item.name" :value="item.code" />
|
||||
</el-select>
|
||||
<img v-if="selectedTemplate" :src="selectedTemplate.preview_url" :alt="selectedTemplate.name" />
|
||||
<p v-if="selectedTemplate" class="template-fields">Excel 字段:{{ selectedImportColumns.join("、") }}</p>
|
||||
</div>
|
||||
|
||||
<el-upload
|
||||
@@ -129,6 +130,12 @@ let pregenerationTimer: number | null = null;
|
||||
|
||||
const pregenerationDone = computed(() => ["completed", "completed_with_errors"].includes(pregenerationJob.value?.status || ""));
|
||||
const selectedTemplate = computed(() => templates.value.find((item) => item.code === templateCode.value));
|
||||
const selectedImportColumns = computed(() => [
|
||||
"姓名",
|
||||
"手机号",
|
||||
"项目代码",
|
||||
...(selectedTemplate.value?.dynamic_fields.filter((field) => field !== "姓名") || []),
|
||||
]);
|
||||
|
||||
function templateName(code: string) {
|
||||
return templates.value.find((item) => item.code === code)?.name || code;
|
||||
@@ -149,7 +156,11 @@ function pickFile(file: UploadFile) {
|
||||
}
|
||||
|
||||
function downloadTemplate() {
|
||||
downloadFile("/admin/import-batches/template", "certificate-import-template.xlsx");
|
||||
if (!selectedTemplate.value) return;
|
||||
downloadFile(
|
||||
`/admin/import-batches/template?template_code=${encodeURIComponent(templateCode.value)}`,
|
||||
`certificate-import-${templateCode.value}.xlsx`,
|
||||
);
|
||||
}
|
||||
|
||||
async function loadBatches() {
|
||||
@@ -291,6 +302,13 @@ onUnmounted(stopPregenerationPolling);
|
||||
border: 1px solid #edf2f4;
|
||||
}
|
||||
|
||||
.template-fields {
|
||||
grid-column: 1 / -1;
|
||||
margin: 0;
|
||||
color: var(--app-muted);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.import-tip {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user