forked from yoone/API
1
0
Fork 0
API/src/configuration.ts

166 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
Configuration,
App,
Inject,
MidwayDecoratorService,
Logger,
Config,
} from '@midwayjs/core';
import * as koa from '@midwayjs/koa';
import * as validate from '@midwayjs/validate';
import * as info from '@midwayjs/info';
import * as orm from '@midwayjs/typeorm';
import { DataSource } from 'typeorm';
import { join } from 'path';
import { DefaultErrorFilter } from './filter/default.filter';
import { NotFoundFilter } from './filter/notfound.filter';
import { ReportMiddleware } from './middleware/report.middleware';
import { QueryNormalizeMiddleware } from './middleware/query-normalize.middleware';
import * as swagger from '@midwayjs/swagger';
import * as crossDomain from '@midwayjs/cross-domain';
import * as cron from '@midwayjs/cron';
import * as jwt from '@midwayjs/jwt';
import * as upload from '@midwayjs/upload';
import { USER_KEY } from './decorator/user.decorator';
import { SiteService } from './service/site.service';
import { AuthMiddleware } from './middleware/auth.middleware';
@Configuration({
imports: [
koa,
validate,
{
component: info,
enabledEnvironment: ['local', 'prod'],
},
orm,
swagger,
crossDomain,
cron,
jwt,
upload,
],
importConfigs: [join(__dirname, './config')],
})
export class MainConfiguration {
@App('koa')
app: koa.Application;
@Inject()
decoratorService: MidwayDecoratorService;
@Inject()
jwtService: jwt.JwtService; // 注入 JwtService 实例
@Inject()
siteService: SiteService;
@Logger()
logger; // 注入 Logger 实例
@Config('typeorm.dataSource.default')
typeormDataSourceConfig; // 注入 TypeORM 数据源配置
async onConfigLoad() {
// 在组件初始化之前,先检查并创建数据库
await this.initializeDatabase();
}
async onReady() {
// add middleware
this.app.useMiddleware([QueryNormalizeMiddleware, ReportMiddleware, AuthMiddleware]);
// add filter
this.app.useFilter([NotFoundFilter, DefaultErrorFilter]);
this.decoratorService.registerParameterHandler(
USER_KEY,
async (
options
): Promise<{
id: number;
userName: string;
}> => {
const ctx = options.originArgs[0];
const token = ctx.headers['authorization']?.split(' ')[1];
const config = ctx.app.getConfig('jwt'); // 动态获取配置项
if (!token) {
ctx.throw(401, 'Token not found');
}
try {
const decoded: any = this.jwtService.verify(token, config.secret); // 替换为你的密钥
return decoded;
} catch (error) {
ctx.throw(401, 'Invalid token');
}
}
);
}
/**
* 初始化数据库(如果不存在则创建)
*/
private async initializeDatabase(): Promise<void> {
// 使用注入的数据库配置
const typeormConfig = this.typeormDataSourceConfig;
// 创建一个临时的 DataSource不指定数据库用于创建数据库
const tempDataSource = new DataSource({
type: 'mysql',
host: typeormConfig.host,
port: typeormConfig.port,
username: typeormConfig.username,
password: typeormConfig.password,
database: undefined, // 不指定数据库
synchronize: true,
logging: false,
});
try {
this.logger.info(`正在检查数据库是否存在...`+ JSON.stringify(typeormConfig));
// 初始化临时数据源
await tempDataSource.initialize();
// 创建查询运行器
const queryRunner = tempDataSource.createQueryRunner();
try {
// 检查数据库是否存在
const databases = await queryRunner.query(
`SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = ?`,
[typeormConfig.database]
);
const databaseExists = Array.isArray(databases) && databases.length > 0;
if (!databaseExists) {
this.logger.info(`数据库 ${typeormConfig.database} 不存在,正在创建...`);
// 创建数据库
await queryRunner.query(
`CREATE DATABASE \`${typeormConfig.database}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci`
);
this.logger.info(`数据库 ${typeormConfig.database} 创建成功`);
} else {
this.logger.info(`数据库 ${typeormConfig.database} 已存在`);
}
} finally {
// 释放查询运行器
await queryRunner.release();
}
} catch (error) {
this.logger.error('数据库初始化失败:', error);
throw error;
} finally {
// 关闭临时数据源
if (tempDataSource.isInitialized) {
await tempDataSource.destroy();
}
}
}
}