# 库存3D查看器 Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. **Goal:** 实现库存3D查看器,用户可在 Three.js 3D 场景中巡视仓库、点击货位查看库存详情 **Architecture:** 前端 Vue 3 + Element Plus + Three.js,后端 ASP.NET Core 6 Web API + SignalR 实时推送 **Tech Stack:** Three.js, @microsoft/signalr, Element Plus, Vue 3 Composition API --- ## 文件结构 ``` 后端 (WIDESEA_WMSServer) ├── WIDESEA_DTO/Stock/Stock3DLayoutDTO.cs # 3D布局响应DTO [新建] ├── WIDESEA_IStockService/IStockInfoService.cs # 添加Get3DLayoutAsync方法签名 [修改] ├── WIDESEA_StockService/StockInfoService.cs # 实现Get3DLayoutAsync [修改] ├── WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs # 添加Get3DLayout端点 [修改] └── WIDESEA_WMSServer/Hubs/StockHub.cs # SignalR Hub [新建] 前端 (WIDESEA_WMSClient) ├── package.json # 添加three依赖 [修改] ├── src/router/viewGird.js # 注册路由 [修改] ├── src/views/stock/stockChat.vue # 主页面组件 [新建] └── src/extension/stock/stockChat.js # 扩展配置 [新建] ``` --- ## 实现任务 ### Task 1: 后端 - 创建 Stock3DLayoutDTO **Files:** - Create: `WIDESEA_WMSServer/WIDESEA_DTO/Stock/Stock3DLayoutDTO.cs` **详细规范:** 创建两个 DTO 类: 1. `Stock3DLayoutDTO` - 包含仓库基本信息、尺寸、筛选列表、货位数组 2. `Location3DItemDTO` - 包含单个货位的所有3D渲染所需数据 **验收标准:** - DTO 包含所有 spec 中定义的字段 - 命名空间正确 - 可以被 Service 层正确引用 ```csharp namespace WIDESEA_DTO.Stock { /// /// 仓库3D布局响应DTO /// public class Stock3DLayoutDTO { public int WarehouseId { get; set; } public string WarehouseName { get; set; } public int MaxRow { get; set; } public int MaxColumn { get; set; } public int MaxLayer { get; set; } public List MaterielCodeList { get; set; } = new(); public List BatchNoList { get; set; } = new(); public List Locations { get; set; } = new(); } /// /// 货位3D数据项 /// public class Location3DItemDTO { public int LocationId { get; set; } public string LocationCode { get; set; } public int Row { get; set; } public int Column { get; set; } public int Layer { get; set; } public int LocationStatus { get; set; } // 0=空, 1=占用, 2=锁定, 3=禁用 public int StockStatus { get; set; } // 0=无货, 1=有货, 2=库存紧张, 3=已满 public float StockQuantity { get; set; } public float MaxCapacity { get; set; } public string? PalletCode { get; set; } public string? MaterielCode { get; set; } public string? MaterielName { get; set; } public string? BatchNo { get; set; } } } ``` --- ### Task 2: 后端 - 更新 IStockInfoService 接口 **Files:** - Modify: `WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs` **详细规范:** 在接口中添加方法签名: ```csharp /// /// 获取仓库3D布局数据 /// /// 仓库ID /// 3D布局DTO Task Get3DLayoutAsync(int warehouseId); ``` **验收标准:** - 方法签名正确 - 添加了文档注释 - 引用了 Stock3DLayoutDTO --- ### Task 3: 后端 - 实现 Get3DLayoutAsync **Files:** - Modify: `WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs` **详细规范:** 实现 Get3DLayoutAsync 方法: 1. 查询仓库信息 2. 查询该仓库所有货位 3. 查询库存信息(包含明细) 4. 提取物料编号和批次号列表 5. 映射到 Location3DItemDTO 6. 计算仓库尺寸 **验收标准:** - 方法能正确返回 Stock3DLayoutDTO - 所有 locationStatus 和 stockStatus 值正确映射 - 性能适合中型仓库(1000-5000货位) --- ### Task 4: 后端 - 添加 API 端点 **Files:** - Modify: `WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs` **详细规范:** 添加端点: ```csharp /// /// 获取仓库3D布局 /// /// 仓库ID /// 3D布局数据 [HttpGet("Get3DLayout")] public async Task Get3DLayout(int warehouseId) { var result = await Service.Get3DLayoutAsync(warehouseId); return WebResponseContent.Instance.OK(result); } ``` **验收标准:** - 路由正确:GET /api/StockInfo/Get3DLayout?warehouseId={id} - 返回格式符合 WebResponseContent 规范 --- ### Task 5: 后端 - 创建 SignalR Hub **Files:** - Create: `WIDESEA_WMSServer/WIDESEA_WMSServer/Hubs/StockHub.cs` - Modify: `WIDESEA_WMSServer/WIDESEA_WMSServer/Program.cs` **详细规范:** 1. 创建 StockHub 类,继承 Microsoft.AspNetCore.SignalR.Hub 2. 添加 SendStockUpdate 方法供外部调用 3. 在 Program.cs 中注册 SignalR 服务并映射 Hub **验收标准:** - Hub 可被前端连接 - SendStockUpdate 方法存在且可被调用 --- ### Task 6: 前端 - 安装 Three.js 依赖 **Files:** - Modify: `WIDESEA_WMSClient/package.json` **详细规范:** 添加 three 依赖到 package.json: ```json "three": "^0.160.0" ``` **验收标准:** - package.json 包含 three 依赖 - 版本号合理(^0.160.0 或更新稳定版) --- ### Task 7: 前端 - 注册路由 **Files:** - Modify: `WIDESEA_WMSClient/src/router/viewGird.js` **详细规范:** 在 stockView 路由后添加: ```javascript { path: '/stockChat', name: 'stockChat', component: () => import('@/views/stock/stockChat.vue') } ``` **验收标准:** - 路由注册正确 - 与其他路由格式一致 --- ### Task 8: 前端 - 创建 stockChat.vue 主组件 **Files:** - Create: `WIDESEA_WMSClient/src/views/stock/stockChat.vue` **详细规范:** 组件必须包含: 1. 仓库 Tabs(el-tabs) 2. 工具栏(筛选 + 重置视角按钮) 3. 3D Canvas 容器 4. 状态图例 5. 详情弹窗(el-dialog fullscreen) Three.js 场景: 1. 场景初始化(背景色 0x1a1a2e) 2. 透视相机 3. WebGLRenderer 4. OrbitControls(阻尼启用的轨道控制器) 5. 环境光 + 定向光 6. 地面(PlaneGeometry,网格) 7. InstancedMesh 批量渲染货位 8. Raycaster 点击拾取 9. 相机 lerp 聚焦动画 颜色编码(前端实现): - DISABLED(3): 0x2d2d2d - LOCKED(2): 0xF56C6C - EMPTY(0/无货): 0x4a4a4a - HAS_STOCK(1): 0x409EFF - LOW_STOCK(2): 0xE6A23C - FULL(3): 0x67C23A **验收标准:** - 页面可以正常加载 - Three.js 场景正确初始化 - 点击货位能显示详情弹窗 - 颜色编码正确 --- ### Task 9: 前端 - 创建扩展配置文件 **Files:** - Create: `WIDESEA_WMSClient/src/extension/stock/stockChat.js` **详细规范:** 创建标准扩展文件格式: ```javascript let extension = { components: { gridHeader: '', gridBody: '', gridFooter: '', modelHeader: '', modelBody: '', modelFooter: '' }, tableAction: '', buttons: { view: [], box: [], detail: [] }, methods: { onInit() {}, onInited() {} } }; export default extension; ``` **验收标准:** - 符合项目现有扩展文件模式 --- ### Task 10: 前端 - 集成 SignalR 实时更新 **Files:** - Modify: `WIDESEA_WMSClient/src/views/stock/stockChat.vue` **详细规范:** 1. 在 onMounted 中初始化 SignalR 连接 2. 连接 /stockHub 3. 监听 StockUpdated 事件 4. 更新对应货位的 stockQuantity 和 stockStatus 5. 动态更新货位颜色 6. 在 onUnmounted 中断开连接 **验收标准:** - SignalR 连接正常建立 - 收到更新时货位颜色能动态变化