diff --git a/mateclaw-server/src/main/java/vip/mate/system/model/SystemSettingsDTO.java b/mateclaw-server/src/main/java/vip/mate/system/model/SystemSettingsDTO.java index 42f012a5..2687d01f 100644 --- a/mateclaw-server/src/main/java/vip/mate/system/model/SystemSettingsDTO.java +++ b/mateclaw-server/src/main/java/vip/mate/system/model/SystemSettingsDTO.java @@ -34,6 +34,14 @@ public class SystemSettingsDTO { private String serperApiKeyMasked; private String tavilyApiKeyMasked; + // ===== WeChat Official Account (公众号) publish credentials ===== + /** 公众号 AppID (plain — not sensitive). */ + private String weixinoaAppId; + /** 公众号 AppSecret — write-only from the client; never echoed in plaintext. */ + private String weixinoaAppSecret; + /** Masked AppSecret for display. */ + private String weixinoaAppSecretMasked; + // ===== 视频生成配置 ===== /** 是否启用视频生成能力 */ private Boolean videoEnabled; 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 d21431fc..589d11eb 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 @@ -30,6 +30,10 @@ public class SystemSettingService { private static final String SERPER_BASE_URL_KEY = "serperBaseUrl"; private static final String TAVILY_API_KEY_KEY = "tavilyApiKey"; private static final String TAVILY_BASE_URL_KEY = "tavilyBaseUrl"; + + // WeChat Official Account (公众号) publish credentials — read by GzhPublishTool. + private static final String WEIXINOA_APP_ID_KEY = "weixinoa.app_id"; + private static final String WEIXINOA_APP_SECRET_KEY = "weixinoa.app_secret"; private static final String DUCKDUCKGO_ENABLED_KEY = "duckduckgoEnabled"; private static final String SEARXNG_BASE_URL_KEY = "searxngBaseUrl"; @@ -139,6 +143,10 @@ public class SystemSettingService { dto.setSerperApiKeyMasked(maskApiKey(getValue(SERPER_API_KEY_KEY, ""))); dto.setTavilyApiKeyMasked(maskApiKey(getValue(TAVILY_API_KEY_KEY, ""))); + // 公众号发布凭证(AppSecret 脱敏回显,AppID 明文) + dto.setWeixinoaAppId(getValue(WEIXINOA_APP_ID_KEY, "")); + dto.setWeixinoaAppSecretMasked(maskApiKey(getValue(WEIXINOA_APP_SECRET_KEY, ""))); + // 视频生成配置 dto.setVideoEnabled(Boolean.parseBoolean(getValue(VIDEO_ENABLED_KEY, "false"))); dto.setVideoProvider(getValue(VIDEO_PROVIDER_KEY, "auto")); @@ -295,6 +303,14 @@ public class SystemSettingService { if (dto.getTavilyBaseUrl() != null) { saveValue(TAVILY_BASE_URL_KEY, dto.getTavilyBaseUrl(), "Tavily 接口地址"); } + + // 公众号发布凭证(AppSecret 仅在非空时保存,避免脱敏回显覆盖为空) + if (dto.getWeixinoaAppId() != null) { + saveValue(WEIXINOA_APP_ID_KEY, dto.getWeixinoaAppId().trim(), "公众号 AppID"); + } + if (dto.getWeixinoaAppSecret() != null && !dto.getWeixinoaAppSecret().isBlank()) { + saveValue(WEIXINOA_APP_SECRET_KEY, dto.getWeixinoaAppSecret().trim(), "公众号 AppSecret"); + } // Keyless provider 配置 if (dto.getDuckduckgoEnabled() != null) { saveValue(DUCKDUCKGO_ENABLED_KEY, String.valueOf(dto.getDuckduckgoEnabled()), "DuckDuckGo 免 Key 搜索(零配置兜底)"); diff --git a/mateclaw-server/src/main/java/vip/mate/tool/builtin/GzhPackageTool.java b/mateclaw-server/src/main/java/vip/mate/tool/builtin/GzhPackageTool.java index 3c1bec85..b4c924a9 100644 --- a/mateclaw-server/src/main/java/vip/mate/tool/builtin/GzhPackageTool.java +++ b/mateclaw-server/src/main/java/vip/mate/tool/builtin/GzhPackageTool.java @@ -101,8 +101,14 @@ public class GzhPackageTool { // 1. Markdown -> HTML fragment, then inline every style (公众号 drops