docs(migration): 添加清渊传奇PHP到Vue+Node.js移植计划文档

- 新增 MIGRATION.md 详细记录PHP到Node.js架构迁移方案
- 包含项目背景、现有资产盘点、架构设计、任务清单等完整规划
- 记录后端补全、前端补全、PHP停用、部署运维四个阶段实施计划
- 提供技术决策、数据库说明、进度总览等关键信息
- 更新 .gitignore 添加 *_out.txt build_output.txt 构建输出文件过滤
- 修复 utils.js 路径引用问题确保代码正常运行
This commit is contained in:
艾贤凌
2026-04-24 17:57:06 +08:00
parent d8106b2dd2
commit d676faa704
18 changed files with 23 additions and 105 deletions

4
.gitignore vendored
View File

@@ -6,6 +6,8 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log* pnpm-debug.log*
lerna-debug.log* lerna-debug.log*
*_out.txt
build_output.txt
node_modules node_modules
dist dist
@@ -22,3 +24,5 @@ dist-ssr
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
.lingma

View File

@@ -2,7 +2,7 @@ import Router from 'koa-router'
import mysql from '../mysql/index.js' import mysql from '../mysql/index.js'
import * as log4js from '../log4js.js' import * as log4js from '../log4js.js'
import config from '../config/index.js' import config from '../config/index.js'
import { encryptPassword } from '../utils.js' import { encryptPassword } from '../utils/utils.js'
const router = new Router() const router = new Router()

View File

@@ -3,7 +3,7 @@ import mysql from '../mysql/index.js'
import jwt from 'jsonwebtoken' import jwt from 'jsonwebtoken'
import * as log4js from '../log4js.js' import * as log4js from '../log4js.js'
import config from '../config/index.js' import config from '../config/index.js'
import { time, unixTime, encryptPassword, generateCode, getClientIp, isValidAccount, isValidEmail, getDeviceInfo } from '../utils.js' import { time, unixTime, encryptPassword, generateCode, getClientIp, isValidAccount, isValidEmail, getDeviceInfo } from '../utils/utils.js'
import { sendCodeMail } from '../mail.js' import { sendCodeMail } from '../mail.js'
const router = new Router() const router = new Router()

View File

@@ -1,5 +1,5 @@
import config from '../../config/index.js' import config from '../../config/index.js'
import { getClientIp } from '../../utils.js' import { getClientIp } from '../../utils/utils.js'
/** /**
* IP 黑名单过滤中间件 * IP 黑名单过滤中间件

View File

@@ -1,5 +1,5 @@
import * as log4js from '../../log4js.js' import * as log4js from '../../log4js.js'
import { getClientIp } from '../../utils.js' import { getClientIp } from '../../utils/utils.js'
/** /**
* 简单内存限流中间件(基于滑动窗口计数) * 简单内存限流中间件(基于滑动窗口计数)

View File

@@ -3,7 +3,7 @@ import mysql from '../mysql/index.js'
import getGameDB from '../mysql/gameDB.js' import getGameDB from '../mysql/gameDB.js'
import * as log4js from '../log4js.js' import * as log4js from '../log4js.js'
import config from '../config/index.js' import config from '../config/index.js'
import { time, unixTime, getClientIp } from '../utils.js' import { time, unixTime, getClientIp } from '../utils/utils.js'
import { readFileSync, existsSync } from 'fs' import { readFileSync, existsSync } from 'fs'
import { fileURLToPath } from 'url' import { fileURLToPath } from 'url'
import { dirname, join } from 'path' import { dirname, join } from 'path'

View File

@@ -1,3 +0,0 @@
[19:26:51] [INFO] [koa] 🚀 Koa server running on port 3001
[19:28:04] [WARN] [koa] 登录失败 testuser ::1
[20:13:27] [INFO] [koa] 用户登录成功 aceykubbo ::1

View File

@@ -1 +0,0 @@
[11:46:24] [INFO] [koa] 🚀 Koa server running on port 3001

View File

@@ -1,27 +0,0 @@
npm warn Unknown user config "home". This will stop working in the next major version of npm.
vite v7.3.1 building client environment for production...
<script src="/static/js/md5.js"> in "/index.html" can't be bundled without type="module" attribute
<script src="/static/js/common.js?v=1"> in "/index.html" can't be bundled without type="module" attribute
transforming...
✓ 1670 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html  1.05 kB │ gzip: 0.49 kB
dist/assets/agree-BLQpfDVx.css  1.37 kB │ gzip: 0.46 kB
dist/assets/linuxdo-bind-DPWWajSf.css  1.77 kB │ gzip: 0.53 kB
dist/assets/withdraw-DqWlBzRo.css  3.60 kB │ gzip: 0.81 kB
dist/assets/login-BlSp8Yei.css  4.29 kB │ gzip: 1.16 kB
dist/assets/index-KHprj2W-.css 378.12 kB │ gzip: 53.06 kB
dist/assets/agree-C-28jhbg.js  0.92 kB │ gzip: 0.63 kB
dist/assets/linuxdo-bind-CFqSeBhv.js  2.55 kB │ gzip: 1.25 kB
dist/assets/index-7GZNUh9s.js  3.66 kB │ gzip: 1.94 kB
dist/assets/withdraw-09hftHnJ.js  4.85 kB │ gzip: 2.24 kB
dist/assets/login-kOeQ-hLG.js  6.67 kB │ gzip: 2.60 kB
dist/assets/request-CitDfMDA.js  37.58 kB │ gzip: 15.14 kB
dist/assets/index-DjlCHBNb.js 988.31 kB │ gzip: 326.73 kB

(!) Some chunks are larger than 500 kB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ built in 11.94s

View File

@@ -1,25 +0,0 @@
npm warn Unknown user config "home". This will stop working in the next major version of npm.
vite v7.3.1 building client environment for production...
<script src="/static/js/md5.js"> in "/index.html" can't be bundled without type="module" attribute
<script src="/static/js/common.js?v=1"> in "/index.html" can't be bundled without type="module" attribute
transforming...
✓ 1670 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html  1.21 kB │ gzip: 0.54 kB
dist/assets/agree-BLQpfDVx.css  1.37 kB │ gzip: 0.46 kB
dist/assets/linuxdo-bind-DPWWajSf.css  1.77 kB │ gzip: 0.53 kB
dist/assets/withdraw-DqWlBzRo.css  3.60 kB │ gzip: 0.81 kB
dist/assets/login-Dg3cbkYJ.css  4.27 kB │ gzip: 1.16 kB
dist/assets/index-KHprj2W-.css 378.12 kB │ gzip: 53.06 kB
dist/assets/request-Cp8a3QvY.js  0.56 kB │ gzip: 0.42 kB
dist/assets/agree-BcUYvO61.js  1.00 kB │ gzip: 0.67 kB
dist/assets/linuxdo-bind-Dwzc1_1I.js  2.67 kB │ gzip: 1.31 kB
dist/assets/index-DuMdIoFP.js  3.74 kB │ gzip: 1.98 kB
dist/assets/index-C39LcZDB.js  4.34 kB │ gzip: 2.08 kB
dist/assets/withdraw-BUvhXBBH.js  4.97 kB │ gzip: 2.30 kB
dist/assets/login-kvI3nDLX.js  6.79 kB │ gzip: 2.67 kB
dist/assets/vendor-axios-42ANG6Sg.js  37.09 kB │ gzip: 14.85 kB
dist/assets/vendor-vue-CrCesgj8.js 105.59 kB │ gzip: 40.98 kB
dist/assets/vendor-element-DlG_uBZr.js 878.48 kB │ gzip: 284.60 kB
✓ built in 11.71s

View File

@@ -1,27 +0,0 @@
npm warn Unknown user config "home". This will stop working in the next major version of npm.
vite v7.3.1 building client environment for production...
<script src="/static/js/md5.js"> in "/index.html" can't be bundled without type="module" attribute
<script src="/static/js/common.js?v=1"> in "/index.html" can't be bundled without type="module" attribute
transforming...
✓ 1670 modules transformed.
rendering chunks...
computing gzip size...
dist/index.html  1.05 kB │ gzip: 0.49 kB
dist/assets/agree-BLQpfDVx.css  1.37 kB │ gzip: 0.46 kB
dist/assets/linuxdo-bind-DPWWajSf.css  1.77 kB │ gzip: 0.53 kB
dist/assets/withdraw-DqWlBzRo.css  3.60 kB │ gzip: 0.81 kB
dist/assets/login-BlSp8Yei.css  4.29 kB │ gzip: 1.16 kB
dist/assets/index-KHprj2W-.css 378.12 kB │ gzip: 53.06 kB
dist/assets/agree-C-28jhbg.js  0.92 kB │ gzip: 0.63 kB
dist/assets/linuxdo-bind-CFqSeBhv.js  2.55 kB │ gzip: 1.25 kB
dist/assets/index-7GZNUh9s.js  3.66 kB │ gzip: 1.94 kB
dist/assets/withdraw-09hftHnJ.js  4.85 kB │ gzip: 2.24 kB
dist/assets/login-kOeQ-hLG.js  6.67 kB │ gzip: 2.60 kB
dist/assets/request-CitDfMDA.js  37.58 kB │ gzip: 15.14 kB
dist/assets/index-DjlCHBNb.js 988.31 kB │ gzip: 326.73 kB

(!) Some chunks are larger than 500 kB after minification. Consider:
- Using dynamic import() to code-split the application
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.
✓ built in 17.40s

View File

@@ -5,7 +5,6 @@ const loadBar2MaxWidth = 200;
let loadError = false; let loadError = false;
onMounted(()=>{ onMounted(()=>{
const loadBox = document.getElementById('loadBox'), const loadBox = document.getElementById('loadBox'),
logoImg = document.getElementById('logoImg'),
loadBar1 = document.getElementById('loadBar1'), loadBar1 = document.getElementById('loadBar1'),
loadBar2 = document.getElementById('loadBar2'); loadBar2 = document.getElementById('loadBar2');
@@ -18,7 +17,6 @@ onMounted(()=>{
smallScreen = screenWidth <= 0, smallScreen = screenWidth <= 0,
isHorizontal = isMobile() && screenHeight <= 590; isHorizontal = isMobile() && screenHeight <= 590;
if (loadBox) loadBox.style.paddingTop = (!isHorizontal ? (screenHeight / 4) : 50) + 'px'; if (loadBox) loadBox.style.paddingTop = (!isHorizontal ? (screenHeight / 4) : 50) + 'px';
if (logoImg) logoImg.width = isHorizontal || smallScreen ? 300 : 500;
if (loadBar1) { if (loadBar1) {
loadBar1Width += 20; loadBar1Width += 20;
if (loadBar1Width > 100) loadBar1Width = 0; if (loadBar1Width > 100) loadBar1Width = 0;
@@ -73,7 +71,6 @@ onMounted(()=>{
<template> <template>
<div id="logDiv" style="position:absolute; top: 31%; left: 50%;transform: translate(-50%,-50%)"> <div id="logDiv" style="position:absolute; top: 31%; left: 50%;transform: translate(-50%,-50%)">
<div style="display: flex;flex-direction: column; align-items: center;gap: 4px;justify-content: center"> <div style="display: flex;flex-direction: column; align-items: center;gap: 4px;justify-content: center">
<img id="logoImg" align="center" width="380" src="/login/logo.png" class="mb-20"/>
<div id="label" style="color: #b4792e; font-size: 20px;"> <div id="label" style="color: #b4792e; font-size: 20px;">
首次加载时间较长请耐心等待如长时间无响应 <span class="font_small"> 首次加载时间较长请耐心等待如长时间无响应 <span class="font_small">
<a onClick="window.location.reload()" class="link_color">请点此刷新</a> / <a onClick="window.location.reload()" class="link_color">请点此刷新</a> /

View File

@@ -32,13 +32,14 @@ onMounted(async () => {
// 解析 JWT 获取账号信息 // 解析 JWT 获取账号信息
const payload = parseJwt(token) const payload = parseJwt(token)
if (!payload?.username) { if (!payload?.username) {
error.value = '登录信息无效,请重新登录'
sessionStorage.removeItem('CQ-TOKEN') sessionStorage.removeItem('CQ-TOKEN')
router.replace('/login') setTimeout(() => router.replace('/login'), 2000)
return return
} }
const account = payload.username const account = payload.username
const password = payload.password // md5 密码哈希,用于游戏客户端鉴权 const password = payload.password || '' // md5 密码哈希,用于游戏客户端鉴权
const serverId = payload.server_id || 1 const serverId = payload.server_id || 1
// 调用 enter_game 接口,更新登录信息 // 调用 enter_game 接口,更新登录信息

View File

@@ -66,7 +66,16 @@ async function handleLogin() {
if (res.code === 0) { if (res.code === 0) {
sessionStorage.setItem('CQ-TOKEN', res.token) sessionStorage.setItem('CQ-TOKEN', res.token)
ElMessage.success(res.message || '登录成功') ElMessage.success(res.message || '登录成功')
setTimeout(() => router.push('/index'), 1500) // 确保token被正确存储后再跳转
setTimeout(() => {
// 验证token是否已正确存储
const storedToken = sessionStorage.getItem('CQ-TOKEN')
if (storedToken) {
router.push('/index')
} else {
ElMessage.error('登录状态保存失败,请重试')
}
}, 1500)
} else { } else {
ElMessage.error(res.message || '登录失败') ElMessage.error(res.message || '登录失败')
} }

View File

@@ -10,6 +10,7 @@ export default defineConfig({
} }
}, },
server: { server: {
port: 3176,
proxy: { proxy: {
'/api': { '/api': {
target: 'http://localhost:3001', target: 'http://localhost:3001',

View File

@@ -1,11 +0,0 @@
npm warn Unknown user config "home". This will stop working in the next major version of npm.
20:23:55 [vite] (client) Re-optimizing dependencies because vite config has changed
VITE v7.3.1 ready in 970 ms
➜ Local: http://localhost:5173/
 ➜ Network: use --host to expose
[@vue/compiler-sfc] `defineOptions` is a compiler macro and no longer needs to be imported.
d:\code\chuanqi-qycq-web\module\web>