优化结构

This commit is contained in:
Yvan
2026-08-28 00:29:40 +08:00
parent 04ff85116c
commit 03a4131f6e
118 changed files with 758 additions and 834 deletions
+93 -13
View File
@@ -191,12 +191,103 @@ func (r *exportRepo) QueryExport(ctx context.Context, t *system.ExportTemplate,
if err != nil {
return nil, "", err
}
var rows []map[string]any
preview := query.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Find(&[]map[string]any{}) })
err = query.Find(&rows).Error
rows, err := queryExportRows(query)
return rows, preview, err
}
func queryExportRows(query *gorm.DB) ([]map[string]any, error) {
rows, err := query.Rows()
if err != nil {
return nil, err
}
defer rows.Close()
columns, err := rows.Columns()
if err != nil {
return nil, err
}
columnTypes, err := rows.ColumnTypes()
if err != nil {
return nil, err
}
result := make([]map[string]any, 0)
for rows.Next() {
values := make([]any, len(columns))
destinations := make([]any, len(values))
for index := range values {
destinations[index] = &values[index]
}
if err := rows.Scan(destinations...); err != nil {
return nil, err
}
item := make(map[string]any, len(columns))
for index, column := range columns {
typeName := ""
if index < len(columnTypes) {
typeName = columnTypes[index].DatabaseTypeName()
}
item[column] = exportQueryValue(values[index], typeName)
}
result = append(result, item)
}
if err := rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func exportQueryValue(value any, databaseType string) any {
bytesValue, ok := value.([]byte)
if !ok {
return value
}
raw := string(bytesValue)
typeName := strings.ToUpper(databaseType)
if strings.Contains(typeName, "INT") || strings.Contains(typeName, "SERIAL") {
if integer, err := strconv.ParseInt(raw, 10, 64); err == nil {
return integer
}
}
if strings.Contains(typeName, "DECIMAL") || strings.Contains(typeName, "NUMERIC") || strings.Contains(typeName, "NUMBER") || strings.Contains(typeName, "REAL") || strings.Contains(typeName, "DOUBLE") || strings.Contains(typeName, "FLOAT") {
if decimal, ok := exactExportFloat(raw); ok {
return decimal
}
}
return raw
}
func exactExportFloat(value string) (float64, bool) {
decimal, err := strconv.ParseFloat(value, 64)
if err != nil {
return 0, false
}
return decimal, normalizeDecimal(value) == normalizeDecimal(strconv.FormatFloat(decimal, 'f', -1, 64))
}
func normalizeDecimal(value string) string {
value = strings.TrimSpace(value)
negative := strings.HasPrefix(value, "-")
value = strings.TrimPrefix(value, "+")
value = strings.TrimPrefix(value, "-")
parts := strings.SplitN(value, ".", 2)
whole := strings.TrimLeft(parts[0], "0")
if whole == "" {
whole = "0"
}
fraction := ""
if len(parts) == 2 {
fraction = strings.TrimRight(parts[1], "0")
}
result := whole
if fraction != "" {
result += "." + fraction
}
if negative && result != "0" {
result = "-" + result
}
return result
}
func exportColumns(raw string) ([]string, error) {
columns := make([]string, 0)
decoder := json.NewDecoder(strings.NewReader(raw))
@@ -338,17 +429,6 @@ func (r *exportRepo) PreviewExport(ctx context.Context, t *system.ExportTemplate
}
return query.ToSQL(func(tx *gorm.DB) *gorm.DB { return tx.Find(&[]map[string]any{}) }), nil
}
func parseTemplateColumns(raw string) map[string]string {
out := map[string]string{}
parts := strings.Split(strings.Trim(strings.TrimSpace(raw), "{}"), ",")
for _, part := range parts {
pair := strings.SplitN(part, ":", 2)
if len(pair) == 2 {
out[strings.Trim(strings.TrimSpace(pair[0]), `"`)] = strings.Trim(strings.TrimSpace(pair[1]), `"`)
}
}
return out
}
func (r *exportRepo) ImportExportRows(ctx context.Context, t *system.ExportTemplate, rows []map[string]any) error {
if err := system.ValidateExportTemplate(t); err != nil {
return err