feat: 初始化项目结构并添加核心功能模块

- 新增文档模板和导航结构
- 实现服务器基础API路由和控制器
- 添加扩展插件配置和前端框架
- 引入多租户和权限管理模块
- 集成日志和数据库配置
- 添加核心业务模型和类型定义
This commit is contained in:
2026-03-17 22:07:19 +08:00
parent c0870dce50
commit 136c2fa579
728 changed files with 107690 additions and 5614 deletions

View File

@@ -0,0 +1,96 @@
import db from '../config/database';
import { RedisService } from '../utils/RedisService';
export interface AppConfig {
key: string;
value: any;
description?: string;
isEnabled: boolean;
}
export class ConfigService {
private static TABLE_NAME = 'cf_config';
private static HISTORY_TABLE = 'cf_config_history';
/**
* [CORE_DEV_06/16] 初始化配置表与历史表
*/
static async initTable() {
const exists = await db.schema.hasTable(this.TABLE_NAME);
if (!exists) {
await db.schema.createTable(this.TABLE_NAME, (table) => {
table.string('key').notNullable();
table.string('tenantId').defaultTo('SYSTEM').index();
table.json('value');
table.string('description');
table.boolean('isEnabled').defaultTo(true);
table.integer('version').defaultTo(1); // [CORE_DEV_16] 版本控制
table.timestamps(true, true);
table.primary(['key', 'tenantId']);
});
// ... (seed data remains same)
}
const historyExists = await db.schema.hasTable(this.HISTORY_TABLE);
if (!historyExists) {
await db.schema.createTable(this.HISTORY_TABLE, (table) => {
table.increments('id').primary();
table.string('key').notNullable();
table.string('tenantId').notNullable();
table.json('value');
table.integer('version').notNullable();
table.string('changeLog');
table.timestamp('created_at').defaultTo(db.fn.now());
table.index(['key', 'tenantId']);
});
}
}
/**
* [CORE_DEV_16] 更新配置并保存历史版本
*/
static async updateConfig(key: string, data: Partial<AppConfig> & { changeLog?: string }, tenantId: string = 'SYSTEM') {
const current = await this.getConfig(key, tenantId);
const newVersion = (current?.version || 0) + 1;
const updateData: any = { ...data, version: newVersion };
delete updateData.changeLog;
if (data.value) updateData.value = JSON.stringify(data.value);
await db.transaction(async (trx) => {
// 1. 更新主表
await trx(this.TABLE_NAME).where({ key, tenantId }).update(updateData);
// 2. 插入历史记录
await trx(this.HISTORY_TABLE).insert({
key,
tenantId,
value: updateData.value || JSON.stringify(current?.value),
version: newVersion,
changeLog: data.changeLog || 'Automated update'
});
});
// [CORE_DEV_12] 分布式配置热更新通知
await RedisService.publishConfigChange(tenantId, key, data.value || data.isEnabled);
}
/**
* [CORE_DEV_16] 配置版本回滚
*/
static async rollbackConfig(key: string, version: number, tenantId: string = 'SYSTEM') {
const history = await db(this.HISTORY_TABLE).where({ key, tenantId, version }).first();
if (!history) throw new Error(`Version ${version} not found for config ${key}`);
await this.updateConfig(key, {
value: typeof history.value === 'string' ? JSON.parse(history.value) : history.value,
changeLog: `Rollback to version ${version}`
}, tenantId);
}
static async isFeatureEnabled(key: string, tenantId: string = 'SYSTEM'): Promise<boolean> {
const config = await this.getConfig(key, tenantId);
return config ? config.isEnabled : false;
}
}