优化结构

This commit is contained in:
Yvan
2026-08-24 13:56:06 +08:00
parent 0b6b8ddf1a
commit acaee94858
21 changed files with 249 additions and 3025 deletions
+177 -15
View File
@@ -3,7 +3,8 @@ package initialize
import (
"context"
"encoding/json"
"errors"
"fmt"
"time"
"kra/internal/config"
)
@@ -34,17 +35,20 @@ func (r *Repo) SaveConfigurationJSON(ctx context.Context, raw json.RawMessage) e
if err := json.Unmarshal(raw, &value); err != nil {
return err
}
if err := mergeJSON(value.Data, &next.Data); err != nil {
if next.Data == nil {
next.Data = &config.Data{}
}
if next.Admin == nil {
next.Admin = &config.Admin{}
}
if err := mergeDataJSON(value.Data, &next.Data); err != nil {
return err
}
if err := mergeJSON(value.Admin, &next.Admin); err != nil {
if err := mergeAdminJSON(value.Admin, &next.Admin); err != nil {
return err
}
if len(value.Email) > 0 && string(value.Email) != "null" {
if next.Admin == nil {
next.Admin = &config.Admin{}
}
if err := mergeJSON(value.Email, &next.Admin.Email); err != nil {
if err := mergeEmailJSON(value.Email, &next.Admin.Email); err != nil {
return err
}
}
@@ -79,13 +83,144 @@ func mergeJSON(raw json.RawMessage, target any) error {
return json.Unmarshal(raw, target)
}
func mergeDataJSON(raw json.RawMessage, target **config.Data) error {
return mergeJSONMap(raw, target, func(values map[string]any) error {
if redis := jsonObject(values["redis"]); redis != nil {
if err := normalizeDuration(redis, "read_timeout", "readTimeout"); err != nil {
return err
}
if err := normalizeDuration(redis, "write_timeout", "writeTimeout"); err != nil {
return err
}
}
if items, ok := values["redis_list"].([]any); ok {
for _, item := range items {
redis := jsonObject(item)
if err := normalizeDuration(redis, "read_timeout", "readTimeout"); err != nil {
return err
}
if err := normalizeDuration(redis, "write_timeout", "writeTimeout"); err != nil {
return err
}
}
}
return nil
})
}
func mergeAdminJSON(raw json.RawMessage, target **config.Admin) error {
return mergeJSONMap(raw, target, func(values map[string]any) error {
moveJSONKey(values, "routerPrefix", "router_prefix")
if jwt := jsonObject(values["jwt"]); jwt != nil {
moveJSONKey(jwt, "signingKey", "signing_key")
moveJSONKey(jwt, "expiresTime", "expires_time")
moveJSONKey(jwt, "bufferTime", "buffer_time")
if err := normalizeDuration(jwt, "expires_time", "expiresTime"); err != nil {
return err
}
if err := normalizeDuration(jwt, "buffer_time", "bufferTime"); err != nil {
return err
}
}
if captcha := jsonObject(values["captcha"]); captcha != nil {
moveJSONKey(captcha, "keyLong", "key_long")
moveJSONKey(captcha, "imgWidth", "img_width")
moveJSONKey(captcha, "imgHeight", "img_height")
moveJSONKey(captcha, "storeExpiration", "store_expiration")
return normalizeDuration(captcha, "store_expiration", "storeExpiration")
}
if local := jsonObject(values["local"]); local != nil {
moveJSONKey(local, "storePath", "store_path")
moveJSONKey(local, "pathPrefix", "path_prefix")
}
if media := jsonObject(values["media"]); media != nil {
moveJSONKey(media, "sessionTtl", "session_ttl")
moveJSONKey(media, "maxFileSize", "max_file_size")
moveJSONKey(media, "chunkDir", "chunk_dir")
}
if system := jsonObject(values["system"]); system != nil {
moveJSONKey(system, "useRedis", "use_redis")
moveJSONKey(system, "useMultipoint", "use_multipoint")
moveJSONKey(system, "useStrictAuth", "use_strict_auth")
moveJSONKey(system, "disableAutoMigrate", "disable_auto_migrate")
moveJSONKey(system, "useMongo", "use_mongo")
moveJSONKey(system, "iplimitCount", "iplimit_count")
moveJSONKey(system, "iplimitTime", "iplimit_time")
}
return nil
})
}
func mergeEmailJSON(raw json.RawMessage, target **config.Email) error {
return mergeJSONMap(raw, target, func(values map[string]any) error {
moveJSONKey(values, "is-ssl", "is_ssl")
moveJSONKey(values, "is-loginauth", "is_login_auth")
return nil
})
}
func mergeJSONMap(raw json.RawMessage, target any, transform func(map[string]any) error) error {
if len(raw) == 0 || string(raw) == "null" {
return nil
}
var values map[string]any
if err := json.Unmarshal(raw, &values); err != nil {
return err
}
if transform != nil {
if err := transform(values); err != nil {
return err
}
}
normalized, err := json.Marshal(values)
if err != nil {
return err
}
return mergeJSON(normalized, target)
}
func jsonObject(value any) map[string]any {
result, _ := value.(map[string]any)
return result
}
func normalizeDuration(values map[string]any, keys ...string) error {
if values == nil {
return nil
}
for _, key := range keys {
raw, ok := values[key]
if !ok {
continue
}
text, ok := raw.(string)
if !ok {
return nil
}
value, err := time.ParseDuration(text)
if err != nil {
return fmt.Errorf("invalid duration %q: %w", text, err)
}
values[key] = int64(value)
return nil
}
return nil
}
func moveJSONKey(values map[string]any, oldKey, newKey string) {
if value, ok := values[oldKey]; ok {
values[newKey] = value
delete(values, oldKey)
}
}
func managementConfig(value *config.Config) map[string]any {
result := map[string]any{"data": map[string]any{}, "admin": map[string]any{}, "email": map[string]any{}}
if value == nil {
return result
}
if value.Data != nil {
result["data"] = value.Data
result["data"] = managementData(value.Data)
}
if value.Admin != nil {
admin := value.Admin
@@ -113,6 +248,36 @@ func managementConfig(value *config.Config) map[string]any {
return result
}
func managementData(value *config.Data) any {
if value == nil {
return map[string]any{}
}
raw, err := json.Marshal(value)
if err != nil {
return value
}
var result map[string]any
if json.Unmarshal(raw, &result) != nil {
return value
}
if redis := jsonObject(result["redis"]); redis != nil {
redis["read_timeout"] = value.Redis.ReadTimeout.String()
redis["write_timeout"] = value.Redis.WriteTimeout.String()
}
if items, ok := result["redis_list"].([]any); ok {
for index, item := range items {
if index >= len(value.RedisList) || value.RedisList[index] == nil {
continue
}
if redis := jsonObject(item); redis != nil {
redis["read_timeout"] = value.RedisList[index].ReadTimeout.String()
redis["write_timeout"] = value.RedisList[index].WriteTimeout.String()
}
}
}
return result
}
func managementJWT(value *config.JWT) any {
if value == nil {
return map[string]any{}
@@ -336,14 +501,11 @@ func refreshDatabaseSource(database *config.Database) error {
if database == nil {
return nil
}
if database.Driver == "sqlite" && database.Path == "" {
return errors.New("sqlite database path is required")
}
if database.Driver == "sqlite" {
database.Source = database.Path
} else {
hasStructuredConfig := database.Host != "" || database.Port != "" || database.User != "" || database.Password != "" || database.Name != "" || database.Config != "" || database.Path != ""
if hasStructuredConfig {
// Driver-specific DSN construction remains in data. Clearing Source
// makes the data backend rebuild it from structured values.
// makes the data backend rebuild it from structured values, while a
// standalone DSN is preserved when no structured fields are supplied.
database.Source = ""
}
return nil