|
@@ -13,7 +13,7 @@ import path from 'path';
|
|
|
import fs from 'fs';
|
|
import fs from 'fs';
|
|
|
import http from 'http';
|
|
import http from 'http';
|
|
|
import { config } from './config';
|
|
import { config } from './config';
|
|
|
-import { connectDatabase } from './models';
|
|
|
|
|
|
|
+import { connectDatabase, prisma } from './models';
|
|
|
import { errorHandler } from './middleware/errorHandler';
|
|
import { errorHandler } from './middleware/errorHandler';
|
|
|
import { requestLogger } from './services/requestLogger';
|
|
import { requestLogger } from './services/requestLogger';
|
|
|
import { httpLogger } from './services/logger.service';
|
|
import { httpLogger } from './services/logger.service';
|
|
@@ -210,6 +210,32 @@ async function start() {
|
|
|
// 5. 初始化 WebSocket 服务
|
|
// 5. 初始化 WebSocket 服务
|
|
|
initWebSocket(server);
|
|
initWebSocket(server);
|
|
|
|
|
|
|
|
|
|
+ // 5.5 启动巡检:扫脏数据 audioUrl,防止 #audio-play-404-on-prod 复发
|
|
|
|
|
+ // 生产 nginx 不反代 /uploads/,任何 audioUrl 仍是 /uploads/... 的章节前端播放必 404。
|
|
|
|
|
+ // 这里只报警不 fail boot(避免历史脏数据导致服务起不来)。
|
|
|
|
|
+ try {
|
|
|
|
|
+ const dirty = await prisma.bookChapter.count({
|
|
|
|
|
+ where: { audioUrl: { startsWith: '/uploads/' } },
|
|
|
|
|
+ });
|
|
|
|
|
+ if (dirty > 0) {
|
|
|
|
|
+ console.error(`🚨 [BootWatchdog] 发现 ${dirty} 个 chapter 的 audioUrl 是本地路径 (/uploads/...)!`);
|
|
|
|
|
+ console.error(`🚨 [BootWatchdog] 生产 nginx 不反代 /uploads/,这些章节播放必 404。`);
|
|
|
|
|
+ console.error(`🚨 [BootWatchdog] 修复: cd server && STORAGE_TYPE=oss npx tsx scripts/fix-local-audio-urls.ts`);
|
|
|
|
|
+ // 列出前 5 个脏数据 chapter id 方便定位
|
|
|
|
|
+ const samples = await prisma.bookChapter.findMany({
|
|
|
|
|
+ where: { audioUrl: { startsWith: '/uploads/' } },
|
|
|
|
|
+ select: { id: true, level: true, audioUrl: true, bookId: true },
|
|
|
|
|
+ take: 5,
|
|
|
|
|
+ orderBy: { id: 'asc' },
|
|
|
|
|
+ });
|
|
|
|
|
+ console.error(`🚨 [BootWatchdog] 样例:`, JSON.stringify(samples));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ console.log('✅ [BootWatchdog] 脏数据巡检通过:无 /uploads/... 本地路径 audioUrl');
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e: any) {
|
|
|
|
|
+ console.warn('[BootWatchdog] 巡检异常(不阻塞启动):', e?.message || e);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 6. 启动服务
|
|
// 6. 启动服务
|
|
|
// 清理 temp 目录中的残留临时文件
|
|
// 清理 temp 目录中的残留临时文件
|
|
|
FFmpegProcessor.cleanupAllTempFiles();
|
|
FFmpegProcessor.cleanupAllTempFiles();
|