M0-M11 狩夜人笔记初始实现:11里程碑+86测试

This commit is contained in:
hunter-dev
2026-08-24 20:35:22 +08:00
commit 3ebd33536b
106 changed files with 10490 additions and 0 deletions
@@ -0,0 +1,53 @@
// VaultService — 统筹库管理:默认库、切换、最近库(FR-V)
import nodePath from 'node:path';
import { promises as fs } from 'node:fs';
import { app, dialog } from 'electron';
import { DEFAULT_VAULT_NAME } from '@hunter/shared';
import type { VaultMeta } from '@hunter/shared';
import { ConfigStore } from './config-store.js';
import { FileService } from './file-service.js';
import { SearchService } from './search-service.js';
export class VaultService {
fileService: FileService | null = null;
searchService: SearchService | null = null;
private config: ConfigStore;
constructor() {
this.config = new ConfigStore(app.getPath('userData'));
}
// 启动时初始化:确保有当前库(无则创建默认库)
async init(): Promise<VaultMeta> {
let meta = await this.config.getVaultMeta();
if (!meta.currentRoot) {
const defaultRoot = nodePath.join(app.getPath('userData'), DEFAULT_VAULT_NAME);
await fs.mkdir(defaultRoot, { recursive: true });
meta = await this.config.setCurrentRoot(defaultRoot);
}
this.fileService = new FileService(meta.currentRoot);
this.searchService = new SearchService(meta.currentRoot, this.fileService);
return meta;
}
async getMeta(): Promise<VaultMeta> { return this.config.getVaultMeta(); }
// 通过系统对话框选择并切换库(FR-V3)
async pickAndSwitch(): Promise<VaultMeta | null> {
const result = await dialog.showOpenDialog({ properties: ['openDirectory'] });
if (result.canceled || result.filePaths.length === 0) return null;
return this.switch(result.filePaths[0]);
}
async switch(root: string): Promise<VaultMeta> {
// 校验是存在的目录
const stat = await fs.stat(root).catch(() => null);
if (!stat || !stat.isDirectory()) throw new Error('目标路径不是有效目录: ' + root);
const meta = await this.config.setCurrentRoot(root);
this.fileService = new FileService(root);
this.searchService = new SearchService(root, this.fileService);
return meta;
}
async setDefaultRoot(root: string): Promise<void> { await this.config.setDefaultRoot(root); }
}