mirror of
https://github.com/jiangrui1994/CloudSaver.git
synced 2026-01-11 07:38:45 +08:00
backend:优化后端启动文件
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user