diff --git a/sqle/api/controller/v1/rule.go b/sqle/api/controller/v1/rule.go index 92b78d007..0e209f1e7 100644 --- a/sqle/api/controller/v1/rule.go +++ b/sqle/api/controller/v1/rule.go @@ -20,7 +20,6 @@ import ( "github.com/actiontech/sqle/sqle/locale" "github.com/actiontech/sqle/sqle/model" - "github.com/gocarina/gocsv" "github.com/labstack/echo/v4" ) @@ -1502,38 +1501,94 @@ func ExportRuleTemplateFile(c echo.Context) error { } func exportTemplateFile(c echo.Context, exportType ExportType, templateFile interface{}, templateName string) error { - var name, desc, dbType string - var content interface{} - if ruleTemplateExport, ok := templateFile.(*RuleTemplateExport); ok { - name = ruleTemplateExport.Name - desc = ruleTemplateExport.Desc - dbType = ruleTemplateExport.DBType - content = ruleTemplateExport.RuleList - } else if ruleTemplateExportErr, ok := templateFile.(*RuleTemplateExportErr); ok { - name = ruleTemplateExportErr.Name - desc = ruleTemplateExportErr.Desc - dbType = ruleTemplateExportErr.DBType - content = ruleTemplateExportErr.RuleList - } else { - return controller.JSONBaseErrorReq(c, errors.New(errors.DataInvalid, fmt.Errorf("template file is invalid"))) - } - switch exportType { case CsvExportType: + var name, desc, dbType string + var columnNameList []string + var columnContentList [][]string + + ctx := c.Request().Context() + defaultColumnNameList := []string{ + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleName), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleDesc), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleAnnotation), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleLevel), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleCategory), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateInstType), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleParam), + } + + convertToContentList := func(ruleTemplateInfo RuleTemplateRuleInfo) ([]string, error) { + paramsBytes, err := json.Marshal(ruleTemplateInfo.Params) + if err != nil { + return nil, err + } + + return []string{ + ruleTemplateInfo.Name, + ruleTemplateInfo.Desc, + ruleTemplateInfo.Annotation, + ruleTemplateInfo.Level, + ruleTemplateInfo.Typ, + ruleTemplateInfo.DBType, + string(paramsBytes), + }, nil + } + + if ruleTemplateExport, ok := templateFile.(*RuleTemplateExport); ok { + name = ruleTemplateExport.Name + desc = ruleTemplateExport.Desc + dbType = ruleTemplateExport.DBType + columnNameList = defaultColumnNameList + for _, res := range ruleTemplateExport.RuleList { + contentList, err := convertToContentList(res.RuleTemplateRuleInfo) + if err != nil { + return controller.JSONBaseErrorReq(c, err) + } + + columnContentList = append(columnContentList, contentList) + } + } else if ruleTemplateExportErr, ok := templateFile.(*RuleTemplateExportErr); ok { + name = ruleTemplateExportErr.Name + desc = ruleTemplateExportErr.Desc + dbType = ruleTemplateExportErr.DBType + columnNameList = append(defaultColumnNameList, locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateRuleErr)) + + for _, res := range ruleTemplateExportErr.RuleList { + contentList, err := convertToContentList(res.RuleTemplateRuleInfo) + if err != nil { + return controller.JSONBaseErrorReq(c, err) + } + + columnContentList = append(columnContentList, + contentList, + []string{res.RuleErr}, + ) + } + } else { + return controller.JSONBaseErrorReq(c, errors.New(errors.DataInvalid, fmt.Errorf("template file is invalid"))) + } + buf := new(bytes.Buffer) buf.WriteString("\xEF\xBB\xBF") // 写入UTF-8 BOM - writer := gocsv.DefaultCSVWriter(buf) - err := writer.WriteAll([][]string{{"规则模版名", "描述", "数据源类型"}, {name, desc, dbType}}) + writer := csv.NewWriter(buf) + err := writer.WriteAll([][]string{{ + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateName), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateDesc), + locale.Bundle.LocalizeMsgByCtx(ctx, locale.RuleTemplateInstType), + }, {name, desc, dbType}}) if err != nil { return controller.JSONBaseErrorReq(c, err) } - data, err := gocsv.MarshalBytes(content) - if err != nil { + if err = writer.Write(columnNameList); err != nil { + return controller.JSONBaseErrorReq(c, err) + } + + if err := writer.WriteAll(columnContentList); err != nil { return controller.JSONBaseErrorReq(c, err) } - buf.Write(data) c.Response().Header().Set(echo.HeaderContentDisposition, mime.FormatMediaType("attachment", map[string]string{"filename": fmt.Sprintf("RuleTemplate-%v.csv", templateName)})) @@ -1606,12 +1661,12 @@ type RuleTemplateRes struct { } type RuleTemplateRuleInfo struct { - Name string `csv:"规则名"` - Desc string `csv:"描述"` - Annotation string `csv:"规则注解"` - Level string `csv:"规则等级"` - Typ string `csv:"规则分类"` - DBType string `csv:"数据源类型"` + Name string + Desc string + Annotation string + Level string + Typ string + DBType string Params []RuleParamRes } @@ -1622,7 +1677,7 @@ type RuleTemplateExportErr struct { type RuleTemplateResErr struct { RuleTemplateRuleInfo - RuleErr string `csv:"问题"` + RuleErr string } type RuleParamRes struct { diff --git a/sqle/locale/active.en.toml b/sqle/locale/active.en.toml index 105d15f43..1995a9e27 100644 --- a/sqle/locale/active.en.toml +++ b/sqle/locale/active.en.toml @@ -76,6 +76,16 @@ ConfigFeishuTestContent = "This is a test approval, used to test whether the SQL ConfigTestAudit = "Test approval" DefaultRuleTemplatesDesc = "Default rule template" DefaultTemplatesDesc = "%s default template" +RuleTemplateName = "Rule template name" +RuleTemplateDesc = "Rule template description" +RuleTemplateInstType = "instance type" +RuleTemplateRuleName = "rule name" +RuleTemplateRuleDesc = "desc" +RuleTemplateRuleAnnotation = "annotation" +RuleTemplateRuleLevel = "level" +RuleTemplateRuleCategory = "category" +RuleTemplateRuleParam = "param" +RuleTemplateRuleErr = "error" EnumSlowLogFileSource = "Collected from slow.log file, need to adapt scanner" EnumSlowLogTableSource = "Collected from mysql.slow_log table" ExportCreateTime = "Created time" diff --git a/sqle/locale/active.zh.toml b/sqle/locale/active.zh.toml index d4f91b8ea..4476bf0a8 100644 --- a/sqle/locale/active.zh.toml +++ b/sqle/locale/active.zh.toml @@ -76,6 +76,16 @@ ConfigFeishuTestContent = "这是一条测试审批,用来测试SQLE飞书审批 ConfigTestAudit = "测试审批" DefaultRuleTemplatesDesc = "默认规则模板" DefaultTemplatesDesc = "%s 默认模板" +RuleTemplateName = "规则模板名" +RuleTemplateDesc = "规则模板描述" +RuleTemplateInstType = "数据源类型" +RuleTemplateRuleName = "规则名" +RuleTemplateRuleDesc = "规则描述" +RuleTemplateRuleAnnotation = "规则注解" +RuleTemplateRuleLevel = "规则等级" +RuleTemplateRuleCategory = "规则分类" +RuleTemplateRuleParam = "规则参数" +RuleTemplateRuleErr = "问题" EnumSlowLogFileSource = "从slow.log 文件采集,需要适配scanner" EnumSlowLogTableSource = "从mysql.slow_log 表采集" ExportCreateTime = "创建时间" diff --git a/sqle/locale/message_zh.go b/sqle/locale/message_zh.go index 0d24fcf89..283941c28 100644 --- a/sqle/locale/message_zh.go +++ b/sqle/locale/message_zh.go @@ -17,8 +17,18 @@ import ( // rule template var ( - DefaultRuleTemplatesDesc = &i18n.Message{ID: "DefaultRuleTemplatesDesc", Other: "默认规则模板"} - DefaultTemplatesDesc = &i18n.Message{ID: "DefaultTemplatesDesc", Other: "%s 默认模板"} + DefaultRuleTemplatesDesc = &i18n.Message{ID: "DefaultRuleTemplatesDesc", Other: "默认规则模板"} + DefaultTemplatesDesc = &i18n.Message{ID: "DefaultTemplatesDesc", Other: "%s 默认模板"} + RuleTemplateName = &i18n.Message{ID: "RuleTemplateName", Other: "规则模板名"} + RuleTemplateDesc = &i18n.Message{ID: "RuleTemplateDesc", Other: "规则模板描述"} + RuleTemplateInstType = &i18n.Message{ID: "RuleTemplateInstType", Other: "数据源类型"} + RuleTemplateRuleName = &i18n.Message{ID: "RuleTemplateRuleName", Other: "规则名"} + RuleTemplateRuleDesc = &i18n.Message{ID: "RuleTemplateRuleDesc", Other: "规则描述"} + RuleTemplateRuleAnnotation = &i18n.Message{ID: "RuleTemplateRuleAnnotation", Other: "规则注解"} + RuleTemplateRuleLevel = &i18n.Message{ID: "RuleTemplateRuleLevel", Other: "规则等级"} + RuleTemplateRuleCategory = &i18n.Message{ID: "RuleTemplateRuleCategory", Other: "规则分类"} + RuleTemplateRuleParam = &i18n.Message{ID: "RuleTemplateRuleParam", Other: "规则参数"} + RuleTemplateRuleErr = &i18n.Message{ID: "RuleTemplateRuleErr", Other: "问题"} ) // task