diff --git a/docker-compose.yml b/docker-compose.yml index d8308237..59310964 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -71,6 +71,8 @@ services: SERPER_API_KEY: ${SERPER_API_KEY:-} JWT_SECRET: ${JWT_SECRET:-} MATECLAW_CORS_ALLOWED_ORIGINS: ${MATECLAW_CORS_ALLOWED_ORIGINS:-} + # SearXNG: tell the app where to reach the sidecar container + SEARXNG_BASE_URL: ${SEARXNG_BASE_URL:-http://searxng:8080} ports: - "18080:18088" # host:container — app listens on 18088 inside the container volumes: diff --git a/mateclaw-server/src/main/java/vip/mate/system/service/SystemSettingService.java b/mateclaw-server/src/main/java/vip/mate/system/service/SystemSettingService.java index 8471102c..6251c0f4 100644 --- a/mateclaw-server/src/main/java/vip/mate/system/service/SystemSettingService.java +++ b/mateclaw-server/src/main/java/vip/mate/system/service/SystemSettingService.java @@ -64,6 +64,18 @@ public class SystemSettingService { private final SystemSettingMapper systemSettingMapper; + /** + * Resolve the SearXNG base URL: DB value takes priority; fall back to the + * {@code SEARXNG_BASE_URL} environment variable so Docker deployments work + * out-of-the-box without manual configuration in the UI. + */ + private String resolveSearxngBaseUrl() { + String dbValue = getValue(SEARXNG_BASE_URL_KEY, ""); + if (dbValue != null && !dbValue.isBlank()) return dbValue; + String envValue = System.getenv("SEARXNG_BASE_URL"); + return (envValue != null && !envValue.isBlank()) ? envValue : ""; + } + public SystemSettingsDTO getSettings() { SystemSettingsDTO dto = new SystemSettingsDTO(); dto.setLanguage(getValue(LANGUAGE_KEY, "zh-CN")); @@ -79,7 +91,7 @@ public class SystemSettingService { dto.setTavilyBaseUrl(getValue(TAVILY_BASE_URL_KEY, "https://api.tavily.com/search")); // Keyless provider 配置 dto.setDuckduckgoEnabled(Boolean.parseBoolean(getValue(DUCKDUCKGO_ENABLED_KEY, "true"))); - dto.setSearxngBaseUrl(getValue(SEARXNG_BASE_URL_KEY, "")); + dto.setSearxngBaseUrl(resolveSearxngBaseUrl()); // API Key 脱敏回显 dto.setSerperApiKeyMasked(maskApiKey(getValue(SERPER_API_KEY_KEY, ""))); dto.setTavilyApiKeyMasked(maskApiKey(getValue(TAVILY_API_KEY_KEY, ""))); @@ -153,7 +165,7 @@ public class SystemSettingService { dto.setTavilyApiKey(getValue(TAVILY_API_KEY_KEY, "")); dto.setTavilyBaseUrl(getValue(TAVILY_BASE_URL_KEY, "https://api.tavily.com/search")); dto.setDuckduckgoEnabled(Boolean.parseBoolean(getValue(DUCKDUCKGO_ENABLED_KEY, "true"))); - dto.setSearxngBaseUrl(getValue(SEARXNG_BASE_URL_KEY, "")); + dto.setSearxngBaseUrl(resolveSearxngBaseUrl()); return dto; } diff --git a/mateclaw-server/src/main/resources/db/migration/h2/V38__wiki_chunk_content_mediumtext.sql b/mateclaw-server/src/main/resources/db/migration/h2/V38__wiki_chunk_content_mediumtext.sql new file mode 100644 index 00000000..2e233ccb --- /dev/null +++ b/mateclaw-server/src/main/resources/db/migration/h2/V38__wiki_chunk_content_mediumtext.sql @@ -0,0 +1,3 @@ +-- V38: Expand mate_wiki_chunk.content to CLOB (H2 equivalent of MEDIUMTEXT) +-- H2's TEXT is already effectively unbounded, but align with MySQL change for consistency. +ALTER TABLE mate_wiki_chunk ALTER COLUMN content CLOB NOT NULL; diff --git a/mateclaw-server/src/main/resources/db/migration/mysql/V38__wiki_chunk_content_mediumtext.sql b/mateclaw-server/src/main/resources/db/migration/mysql/V38__wiki_chunk_content_mediumtext.sql new file mode 100644 index 00000000..e98c7898 --- /dev/null +++ b/mateclaw-server/src/main/resources/db/migration/mysql/V38__wiki_chunk_content_mediumtext.sql @@ -0,0 +1,11 @@ +-- V38: Expand mate_wiki_chunk.content from TEXT (64KB) to MEDIUMTEXT (16MB) +-- TEXT max = 65,535 bytes; a 30,000-char Chinese chunk needs ~90,000 bytes (3 bytes/char UTF-8). +-- MEDIUMTEXT supports up to 16,777,215 bytes, safely covering any realistic chunk size. +SET @c := (SELECT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS + WHERE TABLE_SCHEMA = DATABASE() + AND TABLE_NAME = 'mate_wiki_chunk' + AND COLUMN_NAME = 'content'); +SET @s := IF(@c = 'text', + 'ALTER TABLE mate_wiki_chunk MODIFY COLUMN content MEDIUMTEXT NOT NULL', + 'SELECT 1'); +PREPARE stmt FROM @s; EXECUTE stmt; DEALLOCATE PREPARE stmt;