Conversation
…or interface Add backend infrastructure for multi-format audit report export: - Extend ExportFormat enum with HTML/PDF/WORD constants - Add NormalizeExportFormatStr function for string-based format normalization - Define AuditReportData, AuditSummary, AuditStatistics, LevelCount, RuleHit, AuditSQLItem, and ReportLabels data model structs - Define ReportGenerator interface with Generate and Format methods - Add CSVHeaders() and ToCSVRow() helper methods for CSV export - Add unit tests for NormalizeExportFormatStr with map case pattern
Implement CSVReportGenerator that reuses the existing CSVBuilder to generate CSV audit reports via the ReportGenerator interface. Add comprehensive unit tests covering normal data, empty SQL list, and special character escaping (comma, newline, double quote).
…ests
- Add self-contained HTML report template (templates/audit_report.html) with
4 content modules: audit summary, result statistics, problem SQL list, and
rule hit statistics. All text uses Go template i18n variables, CSS is inlined,
SQL displayed in <pre> tags, logo supports base64 embedding.
- Add report_html_template.go using embed.FS to embed the HTML template file.
- Add report_html.go implementing HTMLReportGenerator with html/template for
automatic XSS prevention via HTML escaping. Content-Type: text/html,
filename format: SQL_audit_report_{instance}_{taskId}.html.
- Add 4 unit tests: Normal (ContentType, HTML tags, SQL content, labels),
XSSPrevention (script/img tags escaped), EmptyData (empty SQL list renders),
LargeData (10000 SQL items performance check).
… export Refactor the DownloadTaskSQLReportFile API handler to support exporting audit reports in multiple formats (CSV, HTML, PDF, WORD) via the new export_format query parameter. Default to CSV for backward compatibility. Key changes: - Add BuildAuditReportData function in report_data_builder.go that converts Task + SQL data into AuditReportData (placed in controller layer to avoid circular dependency between utils and model packages) - Refactor DownloadTaskSQLReportFile to use BuildAuditReportData and ExportAuditReport for format-agnostic report generation - Add 16 new i18n locale messages for report labels (zh/en TOML + Go vars) - Update Swagger annotations with export_format parameter - Add comprehensive unit tests for helper functions: toLevelCounts, toRuleHits, extractRuleInfo, buildReportLabels (13 test functions, map case pattern, covering normal/empty/nil/edge cases) Requirement refs: REQ-6.1, REQ-6.2, REQ-6.4, REQ-NF-2.1, REQ-NF-3.1
Update swagger.json, swagger.yaml, and docs.go to include the new
export_format query parameter (type: string, default: csv) for the
/v1/tasks/audits/{task_id}/sql_report endpoint. Also update response
description from "sql report csv file" to "sql report file" to reflect
multi-format support.
… fallback (CE part)
PR Reviewer Guide 🔍(Review updated until commit 2c3d81f)
|
|
Failed to generate code suggestions for PR |
|
Persistent review updated to latest commit 2d973a0 |
PR Code Suggestions ✨No code suggestions found for the PR. |
…tData function Updated the BuildAuditReportData function to initialize sqlList and problemSQLs with a predefined capacity based on taskSQLsDetail length, improving performance and memory usage.
|
Persistent review updated to latest commit 0fc0407 |
|
Failed to generate code suggestions for PR |
| // NormalizeExportFormatStr 规范化导出格式参数(字符串版本)。 | ||
| // 空字符串默认返回 CSV(向后兼容);无效格式返回错误。 | ||
| // 支持 html/pdf/word/docx/excel/xlsx/csv 等输入的规范化。 | ||
| func NormalizeExportFormatStr(format string) (ExportFormat, error) { | ||
| switch strings.ToLower(strings.TrimSpace(format)) { | ||
| case "html": | ||
| return ExportFormatHTML, nil | ||
| case "pdf": | ||
| return ExportFormatPDF, nil | ||
| case "word", "docx": | ||
| return ExportFormatWORD, nil | ||
| case "excel", "xlsx": | ||
| return ExcelExportFormat, nil | ||
| case "csv", "": | ||
| return CsvExportFormat, nil | ||
| default: | ||
| return "", fmt.Errorf("unsupported export format: %s", format) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
ExportFormat也是导出格式的业务对象,应当移动到业务层
| // ReportType 返回生成器对应的导出格式 | ||
| ReportType() utils.ExportFormat |
There was a problem hiding this comment.
目前这个接口没有被除了单元测试之外的地方用到
| // @Param task_id path string true "task id" | ||
| // @Param no_duplicate query boolean false "select unique (fingerprint and audit result) for task sql" | ||
| // @Success 200 file 1 "sql report csv file" | ||
| // @Param export_format query string false "export format: csv, html, pdf, word" default(csv) |
| { | ||
| "type": "string", | ||
| "description": "export format: csv, html, pdf, word", | ||
| "name": "export_format", | ||
| "in": "query", | ||
| "default": "csv" | ||
| } |
| // toLevelCounts 将等级分布 map 转换为有序的 LevelCount 切片。 | ||
| // 按 error > warn > notice > normal 顺序排列。 | ||
| func toLevelCounts(dist map[string]int) []auditreport.LevelCount { | ||
| if len(dist) == 0 { | ||
| return []auditreport.LevelCount{} | ||
| } | ||
|
|
||
| levelOrder := map[string]int{ | ||
| "error": 0, | ||
| "warn": 1, | ||
| "notice": 2, | ||
| "normal": 3, | ||
| } | ||
|
|
||
| result := make([]auditreport.LevelCount, 0, len(dist)) | ||
| for level, count := range dist { | ||
| result = append(result, auditreport.LevelCount{ | ||
| Level: level, | ||
| Count: count, | ||
| }) | ||
| } | ||
|
|
||
| sort.Slice(result, func(i, j int) bool { | ||
| oi, ok := levelOrder[result[i].Level] | ||
| if !ok { | ||
| oi = 99 | ||
| } | ||
| oj, ok := levelOrder[result[j].Level] | ||
| if !ok { | ||
| oj = 99 | ||
| } | ||
| return oi < oj | ||
| }) | ||
|
|
||
| return result | ||
| } |
There was a problem hiding this comment.
可以移除,没必要这么复杂,一开始定义一个数组就可以了
levelCounts := []LevelCount{
{Level: "normal", Count: 0},
{Level: "notice", Count: 0},
{Level: "warn", Count: 0},
{Level: "error", Count: 0},
}
根据level类型,在对应下标的元素里面++,不需要在Map和Array/Slice之间杂耍
// LevelCount 等级统计
type LevelCount struct {
Level string json:"level" // normal/notice/warn/error
Count int json:"count"
}
Define ExportFormat and NormalizeExportFormatStr in auditreport; keep utils.ExportFormat for generic csv/excel data export only.
Use one time.Now for GeneratedAt and fallback audit time; build level stats with fixed-order slices instead of map plus sort.
Use auditreport.NormalizeExportFormatStr; document Enums in swagger.
|
Persistent review updated to latest commit 2c3d81f |
PR Code Suggestions ✨No code suggestions found for the PR. |
| // 1. 获取 SQL 列表 | ||
| data := map[string]interface{}{ | ||
| "task_id": fmt.Sprintf("%d", task.ID), | ||
| "no_duplicate": noDuplicate, | ||
| } | ||
|
|
There was a problem hiding this comment.
应该定义一个FilterOption 结构体,明确能用哪些参数进行筛选
| return strings.Join(ruleNames, ", "), strings.Join(suggestions, "; ") | ||
| } | ||
|
|
||
| // formatLevelDistribution 将各等级计数转为 LevelCount 切片:先按固定顺序输出非零的标准等级, |
There was a problem hiding this comment.
和上次比,没有进步啊,非得排序一下,直接做一个[]auditreport.LevelCount的数组,长度4
每次统计的时候在对应的元素里面 LevelArray[index].count ++就行了
| } | ||
|
|
||
| // toLevelCounts 将等级分布 map 转为 LevelCount 切片(供测试与 map 输入场景)。 | ||
| func toLevelCounts(dist map[string]int) []auditreport.LevelCount { |
| }) | ||
| } | ||
|
|
||
| sort.Slice(result, func(i, j int) bool { |
There was a problem hiding this comment.
这里排序是合理的,在界面上规则顺序保持一致,提高影响用户体验
| "task_id": taskId, | ||
| "no_duplicate": req.NoDuplicate, | ||
| } | ||
| ctx := c.Request().Context() |
|
|
||
| // LevelCount 等级统计 | ||
| type LevelCount struct { | ||
| Level string `json:"level"` // normal/notice/warn/error |
User description
关联的 issue
描述你的变更
https://github.com/actiontech/sqle-ee/issues/2689
确认项(pr提交后操作)
Tip
请在指定复审人之前,确认并完成以下事项,完成后✅
not_compatibleneed_update_docDescription
新增审核报告多格式导出功能,支持CSV和HTML格式(企业版支持PDF/WORD)
实现通用报告生成器接口及导出格式规范化处理
重构下载审核报告接口,移除原有CSV构建逻辑,直接调用统一导出服务
补充单元测试、API文档、Swagger配置和本地化消息更新以支持新功能
Diagram Walkthrough
File Walkthrough
8 files
构建审核报告数据模型并统计SQL审核信息重构下载报告接口,增加export_format查询参数定义审核报告导出格式常量及规范化处理方法实现CSV格式报告生成器,复用CSVBuilder定义审核报告数据模型与通用ReportGenerator接口实现CE版统一导出入口,限制PDF/WORD格式实现HTML格式报告生成器,基于html/template渲染嵌入审核报告HTML模板文件,供HTML渲染使用3 files
添加审核报告数据构建功能单元测试添加CE版导出功能限制的单元测试为CSV与HTML报告生成器增加覆盖率测试7 files
更新API文档,增加导出格式参数说明添加审核报告导出相关本地化消息支持更新Swagger文档,增加export_format参数描述调整Swagger YAML,补充导出格式参数入参及响应描述增加英文本地化审核报告导出标签增加中文本地化审核报告导出标签添加审核报告HTML模板,定义各模块样式及布局1 files
更新文件保存函数注释,说明导出格式用途1 files
升级CI工作流中actions版本以提高稳定性