Files

293 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# order_site
快手自动发货与履约管理系统。
前后端分离架构:接收外部订单、按规则匹配发货平台、生成统一领取链接,并提供后台做平台配置、任务追踪和人工复核。
## 技术栈
| 层 | 技术 |
| --- | --- |
| 前端 | React 19、Vite 8、Ant Design 6、React Router 7、TanStack Query、TypeScript |
| 后端 | Node.js、Express 5、TypeScript、PostgreSQL、node-pg-migrate |
| 网关 | Caddy |
| 运行 | Docker Compose(开发 / 生产分离) |
## 目录结构
```text
apps/
backend/ 后端 API、任务编排、平台对接、数据库迁移
src/
db/migrations/ SQL 迁移(001 基线 + 后续渐进增量)
data/ 本地运行数据与平台配置(敏感,默认不提交)
frontend/ React 管理后台 + 用户领取页
deploy/
caddy/ Caddy 反向代理
docker/ 前后端 Dockerfile
mac-dev.sh / ubuntu-deploy.sh
docs/ 平台接口、履约链路、部署说明
docker-compose.dev.yml 本地 Docker 开发环境
docker-compose.yml 生产 / 服务器 Compose
```
## 业务边界(简图)
```text
91 卡券进单
→ 本系统建单 / 匹配商品 / 创建履约任务
→ 返回统一 claimUrl
用户打开领取页
→ 可选:快手行业电子凭证自动核销
→ kuaishou-cloud / kuaishou-feifei / 人工 完成发货
后台
→ 订单任务、平台配置、审计、人工复核
接单平台(打手众包)
→ 工单发布到抢单大厅,打手抢单代练
→ 提交验收 / 问题单处置 / 任务时限超时自动判定
```
更完整的链路说明见:`docs/履约配置/多发货平台与电子凭证整体链路.md`
## 本地开发
推荐直接用 Docker,本机不必单独装 Node / PostgreSQL。
```bash
cp .env.mac-docker.example .env
docker compose -f docker-compose.dev.yml up -d --build
```
常用入口:
| 入口 | 地址 |
| --- | --- |
| 前端 / 后台 / 领取页 | `http://localhost` |
| 后端健康检查 | `http://localhost/health` |
| 后端就绪检查 | `http://localhost/health/ready` |
| 后端 API 前缀 | `http://localhost/api/v1/...` |
常用命令:
```bash
docker compose -f docker-compose.dev.yml ps
docker compose -f docker-compose.dev.yml logs -f backend
docker compose -f docker-compose.dev.yml logs -f frontend
docker compose -f docker-compose.dev.yml down
```
Mac 也可使用:
```bash
bash deploy/mac-dev.sh
```
## 开发验证
以容器内执行为准:
```bash
docker compose -f docker-compose.dev.yml exec -T backend npm test
docker compose -f docker-compose.dev.yml exec -T backend npm run format:check
docker compose -f docker-compose.dev.yml exec -T backend npm run typecheck
docker compose -f docker-compose.dev.yml exec -T backend npm run build
docker compose -f docker-compose.dev.yml exec -T frontend npm test
docker compose -f docker-compose.dev.yml exec -T frontend npm run format:check
docker compose -f docker-compose.dev.yml exec -T frontend npm run typecheck
docker compose -f docker-compose.dev.yml exec -T frontend npm run build
```
### 本地推送检查
本项目不使用 Gitea Actions。需要在本机推送前自动执行前后端检查时,启用本地 Git hook:
```bash
bash scripts/install-git-hooks.sh
```
启用后,每次 `git push` 会依次执行 `apps/backend``apps/frontend``npm run check`
仅临时跳过检查时使用:
```bash
SKIP_CHECKS=1 git push
```
## 数据库迁移
采用 **基线 + 渐进增量** 策略,由 `node-pg-migrate` 管理,记录表为 `schema_migrations`
| 文件 | 含义 |
| --- | --- |
| `001_init.sql` | 空库基线,建立完整业务结构 |
| `002_xxx.sql` ~ `009_xxx.sql` | 后续结构变更的增量 SQL(含接单平台 004~009 |
约定:
1. **不要修改**已经应用到共享/生产环境的历史迁移文件。
2. 结构变更一律新增迁移文件,不要回写 `001_init.sql`
3. 空库按序号依次执行 `001 → 002 → …`;已有库只执行尚未记录的增量。
4. 后端启动时自动 `up`;也可手动执行。
常用命令(容器内):
```bash
# 查看本地文件与数据库对齐状态
docker compose -f docker-compose.dev.yml exec -T backend npm run db:migrate:status
# 手动执行未应用迁移
docker compose -f docker-compose.dev.yml exec -T backend npm run db:migrate
# 创建下一份增量迁移(示例)
docker compose -f docker-compose.dev.yml exec -T backend npm run db:migrate:create -- add_task_priority
```
宿主机直连开发库(注意主机名):
```bash
cd apps/backend
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/order_site npm run db:migrate:status
DATABASE_URL=postgres://postgres:postgres@127.0.0.1:5432/order_site npm run db:migrate
```
本地需要清空数据重建库时(会丢开发数据):
```bash
docker compose -f docker-compose.dev.yml down
docker volume rm order_site_postgres_dev_data
docker compose -f docker-compose.dev.yml up -d --build
```
更多说明见 `docs/部署启动与数据库重建.md`
## 环境变量
本地:
```bash
cp .env.mac-docker.example .env
```
生产:
```bash
cp .env.server.example .env
```
常用变量:
| 变量 | 说明 |
| --- | --- |
| `APP_DOMAIN` / `CADDY_SITE_ADDR` | 后台与领取页域名、Caddy 主站监听地址 |
| `WORKER_SITE_ADDR` | 打手端独立域名,如 `https://worker.khhao.com` |
| `CLAIM_BASE_URL` | 领取页完整前缀,如 `https://域名/#/claim` |
| `CLAIM_TOKEN_TTL_HOURS` | 领取链接有效期(小时);`0` 表示长期有效,正整数表示限时 |
| `DATABASE_URL` | PostgreSQL 连接串(容器内主机名用 `postgres` |
| `ADMIN_SESSION_SECRET` | 后台登录态签名密钥 |
| `ADMIN_DEFAULT_USERS_JSON` | 默认后台用户 |
| `KAQUAN91_USER_ID` / `KAQUAN91_SECRET` | 91 卡券开放接口凭据 |
## 运行数据
| 环境 | 路径 / Volume |
| --- | --- |
| 本地后端配置与日志 | `apps/backend/data` |
| 本地 PostgreSQL | Docker volume `postgres_dev_data` |
| 生产后端数据 | `apps/backend/data`(与本地路径一致) |
| 生产 PostgreSQL | Docker volume `postgres_data` |
| 生产 Caddy | Docker volume `caddy_data` |
注意:`apps/backend/data/*.json` 可能含账号、Cookie、token 等敏感信息,默认不进仓库;只保留 `*.example.json` 模板。
## 生产部署
```bash
cp .env.server.example .env
# 编辑真实配置后:
mkdir -p apps/backend/data
sudo chown -R 1001:1001 apps/backend/data
docker compose up -d --build
```
Ubuntu 一键脚本:
```bash
bash deploy/ubuntu-deploy.sh
```
首次若无 `.env`,脚本会从示例生成模板并退出;填好后再执行一次即可。脚本会检查 Docker、占位配置、数据目录权限,构建启动并等待健康检查。
常用参数:
| 参数 | 说明 |
| --- | --- |
| `--skip-backup` | 跳过部署前的自动数据库备份(默认每次部署都会先 `pg_dump` 再上传 OSS,数据量较大时耗时明显)。仅代码改动、无 schema 变更时可加;涉及数据库迁移或 `--reset-db` 前建议保留备份 |
| `--reset-db` | 删除 PostgreSQL 数据卷后按 migrations 全量重建(执行前会自动抓取最后一份备份) |
| `--yes` | 跳过 `--reset-db` 的交互确认(等价于 `RESET_DB_CONFIRM=1` |
`--skip-backup` 也可用环境变量 `SKIP_BACKUP=true bash deploy/ubuntu-deploy.sh` 代替。备份与恢复的完整说明见 `docs/数据库备份与恢复.md`
生产入口示例:
- 前端与领取页:`https://你的域名/`
- 健康检查:`https://你的域名/health`
- API`https://你的域名/api/v1/...`
生产 Compose 会:启动 PostgreSQL → 后端自动迁移 → 初始化默认管理员 → 同步履约目录 → Caddy 暴露前端与 API。
## 主要模块
| 路径 | 职责 |
| --- | --- |
| `apps/backend/src/routes` | 开放接口 / 领取 / 后台 API |
| `apps/backend/src/routes/worker` | 打手端 API(抢单大厅、我的订单、验收) |
| `apps/backend/src/services/order` | 订单入库、商品匹配、任务同步 |
| `apps/backend/src/services/fulfillment` | 履约路由与执行器(cloud / feifei / 人工) |
| `apps/backend/src/services/worker-platform` | 接单平台业务(工单、等级、押金结算、超时扫描) |
| `apps/backend/src/services/platforms` | 外部平台对接 |
| `apps/backend/src/services/admin` | 后台鉴权、读写、配置 |
| `apps/backend/src/services/scheduler` | 定时任务(云账号健康检查、工单超时扫描) |
| `apps/backend/src/repositories` | 数据访问 |
| `apps/backend/src/db/migrations` | 数据库迁移 |
| `apps/frontend/src/pages/admin` | 管理后台页面 |
| `apps/frontend/src/pages/worker` | 打手端页面(大厅、我的订单、个人中心) |
| `apps/frontend/src/pages/claim` | 用户领取页 |
## 接单平台(打手众包)
用于将部分订单转为打手代练任务,与主履约流程解耦:
| 能力 | 说明 |
| --- | --- |
| 抢单大厅 | 打手按分类/关键词筛选,实时刷新、冻结押金抢单;拼单工单按份参与 |
| 我的订单 | 代练中 / 待验收 / 问题单流转,提交验收支持图片粘贴与拖拽 |
| 任务时限 | 工单可配置时限,超时由定时扫描 + 接口惰性判定双重处置(退回大厅 / 取消退押金 / 取消扣押金),并统计每个打手的超时订单数 |
| 等级权限 | VIP 等级体系:免押额度、最大同时接单量、大厅可见延迟 |
| 资金 | 押金冻结 / 退还 / 扣除流水,充值申请与提现审核 |
| 物品规则 | 按商品/SKU 匹配自动生成工单,可继承默认时限与拼单配置 |
| 管理后台 | 接单工单 CRUD、打手账号管理、问题单处置、定时任务管理,功能标签页记忆上次选择 |
说明:
- 打手通过**手机号验证码注册**并设置密码,注册后直接可用;登录使用手机号 + 密码。
- 短信默认 Mock 模式(验证码打印到服务日志),生产配置 `WORKER_SMS_PROVIDER=aliyun` + 阿里云凭据后走真实短信。
- 来源订单同步由物品规则驱动(`syncWorkerOrdersForSourceOrder`)。
- 工单状态机独立于主履约任务:`pending_material → unassigned → open → in_progress → pending_acceptance → accepted / cancelled`,另有 `problem`
- 超时扫描定时任务默认 60 秒执行一次(配置见后台"平台配置 → 定时任务")。
## 提交前检查
```bash
docker compose -f docker-compose.dev.yml exec -T backend npm run check
docker compose -f docker-compose.dev.yml exec -T frontend npm run check
```
代码格式由仓库根目录的 Prettier 配置统一管理。修改代码后可在对应应用目录执行
`npm run format`,提交前使用 `npm run format:check` 只检查、不修改文件。
确认:
- 未提交真实账号、Cookie、token、手机号或生产配置
- `.env` 未入库
- **结构变更的 migration 与业务代码同 PR 提交**
- 领取链接相关改动已在 Docker 环境验证