u
This commit is contained in:
@@ -1,35 +1,11 @@
|
||||
import { OpenAPIHono } from '@hono/zod-openapi'
|
||||
import { errorHandler } from './utils/errorHandler'
|
||||
import base from './api/base'
|
||||
import usersRouter from './api/users/index'
|
||||
import zichanRoute from './api/zichan/index'
|
||||
import zichanCategoryRouter from './api/zichan-category'
|
||||
import zichanAreaRouter from './api/zichan-area/index'
|
||||
import { initConfigRouter, initStatusRouter } from './api/init'
|
||||
import alertNotifyConfigsRoute from './api/alert-notify-configs/index'
|
||||
import authRoute from './api/auth/index'
|
||||
import themeSettingsRoute from './api/theme-settings/index'
|
||||
import deviceTypesRoute from './api/device-types/index'
|
||||
import alertRulesRoute from '@/server/api/alert-rules/index'
|
||||
import deviceInstancesRoute from '@/server/api/device-instances'
|
||||
import rackRoute from '@/server/api/rack'
|
||||
import rackServerTypeRoute from '@/server/api/rack-server-type'
|
||||
import rackServerRoute from '@/server/api/rack-server/index'
|
||||
import zichanTransferRoute from '@/server/api/zichan-transfer/index'
|
||||
import monitorDataRoute from '@/server/api/monitor-data/index'
|
||||
import alertRoute from '@/server/api/alerts/index'
|
||||
import alertsHandlesRoute from '@/server/api/alerts/handles/index'
|
||||
import monitorMapRoute from '@/server/api/monitor-map/index'
|
||||
import knowInfoRoute from '@/server/api/know-info/index'
|
||||
import monitorTaskRoute from '@/server/api/monitor-task/index'
|
||||
import filesRoute from '@/server/api/files/index'
|
||||
import fileCategoryRoute from '@/server/api/file-category/index'
|
||||
import bigRoute from '@/server/api/big/index'
|
||||
import { AuthContext } from './types/context'
|
||||
import { AppDataSource } from './data-source'
|
||||
import { authMiddleware } from './middleware/auth.middleware'
|
||||
import { MonitorService } from './modules/monitor/monitor.service'
|
||||
import { MonitorSchedulerService } from './modules/monitor/monitor-scheduler.service'
|
||||
|
||||
const api = new OpenAPIHono<AuthContext>()
|
||||
|
||||
@@ -46,15 +22,6 @@ api.use('/api/v1/*', async (c, next) => {
|
||||
api.use('/api/v1/*', async (c, next) => {
|
||||
if(!AppDataSource.isInitialized) {
|
||||
await AppDataSource.initialize();
|
||||
|
||||
// 初始化监控任务调度器
|
||||
try {
|
||||
const monitorService = new MonitorService(AppDataSource);
|
||||
const scheduler = new MonitorSchedulerService(AppDataSource, monitorService);
|
||||
await scheduler.init();
|
||||
} catch (error) {
|
||||
console.error('监控任务调度器初始化失败:', error);
|
||||
}
|
||||
}
|
||||
await next();
|
||||
})
|
||||
@@ -82,24 +49,10 @@ if(!import.meta.env.PROD){
|
||||
})
|
||||
}
|
||||
|
||||
// Register routes
|
||||
const routes = api
|
||||
.route('/api/v1/init', initConfigRouter)
|
||||
.route('/api/v1/init', initStatusRouter)
|
||||
.route('/api/v1/base', base)
|
||||
|
||||
|
||||
const userRoutes = api.route('/api/v1/users', usersRouter)
|
||||
|
||||
const zichanRoutes = api
|
||||
.route('/api/v1/zichan', zichanRoute.getRoute)
|
||||
.route('/api/v1/zichan', zichanRoute.getByIdRoute)
|
||||
.route('/api/v1/zichan', zichanRoute.postRoute)
|
||||
.route('/api/v1/zichan', zichanRoute.putByIdRoute)
|
||||
.route('/api/v1/zichan', zichanRoute.deleteByIdRoute)
|
||||
|
||||
const zichanCategoryRoutes = api.route('/api/v1/zichan-category', zichanCategoryRouter)
|
||||
|
||||
const zichanAreaRoutes = api.route('/api/v1/zichan-area', zichanAreaRouter)
|
||||
|
||||
const authRoutes = api
|
||||
.route('/api/v1/auth', authRoute.loginRoute.passwordRoute)
|
||||
|
||||
@@ -1,192 +0,0 @@
|
||||
import { OpenAPIHono, createRoute, z } from '@hono/zod-openapi';
|
||||
import { ErrorSchema } from '../utils/errorHandler';
|
||||
import { AppDataSource } from '../data-source';
|
||||
import { UserEntity as User } from '../modules/users/user.entity';
|
||||
import { Role } from '../modules/users/role.entity';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { generateJwtSecret } from '../utils/env-init';
|
||||
import { writeFileSync } from 'fs';
|
||||
|
||||
const initRouter = new OpenAPIHono();
|
||||
|
||||
// Zod 验证模式
|
||||
const DatabaseConfigSchema = z.object({
|
||||
host: z.string(),
|
||||
port: z.number(),
|
||||
username: z.string(),
|
||||
password: z.string(),
|
||||
database: z.string()
|
||||
});
|
||||
|
||||
const AdminUserSchema = z.object({
|
||||
username: z.string().min(3),
|
||||
password: z.string().min(8)
|
||||
});
|
||||
|
||||
const InitConfigSchema = z.object({
|
||||
dbConfig: DatabaseConfigSchema,
|
||||
adminUser: AdminUserSchema
|
||||
});
|
||||
|
||||
// 检查初始化状态路由
|
||||
const statusRoute = createRoute({
|
||||
method: 'get',
|
||||
path: '/status',
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({
|
||||
initialized: z.boolean()
|
||||
})
|
||||
}
|
||||
},
|
||||
description: '返回系统初始化状态'
|
||||
},
|
||||
500: {
|
||||
description: '初始化状态检查失败',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: ErrorSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const initStatusRouter = initRouter.openapi(statusRoute, async (c) => {
|
||||
try {
|
||||
const isInitialized = await checkInitialization();
|
||||
return c.json({ initialized: isInitialized }, 200);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
code: 500,
|
||||
message: '初始化状态检查失败'
|
||||
}, 500);
|
||||
}
|
||||
});
|
||||
|
||||
// 提交配置路由
|
||||
const configRoute = createRoute({
|
||||
method: 'post',
|
||||
path: '/config',
|
||||
request: {
|
||||
body: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: InitConfigSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
description: '系统初始化成功',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: z.object({
|
||||
success: z.boolean(),
|
||||
jwtSecret: z.string().optional()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
400: {
|
||||
description: '初始化失败',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: ErrorSchema
|
||||
}
|
||||
}
|
||||
},
|
||||
500: {
|
||||
description: '服务器内部错误',
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: ErrorSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const initConfigRouter = initRouter.openapi(configRoute, async (c) => {
|
||||
const { dbConfig, adminUser } = c.req.valid('json');
|
||||
|
||||
if (await checkInitialization()) {
|
||||
return c.json({
|
||||
code: 400,
|
||||
message: '系统已初始化'
|
||||
}, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
await validateDatabase(dbConfig);
|
||||
await generateEnvFile(dbConfig);
|
||||
const jwtSecret = generateJwtSecret();
|
||||
await createAdminUser(adminUser);
|
||||
|
||||
return c.json({
|
||||
success: true,
|
||||
jwtSecret
|
||||
}, 200);
|
||||
} catch (error) {
|
||||
return c.json({
|
||||
code: 400,
|
||||
message: error instanceof Error ? error.message : '未知错误'
|
||||
}, 400);
|
||||
}
|
||||
});
|
||||
|
||||
export { initStatusRouter, initConfigRouter };
|
||||
|
||||
|
||||
async function checkInitialization(): Promise<boolean> {
|
||||
// 检查数据库是否已初始化
|
||||
return AppDataSource.isInitialized;
|
||||
}
|
||||
|
||||
async function validateDatabase(config: any) {
|
||||
// 使用TypeORM验证数据库连接
|
||||
const testDataSource = AppDataSource.setOptions(config);
|
||||
await testDataSource.initialize();
|
||||
await testDataSource.destroy();
|
||||
}
|
||||
|
||||
async function generateEnvFile(config: any) {
|
||||
const envContent = `DB_HOST=${config.host}
|
||||
DB_PORT=${config.port}
|
||||
DB_USERNAME=${config.username}
|
||||
DB_PASSWORD=${config.password}
|
||||
DB_DATABASE=${config.database}
|
||||
`;
|
||||
writeFileSync('.env', envContent);
|
||||
}
|
||||
|
||||
async function createAdminUser(userData: any) {
|
||||
const userRepo = AppDataSource.getRepository(User);
|
||||
const roleRepo = AppDataSource.getRepository(Role);
|
||||
|
||||
// 检查是否已存在管理员
|
||||
const existingAdmin = await userRepo.findOne({ where: { username: userData.username } });
|
||||
if (existingAdmin) {
|
||||
throw new Error('管理员用户已存在');
|
||||
}
|
||||
|
||||
// 创建管理员角色
|
||||
let adminRole = await roleRepo.findOne({ where: { name: 'admin' } });
|
||||
if (!adminRole) {
|
||||
adminRole = roleRepo.create({ name: 'admin', permissions: ['*'] });
|
||||
await roleRepo.save(adminRole);
|
||||
}
|
||||
|
||||
// 创建管理员用户
|
||||
const hashedPassword = await bcrypt.hash(userData.password, 10);
|
||||
const adminUser = userRepo.create({
|
||||
username: userData.username,
|
||||
password: hashedPassword,
|
||||
roles: [adminRole]
|
||||
});
|
||||
|
||||
await userRepo.save(adminUser);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
import { createRoute, OpenAPIHono } from '@hono/zod-openapi'
|
||||
import { z } from 'zod'
|
||||
import { AppDataSource } from '../data-source'
|
||||
import { HTTPException } from 'hono/http-exception';
|
||||
import { authMiddleware } from '../middleware/auth.middleware';
|
||||
import { AuthContext } from '../types/context';
|
||||
|
||||
interface Migration {
|
||||
name: string;
|
||||
timestamp: number;
|
||||
}
|
||||
|
||||
const app = new OpenAPIHono<AuthContext>()
|
||||
|
||||
const MigrationResponseSchema = z.object({
|
||||
success: z.boolean(),
|
||||
message: z.string(),
|
||||
migrations: z.array(z.string()).optional()
|
||||
})
|
||||
|
||||
const runMigrationRoute = createRoute({
|
||||
method: 'post',
|
||||
path: '/migrations/run',
|
||||
middleware: authMiddleware,
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: MigrationResponseSchema
|
||||
}
|
||||
},
|
||||
description: 'Migrations executed successfully'
|
||||
},
|
||||
500: {
|
||||
description: 'Migration failed'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const revertMigrationRoute = createRoute({
|
||||
method: 'post',
|
||||
path: '/migrations/revert',
|
||||
middleware: authMiddleware,
|
||||
responses: {
|
||||
200: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: MigrationResponseSchema
|
||||
}
|
||||
},
|
||||
description: 'Migration reverted successfully'
|
||||
},
|
||||
500: {
|
||||
description: 'Revert failed'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
app.openapi(runMigrationRoute, async (c) => {
|
||||
try {
|
||||
const migrations = await AppDataSource.runMigrations()
|
||||
return c.json({
|
||||
success: true,
|
||||
message: 'Migrations executed successfully',
|
||||
migrations: migrations.map((m: Migration) => m.name)
|
||||
})
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
app.openapi(revertMigrationRoute, async (c) => {
|
||||
try {
|
||||
await AppDataSource.undoLastMigration()
|
||||
const migrations = await AppDataSource.showMigrations()
|
||||
return c.json({
|
||||
success: true,
|
||||
message: 'Migration reverted successfully',
|
||||
migrations: migrations
|
||||
})
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
export default app
|
||||
export type AppType = typeof app
|
||||
@@ -6,7 +6,6 @@ import process from 'node:process'
|
||||
// 全局配置常量
|
||||
const GLOBAL_CONFIG: GlobalConfig = {
|
||||
OSS_BASE_URL: process.env.OSS_BASE_URL || 'https://oss.d8d.fun',
|
||||
// API_BASE_URL: '/api',
|
||||
APP_NAME: process.env.APP_NAME || '多八多Aider',
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user