ApiController.ts•14.7 kB
import { Request, Response } from 'express';
import { projectStorage, documentStorage, ruleStorage } from '../utils/storage.js';
import { Document, DocumentType } from '../models/Document.js';
import { Rule } from '../models/Rule.js';
import { marked } from 'marked';
import fs from 'fs-extra';
import path from 'path';
import config from '../utils/config.js';
/**
* 项目API控制器
*/
export class ProjectController {
/**
* 获取所有项目
*/
static async getAll(req: Request, res: Response) {
try {
const projects = await projectStorage.getAll();
return res.json({
success: true,
data: projects.map(p => ({
id: p.id,
name: p.name,
description: p.description,
createdAt: p.createdAt,
updatedAt: p.updatedAt
}))
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取项目列表失败'
});
}
}
/**
* 获取项目详情
*/
static async getById(req: Request, res: Response) {
try {
const { id } = req.params;
const project = await projectStorage.getById(id);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
// 获取项目文档
const docs = await documentStorage.getByProjectId(id);
return res.json({
success: true,
data: {
id: project.id,
name: project.name,
description: project.description,
createdAt: project.createdAt,
updatedAt: project.updatedAt,
documents: docs.map(doc => ({
id: doc.id,
name: doc.name,
type: doc.type,
updatedAt: doc.updatedAt
}))
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取项目失败'
});
}
}
/**
* 创建项目
*/
static async create(req: Request, res: Response) {
try {
const { name, description } = req.body;
if (!name) {
return res.status(400).json({
success: false,
error: '项目名称不能为空'
});
}
const project = await projectStorage.create(name, description || '');
// 为新项目创建默认文档
const defaultDocs = [];
for (const [type, template] of Object.entries(config.defaultDocumentTemplates)) {
const docName = Document.getFileName(type);
const doc = await documentStorage.create(
project.id,
docName,
template,
type
);
defaultDocs.push(doc);
}
return res.status(201).json({
success: true,
data: {
id: project.id,
name: project.name,
description: project.description,
createdAt: project.createdAt,
updatedAt: project.updatedAt,
documents: defaultDocs.map(d => d.name)
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '创建项目失败'
});
}
}
/**
* 更新项目
*/
static async update(req: Request, res: Response) {
try {
const { id } = req.params;
const { name, description } = req.body;
const project = await projectStorage.update(id, name, description);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
return res.json({
success: true,
data: {
id: project.id,
name: project.name,
description: project.description,
updatedAt: project.updatedAt
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '更新项目失败'
});
}
}
/**
* 删除项目
*/
static async delete(req: Request, res: Response) {
try {
const { id } = req.params;
// 先删除项目下所有的文档
const docs = await documentStorage.getByProjectId(id);
for (const doc of docs) {
await documentStorage.delete(doc.id);
}
// 再删除项目规则
const rules = await ruleStorage.getProjectRules(id);
for (const rule of rules) {
await ruleStorage.delete(rule.id);
}
// 最后删除项目
const success = await projectStorage.delete(id);
if (!success) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
return res.json({
success: true,
message: '项目删除成功'
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '删除项目失败'
});
}
}
}
/**
* 文档API控制器
*/
export class DocumentController {
/**
* 获取项目所有文档
*/
static async getByProject(req: Request, res: Response) {
try {
const { projectId } = req.params;
// 检查项目是否存在
const project = await projectStorage.getById(projectId);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
const docs = await documentStorage.getByProjectId(projectId);
return res.json({
success: true,
data: docs.map(doc => ({
id: doc.id,
name: doc.name,
type: doc.type,
updatedAt: doc.updatedAt
}))
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取项目文档失败'
});
}
}
/**
* 获取文档内容
*/
static async getContent(req: Request, res: Response) {
try {
const { projectId, type } = req.params;
// 检查项目是否存在
const project = await projectStorage.getById(projectId);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
const docs = await documentStorage.getByProjectId(projectId);
const doc = docs.find(d => d.type === type);
if (!doc) {
return res.status(404).json({
success: false,
error: '文档不存在'
});
}
// 将Markdown转换为HTML
const html = marked(doc.content);
return res.json({
success: true,
data: {
id: doc.id,
name: doc.name,
content: doc.content,
html: html,
type: doc.type,
updatedAt: doc.updatedAt
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取文档内容失败'
});
}
}
/**
* 更新文档内容
*/
static async updateContent(req: Request, res: Response) {
try {
const { projectId, type } = req.params;
const { content } = req.body;
if (!content) {
return res.status(400).json({
success: false,
error: '文档内容不能为空'
});
}
// 检查项目是否存在
const project = await projectStorage.getById(projectId);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
const docs = await documentStorage.getByProjectId(projectId);
const doc = docs.find(d => d.type === type);
if (!doc) {
// 文档不存在,创建新文档
const docName = Document.getFileName(type);
const newDoc = await documentStorage.create(
projectId,
docName,
content,
type
);
return res.status(201).json({
success: true,
data: {
id: newDoc.id,
name: newDoc.name,
type: newDoc.type,
updatedAt: newDoc.updatedAt
},
message: '文档创建成功'
});
} else {
// 更新已有文档
const updatedDoc = await documentStorage.update(doc.id, content);
if (!updatedDoc) {
return res.status(500).json({
success: false,
error: '文档更新失败'
});
}
return res.json({
success: true,
data: {
id: updatedDoc.id,
name: updatedDoc.name,
type: updatedDoc.type,
updatedAt: updatedDoc.updatedAt
},
message: '文档更新成功'
});
}
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '更新文档内容失败'
});
}
}
}
/**
* 规则API控制器
*/
export class RuleController {
/**
* 获取项目规则列表
*/
static async getByProject(req: Request, res: Response) {
try {
const { projectId } = req.params;
// 检查项目是否存在
const project = await projectStorage.getById(projectId);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
// 获取项目特定规则
const projectRules = await ruleStorage.getProjectRules(projectId);
// 获取全局规则
const globalRules = await ruleStorage.getGlobalRules();
return res.json({
success: true,
data: {
projectRules: projectRules.map(rule => ({
id: rule.id,
name: rule.name,
description: rule.description,
isGlobal: false,
updatedAt: rule.updatedAt
})),
globalRules: globalRules.map(rule => ({
id: rule.id,
name: rule.name,
description: rule.description,
isGlobal: true,
updatedAt: rule.updatedAt
}))
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取项目规则失败'
});
}
}
/**
* 获取规则内容
*/
static async getById(req: Request, res: Response) {
try {
const { id } = req.params;
const rule = await ruleStorage.getById(id);
if (!rule) {
return res.status(404).json({
success: false,
error: '规则不存在'
});
}
return res.json({
success: true,
data: {
id: rule.id,
name: rule.name,
content: rule.content,
description: rule.description,
isGlobal: rule.isGlobal,
projectId: rule.projectId,
createdAt: rule.createdAt,
updatedAt: rule.updatedAt
}
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '获取规则内容失败'
});
}
}
/**
* 创建规则
*/
static async create(req: Request, res: Response) {
try {
const { name, content, isGlobal, projectId, description } = req.body;
if (!name || !content) {
return res.status(400).json({
success: false,
error: '规则名称和内容不能为空'
});
}
if (isGlobal === undefined) {
return res.status(400).json({
success: false,
error: '是否全局规则必须指定'
});
}
// 如果不是全局规则,项目ID必须存在
if (!isGlobal && !projectId) {
return res.status(400).json({
success: false,
error: '项目规则必须指定项目ID'
});
}
// 如果是项目规则,确认项目存在
if (!isGlobal && projectId) {
const project = await projectStorage.getById(projectId);
if (!project) {
return res.status(404).json({
success: false,
error: '项目不存在'
});
}
}
const rule = await ruleStorage.create(name, content, isGlobal, projectId, description);
return res.status(201).json({
success: true,
data: {
id: rule.id,
name: rule.name,
description: rule.description,
isGlobal: rule.isGlobal,
projectId: rule.projectId,
createdAt: rule.createdAt,
updatedAt: rule.updatedAt
},
message: '规则创建成功'
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '创建规则失败'
});
}
}
/**
* 更新规则
*/
static async update(req: Request, res: Response) {
try {
const { id } = req.params;
const { content, description } = req.body;
if (!content) {
return res.status(400).json({
success: false,
error: '规则内容不能为空'
});
}
const rule = await ruleStorage.update(id, content, description);
if (!rule) {
return res.status(404).json({
success: false,
error: '规则不存在'
});
}
return res.json({
success: true,
data: {
id: rule.id,
name: rule.name,
description: rule.description,
updatedAt: rule.updatedAt
},
message: '规则更新成功'
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '更新规则失败'
});
}
}
/**
* 删除规则
*/
static async delete(req: Request, res: Response) {
try {
const { id } = req.params;
const success = await ruleStorage.delete(id);
if (!success) {
return res.status(404).json({
success: false,
error: '规则不存在'
});
}
return res.json({
success: true,
message: '规则删除成功'
});
} catch (error: any) {
return res.status(500).json({
success: false,
error: error.message || '删除规则失败'
});
}
}
}