storage.ts•9.17 kB
import fs from 'fs-extra';
import path from 'path';
import config from './config.js';
import { Project, IProject } from '../models/Project.js';
import { Document, IDocument } from '../models/Document.js';
import { Rule, IRule } from '../models/Rule.js';
/**
* 项目数据存储类
*/
export class ProjectStorage {
private projectsFile: string;
private projects: Map<string, Project>;
constructor() {
this.projectsFile = config.projectsDataFile;
this.projects = new Map();
}
/**
* 加载所有项目数据
*/
async load(): Promise<void> {
try {
if (await fs.pathExists(this.projectsFile)) {
const data = await fs.readJSON(this.projectsFile);
this.projects.clear();
data.forEach((item: IProject) => {
const project = Project.fromJSON(item);
this.projects.set(project.id, project);
});
}
} catch (error) {
console.error('加载项目数据失败:', error);
this.projects.clear();
}
}
/**
* 保存所有项目数据
*/
async save(): Promise<void> {
try {
const data = Array.from(this.projects.values()).map(project => project.toJSON());
await fs.writeJSON(this.projectsFile, data, { spaces: 2 });
} catch (error) {
console.error('保存项目数据失败:', error);
}
}
/**
* 获取所有项目
*/
async getAll(): Promise<Project[]> {
await this.load();
return Array.from(this.projects.values());
}
/**
* 根据ID获取项目
*/
async getById(id: string): Promise<Project | null> {
await this.load();
return this.projects.get(id) || null;
}
/**
* 创建新项目
*/
async create(name: string, description: string, rules?: string[]): Promise<Project> {
await this.load();
const project = new Project(name, description, rules);
this.projects.set(project.id, project);
await this.save();
// 创建项目目录
const projectDir = path.join(config.projectsDir, project.id);
await fs.ensureDir(projectDir);
return project;
}
/**
* 更新项目
*/
async update(id: string, name?: string, description?: string, rules?: string[]): Promise<Project | null> {
await this.load();
const project = this.projects.get(id);
if (!project) return null;
project.update(name, description, rules);
await this.save();
return project;
}
/**
* 删除项目
*/
async delete(id: string): Promise<boolean> {
await this.load();
if (!this.projects.has(id)) return false;
this.projects.delete(id);
await this.save();
// 删除项目目录
const projectDir = path.join(config.projectsDir, id);
if (await fs.pathExists(projectDir)) {
await fs.remove(projectDir);
}
return true;
}
}
/**
* 文档数据存储类
*/
export class DocumentStorage {
private documentsFile: string;
private documents: Map<string, Document>;
constructor() {
this.documentsFile = config.documentsDataFile;
this.documents = new Map();
}
/**
* 加载所有文档数据
*/
async load(): Promise<void> {
try {
if (await fs.pathExists(this.documentsFile)) {
const data = await fs.readJSON(this.documentsFile);
this.documents.clear();
data.forEach((item: IDocument) => {
const doc = Document.fromJSON(item);
this.documents.set(doc.id, doc);
});
}
} catch (error) {
console.error('加载文档数据失败:', error);
this.documents.clear();
}
}
/**
* 保存所有文档数据
*/
async save(): Promise<void> {
try {
const data = Array.from(this.documents.values()).map(doc => doc.toJSON());
await fs.writeJSON(this.documentsFile, data, { spaces: 2 });
} catch (error) {
console.error('保存文档数据失败:', error);
}
}
/**
* 获取所有文档
*/
async getAll(): Promise<Document[]> {
await this.load();
return Array.from(this.documents.values());
}
/**
* 根据项目ID获取文档
*/
async getByProjectId(projectId: string): Promise<Document[]> {
await this.load();
return Array.from(this.documents.values()).filter(doc => doc.projectId === projectId);
}
/**
* 根据ID获取文档
*/
async getById(id: string): Promise<Document | null> {
await this.load();
return this.documents.get(id) || null;
}
/**
* 创建新文档
*/
async create(projectId: string, name: string, content: string, type: string, metadata?: Record<string, any>): Promise<Document> {
await this.load();
const doc = new Document(projectId, name, content, type, metadata);
this.documents.set(doc.id, doc);
await this.save();
// 保存文档到项目目录
try {
const projectDir = path.join(config.projectsDir, projectId);
await fs.ensureDir(projectDir);
const fileName = Document.getFileName(type);
await fs.writeFile(path.join(projectDir, fileName), content);
} catch (error) {
console.error('保存文档文件失败:', error);
}
return doc;
}
/**
* 更新文档
*/
async update(id: string, content: string, metadata?: Record<string, any>): Promise<Document | null> {
await this.load();
const doc = this.documents.get(id);
if (!doc) return null;
doc.update(content, metadata);
await this.save();
// 更新文档文件
try {
const projectDir = path.join(config.projectsDir, doc.projectId);
const fileName = Document.getFileName(doc.type);
await fs.writeFile(path.join(projectDir, fileName), content);
} catch (error) {
console.error('更新文档文件失败:', error);
}
return doc;
}
/**
* 删除文档
*/
async delete(id: string): Promise<boolean> {
await this.load();
const doc = this.documents.get(id);
if (!doc) return false;
this.documents.delete(id);
await this.save();
// 删除文档文件
try {
const projectDir = path.join(config.projectsDir, doc.projectId);
const fileName = Document.getFileName(doc.type);
const filePath = path.join(projectDir, fileName);
if (await fs.pathExists(filePath)) {
await fs.remove(filePath);
}
} catch (error) {
console.error('删除文档文件失败:', error);
}
return true;
}
}
/**
* 规则数据存储类
*/
export class RuleStorage {
private rulesFile: string;
private rules: Map<string, Rule>;
constructor() {
this.rulesFile = config.rulesDataFile;
this.rules = new Map();
}
/**
* 加载所有规则数据
*/
async load(): Promise<void> {
try {
if (await fs.pathExists(this.rulesFile)) {
const data = await fs.readJSON(this.rulesFile);
this.rules.clear();
data.forEach((item: IRule) => {
const rule = Rule.fromJSON(item);
this.rules.set(rule.id, rule);
});
}
} catch (error) {
console.error('加载规则数据失败:', error);
this.rules.clear();
}
}
/**
* 保存所有规则数据
*/
async save(): Promise<void> {
try {
const data = Array.from(this.rules.values()).map(rule => rule.toJSON());
await fs.writeJSON(this.rulesFile, data, { spaces: 2 });
} catch (error) {
console.error('保存规则数据失败:', error);
}
}
/**
* 获取所有规则
*/
async getAll(): Promise<Rule[]> {
await this.load();
return Array.from(this.rules.values());
}
/**
* 获取全局规则
*/
async getGlobalRules(): Promise<Rule[]> {
await this.load();
return Array.from(this.rules.values()).filter(rule => rule.isGlobal);
}
/**
* 获取项目规则
*/
async getProjectRules(projectId: string): Promise<Rule[]> {
await this.load();
return Array.from(this.rules.values()).filter(rule => rule.projectId === projectId);
}
/**
* 根据ID获取规则
*/
async getById(id: string): Promise<Rule | null> {
await this.load();
return this.rules.get(id) || null;
}
/**
* 创建新规则
*/
async create(name: string, content: string, isGlobal: boolean = false, projectId?: string, description?: string): Promise<Rule> {
await this.load();
const rule = new Rule(name, content, isGlobal, projectId, description);
this.rules.set(rule.id, rule);
await this.save();
return rule;
}
/**
* 更新规则
*/
async update(id: string, content: string, description?: string): Promise<Rule | null> {
await this.load();
const rule = this.rules.get(id);
if (!rule) return null;
rule.update(content, description);
await this.save();
return rule;
}
/**
* 删除规则
*/
async delete(id: string): Promise<boolean> {
await this.load();
if (!this.rules.has(id)) return false;
this.rules.delete(id);
await this.save();
return true;
}
}
// 导出单例实例
export const projectStorage = new ProjectStorage();
export const documentStorage = new DocumentStorage();
export const ruleStorage = new RuleStorage();