backend:优化后端启动文件

This commit is contained in:
jiangrui
2025-03-10 11:21:52 +08:00
parent 0a9b053dff
commit 755a424530
2 changed files with 129 additions and 60 deletions

View File

@@ -1,76 +1,146 @@
// filepath: /d:/code/CloudDiskDown/backend/src/app.ts // filepath: /d:/code/CloudDiskDown/backend/src/app.ts
import "./types/express"; import "./types/express";
import express from "express"; import express, { Application } from "express";
import cors from "cors"; import cors from "cors";
import cookieParser from "cookie-parser"; import cookieParser from "cookie-parser";
import { QueryTypes } from "sequelize";
// 路由和中间件导入
import routes from "./routes/api"; import routes from "./routes/api";
import { errorHandler } from "./middleware/errorHandler"; import { errorHandler } from "./middleware/errorHandler";
import sequelize from "./config/database";
import { authMiddleware } from "./middleware/auth"; import { authMiddleware } from "./middleware/auth";
// 数据库和服务相关
import sequelize from "./config/database";
import GlobalSetting from "./models/GlobalSetting"; import GlobalSetting from "./models/GlobalSetting";
import Searcher from "./services/Searcher"; import Searcher from "./services/Searcher";
const app = express(); // 常量配置
const PUBLIC_ROUTES = ["/user/login", "/user/register"];
const IMAGE_PATH = "tele-images";
const DEFAULT_PORT = 8009;
app.use( // 全局设置默认值
cors({ const DEFAULT_GLOBAL_SETTINGS = {
origin: "*", httpProxyHost: "127.0.0.1",
credentials: true, httpProxyPort: 7890,
methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], isProxyEnabled: false,
allowedHeaders: ["Content-Type", "Authorization", "Cookie"], CommonUserCode: 9527,
}) AdminUserCode: 230713,
);
app.use(cookieParser());
app.use(express.json());
// 应用 token 验证中间件,排除登录和注册接口
app.use((req, res, next) => {
if (
req.path === "/user/login" ||
req.path === "/user/register" ||
req.path.includes("tele-images")
) {
return next();
}
authMiddleware(req, res, next);
});
app.use("/", routes);
const initializeGlobalSettings = async (): Promise<void> => {
const settings = await GlobalSetting.findOne();
if (!settings) {
await GlobalSetting.create({
httpProxyHost: "127.0.0.1",
httpProxyPort: 7890,
isProxyEnabled: true,
CommonUserCode: 9527,
AdminUserCode: 230713,
});
console.log("Global settings initialized with default values.");
}
await Searcher.updateAxiosInstance();
}; };
// 错误处理 class App {
app.use(errorHandler); private app: Application;
const PORT = process.env.PORT || 8009; constructor() {
this.app = express();
this.setupMiddlewares();
this.setupRoutes();
this.setupErrorHandling();
}
// 在同步前禁用外键约束,同步后重新启用 private setupMiddlewares(): void {
sequelize // CORS 配置
.query("PRAGMA foreign_keys = OFF") // 禁用外键 this.app.use(
.then(() => sequelize.sync({ alter: true })) cors({
.then(() => sequelize.query("PRAGMA foreign_keys = ON")) // 重新启用外键 origin: "*",
.then(() => { credentials: true,
app.listen(PORT, async () => { methods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
await initializeGlobalSettings(); allowedHeaders: ["Content-Type", "Authorization", "Cookie"],
console.log(`Server is running on port ${PORT}`); })
);
this.app.use(cookieParser());
this.app.use(express.json());
// 身份验证中间件
this.app.use((req, res, next) => {
if (PUBLIC_ROUTES.includes(req.path) || req.path.includes(IMAGE_PATH)) {
return next();
}
authMiddleware(req, res, next);
}); });
}) }
.catch((error) => {
console.error("Database sync failed:", error);
});
export default app; private setupRoutes(): void {
this.app.use("/", routes);
}
private setupErrorHandling(): void {
this.app.use(errorHandler);
}
private async initializeGlobalSettings(): Promise<void> {
try {
const settings = await GlobalSetting.findOne();
if (!settings) {
await GlobalSetting.create(DEFAULT_GLOBAL_SETTINGS);
console.log("✅ Global settings initialized with default values.");
}
await Searcher.updateAxiosInstance();
} catch (error) {
console.error("❌ Failed to initialize global settings:", error);
throw error;
}
}
private async cleanupBackupTables(): Promise<void> {
try {
// 查询所有以 '_backup' 结尾的备份表
const backupTables = await sequelize.query<{ name: string }>(
"SELECT name FROM sqlite_master WHERE type='table' AND name LIKE '%\\_backup%' ESCAPE '\\'",
{ type: QueryTypes.SELECT }
);
// 逐个删除备份表
for (const table of backupTables) {
if (table?.name) {
await sequelize.query(`DROP TABLE IF EXISTS ${table.name}`);
console.log(`✅ Cleaned up backup table: ${table.name}`);
}
}
} catch (error) {
console.error("❌ Failed to cleanup backup tables:", error);
throw error;
}
}
public async start(): Promise<void> {
try {
// 数据库初始化流程
await sequelize.query("PRAGMA foreign_keys = OFF");
console.log("📝 Foreign keys disabled for initialization...");
await this.cleanupBackupTables();
console.log("🧹 Backup tables cleaned up");
await sequelize.sync({ alter: true });
console.log("📚 Database schema synchronized");
await sequelize.query("PRAGMA foreign_keys = ON");
console.log("🔐 Foreign keys re-enabled");
// 启动服务器
const port = process.env.PORT || DEFAULT_PORT;
this.app.listen(port, async () => {
await this.initializeGlobalSettings();
console.log(`
🚀 Server is running on port ${port}
🔧 Environment: ${process.env.NODE_ENV || "development"}
`);
});
} catch (error) {
console.error("❌ Failed to start server:", error);
process.exit(1);
}
}
}
// 创建并启动应用
const application = new App();
application.start().catch((error) => {
console.error("❌ Application failed to start:", error);
process.exit(1);
});
export default application;

View File

@@ -13,7 +13,6 @@ export function createAxiosInstance(
proxyConfig?: ProxyConfig proxyConfig?: ProxyConfig
): AxiosInstance { ): AxiosInstance {
let agent; let agent;
console.log(proxyConfig);
if (useProxy && proxyConfig) { if (useProxy && proxyConfig) {
agent = tunnel.httpsOverHttp({ agent = tunnel.httpsOverHttp({
proxy: proxyConfig, proxy: proxyConfig,