From 0de192c9b4c4a7d821331a6dd1d9c376c3aae549 Mon Sep 17 00:00:00 2001 From: zhouyonggao <1971162852@qq.com> Date: Thu, 18 Dec 2025 20:58:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(export):=20=E6=A0=B9=E6=8D=AE=E9=A2=84?= =?UTF-8?q?=E4=BC=B0=E8=A1=8C=E6=95=B0=E9=99=90=E5=88=B6xlsx=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增xlsx格式最大行数阈值配置,超过该阈值则导出格式强制为csv - 查询export_jobs表中作业的预估行数用于判断格式切换 - 记录格式切换时的日志,包含作业ID、预估行数及阈值信息 - 避免xlsx格式导出过大文件,提高导出效率和稳定性 - 在export常量中添加XlsxMaxRows配置项,默认值为100000行 --- server/internal/api/exports.go | 18 ++++++++++++++++++ server/internal/constants/constants.go | 3 +++ 2 files changed, 21 insertions(+) diff --git a/server/internal/api/exports.go b/server/internal/api/exports.go index 8a6879f..53916e1 100644 --- a/server/internal/api/exports.go +++ b/server/internal/api/exports.go @@ -393,6 +393,24 @@ func (a *ExportsAPI) runJob(id uint64, db *sql.DB, q string, args []interface{}, } } } + + // 检查预估行数,如果超过阈值且格式是xlsx,强制改为csv + if fmt == "xlsx" { + var rowEstimate int64 + estRow := a.meta.QueryRow("SELECT row_estimate FROM export_jobs WHERE id=?", id) + _ = estRow.Scan(&rowEstimate) + if rowEstimate > constants.ExportThresholds.XlsxMaxRows { + logging.JSON("INFO", map[string]interface{}{ + "event": "force_csv_format", + "job_id": id, + "row_estimate": rowEstimate, + "threshold": constants.ExportThresholds.XlsxMaxRows, + "reason": "row_estimate exceeds xlsx max rows, forcing csv format", + }) + fmt = "csv" + } + } + rrepo.StartJob(a.meta, id) if fmt == "csv" { newBaseWriter := func() (exporter.RowWriter, error) { diff --git a/server/internal/constants/constants.go b/server/internal/constants/constants.go index 39d14f9..ebcfc4b 100644 --- a/server/internal/constants/constants.go +++ b/server/internal/constants/constants.go @@ -60,12 +60,15 @@ var ExportThresholds = struct { ChunkThreshold int64 // ProgressUpdateInterval 进度更新间隔(行数) ProgressUpdateInterval int64 + // XlsxMaxRows xlsx格式最大行数,超过则强制使用csv + XlsxMaxRows int64 }{ MaxRowsPerFile: 300000, PassScoreThreshold: 60, ChunkDays: 10, ChunkThreshold: 50000, ProgressUpdateInterval: 1000, + XlsxMaxRows: 100000, } // BatchSizes 批量处理大小配置