From 0dad5f9fbf4e4173dd9447444a9e8bd4702d15f6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 2 Feb 2026 14:37:19 +0800 Subject: [PATCH] Add detailed migration plan for glass-v2 features --- projects/glass-v2-migration-detailed-plan.md | 580 +++++++++++++++++++ 1 file changed, 580 insertions(+) create mode 100644 projects/glass-v2-migration-detailed-plan.md diff --git a/projects/glass-v2-migration-detailed-plan.md b/projects/glass-v2-migration-detailed-plan.md new file mode 100644 index 0000000..1aaca9f --- /dev/null +++ b/projects/glass-v2-migration-detailed-plan.md @@ -0,0 +1,580 @@ +# glass-v2 迁移详细计划 + +## 📋 概述 + +将 glass-v2 的 5 个功能模块迁移到 glass 项目,同时适配: +1. 多租户架构(team_id 隔离) +2. Spatie Permission 权限系统 +3. Filament 4.x API + +--- + +## 🎯 模块清单 + +### 1. 产品分类管理(ProductCategory) + +#### 数据库 +**状态**: glass 项目已有 `categories` 表,需要增强 +**已创建的迁移**: +- ✅ `2026_02_02_140000_add_icon_and_color_to_categories_table.php` + +#### 模型适配 +**需要**: 创建或更新 `app/Models/Category.php` +```php + 'boolean', + 'sort_order' => 'integer', + ]; + + // 添加字段以兼容 v2 + protected $appends = ['is_active']; + + public function getIsActiveAttribute(): bool + { + return $this->status === 'active'; + } + + public function products(): HasMany + { + return $this->hasMany(Product::class); + } + + protected static function boot() + { + parent::boot(); + + static::creating(function ($category) { + if (empty($category->slug)) { + $category->slug = \Illuminate\Support\Str::slug($category->name); + } + }); + } +} +``` + +#### Filament 资源 +**需要创建**: `app/Filament/Resources/Categories/CategoryResource.php` +**来源**: v2 的 `ProductCategoryResource.php` +**适配点**: +1. 修改命名空间:`ProductCategories` → `Categories` +2. 修改模型:`ProductCategory` → `Category` +3. 修改权限检查: + ```php + // v2: auth()->user()->is_admin + // glass: 使用 Gate 或 Policy + public static function canViewAny(): bool + { + return auth()->user()->can('view_any_categories'); + } + ``` +4. 修改导航组:'库存与供应链' → 保持 +5. 添加团队范围:默认会应用 BelongsToTenant + +#### Seeder +**需要创建**: `database/seeders/CategorySeeder.php` +**预置数据**: +- 镜架 (heroicon-o-eye, 蓝色 #3b82f6) +- 镜片 (heroicon-o-circle-stack, 绿色 #10b981) +- 隐形眼镜 (heroicon-o-eye-dropper, 紫色 #8b5cf6) +- 护理液 (heroicon-o-beaker, 青色 #06b6d4) +- 配件 (heroicon-o-wrench-screwdriver, 橙色 #f59e0b) + +--- + +### 2. 品牌管理(Brand) + +#### 数据库 +**状态**: glass 项目已有 `brands` 表,需要增强 +**已创建的迁移**: +- ✅ `2026_02_02_140100_add_slug_and_sort_order_to_brands_table.php` + +#### 模型适配 +**需要**: 创建或更新 `app/Models/Brand.php` +```php + 'boolean', + 'sort_order' => 'integer', + ]; + + protected $appends = ['is_active']; + + public function getIsActiveAttribute(): bool + { + return $this->status === 'active'; + } + + public function products(): HasMany + { + return $this->hasMany(Product::class); + } + + protected static function boot() + { + parent::boot(); + + static::creating(function ($brand) { + if (empty($brand->slug)) { + $brand->slug = \Illuminate\Support\Str::slug($brand->name); + } + }); + } +} +``` + +#### Filament 资源 +**需要创建**: `app/Filament/Resources/Brands/BrandResource.php` +**来源**: v2 的 `BrandResource.php` +**适配点**: +1. 模型名称保持不变 +2. 修改权限检查(同上) +3. 确保 logo 上传目录正确:`brands/` + +#### Seeder +**需要创建**: `database/seeders/BrandSeeder.php` +**预置数据**: +- 雷朋 (Ray-Ban, 意大利) +- 暴龙 (Bolon, 中国) +- 蔡司 (Zeiss, 德国) +- 依视路 (Essilor, 法国) +- 强生 (Johnson, 美国) +- 博士伦 (Bausch & Lomb, 美国) +- 海昌 (Hydron, 中国) + +--- + +### 3. 采购订单管理(PurchaseOrder) + +#### 数据库 +**状态**: glass 项目没有此表 +**已创建的迁移**: +- ✅ `2026_02_02_140200_create_purchase_orders_table.php` +- ✅ `2026_02_02_140300_create_purchase_order_items_table.php` + +#### 模型 +**需要创建**: `app/Models/PurchaseOrder.php` 和 `app/Models/PurchaseOrderItem.php` +**来源**: v2 的模型 +**适配点**: +1. 添加 `BelongsToTenant` trait +2. 确保所有关系正确 +3. 添加团队范围查询 + +**PurchaseOrderItem**: +```php + 'integer', + 'received_quantity' => 'integer', + 'unit_cost' => 'decimal:2', + 'total_cost' => 'decimal:2', + ]; + + public function purchaseOrder(): BelongsTo + { + return $this->belongsTo(PurchaseOrder::class); + } + + public function product(): BelongsTo + { + return $this->belongsTo(Product::class); + } + + public function getPendingQuantityAttribute(): int + { + return $this->quantity - $this->received_quantity; + } +} +``` + +#### Filament 资源 +**需要创建**: `app/Filament/Resources/PurchaseOrders/PurchaseOrderResource.php` +**来源**: v2 的 `PurchaseOrderResource.php` +**适配点**: +1. 修改权限检查 +2. 确保关联关系正确加载(`with()`) +3. 状态流转逻辑保持不变 + +#### 权限配置 +**需要添加到 RoleAndPermissionSeeder**: +```php +$purchasePermissions = [ + 'view_any_purchase_orders', + 'view_purchase_orders', + 'create_purchase_orders', + 'update_purchase_orders', + 'delete_purchase_orders', + 'receive_purchase_orders', + 'stock_in_purchase_orders', +]; + +// 分配角色 +$manager->givePermissionTo($purchasePermissions); +$warehouseStaff->givePermissionTo(['view_any_purchase_orders', 'view_purchase_orders', 'create_purchase_orders', 'receive_purchase_orders']); +``` + +--- + +### 4. 库存流水管理(InventoryTransaction) + +#### 数据库 +**状态**: glass 项目没有此表 +**已创建的迁移**: +- ✅ `2026_02_02_140400_create_inventory_transactions_table.php` + +#### 模型 +**需要创建**: `app/Models/InventoryTransaction.php` +**来源**: v2 的模型 +**适配点**: +1. 添加 `BelongsToTenant` trait +2. 确保多态关联正确 + +```php + 'integer', + 'balance_after' => 'integer', + ]; + + public function product(): BelongsTo + { + return $this->belongsTo(Product::class); + } + + public function staff(): BelongsTo + { + return $this->belongsTo(User::class, 'staff_id'); + } + + public function reference(): MorphTo + { + return $this->morphTo(); + } +} +``` + +#### Filament 资源 +**需要创建**: `app/Filament/Resources/InventoryTransactions/InventoryTransactionResource.php` +**来源**: v2 的 `InventoryTransactionResource.php` +**适配点**: +1. 修改权限检查 +2. 保持只读(表单禁用) +3. 过滤器适配 Filament 4.x + +#### 权限配置 +**需要添加**: +```php +$inventoryPermissions = [ + 'view_any_inventory_transactions', + 'view_inventory_transactions', +]; + +// 所有角色都可以查看库存流水 +$allRoles->each(fn($role) => $role->givePermissionTo($inventoryPermissions)); +``` + +--- + +### 5. 员工排班管理(StaffSchedule) + +#### 数据库 +**状态**: glass 项目没有此表 +**已创建的迁移**: +- ✅ `2026_02_02_140500_create_staff_schedules_table.php` + +#### 模型 +**需要创建**: `app/Models/StaffSchedule.php` +**来源**: v2 的模型 +**适配点**: +1. 添加 `BelongsToTenant` trait +2. 保持所有辅助方法 + +```php +givePermissionTo($schedulePermissions); +$shopOwner->givePermissionTo($schedulePermissions); +``` + +--- + +## 🔧 全局适配步骤 + +### 1. 权限系统扩展 + +在 `database/seeders/RoleAndPermissionSeeder.php` 中添加: + +```php +// 产品分类和品牌权限 +$categoryAndBrandPermissions = [ + 'view_any_categories', + 'view_categories', + 'create_categories', + 'update_categories', + 'delete_categories', + 'view_any_brands', + 'view_brands', + 'create_brands', + 'update_brands', + 'delete_brands', +]; + +// 采购订单权限(已在上方定义) +// 库存流水权限(已在上方定义) +// 员工排班权限(已在上方定义) + +// 分配给角色 +$shopOwner->givePermissionTo([...$categoryAndBrandPermissions, ...$purchasePermissions, ...$inventoryPermissions, ...$schedulePermissions]); +$shopAdmin->givePermissionTo([...$categoryAndBrandPermissions, ...$purchasePermissions, ...$inventoryPermissions]); +$manager->givePermissionTo([...$categoryAndBrandPermissions, ...$purchasePermissions, ...$inventoryPermissions]); +$warehouseStaff->givePermissionTo(['view_any_categories', 'view_any_brands', ...$purchasePermissions, ...$inventoryPermissions]); +``` + +### 2. 中文本地化更新 + +在 `lang/zh_CN.json` 中添加: + +```json +{ + "resources": { + "categories": { + "label": "产品分类", + "plural_label": "产品分类", + "navigation_label": "产品分类" + }, + "brands": { + "label": "品牌", + "plural_label": "品牌", + "navigation_label": "品牌管理" + }, + "purchase_orders": { + "label": "采购单", + "plural_label": "采购管理", + "navigation_label": "采购订单" + }, + "inventory_transactions": { + "label": "库存记录", + "plural_label": "库存交易记录", + "navigation_label": "库存" + }, + "staff_schedules": { + "label": "排班", + "plural_label": "员工排班管理", + "navigation_label": "员工排班" + } + }, + "actions": { + "receive": "收货入库", + "stock_in": "补入库", + "duplicate": "复制到明天" + } +} +``` + +### 3. 导航分组组织 + +在所有 Resource 中统一导航分组: +- 产品分类:`库存与供应链` +- 品牌管理:`库存与供应链` +- 采购订单:`库存与供应链` +- 库存流水:`库存与供应链` +- 员工排班:`系统管理` 或保持单独 + +--- + +## ✅ 检查清单 + +### 迁移前 +- [ ] 备份 glass 项目数据库 +- [ ] 确认 glass 项目的数据库连接配置 +- [ ] 准备测试数据 + +### 数据库迁移 +- [ ] 运行所有新迁移文件 +- [ ] 验证表结构正确 +- [ ] 检查外键约束 + +### 模型创建 +- [ ] 创建所有模型文件 +- [ ] 添加 BelongsToTenant trait +- [ ] 测试模型关系 + +### Filament 资源 +- [ ] 创建所有 Resource 文件 +- [ ] 适配权限检查 +- [ ] 测试表单和表格 + +### Seeder +- [ ] 创建 CategorySeeder +- [ ] 创建 BrandSeeder +- [ ] 运行 Seeder 填充初始数据 + +### 测试 +- [ ] 测试 CRUD 操作 +- [ ] 测试权限隔离 +- [ ] 测试跨租户数据隔离 +- [ ] 测试采购订单收货流程 +- [ ] 测试库存流水自动记录 + +--- + +## 🚀 执行顺序 + +### 第一步:数据库结构(30 分钟) +```bash +# 所有迁移文件已创建,运行迁移 +#(需要先配置数据库连接) +php artisan migrate +``` + +### 第二步:模型创建(45 分钟) +1. 复制并适配所有模型 +2. 添加 BelongsToTenant trait +3. 测试关系 + +### 第三步:Filament 资源(1 小时) +1. 复制所有 Resource 文件 +2. 适配权限检查 +3. 调整导航 + +### 第四步:权限和 Seeder(30 分钟) +1. 更新 RoleAndPermissionSeeder +2. 创建 CategorySeeder 和 BrandSeeder +3. 运行 Seeder + +### 第五步:测试和调试(30 分钟) +1. 测试所有功能 +2. 修复问题 + +**总预计时间**: 3 小时 + +--- + +美羊羊 🐑