Add login gate, calculation history, and AI markdown download.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-13 09:39:38 +08:00
parent abf78cbbb5
commit 462bec2739
23 changed files with 878 additions and 74 deletions
+66
View File
@@ -0,0 +1,66 @@
import {
HISTORY_MAX_ITEMS,
HISTORY_STORAGE_KEY,
type CalcHistoryEntry,
} from "@/lib/history/types";
export function loadHistory(): CalcHistoryEntry[] {
if (typeof window === "undefined") {
return [];
}
try {
const raw = localStorage.getItem(HISTORY_STORAGE_KEY);
if (!raw) {
return [];
}
const parsed = JSON.parse(raw) as CalcHistoryEntry[];
return Array.isArray(parsed) ? parsed : [];
} catch {
return [];
}
}
export function saveHistoryEntry(
entry: Omit<CalcHistoryEntry, "id" | "createdAt">,
): CalcHistoryEntry {
const full: CalcHistoryEntry = {
...entry,
id: crypto.randomUUID(),
createdAt: new Date().toISOString(),
};
const list = [full, ...loadHistory()].slice(0, HISTORY_MAX_ITEMS);
localStorage.setItem(HISTORY_STORAGE_KEY, JSON.stringify(list));
return full;
}
export function deleteHistoryEntry(id: string): void {
const list = loadHistory().filter((e) => e.id !== id);
localStorage.setItem(HISTORY_STORAGE_KEY, JSON.stringify(list));
}
export function downloadMarkdown(content: string, filename: string) {
const blob = new Blob([content], { type: "text/markdown;charset=utf-8" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = filename.endsWith(".md") ? filename : `${filename}.md`;
a.click();
URL.revokeObjectURL(url);
}
export function buildHistoryMarkdown(entry: CalcHistoryEntry): string {
const lines = [
`# ${entry.title}`,
"",
`- 类型:${entry.mode}`,
`- 时间:${new Date(entry.createdAt).toLocaleString("zh-CN")}`,
`- 问事:${entry.question}`,
"",
...Object.entries(entry.meta).map(([k, v]) => `- ${k}${v}`),
"",
"---",
"",
entry.completion,
];
return lines.join("\n");
}
+21
View File
@@ -0,0 +1,21 @@
export type CalcMode = "liuyao" | "bazi" | "combined";
export interface CalcHistoryEntry {
id: string;
mode: CalcMode;
title: string;
question: string;
summary: string;
completion: string;
meta: Record<string, string>;
createdAt: string;
}
export const HISTORY_STORAGE_KEY = "zhimingge-calc-history";
export const HISTORY_MAX_ITEMS = 100;
export const MODE_LABELS: Record<CalcMode, string> = {
liuyao: "六爻算卦",
bazi: "生辰八字",
combined: "综合测算",
};