2026-03-16 12:05:55 +08:00
|
|
|
|
import Koa from 'koa'
|
|
|
|
|
|
import Router from 'koa-router'
|
|
|
|
|
|
import bodyParser from 'koa-bodyparser'
|
|
|
|
|
|
import koaStatic from 'koa-static'
|
|
|
|
|
|
import config from '../config/index.js'
|
|
|
|
|
|
import * as log4js from '../log4js.js'
|
|
|
|
|
|
import auth from './auth.js'
|
|
|
|
|
|
import login from './login.js'
|
|
|
|
|
|
import registry from './registry.js'
|
|
|
|
|
|
import linuxdo from './linuxdo.js'
|
|
|
|
|
|
import errorHandler from './middleware/errorHandler.js'
|
|
|
|
|
|
import ipFilter from './middleware/ipFilter.js'
|
|
|
|
|
|
import rateLimiter from './middleware/rateLimiter.js'
|
2025-12-24 22:27:36 +08:00
|
|
|
|
|
2026-03-16 12:05:55 +08:00
|
|
|
|
const app = new Koa()
|
|
|
|
|
|
const router = new Router()
|
2025-12-24 22:27:36 +08:00
|
|
|
|
|
2026-03-16 12:05:55 +08:00
|
|
|
|
// ─── 基础路由 ────────────────────────────────────────────────────────────────
|
2025-12-24 22:27:36 +08:00
|
|
|
|
router.get('/', (ctx) => {
|
2026-03-16 12:05:55 +08:00
|
|
|
|
ctx.body = { message: 'Chuanqi Server Running!' }
|
|
|
|
|
|
})
|
2025-12-24 22:27:36 +08:00
|
|
|
|
|
|
|
|
|
|
router.get('/api/config', (ctx) => {
|
2026-03-16 12:05:55 +08:00
|
|
|
|
ctx.body = {
|
|
|
|
|
|
data: {
|
|
|
|
|
|
gameName: config.game.name,
|
|
|
|
|
|
gameDescription: config.game.description,
|
|
|
|
|
|
codeOpen: config.code.open,
|
|
|
|
|
|
regCodeOpen: config.code.regCodeOpen,
|
|
|
|
|
|
regOpen: config.account.regOpen,
|
|
|
|
|
|
loginOpen: config.account.loginOpen,
|
|
|
|
|
|
linuxdoAuthorizeUrl: `/api/linuxdo/authorize`,
|
|
|
|
|
|
// 提现相关
|
|
|
|
|
|
withdrawRatio: config.withdraw.ratio,
|
|
|
|
|
|
withdrawMinOnce: config.withdraw.minOnce,
|
|
|
|
|
|
currencyName: config.currency.list[config.withdraw.type] || '货币',
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// ─── 中间件 ──────────────────────────────────────────────────────────────────
|
|
|
|
|
|
app.proxy = true
|
|
|
|
|
|
|
|
|
|
|
|
// 1. 统一错误处理(最外层,捕获所有异常)
|
|
|
|
|
|
app.use(errorHandler)
|
|
|
|
|
|
|
|
|
|
|
|
// 2. 请求日志
|
|
|
|
|
|
app.use(async (ctx, next) => {
|
|
|
|
|
|
log4js.koa.debug(`${ctx.method} ${ctx.path}`)
|
|
|
|
|
|
await next()
|
2025-12-24 22:27:36 +08:00
|
|
|
|
})
|
2026-03-16 12:05:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 3. IP 黑名单过滤
|
|
|
|
|
|
app.use(ipFilter)
|
|
|
|
|
|
|
|
|
|
|
|
// 4. 请求限流(防暴力破解)
|
|
|
|
|
|
app.use(rateLimiter)
|
|
|
|
|
|
|
|
|
|
|
|
// 5. body 解析
|
|
|
|
|
|
app.use(bodyParser({
|
|
|
|
|
|
enableTypes: ['json', 'form'],
|
|
|
|
|
|
formLimit: '10mb',
|
|
|
|
|
|
jsonLimit: '10mb',
|
|
|
|
|
|
}))
|
|
|
|
|
|
|
|
|
|
|
|
// 6. JWT 鉴权
|
2025-12-24 23:48:14 +08:00
|
|
|
|
app.use(auth)
|
2026-03-16 12:05:55 +08:00
|
|
|
|
|
|
|
|
|
|
// 路由挂载
|
|
|
|
|
|
app.use(router.routes())
|
|
|
|
|
|
app.use(router.allowedMethods())
|
2025-12-25 01:33:46 +08:00
|
|
|
|
app.use(login)
|
2026-03-16 12:05:55 +08:00
|
|
|
|
app.use(registry)
|
|
|
|
|
|
app.use(linuxdo)
|
2025-12-24 22:27:36 +08:00
|
|
|
|
|
2026-03-16 12:05:55 +08:00
|
|
|
|
// 静态文件(部署时前端 dist 挂到 /www)
|
|
|
|
|
|
app.use(koaStatic('/www'))
|
2025-12-24 22:27:36 +08:00
|
|
|
|
|
2026-03-16 12:05:55 +08:00
|
|
|
|
// ─── 启动 ────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
const PORT = process.env.PORT || 3001
|
2025-12-24 22:27:36 +08:00
|
|
|
|
app.listen(PORT, () => {
|
2026-03-16 12:05:55 +08:00
|
|
|
|
log4js.koa.info(`🚀 Koa server running on port ${PORT}`)
|
|
|
|
|
|
})
|