feat(admin): 成绩导出改为 Excel + 板块迁移配套接口(R29)
- service/admin.js: 抽出 buildScoreExportTable(group) 作单一数据源(CSV/XLSX 共用,消除表头漂移) + 新增 exportToXlsx()(SheetJS aoa_to_sheet + write buffer + !cols 列宽) - controller/admin.js: 新增 exportExcel()(xlsx MIME + ctx.attachment 中文文件名编码) - router.js: 新增 GET /api/admin/export-excel/:group(adminAuth) - export-csv 路由刻意保留:verify_full_e2e.py B10/D10、verify_upload_download.py B2 依赖其非空断言
This commit is contained in:
@@ -261,6 +261,34 @@ class AdminController extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出提交记录为 Excel(.xlsx)(R29)
|
||||
* GET /api/admin/export-excel/:group
|
||||
*
|
||||
* 测试人员反馈「导出 CSV 不如直接导出 Excel」:CSV 在 Excel 中打开时中文易乱码、
|
||||
* 身份证号 / 手机号会被转成科学计数法。此处直接下发真正的 xlsx。
|
||||
* ⚠️ 与 exportCsv 共用 service.admin.buildScoreExportTable(表头/口径单一数据源)。
|
||||
*/
|
||||
async exportExcel() {
|
||||
const { ctx, service } = this;
|
||||
if (!this._ensureAdmin()) return;
|
||||
|
||||
try {
|
||||
const { group } = ctx.params;
|
||||
if (!this._validateGroup(group, true)) return;
|
||||
|
||||
const buf = await service.admin.exportToXlsx(group);
|
||||
|
||||
const fileName = `${group}_scores_${new Date().toISOString().slice(0, 10)}.xlsx`;
|
||||
ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||
ctx.attachment(fileName);
|
||||
ctx.body = buf;
|
||||
} catch (err) {
|
||||
ctx.logger.error('导出 Excel 失败:', err);
|
||||
ctx.body = ctx.helper.error(500, '导出 Excel 失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量下载某组所有提交文件为 ZIP
|
||||
* GET /api/admin/batch-download/:group
|
||||
|
||||
Reference in New Issue
Block a user