166 lines
4.7 KiB
TypeScript
166 lines
4.7 KiB
TypeScript
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();
|
||
}
|
||
}
|
||
}
|
||
}
|