Files
blog/write-server/src/lib/bot/sessions.ts
T
2026-06-22 13:43:22 +08:00

103 lines
2.7 KiB
TypeScript

import { createPost, updatePost, getPost } from "@/lib/posts";
import { DEFAULT_AUTHOR, CONTENT_DIR } from "@/lib/config";
import path from "path";
export interface Session {
title: string;
slug: string;
content: string;
categories: string[];
tags: string[];
author: string;
draft: boolean;
chunks: string[];
originalSlug?: string;
dirPath: string;
}
function computeDirPath(title: string, date?: string, slug?: string): string {
const d = date ? new Date(date) : new Date();
const year = d.getFullYear().toString();
const dateStr = d.toISOString().slice(0, 10);
const titlePart = (title || "untitled")
.replace(/[^\w一-鿿㐀-䶿]+/g, "-")
.replace(/^-+|-+$/g, "")
.toLowerCase() || "post";
const uniquePart = slug || Date.now().toString(36);
return path.join(CONTENT_DIR, year, `${dateStr}-${titlePart}-${uniquePart}`);
}
const sessions = new Map<number, Session>();
export function getSession(chatId: number): Session {
if (!sessions.has(chatId)) {
sessions.set(chatId, {
title: "",
slug: "",
content: "",
categories: [],
tags: [],
author: DEFAULT_AUTHOR,
draft: true,
chunks: [],
dirPath: "",
});
}
return sessions.get(chatId)!;
}
export function hasSession(chatId: number): boolean {
return sessions.has(chatId);
}
export function clearSession(chatId: number): void {
sessions.delete(chatId);
}
export function appendContent(chatId: number, text: string): void {
const s = getSession(chatId);
s.chunks.push(text + "\n\n");
s.content += text + "\n\n";
}
export function undoLastChunk(chatId: number): boolean {
const s = getSession(chatId);
if (s.chunks.length === 0) return false;
const lastChunk = s.chunks.pop()!;
const idx = s.content.lastIndexOf(lastChunk);
if (idx >= 0) {
s.content = s.content.slice(0, idx) + s.content.slice(idx + lastChunk.length);
}
return true;
}
export function initSessionDir(chatId: number, title: string, date?: string): void {
const s = getSession(chatId);
if (!s.dirPath) {
s.dirPath = computeDirPath(title, date, s.slug);
}
}
export async function saveSession(s: Session, isDraft: boolean): Promise<void> {
const dateStr = new Date().toISOString().slice(0, 10);
const frontMatter = {
title: s.title,
slug: s.slug,
date: dateStr,
draft: isDraft,
categories: s.categories,
tags: s.tags,
author: s.author,
};
const existing = getPost(s.slug);
if (existing) {
const result = updatePost(s.slug, frontMatter, s.content);
if (!result.success) throw new Error("更新文章失败");
s.dirPath = result.dirPath;
} else {
const dirPath = createPost(frontMatter, s.content);
s.dirPath = dirPath;
}
}