|
|
@@ -15,6 +15,8 @@ import javax.annotation.PostConstruct;
|
|
|
import javax.annotation.PreDestroy;
|
|
|
import java.nio.file.Files;
|
|
|
import java.nio.file.Paths;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.List;
|
|
|
@@ -36,11 +38,30 @@ public class NotionServiceImpl implements INotionService {
|
|
|
private String tokenV2;
|
|
|
private ExecutorService executor;
|
|
|
|
|
|
+ /** 月度容器页缓存: "2026-08" -> pageId,避免所有页面堆积在同一父页面下导致内容超限 */
|
|
|
+ private final ConcurrentHashMap<String, String> monthlyContainers = new ConcurrentHashMap<>();
|
|
|
+ private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
|
|
|
+
|
|
|
@PostConstruct
|
|
|
public void init() {
|
|
|
executor = Executors.newFixedThreadPool(notionConfig.getThreadCount());
|
|
|
+ initParentPage();
|
|
|
+
|
|
|
+ // 加载 token_v2
|
|
|
+ try {
|
|
|
+ tokenV2 = new String(Files.readAllBytes(Paths.get("C:/token_v2.txt"))).trim();
|
|
|
+ log.info("[Notion] token_v2 已加载");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("[Notion] 未找到 token_v2.txt,页面将不会自动公开");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 初始化父页面 ID,支持懒加载重试
|
|
|
+ */
|
|
|
+ private synchronized boolean initParentPage() {
|
|
|
+ if (parentPageId != null) return true;
|
|
|
|
|
|
- // 初始化,获取父页面 ID
|
|
|
try (NotionClient client = new NotionClient(notionConfig.getApiKey())) {
|
|
|
JsonNode result = client.search("");
|
|
|
JsonNode results = result.get("results");
|
|
|
@@ -58,24 +79,34 @@ public class NotionServiceImpl implements INotionService {
|
|
|
}
|
|
|
} catch (Exception ignored) {}
|
|
|
log.info("[Notion] 父页面: {} ({})", title, parentPageId);
|
|
|
- break;
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- if (parentPageId == null) {
|
|
|
- log.warn("[Notion] 未找到可用的父页面,请确保 Integration 已关联页面");
|
|
|
- }
|
|
|
+ log.warn("[Notion] 未找到可用的父页面,请确保 Integration 已关联页面");
|
|
|
+ return false;
|
|
|
} catch (Exception e) {
|
|
|
- log.error("[Notion] 初始化失败", e);
|
|
|
+ log.error("[Notion] 初始化父页面失败", e);
|
|
|
+ return false;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- // 加载 token_v2
|
|
|
- try {
|
|
|
- tokenV2 = new String(Files.readAllBytes(Paths.get("C:/token_v2.txt"))).trim();
|
|
|
- log.info("[Notion] token_v2 已加载");
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("[Notion] 未找到 token_v2.txt,页面将不会自动公开");
|
|
|
- }
|
|
|
+ /**
|
|
|
+ * 获取或创建当前月份的容器页,将页面分散到月度子目录下,避免父页面内容超限
|
|
|
+ */
|
|
|
+ private String getOrCreateMonthlyContainer() {
|
|
|
+ String monthKey = LocalDate.now().format(MONTH_FORMATTER);
|
|
|
+ return monthlyContainers.computeIfAbsent(monthKey, k -> {
|
|
|
+ try (NotionClient client = new NotionClient(notionConfig.getApiKey())) {
|
|
|
+ JsonNode page = client.createPageUnderPage(parentPageId, k);
|
|
|
+ String containerId = page.get("id").asText();
|
|
|
+ log.info("[Notion] 创建月度容器页: {} -> {}", k, containerId);
|
|
|
+ return containerId;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("[Notion] 创建月度容器页失败: {}", k, e);
|
|
|
+ throw new RuntimeException("创建月度容器页失败: " + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -150,7 +181,7 @@ public class NotionServiceImpl implements INotionService {
|
|
|
|
|
|
@Override
|
|
|
public String[] createPageWithPublish(String title, String iframeUrl) {
|
|
|
- if (parentPageId == null) {
|
|
|
+ if (parentPageId == null && !initParentPage()) {
|
|
|
throw new IllegalStateException("父页面未初始化,请确保 Integration 已关联页面");
|
|
|
}
|
|
|
|
|
|
@@ -167,8 +198,11 @@ public class NotionServiceImpl implements INotionService {
|
|
|
embedBlock.put("embed", Collections.singletonMap("url", iframeUrl));
|
|
|
List<Map<String, Object>> children = Collections.singletonList(embedBlock);
|
|
|
|
|
|
+ // 获取当月容器页,避免所有页面堆积在同一父页面下导致内容超限
|
|
|
+ String containerPageId = getOrCreateMonthlyContainer();
|
|
|
+
|
|
|
// 创建页面
|
|
|
- JsonNode page = client.createPageWithChildren(parentPageId, title, children);
|
|
|
+ JsonNode page = client.createPageWithChildren(containerPageId, title, children);
|
|
|
String pageId = page.get("id").asText();
|
|
|
String notionUrl = page.get("url").asText();
|
|
|
String publicUrl = notionUrl;
|