企业级开源版本:面向代理层级、佣金结算、审计追踪与运维部署的完整后台系统。
该仓库目前已落地:
- 需求与口径文档:
docs/ - 佣金结算引擎(纯函数 + 测试):
shared/commission-engine - 后端骨架 + DB 迁移:
backend/
默认无需 Docker:后端使用内置 Postgres(PGlite,WASM)持久化到 backend/.data/。
如你未来要接真实 Postgres,只需设置 DATABASE_URL。
- 推荐 Node.js
22.x(已在本地验证v22.17.0)。 - 仓库已提供
.node-version:22.17.0。 - 若你使用
fnm:
fnm use v22.17.0- 部分环境在 Node
24.x下运行 Next 构建可能出现不稳定报错,建议切回 22.x 再执行前端构建。
- 安装依赖
npm install推荐一键启动(自动迁移 + 初始化管理员 + 同时启动后端/管理端/代理端):
npm run dev:all如果你已经迁移并初始化过数据,使用快速启动:
npm run dev:all:fast- 配置后端环境变量
- 复制
backend/.env.example为backend/.env并按需修改
- 执行迁移(默认使用 PGlite)
npm run migrate- 初始化管理员账号(开发环境)
npm run seed- 启动后端
npm run dev:backend后台内置定时任务:
- 每月 5 号 00:10(本地时区)自动生成上月结算草稿(DRAFT)
- 也可手动调用
POST /admin/settlements/recalculate
说明:
dev:backend脚本已带开发默认JWT_SECRET与TZ=Asia/Shanghai兜底,无需 Docker 可直接启动。
管理端与代理端均使用 Next.js,默认端口如下:
- Admin Web:
http://localhost:3001 - Agent Web:
http://localhost:3002
启动命令(各开一个终端):
npm run dev:admin
npm run dev:agent或直接用上一节的一键命令:
npm run dev:all说明:
- 已默认使用 webpack 模式(
next dev --webpack/next build --webpack),避免 Turbopack 在中文路径下崩溃。 - 管理员默认账号来自
npm run seed:admin / admin123456。 - 代理账号需在管理端“代理管理”中新增后再登录代理端。
健康检查:
GET http://localhost:3000/healthGET http://localhost:3000/health/db
登录接口:
POST http://localhost:3000/auth/login{ "username": "admin", "password": "admin123456" }GET http://localhost:3000/auth/me(Bearer token)
已实现的代理端接口(部分,需 AGENT JWT):
GET /agent/meGET /agent/downlinesGET /agent/downlines/cards(下级/二级下级在网卡列表,卡号脱敏)GET /agent/team-membersGET /agent/team/cards(团队在网卡列表:本人完整号;非本人脱敏)GET /agent/cards(默认仅在网卡;可用?onNetOnly=false查看全部)GET /agent/announcements
已实现的管理端接口(部分):
- 星级:
GET/POST/PUT /admin/agent-levels - 套餐:
GET/POST/PUT /admin/plans - 政策:
GET/POST/PUT /admin/policies - 团队:
GET/POST/PUT /admin/teams、GET /admin/teams/:id/members、POST /admin/teams/:id/members、DELETE /admin/teams/:id/members/:agentId - 代理:
GET/POST/PUT /admin/agents、GET/PUT /admin/agents/:id/upline - 网卡:
GET/POST/PUT /admin/cards、POST /admin/cards/:id/assign、GET/POST /admin/cards/:id/status-events- 删除网卡:
DELETE /admin/cards/:id(仅未参与任何结算行项目的网卡可删除)
- 删除网卡:
- 结算草稿:
POST /admin/settlements/recalculate、GET /admin/settlements/runs(支持commissionMonth/limit/offset)、GET /admin/settlements/runs/:id/items- 删除草稿账单:
DELETE /admin/settlements/runs/:id(仅DRAFT可删除)
- 删除草稿账单:
- 结算执行记录:
GET /admin/settlements/executions(支持commissionMonth/status/triggerType/limit/offset) - 结算审核/入账/调整:
POST /admin/settlements/runs/:id/approvePOST /admin/settlements/runs/:id/unapprovePOST /admin/settlements/runs/:id/postPOST /admin/settlements/runs/:id/adjustGET /admin/settlements/runs/:id/diff(调整单前后对比视图)
- 报表:
GET /admin/reports/settlement-items.csv?commissionMonth=YYYY-MMGET /admin/reports/settlement-items.xlsx?commissionMonth=YYYY-MMGET /admin/reports/bill.csv?commissionMonth=YYYY-MM(账单格式:卡号/入网日期/套餐/月租/状态/扶持期/稳定期/金额/总计)GET /admin/reports/bill.xlsx?commissionMonth=YYYY-MM(同上)GET /admin/reports/settlement-summary/agents?commissionMonth=YYYY-MMGET /admin/reports/settlement-summary/teams?commissionMonth=YYYY-MM- 上述报表支持可选筛选:
beneficiaryAgentId/teamId/levelId/kind/targetKind/periodType/ownerAgentId/cardStatus
- 分录导出:
GET /admin/ledger/entries.csvGET /admin/ledger/entries.xlsx- 支持可选筛选:
commissionMonth/sourceType/settlementRunId/beneficiaryAgentId
- 公告:
GET/POST/PUT /admin/announcements - 审计:
GET /admin/audit-logs(支持entityType/entityId/action/actorUserId+limit/offset)GET /admin/audit-logs.csv(支持与列表同口径筛选)GET /admin/audit-logs.xlsx(支持与列表同口径筛选)GET /admin/audit-logs/export-summary(导出行为统计,支持days/actorUserId/action;action 支持REPORT_EXPORT_SETTLEMENT_ITEMS/REPORT_EXPORT_BILL_FORMAT/LEDGER_EXPORT_ENTRIES/AUDIT_EXPORT_LOGS)
npm test全量验证(测试 + 后端类型检查 + 两个前端 build):
npm run verify联调冒烟检查(需先启动 backend/admin/agent):
npm run smoke:live默认会校验:
backend /healthadmin-web /loginagent-web /login- 管理员登录与
/auth/me /admin/audit-logs、/admin/reports/settlement-items-preview、/admin/ledger/entries
适用于后续部署到 Linux 服务器并长期运行。
- 后端:复制
backend/.env.example为backend/.env,至少设置:JWT_SECRET=<强随机密钥,长度>=16TZ=Asia/Shanghai- 生产建议配置
DATABASE_URL=postgres://...(不建议生产使用 PGlite)
- 前端:分别复制
admin-web/.env.production.example->admin-web/.env.productionagent-web/.env.production.example->agent-web/.env.production- 并把
NEXT_PUBLIC_API_BASE_URL改成服务器后端地址(例如http://127.0.0.1:3000或你的域名 API 地址)
npm run server:preparenpm run server:startnpm run server:status
npm run server:healthnpm run server:stop
npm run server:restartsudo tee /etc/systemd/system/ruwang-taocan.service >/dev/null <<'EOF'
[Unit]
Description=Ruwang Taocan Fullstack Service (backend/admin/agent)
After=network.target
Wants=network.target
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/opt/ruwang-taocan
Environment=NODE_ENV=production
ExecStart=/usr/bin/npm run -s server:start
ExecStop=/usr/bin/npm run -s server:stop
ExecReload=/usr/bin/npm run -s server:restart
TimeoutStartSec=900
TimeoutStopSec=120
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable ruwang-taocan.service
sudo systemctl restart ruwang-taocan.service说明:
- 日志目录:
logs/ - PID 目录:
.run/ - 该模式使用
next start+backend start,不依赖tsx watch,比dev:all更适合服务器常驻。
如果你本机已有 Postgres,可以在 backend/.env 里设置:
DATABASE_URL=postgres://user:pass@localhost:5432/dbname
docker-compose.yml 仍保留作为参考,但本项目开发不依赖 Docker。
- Backend 镜像:
backend/Dockerfile - 生产 compose:
infra/docker-compose.prod.yml
示例:
cd infra
JWT_SECRET='replace-with-strong-secret' docker compose -f docker-compose.prod.yml up -d --build说明:
- 容器启动时会自动执行
npm run migrate,再启动后端服务。 - 生产建议使用真实 Postgres,禁止使用 PGlite。
- 备份与恢复参考:
docs/runbooks/backup-restore.md。