From 2fb57ec4904e276de90c02b51b92696d65e4e5cc Mon Sep 17 00:00:00 2001 From: Yangxt Date: Wed, 30 Sep 2026 11:11:54 +0800 Subject: [PATCH] init --- .cursor/rules/api-conventions.mdc | 31 + .cursor/rules/database.mdc | 26 + .cursor/rules/development-workflow.mdc | 26 + .cursor/rules/docker.mdc | 15 + .cursor/rules/frontend-vue.mdc | 27 + .cursor/rules/inventory.mdc | 38 + .cursor/rules/laravel-backend.mdc | 36 + .cursor/rules/project-core.mdc | 30 + .cursor/rules/py-service.mdc | 29 + .cursor/rules/queue-scheduler.mdc | 23 + .cursor/rules/role.mdc | 9 + .cursor/rules/security-audit.mdc | 23 + .cursor/rules/tenant-isolation.mdc | 27 + .cursor/rules/testing.mdc | 22 + .cursor/rules/wms-domain.mdc | 34 + README.md | 9 +- backend/.editorconfig | 18 + backend/.env.example | 65 + backend/.gitattributes | 11 + backend/.gitignore | 27 + backend/.npmrc | 2 + backend/AGENTS.md | 47 + backend/CLAUDE.md | 47 + backend/README.md | 58 + .../Controllers/Api/V1/HealthController.php | 19 + backend/app/Http/Controllers/Controller.php | 8 + .../app/Http/Middleware/AssignRequestId.php | 31 + .../app/Models/Concerns/BelongsToTenant.php | 36 + backend/app/Models/User.php | 32 + backend/app/Providers/AppServiceProvider.php | 28 + backend/app/Support/ApiExceptionResponse.php | 63 + backend/app/Support/ApiResponse.php | 70 + .../Support/MissingTenantContextException.php | 15 + backend/app/Support/TenantContext.php | 71 + backend/artisan | 18 + backend/bootstrap/app.php | 32 + backend/bootstrap/cache/.gitignore | 2 + backend/bootstrap/providers.php | 7 + backend/composer.json | 86 + backend/composer.lock | 8358 +++++++++++++++++ backend/config/app.php | 126 + backend/config/auth.php | 117 + backend/config/cache.php | 136 + backend/config/database.php | 184 + backend/config/filesystems.php | 80 + backend/config/logging.php | 140 + backend/config/mail.php | 118 + backend/config/queue.php | 129 + backend/config/services.php | 38 + backend/config/session.php | 233 + backend/database/.gitignore | 1 + backend/database/factories/UserFactory.php | 45 + .../0001_01_01_000000_create_users_table.php | 49 + .../0001_01_01_000001_create_cache_table.php | 35 + .../0001_01_01_000002_create_jobs_table.php | 59 + backend/database/seeders/DatabaseSeeder.php | 25 + backend/package.json | 19 + backend/phpunit.xml | 36 + backend/public/.htaccess | 25 + backend/public/favicon.ico | 0 backend/public/index.php | 20 + backend/public/robots.txt | 2 + backend/resources/css/app.css | 9 + backend/resources/js/app.js | 1 + backend/resources/views/welcome.blade.php | 223 + backend/routes/api.php | 10 + backend/routes/console.php | 8 + backend/routes/web.php | 7 + backend/storage/app/.gitignore | 4 + backend/storage/app/private/.gitignore | 2 + backend/storage/app/public/.gitignore | 2 + backend/storage/framework/.gitignore | 10 + backend/storage/framework/cache/.gitignore | 3 + .../storage/framework/cache/data/.gitignore | 2 + backend/storage/framework/sessions/.gitignore | 2 + backend/storage/framework/testing/.gitignore | 2 + backend/storage/framework/views/.gitignore | 2 + backend/storage/logs/.gitignore | 2 + backend/tests/Feature/ApiExceptionTest.php | 86 + backend/tests/Feature/ExampleTest.php | 19 + backend/tests/Feature/HealthTest.php | 35 + backend/tests/Feature/TenantScopeTest.php | 88 + backend/tests/Fixtures/TenantProbe.php | 17 + backend/tests/TestCase.php | 10 + backend/tests/Unit/TenantContextTest.php | 56 + backend/vite.config.js | 24 + docs/07-api.md | 20 +- docs/09-database.md | 2 +- docs/database/00-conventions.md | 74 + docs/database/01-er-overview.md | 100 + docs/database/01-saas/wms_number_sequence.sql | 16 + docs/database/01-saas/wms_permission.sql | 19 + docs/database/01-saas/wms_role.sql | 17 + docs/database/01-saas/wms_role_permission.sql | 16 + docs/database/01-saas/wms_tenant.sql | 21 + docs/database/01-saas/wms_tenant_setting.sql | 15 + docs/database/01-saas/wms_user.sql | 22 + docs/database/01-saas/wms_user_role.sql | 16 + docs/database/02-warehouse/wms_location.sql | 32 + .../02-warehouse/wms_location_strategy.sql | 26 + .../02-warehouse/wms_location_type.sql | 20 + docs/database/02-warehouse/wms_warehouse.sql | 28 + docs/database/02-warehouse/wms_zone.sql | 20 + docs/database/03-master/wms_customer.sql | 21 + .../03-master/wms_customer_warehouse.sql | 17 + docs/database/03-master/wms_package_spec.sql | 23 + docs/database/03-master/wms_product.sql | 19 + docs/database/03-master/wms_sku.sql | 30 + docs/database/03-master/wms_sku_barcode.sql | 18 + docs/database/03-master/wms_supplier.sql | 20 + docs/database/04-inventory/wms_batch.sql | 22 + docs/database/04-inventory/wms_inventory.sql | 32 + .../04-inventory/wms_inventory_alert.sql | 18 + .../04-inventory/wms_inventory_hold.sql | 21 + .../04-inventory/wms_inventory_hold_item.sql | 22 + .../04-inventory/wms_stock_adjustment.sql | 24 + .../wms_stock_adjustment_item.sql | 24 + docs/database/04-inventory/wms_stock_log.sql | 35 + docs/database/04-inventory/wms_stocktake.sql | 21 + .../04-inventory/wms_stocktake_item.sql | 24 + docs/database/05-inbound/wms_inbound.sql | 27 + docs/database/05-inbound/wms_inbound_item.sql | 24 + .../05-inbound/wms_inbound_putaway.sql | 28 + docs/database/05-inbound/wms_inbound_qc.sql | 28 + .../05-inbound/wms_inbound_receipt.sql | 20 + .../05-inbound/wms_inbound_receipt_item.sql | 24 + docs/database/06-outbound/wms_allocation.sql | 26 + docs/database/06-outbound/wms_order.sql | 38 + docs/database/06-outbound/wms_order_item.sql | 23 + docs/database/06-outbound/wms_outbound.sql | 29 + .../06-outbound/wms_outbound_item.sql | 27 + docs/database/06-outbound/wms_package.sql | 24 + .../database/06-outbound/wms_package_item.sql | 22 + .../database/06-outbound/wms_picking_task.sql | 24 + .../06-outbound/wms_picking_task_item.sql | 25 + docs/database/06-outbound/wms_wave.sql | 22 + .../06-outbound/wms_wave_outbound.sql | 16 + docs/database/07-return/wms_return_order.sql | 23 + .../07-return/wms_return_order_item.sql | 25 + docs/database/08-logistics/wms_carrier.sql | 17 + .../08-logistics/wms_freight_rule.sql | 26 + .../08-logistics/wms_logistics_channel.sql | 21 + .../08-logistics/wms_logistics_service.sql | 17 + docs/database/08-logistics/wms_shipment.sql | 27 + .../08-logistics/wms_tracking_event.sql | 21 + docs/database/08-logistics/wms_waybill.sql | 19 + .../09-integration/wms_platform_shop.sql | 19 + .../database/09-integration/wms_sync_task.sql | 23 + .../09-integration/wms_webhook_log.sql | 22 + docs/database/10-audit/wms_api_log.sql | 22 + docs/database/10-audit/wms_login_log.sql | 19 + docs/database/10-audit/wms_operation_log.sql | 24 + docs/database/10-audit/wms_status_log.sql | 21 + docs/database/10-saas.md | 248 + docs/database/20-warehouse.md | 111 + docs/database/30-master-data.md | 186 + docs/database/40-inventory.md | 236 + docs/database/50-inbound.md | 150 + docs/database/60-outbound.md | 324 + docs/database/README.md | 137 +- 160 files changed, 14764 insertions(+), 53 deletions(-) create mode 100644 .cursor/rules/api-conventions.mdc create mode 100644 .cursor/rules/database.mdc create mode 100644 .cursor/rules/development-workflow.mdc create mode 100644 .cursor/rules/docker.mdc create mode 100644 .cursor/rules/frontend-vue.mdc create mode 100644 .cursor/rules/inventory.mdc create mode 100644 .cursor/rules/laravel-backend.mdc create mode 100644 .cursor/rules/project-core.mdc create mode 100644 .cursor/rules/py-service.mdc create mode 100644 .cursor/rules/queue-scheduler.mdc create mode 100644 .cursor/rules/role.mdc create mode 100644 .cursor/rules/security-audit.mdc create mode 100644 .cursor/rules/tenant-isolation.mdc create mode 100644 .cursor/rules/testing.mdc create mode 100644 .cursor/rules/wms-domain.mdc create mode 100644 backend/.editorconfig create mode 100644 backend/.env.example create mode 100644 backend/.gitattributes create mode 100644 backend/.gitignore create mode 100644 backend/.npmrc create mode 100644 backend/AGENTS.md create mode 100644 backend/CLAUDE.md create mode 100644 backend/README.md create mode 100644 backend/app/Http/Controllers/Api/V1/HealthController.php create mode 100644 backend/app/Http/Controllers/Controller.php create mode 100644 backend/app/Http/Middleware/AssignRequestId.php create mode 100644 backend/app/Models/Concerns/BelongsToTenant.php create mode 100644 backend/app/Models/User.php create mode 100644 backend/app/Providers/AppServiceProvider.php create mode 100644 backend/app/Support/ApiExceptionResponse.php create mode 100644 backend/app/Support/ApiResponse.php create mode 100644 backend/app/Support/MissingTenantContextException.php create mode 100644 backend/app/Support/TenantContext.php create mode 100644 backend/artisan create mode 100644 backend/bootstrap/app.php create mode 100644 backend/bootstrap/cache/.gitignore create mode 100644 backend/bootstrap/providers.php create mode 100644 backend/composer.json create mode 100644 backend/composer.lock create mode 100644 backend/config/app.php create mode 100644 backend/config/auth.php create mode 100644 backend/config/cache.php create mode 100644 backend/config/database.php create mode 100644 backend/config/filesystems.php create mode 100644 backend/config/logging.php create mode 100644 backend/config/mail.php create mode 100644 backend/config/queue.php create mode 100644 backend/config/services.php create mode 100644 backend/config/session.php create mode 100644 backend/database/.gitignore create mode 100644 backend/database/factories/UserFactory.php create mode 100644 backend/database/migrations/0001_01_01_000000_create_users_table.php create mode 100644 backend/database/migrations/0001_01_01_000001_create_cache_table.php create mode 100644 backend/database/migrations/0001_01_01_000002_create_jobs_table.php create mode 100644 backend/database/seeders/DatabaseSeeder.php create mode 100644 backend/package.json create mode 100644 backend/phpunit.xml create mode 100644 backend/public/.htaccess create mode 100644 backend/public/favicon.ico create mode 100644 backend/public/index.php create mode 100644 backend/public/robots.txt create mode 100644 backend/resources/css/app.css create mode 100644 backend/resources/js/app.js create mode 100644 backend/resources/views/welcome.blade.php create mode 100644 backend/routes/api.php create mode 100644 backend/routes/console.php create mode 100644 backend/routes/web.php create mode 100644 backend/storage/app/.gitignore create mode 100644 backend/storage/app/private/.gitignore create mode 100644 backend/storage/app/public/.gitignore create mode 100644 backend/storage/framework/.gitignore create mode 100644 backend/storage/framework/cache/.gitignore create mode 100644 backend/storage/framework/cache/data/.gitignore create mode 100644 backend/storage/framework/sessions/.gitignore create mode 100644 backend/storage/framework/testing/.gitignore create mode 100644 backend/storage/framework/views/.gitignore create mode 100644 backend/storage/logs/.gitignore create mode 100644 backend/tests/Feature/ApiExceptionTest.php create mode 100644 backend/tests/Feature/ExampleTest.php create mode 100644 backend/tests/Feature/HealthTest.php create mode 100644 backend/tests/Feature/TenantScopeTest.php create mode 100644 backend/tests/Fixtures/TenantProbe.php create mode 100644 backend/tests/TestCase.php create mode 100644 backend/tests/Unit/TenantContextTest.php create mode 100644 backend/vite.config.js create mode 100644 docs/database/00-conventions.md create mode 100644 docs/database/01-er-overview.md create mode 100644 docs/database/01-saas/wms_number_sequence.sql create mode 100644 docs/database/01-saas/wms_permission.sql create mode 100644 docs/database/01-saas/wms_role.sql create mode 100644 docs/database/01-saas/wms_role_permission.sql create mode 100644 docs/database/01-saas/wms_tenant.sql create mode 100644 docs/database/01-saas/wms_tenant_setting.sql create mode 100644 docs/database/01-saas/wms_user.sql create mode 100644 docs/database/01-saas/wms_user_role.sql create mode 100644 docs/database/02-warehouse/wms_location.sql create mode 100644 docs/database/02-warehouse/wms_location_strategy.sql create mode 100644 docs/database/02-warehouse/wms_location_type.sql create mode 100644 docs/database/02-warehouse/wms_warehouse.sql create mode 100644 docs/database/02-warehouse/wms_zone.sql create mode 100644 docs/database/03-master/wms_customer.sql create mode 100644 docs/database/03-master/wms_customer_warehouse.sql create mode 100644 docs/database/03-master/wms_package_spec.sql create mode 100644 docs/database/03-master/wms_product.sql create mode 100644 docs/database/03-master/wms_sku.sql create mode 100644 docs/database/03-master/wms_sku_barcode.sql create mode 100644 docs/database/03-master/wms_supplier.sql create mode 100644 docs/database/04-inventory/wms_batch.sql create mode 100644 docs/database/04-inventory/wms_inventory.sql create mode 100644 docs/database/04-inventory/wms_inventory_alert.sql create mode 100644 docs/database/04-inventory/wms_inventory_hold.sql create mode 100644 docs/database/04-inventory/wms_inventory_hold_item.sql create mode 100644 docs/database/04-inventory/wms_stock_adjustment.sql create mode 100644 docs/database/04-inventory/wms_stock_adjustment_item.sql create mode 100644 docs/database/04-inventory/wms_stock_log.sql create mode 100644 docs/database/04-inventory/wms_stocktake.sql create mode 100644 docs/database/04-inventory/wms_stocktake_item.sql create mode 100644 docs/database/05-inbound/wms_inbound.sql create mode 100644 docs/database/05-inbound/wms_inbound_item.sql create mode 100644 docs/database/05-inbound/wms_inbound_putaway.sql create mode 100644 docs/database/05-inbound/wms_inbound_qc.sql create mode 100644 docs/database/05-inbound/wms_inbound_receipt.sql create mode 100644 docs/database/05-inbound/wms_inbound_receipt_item.sql create mode 100644 docs/database/06-outbound/wms_allocation.sql create mode 100644 docs/database/06-outbound/wms_order.sql create mode 100644 docs/database/06-outbound/wms_order_item.sql create mode 100644 docs/database/06-outbound/wms_outbound.sql create mode 100644 docs/database/06-outbound/wms_outbound_item.sql create mode 100644 docs/database/06-outbound/wms_package.sql create mode 100644 docs/database/06-outbound/wms_package_item.sql create mode 100644 docs/database/06-outbound/wms_picking_task.sql create mode 100644 docs/database/06-outbound/wms_picking_task_item.sql create mode 100644 docs/database/06-outbound/wms_wave.sql create mode 100644 docs/database/06-outbound/wms_wave_outbound.sql create mode 100644 docs/database/07-return/wms_return_order.sql create mode 100644 docs/database/07-return/wms_return_order_item.sql create mode 100644 docs/database/08-logistics/wms_carrier.sql create mode 100644 docs/database/08-logistics/wms_freight_rule.sql create mode 100644 docs/database/08-logistics/wms_logistics_channel.sql create mode 100644 docs/database/08-logistics/wms_logistics_service.sql create mode 100644 docs/database/08-logistics/wms_shipment.sql create mode 100644 docs/database/08-logistics/wms_tracking_event.sql create mode 100644 docs/database/08-logistics/wms_waybill.sql create mode 100644 docs/database/09-integration/wms_platform_shop.sql create mode 100644 docs/database/09-integration/wms_sync_task.sql create mode 100644 docs/database/09-integration/wms_webhook_log.sql create mode 100644 docs/database/10-audit/wms_api_log.sql create mode 100644 docs/database/10-audit/wms_login_log.sql create mode 100644 docs/database/10-audit/wms_operation_log.sql create mode 100644 docs/database/10-audit/wms_status_log.sql create mode 100644 docs/database/10-saas.md create mode 100644 docs/database/20-warehouse.md create mode 100644 docs/database/30-master-data.md create mode 100644 docs/database/40-inventory.md create mode 100644 docs/database/50-inbound.md create mode 100644 docs/database/60-outbound.md diff --git a/.cursor/rules/api-conventions.mdc b/.cursor/rules/api-conventions.mdc new file mode 100644 index 0000000..f8946ac --- /dev/null +++ b/.cursor/rules/api-conventions.mdc @@ -0,0 +1,31 @@ +--- +description: REST API 路由与统一 JSON 返回格式 +globs: backend/routes/**/*.php,backend/app/Http/**/*.php +alwaysApply: false +--- +# API 规范 + +详见 `docs/07-api.md`。 + +## 路由 +- 统一前缀 `/api/v1/`,资源名复数,路由参数优先业务编码。 +- 状态动作:`POST /api/v1/{resource}/{code}/{action}` + +``` +POST /api/v1/inbounds/{inbound_no}/receive +POST /api/v1/outbounds/{outbound_no}/allocate +``` + +- 认证 Sanctum;每个接口都要经过 Policy / Gate 授权,权限码形如 `outbound:allocate`。 +- 列表接口必须分页并使用统一分页格式。 + +## 统一返回 +所有接口通过统一响应工具(如 `App\Support\ApiResponse`)返回,禁止 Controller 自定义结构。 + +```json +{ "success": true, "message": "OK", "data": {} } +{ "success": false, "message": "操作失败", "errors": {} } +``` + +- 输出数据统一经 API Resource 转换,不直接返回 Model。 +- 验证错误、业务异常、授权失败在异常处理器中统一转换为失败格式。 diff --git a/.cursor/rules/database.mdc b/.cursor/rules/database.mdc new file mode 100644 index 0000000..62e4651 --- /dev/null +++ b/.cursor/rules/database.mdc @@ -0,0 +1,26 @@ +--- +description: MySQL 表设计、迁移与索引规范 +globs: backend/database/**/*.php,backend/app/Models/**/*.php,docs/database/** +alwaysApply: false +--- +# 数据库规范 + +详见 `docs/09-database.md`。表结构设计存放在 `docs/database/`(索引 `docs/database/README.md`)。 + +- **设计先行**:先在 `docs/database/` 中设计并确认表结构,再写迁移;迁移与设计文档必须保持一致,改表时同步更新文档。 + +- InnoDB + utf8mb4;所有表有 `created_at`、`updated_at`。 +- 核心业务表必须有 `tenant_code`;业务编码唯一约束包含租户:`UNIQUE (tenant_code, sku_code)`。 +- 重要业务表按需加 `status`、`version`(乐观锁)、`deleted_at`;**不要无脑给所有表加软删除**,流水类事实表禁止软删除与更新。 +- 数量字段使用整数或 `DECIMAL`,禁止 `FLOAT/DOUBLE`;金额使用 `DECIMAL`。 +- 索引围绕实际查询设计,复合索引通常以 `tenant_code` 为最左列;关注 `warehouse_code`、`customer_code`、`sku_code`、`order_no`、`inbound_no`、`outbound_no`、`location_code`、`status`、`created_at`。 +- 迁移必须可回滚(实现 `down()`),已上线的迁移不修改,新增迁移变更。 +- 表名是单数加 `wms_` 前缀(如 `wms_sku`、`wms_stock_log`)。每张表一个 SQL 文件,放在 `docs/database/` 对应领域目录,约定见 `docs/database/00-conventions.md`。 + +```php +// ✅ +$table->string('tenant_code', 32); +$table->string('sku_code', 64); +$table->unique(['tenant_code', 'sku_code']); +$table->index(['tenant_code', 'status', 'created_at']); +``` diff --git a/.cursor/rules/development-workflow.mdc b/.cursor/rules/development-workflow.mdc new file mode 100644 index 0000000..ecfb22a --- /dev/null +++ b/.cursor/rules/development-workflow.mdc @@ -0,0 +1,26 @@ +--- +description: 分阶段开发流程、修改前后检查清单与禁止事项 +alwaysApply: true +--- +# 开发工作方式 + +像资深项目开发人员一样工作,而不是代码生成器。详见 `docs/15-development-workflow.md`、`docs/16-roadmap.md`。 + +## 分阶段 +- 严格按 Phase 1~17 顺序推进(`docs/16-roadmap.md`),不要一次生成整个项目或几百个文件。 +- 每个 Phase 开始前先说明:目标、涉及模块、数据库变化、API 变化、前端变化、测试方案、风险;确认后再实施。 +- 阶段完成后:检查代码 → 数据库 → 运行测试 → API → 前端 → 修复问题,再进入下一阶段。 + +## 修改前 +理解目录 → 搜索已有实现(不重复造)→ 检查数据库结构、相关 API、前端调用 → 再修改。 + +## 修改后 +检查类型、语法、引用、迁移、API、权限、**租户隔离**,并运行相关测试。 + +## 禁止 +- 跳过架构设计;Controller 堆业务;一个 Model 承担所有业务 +- 忽略 `tenant_code`;直接改库存不留流水;不考虑并发库存 +- Python 直接修改核心 WMS 数据;平台逻辑写死进核心订单模型 +- 过早微服务化;没有测试就继续堆功能;随意增加第三方依赖 +- 重复实现 Element Plus / Admin 框架已提供的能力 +- 魔法字符串、硬编码、重复 SQL、跨模块强耦合 diff --git a/.cursor/rules/docker.mdc b/.cursor/rules/docker.mdc new file mode 100644 index 0000000..e938bdb --- /dev/null +++ b/.cursor/rules/docker.mdc @@ -0,0 +1,15 @@ +--- +description: Docker 开发环境规范 +globs: docker-compose*.yml,docker/**,**/Dockerfile +alwaysApply: false +--- +# Docker 开发环境 + +详见 `docs/13-docker.md`。 + +- 根目录**一个** `docker-compose.yml`,不为小模块建立独立 Compose。 +- 服务:php-fpm(PHP 8.4)、nginx、mysql(8)、redis(7)、node(前端开发)、py-service(FastAPI,构建上下文 `py-service/`)。 +- Queue Worker、Scheduler 为独立服务,复用 PHP 镜像。 +- 镜像定义放 `docker/{service}/`;敏感配置经 `.env` 注入,不写入镜像与 Git。 +- 数据卷持久化 MySQL / Redis;端口、密码可通过 `.env` 配置。 +- 第一阶段不引入 Kubernetes,生产方案在 Phase 17 设计。 diff --git a/.cursor/rules/frontend-vue.mdc b/.cursor/rules/frontend-vue.mdc new file mode 100644 index 0000000..bb5f2b9 --- /dev/null +++ b/.cursor/rules/frontend-vue.mdc @@ -0,0 +1,27 @@ +--- +description: Vue 3 + TypeScript + Element Plus 前端规范(pure-admin-thin) +globs: frontend/**/*.vue,frontend/**/*.ts,frontend/**/*.tsx +alwaysApply: false +--- +# 前端规范 + +详见 `docs/10-frontend.md`。 + +## 框架 +- Admin 基于 pure-admin-thin(i18n 分支),复用其 Layout / Router / 权限 / 标签页 / i18n,不重复实现。 +- UI 只用 Element Plus,不引入 Naive UI 等第二套组件库;不重复实现 Element Plus 已有组件。 +- 新增依赖前先确认框架与现有依赖无法满足。 + +## 结构 +- 页面按业务领域放 `src/views/{domain}/`(warehouse、inventory、inbound、outbound 等)。 +- 接口调用统一放 `src/api/{domain}.ts`,通过框架封装的 HTTP 实例,页面内不直接写 axios。 +- 类型放 `src/types/`,状态 / 枚举常量放 `src/constants/`,禁止魔法字符串。 + +## 编码 +- `