优化结构
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user