58 lines
1.7 KiB
Go
58 lines
1.7 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
func exportAuditCSV(events []ConfigAuditEvent) ([]byte, error) {
|
|
var builder strings.Builder
|
|
writer := csv.NewWriter(&builder)
|
|
if err := writer.Write([]string{"id", "operation", "section", "actor_id", "actor_role", "from_generation", "to_generation", "target_generation", "changed_fields", "confirmation_method", "result", "created_at", "actor_name", "changes"}); err != nil {
|
|
return nil, err
|
|
}
|
|
for _, event := range events {
|
|
changes, err := json.Marshal(event.Changes)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
cells := []string{
|
|
event.ID,
|
|
string(event.Operation),
|
|
string(event.Section),
|
|
event.ActorID,
|
|
event.ActorRole,
|
|
fmt.Sprintf("%d", event.FromGeneration),
|
|
fmt.Sprintf("%d", event.ToGeneration),
|
|
fmt.Sprintf("%d", event.TargetGeneration),
|
|
strings.Join(event.ChangedFields, ","),
|
|
event.ConfirmationMethod,
|
|
event.Result,
|
|
event.CreatedAt.UTC().Format(time.RFC3339Nano),
|
|
event.ActorName,
|
|
string(changes),
|
|
}
|
|
for index, cell := range cells {
|
|
if strings.HasPrefix(cell, "=") || strings.HasPrefix(cell, "+") || strings.HasPrefix(cell, "-") || strings.HasPrefix(cell, "@") || strings.HasPrefix(cell, "\t") || strings.HasPrefix(cell, "\r") {
|
|
cells[index] = "'" + cell
|
|
}
|
|
}
|
|
if err := writer.Write(cells); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
writer.Flush()
|
|
if err := writer.Error(); err != nil {
|
|
return nil, err
|
|
}
|
|
return []byte(builder.String()), nil
|
|
}
|
|
|
|
// ExportConfigAuditCSV 让文件、内存和数据库导出共享字段及表格公式保护。
|
|
func ExportConfigAuditCSV(events []ConfigAuditEvent) ([]byte, error) {
|
|
return exportAuditCSV(events)
|
|
}
|