67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
/**
|
||
* 玩值电竞 - MongoDB 连接(单例)
|
||
* 库名:wanzhi_esports
|
||
*/
|
||
|
||
import { config } from "dotenv"
|
||
import { resolve } from "path"
|
||
config({ path: resolve(process.cwd(), ".env.local") })
|
||
|
||
import { MongoClient, Db } from "mongodb"
|
||
|
||
const DB_NAME = "wanzhi_esports"
|
||
/** 本地开发回退:未设置 MONGODB_URI 时使用(与 00_账号与API索引 一致) */
|
||
const DEFAULT_URI = "mongodb://admin:admin123@localhost:27017?authSource=admin"
|
||
function getUri(): string {
|
||
if (typeof process === "undefined" || !process.env) return DEFAULT_URI
|
||
if (process.env.MONGODB_URI) return process.env.MONGODB_URI
|
||
// Next 等环境下模块加载时 env 可能尚未注入,请求时再尝试加载一次
|
||
try {
|
||
config({ path: resolve(process.cwd(), ".env.local") })
|
||
if (process.env.MONGODB_URI) return process.env.MONGODB_URI
|
||
} catch {
|
||
/* ignore */
|
||
}
|
||
return DEFAULT_URI
|
||
}
|
||
|
||
let client: MongoClient | null = null
|
||
let db: Db | null = null
|
||
|
||
export async function getMongoClient(): Promise<MongoClient> {
|
||
// 开发模式下每次新建连接,避免 Next 热重载后连接失效
|
||
if (process.env.NODE_ENV === "development" && client) {
|
||
try {
|
||
await client.close()
|
||
} catch {
|
||
/* ignore */
|
||
}
|
||
client = null
|
||
db = null
|
||
}
|
||
if (client) return client
|
||
const uri = getUri()
|
||
client = new MongoClient(uri, { serverSelectionTimeoutMS: 10000, connectTimeoutMS: 10000 })
|
||
await client.connect()
|
||
return client
|
||
}
|
||
|
||
export async function getDb(): Promise<Db> {
|
||
if (db) return db
|
||
const c = await getMongoClient()
|
||
db = c.db(DB_NAME)
|
||
return db
|
||
}
|
||
|
||
/** 关闭连接(用于脚本结束或 serverless 冷启动回收) */
|
||
export async function closeMongo(): Promise<void> {
|
||
if (client) {
|
||
await client.close()
|
||
client = null
|
||
db = null
|
||
}
|
||
}
|
||
|
||
export { DB_NAME }
|
||
export const MONGODB_URI = getUri()
|