- drpy-node-admin: 独立的 Vue 3 后台管理项目
- 数据依赖: 通过 MCP (Model Context Protocol) 工具调用 drpy-node 功能
- 耦合问题: admin.js 中动态导入
drpy-node-mcp模块,违反依赖方向
┌─────────────────────────────────────────────────────────────┐
│ drpy-node │
│ ┌──────────────┐ ┌───────────────┐ ┌──────────────┐ │
│ │ Core APIs │ │ Controllers │ │ Static │ │
│ │ │ │ │ │ Files │ │
│ │ - /api/* │◄─┤ - admin.js │◄─┤ /apps/admin │ │
│ │ - /admin/* │ │ - api.js │ │ │ │
│ │ │ │ - config.js │ │ - index.html │ │
│ │ │ │ - ... │ │ - assets/* │ │
│ └──────────────┘ └───────────────┘ └──────────────┘ │
│ ▲ ▲ │
│ │ │ │
│ └──────────────┬─────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ drpy-node-admin (SPA Plugin) ││
│ │ ┌─────────┐ ┌──────────┐ ┌────────────┐ ││
│ │ │ Views │ │ Stores │ │Components │ ││
│ │ └────┬────┘ └────┬─────┘ └──────┬─────┘ ││
│ │ │ │ │ ││
│ │ └──────┬─────┴───────────────┴────┐ ││
│ │ │ API Client (axios) │ ││
│ │ └───────────┬─────────────┘ ││
│ │ │ ││
│ │ ┌───────────┴─────────────┐ ││
│ │ │ REST API Interface │ ││
│ │ │ /api/admin/* │ ││
│ │ └──────────────────────────┘ ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
▲
│
┌───────────────┴───────────────┐
│ drpy-node-mcp (Independent) │
│ ┌────────────────────────┐ │
│ │ MCP Tools │ │
│ │ - systemTools.js │ │
│ │ - spiderTools.js │ │
│ │ - fsTools.js │ │
│ │ - dbTools.js │ │
│ │ - apiTools.js │ │
│ └────────────────────────┘ │
│ ▲ │
│ │ (depends on) │
│ └───────────────────┘
└──────────────────────────────────┘
GET /api/admin/health
Response: {
status: "ok" | "error",
uptime: number,
memory: { used: number, total: number },
version: string
}
POST /api/admin/restart
Response: {
success: boolean,
message: string
}
GET /api/admin/logs?lines=50
Response: {
file: string,
content: string
}
WS /api/admin/logs/stream
Message: {
type: "log" | "error" | "end",
content: string,
timestamp: number
}
GET /api/admin/config?key=section.key
Response: any (配置值)
POST /api/admin/config
Body: {
key: string,
value: any
}
Response: {
success: boolean,
message: string
}
GET /api/admin/sources
Response: {
js: string[],
catvod: string[]
}
POST /api/admin/sources/validate
Body: {
path: string
}
Response: {
isValid: boolean,
message: string
}
POST /api/admin/sources/syntax
Body: {
path: string
}
Response: {
isValid: boolean,
error?: string
}
GET /api/admin/sources/template
Response: {
template: string
}
GET /api/admin/files/list?path=spider/js
Response: [{
name: string,
path: string,
isDirectory: boolean,
size?: number
}]
GET /api/admin/files/read?path=spider/js/test.js
Response: {
type: "text" | "image",
content?: string,
mimeType?: string,
dataUrl?: string
}
POST /api/admin/files/write
Body: {
path: string,
content: string
}
Response: {
success: boolean,
message: string
}
DELETE /api/admin/files/delete?path=spider/js/test.js
Response: {
success: boolean,
message: string
}
POST /api/admin/db/query
Body: {
sql: string
}
Response: [{
// 查询结果行
}]
GET /api/admin/routes
Response: {
registered_controllers: string[]
}
drpy-node/
├── controllers/
│ ├── admin.js # 重构,移除 MCP 依赖
│ └── admin/
│ ├── systemController.js # 系统管理
│ ├── logsController.js # 日志管理
│ ├── sourcesController.js # 源管理
│ ├── filesController.js # 文件管理
│ ├── dbController.js # 数据库查询
│ └── routesController.js # 路由信息
├── utils/
│ └── admin/
│ ├── logReader.js # 日志读取工具
│ ├── configManager.js # 配置管理工具
│ └── fileValidator.js # 文件安全验证
└── apps/
└── admin/ # 新增:编译后的 admin SPA
├── index.html
└── assets/
├── index-*.js
└── index-*.css
drpy-node-admin/
├── src/
│ ├── api/
│ │ ├── client.js # 保持,调整 baseURL
│ │ ├── admin.js # 新增:统一的 admin API 调用
│ │ ├── system.js # 重构:使用 /api/admin/system
│ │ ├── sources.js # 重构:使用 /api/admin/sources
│ │ ├── files.js # 重构:使用 /api/admin/files
│ │ └── db.js # 重构:使用 /api/admin/db
│ ├── views/
│ │ └── ... (保持不变)
│ ├── stores/
│ │ └── ... (保持不变)
│ └── components/
│ └── ... (保持不变)
├── vite.config.js # 调整:output 指向 apps/admin
├── package.json
└── tailwind.config.js
- 创建
controllers/admin/目录 - 实现 6 个子控制器模块
- 每个控制器实现对应的 API 接口
- 移除
import('../drpy-node-mcp/...')动态导入 - 实现独立的业务逻辑
- 注册子控制器路由
- 添加静态文件服务指向
apps/admin/
utils/admin/logReader.js- 日志文件读取utils/admin/configManager.js- 配置文件管理utils/admin/fileValidator.js- 路径安全验证
- 调整
baseURL为/api/admin - 移除 MCP 响应解析逻辑
- 实现标准的 REST API 调用
- 修改
build.outDir为../apps/admin - 修改
base为/admin/ - 添加构建优化配置
- 使用 history 模式或 hash 模式
- 添加路由回退处理
- 运行
npm run admin:build构建 - 验证生成的文件在
apps/admin/目录 - 测试所有功能正常工作
- 清理 MCP 依赖
- 确认 drpy-node 可以独立运行
- 性能测试
// 成功响应
{
success: true,
data?: any,
message?: string
}
// 错误响应
{
success: false,
error: string,
code?: string
}const ErrorCodes = {
UNAUTHORIZED: 'UNAUTHORIZED',
FORBIDDEN: 'FORBIDDEN',
NOT_FOUND: 'NOT_FOUND',
INVALID_PATH: 'INVALID_PATH',
SYNTAX_ERROR: 'SYNTAX_ERROR',
VALIDATION_ERROR: 'VALIDATION_ERROR',
INTERNAL_ERROR: 'INTERNAL_ERROR'
}// 使用与 /apps/ 相同的认证机制
// 所有 /api/admin/* 接口需要 basic authWS /api/admin/logs/stream
// 客户端 → 服务端
{
action: "subscribe" | "unsubscribe" | "clear",
lines?: number
}
// 服务端 → 客户端
{
type: "log" | "error" | "end",
timestamp: number,
content: string
}// 每 30 秒发送一次心跳
// 客户端
setInterval(() => {
ws.send(JSON.stringify({ type: 'heartbeat' }))
}, 30000)
// 服务端响应
{ type: 'pong' }// 只允许访问特定目录
const ALLOWED_PATHS = [
'spider/js',
'spider/js_dr2',
'spider/catvod',
'spider/py',
'spider/xbpq',
'config',
'json',
'docs'
];
// 禁止路径遍历
function validatePath(path) {
return !path.includes('..') &&
!path.includes('~') &&
!path.startsWith('/');
}// 只允许 SELECT 查询
if (!query.trim().toLowerCase().startsWith('select')) {
throw new Error('Only SELECT queries allowed');
}// 禁止写入关键文件
const PROTECTED_FILES = [
'package.json',
'index.js',
'database.db'
];// 使用流式传输大日志文件
const stream = fs.createReadStream(logPath);
stream.on('data', (chunk) => {
ws.send({ type: 'log', content: chunk.toString() });
});// admin 静态资源缓存策略
fastify.register(fastifyStatic, {
root: adminDistPath,
prefix: '/admin/',
cacheControl: 3600, // 1 小时
etag: true
});// 启用 gzip 压缩
import fastifyCompress from '@fastify/compress';
fastify.register(fastifyCompress);- 保留
/admin/mcp接口作为临时兼容层(可配置开关) - 给予过渡期,逐步迁移到新 API
// API 版本号
const API_VERSION = 'v1';
// 所有响应头包含版本
reply.header('X-API-Version', API_VERSION);- 每个控制器函数的单元测试
- 工具函数的单元测试
- API 响应格式验证
- API 端到端测试
- WebSocket 连接测试
- 文件上传下载测试
- 日志流式传输性能
- 大文件读取性能
- 并发请求处理
-
controllers/admin.js- 重构完成 -
controllers/admin/systemController.js- 新增 -
controllers/admin/logsController.js- 新增 -
controllers/admin/sourcesController.js- 新增 -
controllers/admin/filesController.js- 新增 -
controllers/admin/dbController.js- 新增 -
controllers/admin/routesController.js- 新增 -
utils/admin/logReader.js- 新增 -
utils/admin/configManager.js- 新增 -
utils/admin/fileValidator.js- 新增
-
src/api/client.js- baseURL 调整 -
src/api/admin.js- 统一 API 调用 -
src/api/system.js- API 重构 -
src/api/spider.js- API 重构 -
src/api/file.js- API 重构 -
src/api/db.js- API 重构 -
vite.config.js- 构建配置调整 -
package.json- 脚本更新
- API 接口文档
- 部署指南
- 开发指南更新
- 变更日志
| 阶段 | 任务 | 预计时间 |
|---|---|---|
| Phase 1 | API 层实现 | 2-3 天 |
| Phase 2 | 前端适配 | 1-2 天 |
| Phase 3 | 构建与集成 | 1 天 |
| 测试与修复 | 全面测试 | 1-2 天 |
| 总计 | 5-8 天 |
风险: 解耦后功能缺失 应对: 详细的功能对比测试清单
风险: 现有部署环境适配问题 应对: 保持 MCP 临时兼容层
风险: 新架构性能下降 应对: 性能基准测试和优化
- 添加源市场功能
- 添加源订阅功能
- 添加统计分析功能
- 实现主题自定义
- 添加快捷键支持
- 优化移动端体验
- 添加系统监控图表
- 实现日志分析功能
- 添加性能指标展示