diff --git a/README.md b/README.md index e69de29..26e96a3 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,87 @@ +# WMS SaaS + +商业化、多租户的仓储管理系统(Warehouse Management System)。面向电商卖家、海外仓、第三方仓与 3PL,支持多租户、多仓库、多客户、多 SKU,以及入库、出库、库存与电商订单接入。 + +当前处于 **Phase 1:架构与数据模型设计**。设计文档在 [`docs/`](./docs/README.md),代码目录(`backend/`、`frontend/`、`py-service/`)尚未创建。开发顺序见 [`docs/16-roadmap.md`](./docs/16-roadmap.md)。 + +## 架构 + +``` +Vue 3 Admin + │ + ▼ +Laravel REST API ← 唯一的核心业务系统 + │ + ├── MySQL 8 ← 业务事实数据源 + ├── Redis 7 ← Cache / Queue / Lock / Rate Limit + └── Queue / Scheduler + │ + ├── 第三方平台 Adapter(Amazon、Shopify、TikTok Shop 等) + └── Python FastAPI(AI / 数据分析,只读分析,不写核心库) +``` + +| 组件 | 职责 | +| --- | --- | +| `frontend/` | Vue 3 Admin:界面、交互、前端权限展示 | +| `backend/` | Laravel:租户、用户、SKU、仓库、库存、入库、出库、订单、物流、权限、审计 | +| `py-service/` | FastAPI:分析、预测、补货建议、异常检测。只通过 `/internal/v1/` 与 Laravel 交互 | + +## 技术栈 + +| 层 | 选型 | +| --- | --- | +| 前端 | Vue 3、TypeScript、Vite、Element Plus、Pinia、Vue Router(基于 [pure-admin-thin i18n](https://github.com/pure-admin/pure-admin-thin/tree/i18n)) | +| 后端 | Laravel 13、PHP 8.4、Sanctum、Queue、Scheduler | +| 数据 | MySQL 8、Redis 7 | +| 分析 | Python 3、FastAPI、Pydantic | +| 运行 | 根目录一个 `docker-compose.yml`(Phase 17 落地;开发环境见 [`docs/13-docker.md`](./docs/13-docker.md)) | + +API 前缀:`/api/v1/...`。 + +## 仓库结构 + +``` +wms-saas/ +├── backend/ Laravel 核心业务(待建) +├── frontend/ Vue 3 Admin(待建) +├── py-service/ Python AI / Data Service(待建) +├── docs/ 设计文档与表结构 +├── docker-compose.yml 统一开发环境(待建,见 docs/13-docker.md) +└── README.md +``` + +## 不可违背的约束 + +1. **多租户**:单库 + `tenant_code`,由 TenantContext 自动隔离,禁止跨租户读写。 +2. **库存**:余额是结果,流水(`wms_stock_log`)是事实。库存变化必须同事务写流水,且并发安全。 +3. **Laravel 是唯一核心业务系统**:Python 不直接写核心库。 +4. **平台解耦**:订单是统一模型,第三方平台走 Connector / Adapter,核心表不写死平台逻辑。 +5. **状态机**:状态用 Enum,合法转换集中定义。 +6. **业务编码优先**:关联使用 `sku_code`、`outbound_no` 等,自增 ID 只作内部主键。 +7. **分阶段**:按 Phase 1~17 推进,每个阶段先说明方案、再实施、再验证。 + +原则:**简单、清晰、可维护、可扩展、业务优先。** + +## 文档 + +完整设计见 [`docs/README.md`](./docs/README.md)。日常开发先读这些: + +| 文档 | 内容 | +| --- | --- | +| [00 概述](./docs/00-overview.md) | 项目定位与目标 | +| [02 架构](./docs/02-architecture.md) | 分层与职责边界 | +| [03 多租户](./docs/03-multi-tenancy.md) | `tenant_code` 与 TenantContext | +| [05 库存](./docs/05-inventory.md) | 余额、流水、并发 | +| [09 数据库](./docs/09-database.md) | 表设计规范 | +| [database/](./docs/database/README.md) | 按领域的表结构 | +| [16 路线图](./docs/16-roadmap.md) | Phase 顺序与当前阶段 | + +## 本地开发 + +环境与业务代码尚未初始化。进入对应 Phase 后: + +```bash +docker compose up -d +``` + +敏感配置通过 `.env` 注入,不提交到 Git。 diff --git a/docs/00-overview.md b/docs/00-overview.md new file mode 100644 index 0000000..d601269 --- /dev/null +++ b/docs/00-overview.md @@ -0,0 +1,47 @@ +# 00 项目概述 + +## 项目定位 + +从零开发一个**商业化、多租户 SaaS WMS(Warehouse Management System)**。 + +它不是简单的 CRUD 后台,而是一个未来可以长期商业化的正式 SaaS 产品,需要支持: + +- 多个租户 +- 多个仓库 +- 3PL / 海外仓 +- 电商订单接入 + +## 角色要求 + +开发者(含 AI Agent)应以以下身份工作: + +- 资深 SaaS / WMS 系统架构师 +- Laravel 后端工程师 +- Vue 3 前端工程师 +- 具备仓储物流、ERP、3PL、跨境电商仓储业务经验 + +## 最终目标 + +最终系统应成为一个真正商业化的 **SaaS WMS**,支持: + +多租户 + 多仓库 + 多客户 + 多 SKU + 入库 + 出库 + 库存 + 波次 + 拣货 + 打包 + 物流 + 3PL + 电商订单 + 开放 API + AI 数据分析 + +架构要能够支持未来的业务形态与对接对象: + +- 普通电商卖家 +- 海外仓 +- 第三方仓 +- 3PL +- 跨境电商 +- ERP 对接 +- Amazon +- Shopify +- TikTok Shop +- Temu +- Mirakl + +**但第一阶段不要为了这些未来需求提前实现所有功能。** + +## 一句话架构 + +Laravel 负责应用层,Domain 负责 WMS 核心业务规则,Eloquent 负责数据持久化,Queue 负责异步任务,Adapter 负责第三方平台,TenantContext 负责多租户隔离。 diff --git a/docs/01-tech-stack.md b/docs/01-tech-stack.md new file mode 100644 index 0000000..109e8d0 --- /dev/null +++ b/docs/01-tech-stack.md @@ -0,0 +1,63 @@ +# 01 技术栈 + +## 前端 + +- Vue 3 +- TypeScript +- Vite +- Element Plus +- Pinia +- Vue Router +- VueUse +- ECharts +- Axios +- ESLint +- Prettier + +前端 Admin 采用 [pure-admin-thin(i18n 分支)](https://github.com/pure-admin/pure-admin-thin/tree/i18n)。详见 [10-frontend.md](./10-frontend.md)。 + +## 后端 + +- Laravel 13 +- PHP 8.4 + +使用: + +- Laravel Sanctum +- Laravel Queue +- Laravel Scheduler +- Redis +- Laravel HTTP Client +- Laravel Cache +- Laravel Events / Listeners +- Laravel Notifications(需要时使用) +- Laravel Policies / Gates +- Laravel API Resources +- Laravel Form Requests +- Laravel Service / Action 类 +- Laravel Console Commands + +API 采用 RESTful API,统一前缀 `/api/v1/...`。 + +## 数据库 + +- MySQL 8 +- Redis 7 + +## Python 服务 + +Python 作为独立服务存在,不参与 Laravel 核心业务 CRUD。 + +- Python 3.x +- FastAPI +- Pydantic +- HTTP API +- Redis +- 后期根据需要使用 Pandas / NumPy / Scikit-learn / PyTorch / LLM SDK + +详见 [11-py-service.md](./11-py-service.md)。 + +## 依赖原则 + +- 不随意增加第三方依赖。 +- 第一阶段不引入 Kubernetes、Kafka、Elasticsearch、MongoDB、ClickHouse 等(见 [02-architecture.md](./02-architecture.md))。 diff --git a/docs/02-architecture.md b/docs/02-architecture.md new file mode 100644 index 0000000..55ed29d --- /dev/null +++ b/docs/02-architecture.md @@ -0,0 +1,81 @@ +# 02 总体架构 + +## 架构分层 + +``` +Vue 3 + ↓ +Laravel REST API + ↓ +MySQL / Redis + ↓ +Laravel Queue / Scheduler +``` + +Python FastAPI 作为独立 AI / Data Service。 + +## 总体结构 + +``` + Vue 3 + │ + ▼ + Laravel API + │ + ┌──────────────┼──────────────┐ + │ │ │ + ▼ ▼ ▼ + MySQL Redis Queue + │ + ▼ + Workers + │ + ┌────────────┴────────────┐ + │ │ + ▼ ▼ + Third-party APIs Python Service + │ + ┌────────┼────────┐ + ▼ ▼ ▼ + AI Analysis Forecast +``` + +## 三者职责边界 + +| 组件 | 职责 | +| --- | --- | +| Vue 3 | Admin 界面、交互、前端权限展示 | +| Laravel | **唯一的核心业务系统**:租户、用户、SKU、仓库、库存、入库、出库、订单、物流、权限、审计 | +| Python | 独立 AI / 数据分析服务:分析、预测、补货建议、异常检测、AI 助手 | + +- 核心业务逻辑不得迁移到 Python。 +- Python 不得直接修改 Laravel 核心业务数据库。 + +## Redis + +Redis 用于: + +- Cache +- Queue +- Rate Limit +- Lock +- 临时数据 + +**不要把 Redis 当作核心业务数据库。MySQL 永远是业务事实数据源。** + +## 不要过度设计 + +第一阶段不要引入: + +- Kubernetes +- Kafka +- Elasticsearch +- MongoDB +- ClickHouse +- 微服务 +- 独立认证中心 +- Service Mesh + +先使用:**Laravel + MySQL + Redis + Queue**。 + +架构保持模块化,未来确实需要时再拆服务。 diff --git a/docs/03-multi-tenancy.md b/docs/03-multi-tenancy.md new file mode 100644 index 0000000..89e094c --- /dev/null +++ b/docs/03-multi-tenancy.md @@ -0,0 +1,54 @@ +# 03 SaaS 多租户 + +## SaaS First + +系统必须从第一天支持多租户。 + +- 采用:**单数据库 + tenant_code** +- 第一阶段不采用:一个租户一个数据库 + +## 需要租户隔离的表 + +所有核心业务表原则上都需要 `tenant_code`,例如: + +- warehouse +- warehouse_location +- customer +- product +- sku +- inventory +- inbound +- outbound +- shipment +- stock_log + +## tenant_code 是核心数据隔离维度 + +不要依赖开发人员到处手工编写: + +```php +Model::where('tenant_code', $tenantCode) +``` + +应建立统一的租户上下文 **TenantContext**(或类似机制)。 + +目标: + +1. 当前登录用户确定当前 `tenant_code`。 +2. 业务 Service / Repository / Query 默认自动限制当前租户。 +3. 创建数据时自动写入当前 `tenant_code`。 + +**严禁出现:租户 A 可以查询到租户 B 数据。** + +## 需要特别注意的场景 + +TenantContext 不只存在于 HTTP 请求中,以下场景同样必须正确设置租户上下文: + +- Queue Job(在任务载荷中携带 `tenant_code`,执行时恢复上下文) +- Scheduler / Console Command(按租户遍历执行) +- 第三方 Webhook(根据店铺 / 应用凭证解析租户) +- 缓存 Key、锁 Key(必须带 `tenant_code` 前缀) + +## 测试 + +Tenant Isolation 是核心测试项之一,见 [14-testing.md](./14-testing.md)。 diff --git a/docs/04-domain-model.md b/docs/04-domain-model.md new file mode 100644 index 0000000..54b368d --- /dev/null +++ b/docs/04-domain-model.md @@ -0,0 +1,110 @@ +# 04 WMS 领域模型 + +## 业务编码优先 + +业务系统尽量使用明确的业务编码: + +| 编码 | 含义 | +| --- | --- | +| tenant_code | 租户 | +| warehouse_code | 仓库 | +| location_code | 库位 | +| customer_code | 客户 | +| supplier_code | 供应商 | +| product_code | 商品 | +| sku_code | SKU | +| order_no | 订单 | +| inbound_no | 入库单 | +| outbound_no | 出库单 | +| picking_no | 拣货单 | +| shipment_no | 发货单 | +| package_no | 包裹 | + +不要让业务逻辑全部依赖数据库自增 ID。数据库 ID 可以作为内部主键,但业务关联应优先考虑业务编码。 + +## 业务模块(第一阶段设计) + +### 1. SaaS +租户、用户、角色、权限、租户设置、操作日志 + +### 2. 基础资料 +客户、供应商、商品、SKU、SKU 条码、包装规格、重量、尺寸 + +### 3. 仓库 +仓库、库区、库位、库位类型、库位容量、库位策略 + +### 4. 入库 +入库单、入库明细、收货、收货差异、质检、上架、入库流水 + +### 5. 出库 +出库单、出库明细、库存分配、波次、拣货任务、复核、打包、发货 + +### 6. 库存 +库存查询、库存余额、库存流水、库存锁定、库存调整、库存盘点、库存冻结、库存解冻、库存预警 + +### 7. 退货 +退货单、退货收货、退货质检、重新入库、报废 + +### 8. 物流 +物流渠道、承运商、物流服务、运费规则、面单、发货、Tracking + +### 9. 报表 +库存报表、入库报表、出库报表、库存周转、SKU 销量、仓库作业统计 + +### 10. AI / 数据分析(预留 Python 服务接口) +库存分析、SKU 销量分析、缺货预测、补货建议、库存周转分析、异常库存、AI WMS Assistant + +## 订单模型 + +WMS 不应和某一个电商平台强绑定,订单应抽象为统一订单模型,例如: + +- order +- order_item +- order_source +- order_status +- order_external_no +- order_channel + +以后可以支持:Amazon、Shopify、TikTok Shop、Temu、Shopee、Mirakl、ERP、API、手工订单。 + +**不要在核心订单表中写死 Amazon / TikTok 等平台业务逻辑。** + +## 第三方平台架构 + +第三方平台必须采用 **Adapter / Connector** 思路: + +``` +MarketplaceConnector (接口) +├── AmazonConnector +├── ShopifyConnector +├── MiraklConnector +└── TikTokShopConnector +``` + +以后增加平台时,不应该修改大量核心 WMS 代码。核心 WMS 只关心: + +- 统一订单 +- 统一 SKU +- 统一库存 +- 统一物流 +- 统一状态 + +平台实现放在 `app/Infrastructure/Platforms/{Platform}/`,负责平台数据与统一模型之间的映射。 + +## 状态机 + +入库、出库、订单、库存任务不要到处使用: + +```php +if ($status == xxx) +``` + +应设计明确的状态流转。例如出库: + +``` +draft → allocated → picking → picked → packing → packed → shipped → completed +``` + +- 状态使用 PHP Enum 定义,禁止魔法字符串。 +- 允许的状态转换集中定义,**非法状态转换必须被阻止**。 +- 状态变更需记录日志(谁、何时、从何状态到何状态)。 diff --git a/docs/05-inventory.md b/docs/05-inventory.md new file mode 100644 index 0000000..0657a86 --- /dev/null +++ b/docs/05-inventory.md @@ -0,0 +1,101 @@ +# 05 库存设计 + +**库存设计是整个 WMS 的核心。** + +## 库存模型 + +不要简单设计 `sku + warehouse + quantity`,必须建立完整库存模型。 + +### 数量维度 + +| 字段 | 含义 | +| --- | --- | +| available_qty | 可用数量 | +| reserved_qty | 预占 / 锁定数量 | +| picked_qty | 已拣货数量 | +| hold_qty | 冻结数量 | +| damaged_qty | 残损数量 | +| in_transit_qty | 在途数量 | + +### 位置与属性维度 + +- 仓库 +- 库区 +- 库位 +- SKU +- 批次 +- 库存状态 + +### 核心关系 + +``` +SKU + ↓ +Warehouse + ↓ +Zone + ↓ +Location + ↓ +Batch + ↓ +Inventory +``` + +## 库存流水必须是核心数据 + +必须设计 `wms_stock_log`,任何库存变化必须能够追溯。例如: + +``` +入库 +100 +锁定 -20 +拣货 -5 +出库 -5 +盘点 +2 +调整 -1 +``` + +需要能够回答:**为什么这个 SKU 的库存从昨天的 100 变成今天的 76?** + +- 库存余额是结果。 +- 库存流水是事实。 + +不要只修改 `inventory.quantity` 而不留下完整流水。库存余额更新与流水写入必须在同一事务中完成,流水需记录业务单据类型与单号(如 inbound_no / outbound_no)。 + +## 库存并发安全 + +库存扣减必须考虑并发。 + +**禁止:** 先 SELECT → PHP 计算 → UPDATE。这种方式容易产生超卖。 + +根据实际业务采用: + +- 数据库事务 +- 行锁(`SELECT ... FOR UPDATE`) +- 乐观锁(version 字段) +- 原子更新 +- Redis 分布式锁(必要时) + +原子更新示例: + +```sql +UPDATE wms_inventory +SET available_qty = available_qty - :qty, + reserved_qty = reserved_qty + :qty +WHERE tenant_code = :tenant_code + AND id = :id + AND available_qty >= :qty; +-- 受影响行数为 0 即库存不足,必须抛出业务异常 +``` + +必须保证: + +- `available_qty >= 扣减数量` +- 多个并发请求不能导致负库存或重复扣减 + +## 并发验收用例 + +两个请求同时扣减 8 个库存,而实际只有 10 个库存。必须保证: + +- 不会出现 `available_qty = -6` +- 不能出现两个订单都成功扣减 8 diff --git a/docs/06-backend-laravel.md b/docs/06-backend-laravel.md new file mode 100644 index 0000000..3bd3bca --- /dev/null +++ b/docs/06-backend-laravel.md @@ -0,0 +1,109 @@ +# 06 Laravel 后端结构 + +## 分层 + +不要把所有业务代码写进 Controller。推荐: + +``` +Controller + ↓ +FormRequest + ↓ +Service / Action + ↓ +Domain Logic + ↓ +Model / Repository + ↓ +Database +``` + +Controller 只负责: + +- 接收请求 +- 参数验证(通过 FormRequest) +- 调用业务服务 +- 返回 API Resource + +复杂业务必须进入 Service / Action。 + +## Action 命名示例 + +- CreateInboundAction +- ReceiveInboundAction +- PutawayInboundAction +- AllocateOutboundAction +- CreateWaveAction +- PickOrderAction +- PackOrderAction +- ShipOrderAction +- AdjustInventoryAction +- StocktakeAction + +## 目录结构 + +``` +app/ +├── Domain/ # WMS 核心业务规则(状态机、领域规则、值对象、枚举) +│ ├── Inventory/ +│ ├── Order/ +│ ├── Inbound/ +│ ├── Outbound/ +│ ├── Warehouse/ +│ ├── Picking/ +│ ├── Packing/ +│ ├── Shipment/ +│ ├── Return/ +│ └── Logistics/ +│ +├── Application/ # 应用层用例 +│ ├── Inventory/ +│ │ ├── Actions/ +│ │ ├── Services/ +│ │ └── DTOs/ +│ ├── Order/ +│ ├── Inbound/ +│ └── Outbound/ +│ +├── Http/ +│ ├── Controllers/ +│ ├── Requests/ +│ └── Resources/ +│ +├── Models/ # Eloquent 模型(数据持久化) +│ +├── Jobs/ +├── Events/ +├── Listeners/ +├── Policies/ +├── Console/ +├── Support/ # 通用支持:TenantContext、ApiResponse 等 +│ +└── Infrastructure/ # 外部适配 + ├── Cache/ + ├── Queue/ + ├── Logistics/ + └── Platforms/ + ├── Amazon/ + ├── TikTokShop/ + ├── Temu/ + ├── Shopee/ + └── Mirakl/ +``` + +## 职责划分 + +| 层 | 职责 | +| --- | --- | +| Laravel(Http / Application) | 应用层:请求、用例编排、事务边界 | +| Domain | WMS 核心业务规则 | +| Eloquent(Models) | 数据持久化 | +| Queue(Jobs) | 异步任务 | +| Adapter(Infrastructure) | 第三方平台、物流商 | +| TenantContext | 多租户隔离 | + +## 依赖方向 + +- Http → Application → Domain;Infrastructure 实现 Domain / Application 定义的接口。 +- Domain 不依赖 Http、不依赖具体第三方平台。 +- 模块之间避免强耦合,跨模块协作优先通过 Application Service 或 Events。 diff --git a/docs/07-api.md b/docs/07-api.md new file mode 100644 index 0000000..52d534d --- /dev/null +++ b/docs/07-api.md @@ -0,0 +1,58 @@ +# 07 API 规范 + +## 路由 + +RESTful,统一前缀 `/api/v1/`。 + +``` +GET /api/v1/warehouses +GET /api/v1/skus +GET /api/v1/inventory + +POST /api/v1/inbounds +POST /api/v1/inbounds/{inbound_no}/receive +POST /api/v1/inbounds/{inbound_no}/putaway + +GET /api/v1/outbounds +POST /api/v1/outbounds/{outbound_no}/allocate +POST /api/v1/outbounds/{outbound_no}/pick +POST /api/v1/outbounds/{outbound_no}/pack +POST /api/v1/outbounds/{outbound_no}/ship +``` + +要点: + +- 资源名使用复数。 +- 路由参数优先使用业务编码(`inbound_no`、`outbound_no`),而非自增 ID。 +- 业务动作(状态流转)使用 `POST /{resource}/{code}/{action}`。 +- 认证使用 Laravel Sanctum,授权使用 Policies / Gates。 + +## 统一返回格式 + +不要每个 Controller 自己定义一套返回结构。 + +成功: + +```json +{ + "success": true, + "message": "OK", + "data": {} +} +``` + +失败: + +```json +{ + "success": false, + "message": "操作失败", + "errors": {} +} +``` + +分页数据使用统一格式(具体字段在 Phase 2 确定并固化到统一响应工具类中),所有列表接口保持一致。 + +## 内部 API(Python Service) + +Laravel 调用 Python 的内部接口统一使用 `/internal/v1/` 前缀,见 [11-py-service.md](./11-py-service.md)。 diff --git a/docs/08-queue-scheduler.md b/docs/08-queue-scheduler.md new file mode 100644 index 0000000..e4f3cfe --- /dev/null +++ b/docs/08-queue-scheduler.md @@ -0,0 +1,46 @@ +# 08 Queue / Scheduler + +## Queue + +以下任务原则上应进入 Queue: + +- 第三方订单同步 +- 库存同步 +- 物流同步 +- 批量导入 +- 批量导出 +- 面单生成 +- Tracking 同步 +- 大量库存计算 +- 报表生成 +- AI 分析 +- 邮件 / 通知 +- Webhook 处理 + +**不要让用户 HTTP 请求长时间等待第三方 API。** + +Job 要求: + +- 携带 `tenant_code`,执行时恢复 TenantContext。 +- 幂等:重复执行不会产生重复业务数据或重复扣减库存。 +- 配置合理的重试次数、退避与超时。 + +## Scheduler + +使用 Laravel Scheduler,例如: + +- 订单同步 +- 库存同步 +- Tracking 同步 +- 异常订单检查 +- 库存预警 +- AI 分析任务 +- 报表任务 + +所有定时任务必须可配置,并考虑: + +- 防重复执行 +- 失败重试 +- 日志 +- 超时 +- 租户隔离 diff --git a/docs/09-database.md b/docs/09-database.md new file mode 100644 index 0000000..963af94 --- /dev/null +++ b/docs/09-database.md @@ -0,0 +1,67 @@ +# 09 数据库设计 + +## 引擎 + +- MySQL 8:业务事实数据源 +- Redis 7:缓存 / 队列 / 锁 / 限流(非业务数据源) + +## 必须考虑的业务维度 + +- 多租户 +- 多仓库 +- 多客户 +- 多 SKU +- 批次 +- 库位 +- 库存流水 +- 库存锁定 +- 库存预占 +- 并发库存更新 +- 订单状态流转 +- WMS 作业任务 +- 数据审计 + +## 表设计规范 + +所有表: + +- 使用 InnoDB +- utf8mb4 +- 合理索引 +- `created_at` +- `updated_at` + +重要业务表考虑: + +- `deleted_at` +- `version`(乐观锁) +- `status` + +但不要为了"统一"而无脑给所有表增加软删除。库存流水等事实数据不应被删除或修改。 + +## 核心业务表需包含 tenant_code + +见 [03-multi-tenancy.md](./03-multi-tenancy.md)。业务编码的唯一约束应包含租户维度,例如 `UNIQUE (tenant_code, sku_code)`。 + +## 索引 + +索引必须围绕实际查询设计。特别关注: + +- tenant_code +- warehouse_code +- customer_code +- sku_code +- order_no +- inbound_no +- outbound_no +- location_code +- created_at +- status + +复合索引通常以 `tenant_code` 作为最左列。 + +## 设计产出 + +表结构设计统一存放在 [`docs/database/`](./database/README.md)。 + +在写迁移之前,先在 `docs/database/` 中产出并确认表结构,把租户、仓库、库位、SKU、库存、库存流水、入库、出库这几个核心模型定死,再开始写 Laravel。迁移与设计文档必须保持一致。 diff --git a/docs/10-frontend.md b/docs/10-frontend.md new file mode 100644 index 0000000..ae12f5b --- /dev/null +++ b/docs/10-frontend.md @@ -0,0 +1,105 @@ +# 10 前端 + +## 技术栈 + +Vue 3 + TypeScript + Vite + Element Plus + Pinia + Vue Router + VueUse + ECharts + Axios + ESLint + Prettier。 + +## Admin 框架 + +前端 Admin 采用 [pure-admin-thin(i18n 分支)](https://github.com/pure-admin/pure-admin-thin/tree/i18n),代码位于 `frontend/`。pure-admin 原生基于 Element Plus,并内置国际化。 + +- 使用 pure-admin 提供的 Layout / Router / 权限 / 标签页 / i18n 等基础能力 +- Element Plus 作为唯一业务 UI 组件库,不引入 Naive UI 等第二套 UI 库 +- 不要重复实现 pure-admin 已有的 Admin 基础设施 + +## 目录结构 + +``` +src/ +├── api/ +├── assets/ +├── components/ +├── constants/ +├── layouts/ +├── router/ +├── stores/ +├── styles/ +├── types/ +├── utils/ +├── views/ +│ ├── dashboard/ +│ ├── warehouse/ +│ ├── product/ +│ ├── inventory/ +│ ├── inbound/ +│ ├── outbound/ +│ ├── picking/ +│ ├── packing/ +│ ├── shipping/ +│ ├── customer/ +│ ├── supplier/ +│ ├── reports/ +│ └── system/ +└── App.vue +``` + +页面必须按照业务领域组织。若所选 Admin 框架已有约定目录,以框架约定为准,在其中按业务领域组织。 + +## Element Plus 使用规范 + +统一使用 Element Plus,重点组件: + +- ElTable +- ElForm +- ElDialog +- ElDrawer +- ElSelect +- ElCascader +- ElDatePicker +- ElPagination +- ElTabs +- ElSteps +- ElUpload +- ElTree +- ElDescriptions + +所有列表页尽量统一布局: + +``` +查询区 + ↓ +Toolbar + ↓ +Table + ↓ +Pagination +``` + +不要每个页面设计一套完全不同的交互,不要重复实现 Element Plus 已提供的组件。 + +## 前端权限 + +支持: + +- 菜单权限 +- 页面权限 +- Button / API 权限 +- Role +- Tenant + +权限码格式 `模块:动作`,例如: + +``` +inventory:view +inventory:adjust +inventory:export +inbound:view +inbound:create +inbound:receive +outbound:view +outbound:allocate +outbound:pick +outbound:ship +``` + +前端权限仅用于展示控制,最终授权以后端 Policies / Gates 为准。 diff --git a/docs/11-py-service.md b/docs/11-py-service.md new file mode 100644 index 0000000..60fea32 --- /dev/null +++ b/docs/11-py-service.md @@ -0,0 +1,76 @@ +# 11 Python AI / Data Service + +## 定位 + +Python 不参与 Laravel 核心业务 CRUD,作为独立服务存在。**Laravel 是唯一的核心业务系统。** + +## 技术栈 + +- Python 3.x +- FastAPI +- Pydantic +- HTTP API +- Redis +- 后期根据需要使用 Pandas / NumPy / Scikit-learn / PyTorch / LLM SDK + +## 负责范围 + +- AI 分析 +- 库存分析 +- 销量预测 +- 缺货预测 +- 补货建议 +- 仓储数据分析 +- 异常检测 +- AI 助手 +- 后期机器学习 + +## 禁止范围 + +不要把用户、租户、SKU、仓库、库存、入库、出库等核心业务逻辑迁移到 Python。 + +**不要让 Python 直接修改 Laravel 核心业务数据库。** + +## 目录结构 + +``` +py-service/ +└── app/ + ├── main.py + ├── api/ + ├── services/ + ├── schemas/ + ├── models/ + ├── analysis/ + ├── ai/ + ├── tasks/ + └── core/ +``` + +## 与 Laravel 交互 + +Python 只通过 API 与 Laravel 交互,例如: + +``` +POST /internal/v1/inventory/analyze +POST /internal/v1/inventory/forecast +POST /internal/v1/replenishment/recommend +POST /internal/v1/ai/chat +``` + +数据获取优先: + +``` +Laravel → Python(推送数据) +Python → 分析 → 返回结果 +``` + +或通过 Laravel 提供的只读数据接口获取。 + +分析结果由 Laravel 决定是否落库、是否转化为业务动作(如生成补货建议单)。 + +## 注意 + +- 内部接口需要鉴权(内部 Token / 签名),不对公网开放。 +- 请求中需携带 `tenant_code`,分析结果不得跨租户混用。 +- Laravel 调用 Python 的耗时任务应走 Queue,避免阻塞用户请求。 diff --git a/docs/12-security-audit.md b/docs/12-security-audit.md new file mode 100644 index 0000000..8c6e526 --- /dev/null +++ b/docs/12-security-audit.md @@ -0,0 +1,51 @@ +# 12 日志、审计与安全 + +## 日志和审计 + +必须考虑: + +- 登录日志 +- 操作日志 +- API 日志 +- 库存变更日志 +- 订单状态变更日志 +- 入库状态变更 +- 出库状态变更 +- 用户权限变更 + +库存、订单等重要数据的关键变更必须能够追踪: + +| 字段 | 含义 | +| --- | --- | +| 谁 | 操作用户 / 系统任务 | +| 什么时候 | 操作时间 | +| 做了什么 | 操作类型 | +| 修改前 | 变更前数据 | +| 修改后 | 变更后数据 | +| 来源 IP | 请求 IP | +| 请求 ID | 全链路请求标识 | + +## 安全要求 + +必须考虑: + +- SQL Injection +- XSS +- CSRF +- API Authentication +- API Authorization +- Rate Limit +- Tenant Isolation +- 文件上传安全 +- Webhook 签名 +- 密钥加密 +- 敏感信息保护 +- 日志脱敏 + +## 密钥管理 + +任何第三方 API Token、Secret:**禁止直接写入 Git。** + +- 使用 `.env`(不提交)与 `.env.example`(仅占位)。 +- 租户级第三方凭证在数据库中加密存储。 +- 日志中不得输出 Token、密码、完整地址电话等敏感信息。 diff --git a/docs/13-docker.md b/docs/13-docker.md new file mode 100644 index 0000000..77c015b --- /dev/null +++ b/docs/13-docker.md @@ -0,0 +1,20 @@ +# 13 Docker 开发环境 + +## 需要支持的服务 + +- PHP 8.4 +- Laravel +- MySQL 8 +- Redis 7 +- Nginx +- Node.js +- Python +- FastAPI + +## 原则 + +- 在项目根目录提供一个统一的 `docker-compose.yml`。 +- **不要为每个小模块建立独立 Docker Compose。** +- Queue Worker 与 Scheduler 作为独立容器 / 进程运行,复用 PHP 镜像。 +- 敏感配置通过 `.env` 注入,不写入镜像与 Git。 +- 第一阶段不引入 Kubernetes,生产部署方案在 Phase 17 再设计。 diff --git a/docs/14-testing.md b/docs/14-testing.md new file mode 100644 index 0000000..7a7a30d --- /dev/null +++ b/docs/14-testing.md @@ -0,0 +1,41 @@ +# 14 测试要求 + +核心业务必须有测试。**没有测试就不要继续堆功能。** + +## 重点测试 + +- Tenant Isolation +- RBAC +- Inventory +- Concurrent Inventory +- Inbound +- Outbound +- Allocation +- Picking +- Stocktake +- Order Status +- Queue +- API Authorization + +尤其是库存。 + +## 库存并发用例 + +两个请求同时扣减 8 个库存,而实际只有 10 个库存。必须保证: + +- 不会出现 `available_qty = -6` +- 不能出现两个订单都成功扣减 8 + +## 租户隔离用例 + +- 租户 A 的用户通过列表、详情、业务编码、批量操作等任何接口都无法读取或修改租户 B 的数据。 +- Queue Job、Scheduler 执行时只处理其所属租户的数据。 + +## 状态机用例 + +- 合法状态转换成功,并记录状态变更日志。 +- 非法状态转换被拒绝(例如 `draft` 直接 `shipped`)。 + +## 库存流水用例 + +- 每一次库存余额变化都有对应流水,且流水累计值与余额一致。 diff --git a/docs/15-development-workflow.md b/docs/15-development-workflow.md new file mode 100644 index 0000000..d6ff7e8 --- /dev/null +++ b/docs/15-development-workflow.md @@ -0,0 +1,84 @@ +# 15 开发工作方式 + +## 分阶段开发 + +**不要一次生成整个项目。** 必须分阶段开发。 + +每完成一个阶段: + +1. 检查代码 +2. 检查数据库 +3. 运行测试 +4. 检查 API +5. 检查前端 +6. 修复问题 +7. 再进入下一阶段 + +不要为了"快速完成"一次生成几百个文件。 + +## 修改代码前 + +1. 先理解现有目录 +2. 搜索已有实现 +3. 不要重复创建已有功能 +4. 检查数据库结构 +5. 检查相关 API +6. 检查前端调用 +7. 再修改代码 + +## 修改代码后 + +1. 检查类型 +2. 检查语法 +3. 检查引用 +4. 检查数据库迁移 +5. 检查 API +6. 检查权限 +7. 检查租户隔离 +8. 运行相关测试 + +## 代码质量 + +代码必须: + +- 清晰 +- 可维护 +- 类型明确 +- 避免重复 +- 避免超大 Controller +- 避免超大 Service +- 避免魔法字符串 +- 避免硬编码 +- 避免重复 SQL +- 避免跨模块强耦合 + +优先可读性,而不是为了"高级架构"而复杂化。 + +## 需求存在架构问题时 + +不要直接照做,请指出: + +1. 问题是什么 +2. 为什么有问题 +3. 推荐方案 +4. 替代方案 +5. 最终建议 + +如果有多个合理方案,不要擅自选择影响整个项目架构的方案,先说明区别。 + +## 禁止事项 + +- 为了快速开发跳过架构设计 +- Controller 堆业务逻辑 +- 一个 Model 承担所有业务 +- Python 直接修改核心 WMS 数据 +- 忽略 tenant_code +- 忽略库存流水 +- 直接修改库存而没有业务记录 +- 不考虑并发库存 +- 把 Amazon 等平台逻辑写死到核心订单模型 +- 为了所谓高性能过早微服务化 +- 没有测试就继续堆功能 +- 随意增加第三方依赖 +- 重复实现 Element Plus 已经提供的组件 +- 修改已有代码前不检查上下文 diff --git a/docs/16-roadmap.md b/docs/16-roadmap.md new file mode 100644 index 0000000..3235fed --- /dev/null +++ b/docs/16-roadmap.md @@ -0,0 +1,92 @@ +# 16 开发路线图 + +## 第一阶段必须先做设计 + +在写大量代码之前,先输出: + +1. 系统架构 +2. 模块划分 +3. 数据库 ER 关系 +4. 核心数据表 +5. 租户隔离方案 +6. 库存模型 +7. 入库流程 +8. 出库流程 +9. 订单模型 +10. 权限模型 +11. API 设计 +12. Queue / Scheduler 设计 +13. Python Service 边界 +14. Docker 开发环境 +15. 项目目录结构 + +## 第一阶段不要直接实现业务 + +先在 `docs/` 目录下生成以下设计文档及目录结构说明: + +- ARCHITECTURE.md +- database/(数据库总览、ER 关系与表结构设计,入口 `database/README.md`) +- API.md +- DEVELOPMENT.md +- DOCKER.md + +确认架构合理之后,再开始数据库和代码。建议优先产出 `docs/database/` 中的表结构设计,把租户、仓库、库位、SKU、库存、库存流水、入库、出库这几个核心模型定死。 + +## 开发顺序 + +严格按照以下顺序: + +| Phase | 内容 | +| --- | --- | +| 1 | 项目架构设计 | +| 2 | Laravel 基础项目 | +| 3 | Vue 3 + Element Plus Admin | +| 4 | SaaS 租户 / 用户 / RBAC | +| 5 | 仓库 / 库区 / 库位 | +| 6 | 商品 / SKU / 客户 | +| 7 | 库存核心模型 | +| 8 | 库存流水 / 库存并发 | +| 9 | 入库 | +| 10 | 出库 | +| 11 | 拣货 / 波次 / 打包 / 发货 | +| 12 | 物流 | +| 13 | 报表 | +| 14 | 第三方订单接口 | +| 15 | Python AI / Data Service | +| 16 | 测试 / 性能 / 安全 | +| 17 | Docker / Production | + +## 每个 Phase 开始前 + +先说明本阶段: + +- 目标 +- 涉及模块 +- 数据库变化 +- API 变化 +- 前端变化 +- 测试方案 +- 风险 + +然后再实施。 + +## 第一步任务 + +不要写业务代码。先检查当前工作区,然后输出: + +1. 当前项目状态 +2. 推荐的最终目录结构 +3. 系统架构图 +4. Laravel / Vue / Python 三者职责边界 +5. SaaS 多租户方案 +6. WMS 核心领域模型 +7. 核心数据库表清单 +8. 库存模型设计 +9. 入库 / 出库流程 +10. API 分层设计 +11. Queue / Scheduler 设计 +12. Python Service 设计 +13. Docker 开发环境设计 +14. Phase 1 实施计划 + +**暂时不要创建大量代码文件,先完成架构设计。** diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..fdb058a --- /dev/null +++ b/docs/README.md @@ -0,0 +1,34 @@ +# WMS SaaS 项目文档索引 + +本目录由根目录 `README.md`(项目总提示词)按主题拆分而来,是项目设计与开发的约束来源。 + +| 文档 | 内容 | 对应原 README 章节 | +| --- | --- | --- | +| [00-overview.md](./00-overview.md) | 项目定位、最终目标 | 开头、四十 | +| [01-tech-stack.md](./01-tech-stack.md) | 前端 / 后端 / 数据库 / Python 技术栈 | 一 ~ 四 | +| [02-architecture.md](./02-architecture.md) | 总体架构、职责边界、Redis、避免过度设计 | 五、二十一、二十八 | +| [03-multi-tenancy.md](./03-multi-tenancy.md) | SaaS 多租户、tenant_code、TenantContext | 六、七 | +| [04-domain-model.md](./04-domain-model.md) | 业务编码、业务模块、订单模型、第三方平台、状态机 | 八、十二 ~ 十五 | +| [05-inventory.md](./05-inventory.md) | 库存模型、库存流水、并发安全 | 九 ~ 十一 | +| [06-backend-laravel.md](./06-backend-laravel.md) | Laravel 代码分层与目录结构 | 十六、后端框架结构 | +| [07-api.md](./07-api.md) | API 路由规范与统一返回格式 | 十七、十八 | +| [08-queue-scheduler.md](./08-queue-scheduler.md) | 队列与定时任务 | 十九、二十 | +| [09-database.md](./09-database.md) | 数据库设计要求与规范 | 三、二十七 | +| [10-frontend.md](./10-frontend.md) | 前端框架、目录、Element Plus、权限 | 一、二十三 ~ 二十五 | +| [11-py-service.md](./11-py-service.md) | Python AI / Data Service(`py-service/`)边界与结构 | 四、二十二 | +| [12-security-audit.md](./12-security-audit.md) | 日志审计与安全要求 | 二十六、三十五 | +| [13-docker.md](./13-docker.md) | Docker 开发环境 | 二十九 | +| [14-testing.md](./14-testing.md) | 测试要求 | 三十四 | +| [15-development-workflow.md](./15-development-workflow.md) | 开发原则、代码质量、Cursor 工作方式、禁止事项 | 三十、三十六 ~ 三十九 | +| [16-roadmap.md](./16-roadmap.md) | 设计先行、Phase 开发顺序、第一步任务 | 三十一 ~ 三十三、现在开始 | +| [database/](./database/README.md) | 数据库表结构设计(按领域分文件) | — | + +## 核心原则 + +**简单、清晰、可维护、可扩展、业务优先。** + +- Laravel 是唯一的核心业务系统,MySQL 是业务事实数据源。 +- 所有核心业务数据按 `tenant_code` 隔离,由 TenantContext 统一处理。 +- 库存余额是结果,库存流水是事实;库存变更必须并发安全、可追溯。 +- Python 只做 AI / 数据分析,只通过 API 与 Laravel 交互。 +- 分阶段开发,每个 Phase 先说明方案、再实施、再验证。 diff --git a/docs/database/README.md b/docs/database/README.md new file mode 100644 index 0000000..fb2db61 --- /dev/null +++ b/docs/database/README.md @@ -0,0 +1,57 @@ +# 数据库表结构设计 + +本目录存放 WMS SaaS 的数据库表结构设计,是 `backend/database/migrations` 的设计依据。通用规范见 [../09-database.md](../09-database.md)。 + +**先设计、确认,再写迁移;改表时迁移与本目录文档同步更新。** + +## 文件组织 + +按业务领域一个文件,文件内包含该领域所有表: + +| 文件 | 领域 | 对应 Phase | +| --- | --- | --- | +| `00-conventions.md` | 命名、公共字段、类型、索引约定 | 1 | +| `01-er-overview.md` | 全局 ER 关系图 | 1 | +| `10-saas.md` | 租户、用户、角色、权限、租户设置、操作日志 | 4 | +| `20-warehouse.md` | 仓库、库区、库位、库位类型 / 容量 / 策略 | 5 | +| `30-master-data.md` | 客户、供应商、商品、SKU、条码、包装规格 | 6 | +| `40-inventory.md` | 库存余额、批次、库存流水、锁定 / 冻结、调整、盘点 | 7、8 | +| `50-inbound.md` | 入库单、明细、收货、差异、质检、上架 | 9 | +| `60-outbound.md` | 订单、出库单、明细、分配、波次、拣货、复核、打包、发货 | 10、11 | +| `70-return.md` | 退货单、退货收货、质检、重新入库、报废 | — | +| `80-logistics.md` | 物流渠道、承运商、服务、运费规则、面单、Tracking | 12 | +| `90-integration.md` | 第三方平台店铺、凭证、同步任务、Webhook 日志 | 14 | +| `95-audit.md` | 登录日志、API 日志、状态变更日志、数据审计 | 4 起 | + +文件在对应 Phase 开始前创建,不提前为未来阶段编写。 + +## 单表设计模板 + +````markdown +### wms_xxx 表中文名 + +用途:一句话说明。 + +| 字段 | 类型 | 可空 | 默认 | 说明 | +| --- | --- | --- | --- | --- | +| id | BIGINT UNSIGNED | N | AUTO_INCREMENT | 内部主键 | +| tenant_code | VARCHAR(32) | N | | 租户编码 | +| xxx_code | VARCHAR(64) | N | | 业务编码 | +| status | VARCHAR(32) | N | | 状态,取值见下方状态说明 | +| version | INT UNSIGNED | N | 0 | 乐观锁(按需) | +| created_at | TIMESTAMP | Y | | | +| updated_at | TIMESTAMP | Y | | | + +索引: + +| 名称 | 类型 | 字段 | 支撑的查询 | +| --- | --- | --- | --- | +| uk_tenant_xxx_code | UNIQUE | (tenant_code, xxx_code) | 按业务编码查找 | +| idx_tenant_status_created | INDEX | (tenant_code, status, created_at) | 列表筛选 | + +状态说明 / 合法流转(有状态字段时必填)。 + +关联:与哪些表通过哪些业务编码关联。 + +并发 / 审计说明:是否需要行锁、乐观锁、流水、软删除,及原因。 +````