This commit is contained in:
2026-04-18 12:25:58 +03:00
parent 2068154656
commit ebabe7e6d8
3 changed files with 237 additions and 18 deletions

View File

@@ -304,6 +304,20 @@ public class MainVerticle extends AbstractVerticle {
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
// Получить метаданные всех настроек (для построения формы)
router.get("/api/settings/meta").handler(rc -> {
settingsService.getMetadata()
.onSuccess(meta -> rc.response().putHeader("Content-Type", "application/json").end(meta.encode()))
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
// Получить все настройки со значениями по умолчанию
router.get("/api/settings/all").handler(rc -> {
settingsService.getAllWithDefaults()
.onSuccess(settings -> rc.response().putHeader("Content-Type", "application/json").end(settings.encode()))
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
// Обновление настроек (админ)
router.put("/api/admin/settings").handler(rc -> {
JsonObject body = rc.body().asJsonObject();

View File

@@ -1,6 +1,7 @@
package su.xserver.iikocon;
import io.vertx.core.Future;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.sqlclient.Pool;
import io.vertx.sqlclient.templates.SqlTemplate;
@@ -12,6 +13,111 @@ public class SettingsService {
public SettingsService(Pool pool) { this.pool = pool; }
public Future<JsonArray> getMetadata() {
JsonArray meta = new JsonArray();
meta.add(new JsonObject()
.put("key", "site_name")
.put("label", "Site Name")
.put("description", "The name of the application shown in the header and title")
.put("type", "text")
.put("required", true)
);
meta.add(new JsonObject()
.put("key", "site_description")
.put("label", "Site Description")
.put("description", "Brief description for SEO and meta tags")
.put("type", "textarea")
.put("rows", 2)
);
meta.add(new JsonObject()
.put("key", "theme")
.put("label", "Theme")
.put("description", "Default color scheme")
.put("type", "select")
.put("options", new JsonArray()
.add(new JsonObject().put("value", "light").put("label", "Light"))
.add(new JsonObject().put("value", "dark").put("label", "Dark"))
.add(new JsonObject().put("value", "auto").put("label", "Auto (system preference)"))
)
);
meta.add(new JsonObject()
.put("key", "items_per_page")
.put("label", "Items Per Page")
.put("description", "Number of items shown in tables")
.put("type", "number")
.put("required", true)
);
meta.add(new JsonObject()
.put("key", "enable_registration")
.put("label", "Allow Public Registration")
.put("description", "If disabled, only admin can create users")
.put("type", "boolean")
);
meta.add(new JsonObject()
.put("key", "maintenance_mode")
.put("label", "Maintenance Mode")
.put("description", "When enabled, only admins can access the site")
.put("type", "boolean")
);
meta.add(new JsonObject()
.put("key", "default_language")
.put("label", "Default Language")
.put("description", "Interface language")
.put("type", "select")
.put("options", new JsonArray()
.add(new JsonObject().put("value", "en").put("label", "English"))
.add(new JsonObject().put("value", "ru").put("label", "Русский"))
.add(new JsonObject().put("value", "es").put("label", "Español"))
)
);
meta.add(new JsonObject()
.put("key", "session_timeout_minutes")
.put("label", "Session Timeout (minutes)")
.put("description", "How long until inactive users are logged out")
.put("type", "number")
.put("required", true)
);
meta.add(new JsonObject()
.put("key", "logo_url")
.put("label", "Logo URL")
.put("description", "Path or URL to custom logo image")
.put("type", "text")
);
return Future.succeededFuture(meta);
}
public Future<JsonObject> getAllWithDefaults() {
return getAll().compose(values -> {
JsonObject result = new JsonObject();
// Получаем метаданные, чтобы знать ключи
return getMetadata().map(meta -> {
for (Object item : meta) {
JsonObject m = (JsonObject) item;
String key = m.getString("key");
String defaultValue = getDefaultValueByKey(key);
String current = values.getString(key);
result.put(key, current != null ? current : defaultValue);
}
return result;
});
});
}
private String getDefaultValueByKey(String key) {
return switch (key) {
case "site_name" -> "Admin Panel";
case "site_description" -> "";
case "theme" -> "light";
case "items_per_page" -> "20";
case "enable_registration" -> "true";
case "maintenance_mode" -> "false";
case "default_language" -> "en";
case "session_timeout_minutes" -> "60";
case "logo_url" -> "";
default -> "";
};
}
public Future<Void> initDatabase() {
String createTable = """
CREATE TABLE IF NOT EXISTS app_settings (