up
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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 (
|
||||
|
||||
Reference in New Issue
Block a user