# Dense Cargo Space Plan 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. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Display warehouse 03 as a floor-selectable 13排 × 25列 dense-storage map matching the supplied layout while preserving the existing heatmap for every other warehouse. **Architecture:** Add a dedicated read-only KPI endpoint for dense-layout coordinates so the legacy `/kpi/cargoSpacePlan` response remains unchanged. The Vue page branches only when `warehouseId === '03'`, rendering a focused dense-map component with exact coordinate placement, floor controls, special-node colors, and per-floor counts; all other warehouses continue through the current roadway/platoon/ECharts path. **Tech Stack:** Java 17, Spring Boot, Mockito/JUnit 5, Vue 2, Element UI, ECharts 5, SCSS, Playwright. --- ### Task 1: Add a dense-plan KPI response **Files:** - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/controller/KpiController.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/service/KpiService.java` - Modify: `ruoyi-admin/src/main/java/com/ruoyi/kpi/service/impl/KpiServiceImpl.java` - Test: `ruoyi-admin/src/test/java/com/ruoyi/kpi/service/impl/KpiServiceImplTest.java` - [x] **Step 1: Write the failing service test** Add a test that returns two warehouse-03 `BasCargoSpace` records on different floors and asserts that `getDenseCargoSpacePlanData("03")` returns sorted `floors` plus location maps containing `cargoSpaceId`, `thePlatoon`, `theColumn`, `theFloor`, `status`, `groupCoding`, and `thisCargoArea`. ```java Map result = service.getDenseCargoSpacePlanData("03"); assertThat(result.get("floors")).isEqualTo(List.of(1L, 2L)); assertThat(result.get("locations")).asList().hasSize(2); ``` - [x] **Step 2: Run the test and verify the missing-method failure** Run: `D:/BDevTools/maven/apache-maven-3.9.11/bin/mvn.cmd -pl ruoyi-admin -am -Dtest=KpiServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test` Expected: compilation fails because `getDenseCargoSpacePlanData` does not exist. - [x] **Step 3: Implement the service and endpoint** Add `GET /kpi/denseCargoSpacePlan?warehouseId=03` protected by `kpi:cargo:space:plan`. Query `BasCargoSpaceMapper` by warehouse, derive sorted floors, and return plain location maps without JSON-string encoding. ```java @GetMapping("/denseCargoSpacePlan") @PreAuthorize("@ss.hasPermi('kpi:cargo:space:plan')") public AjaxResult getDenseCargoSpacePlan(String warehouseId) { return AjaxResult.success(kpiService.getDenseCargoSpacePlanData(warehouseId)); } ``` - [x] **Step 4: Run the focused backend test** Run: `D:/BDevTools/maven/apache-maven-3.9.11/bin/mvn.cmd -pl ruoyi-admin -am -Dtest=KpiServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test` Expected: all `KpiServiceImplTest` tests pass. ### Task 2: Build the floor-selectable dense map **Files:** - Create: `ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue` - Modify: `ruoyi-ui/src/api/kpi/kpi.js` - Modify: `ruoyi-ui/src/views/kpi/plan/index.vue` - [x] **Step 1: Add the dense-plan API client** ```javascript export function getDenseChartData(query) { return request({ url: '/kpi/denseCargoSpacePlan', method: 'get', params: query }) } ``` - [x] **Step 2: Create the coordinate-grid component** Render a top axis row, 25 descending 列 rows, 13 ascending 排 columns, and a bottom axis row. Place each location with `gridColumn = thePlatoon + 1` and `gridRow = 27 - theColumn`; use status 7 brown, status 8 yellow, status 9 green, and show the eight-digit cargo-space ID inside every real node. ```javascript cellStyle(location) { return { gridColumn: String(Number(location.thePlatoon) + 1), gridRow: String(27 - Number(location.theColumn)) } } ``` - [x] **Step 3: Branch warehouse 03 without changing legacy behavior** Keep the warehouse selector for all warehouses. For warehouse 03, hide roadway/platoon filters, call the dense endpoint, and show floor buttons 1-5. For any other warehouse, retain the existing roadway/platoon calls and ECharts heatmap code. ```javascript isDenseWarehouse() { return String(this.queryParams.warehouseId) === '03' } ``` - [x] **Step 4: Build the production frontend** Run: `npm run build:prod` from `ruoyi-ui`. Expected: Vue production build succeeds with no compile errors. ### Task 3: Verify behavior and visual fidelity **Files:** - Create: `scripts/verify_dense_cargo_space_plan.py` - Verify: `ruoyi-ui/src/views/kpi/plan/index.vue` - Verify: `ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue` - [x] **Step 1: Start the backend and frontend with the webapp-testing helper** Run `python C:/Users/13623/.agents/skills/webapp-testing/scripts/with_server.py --help` first, then start the Spring Boot backend and Vue dev server through the helper. - [x] **Step 2: Verify warehouse 03 in Chromium** Open the KPI cargo-space plan, select warehouse 03, wait for network idle, and verify floor controls, 259 current-floor nodes, the green 王-shaped mother channel, two brown lifts, two yellow conveyors, axis labels, and no console errors. - [x] **Step 3: Verify a legacy warehouse** Switch to warehouse 01 and verify roadway/platoon controls and the existing ECharts heatmap remain visible. - [ ] **Step 4: Commit** ```bash git add docs/superpowers/plans/2026-07-14-dense-cargo-space-plan.md scripts/verify_dense_cargo_space_plan.py ruoyi-admin/src/main/java/com/ruoyi/kpi/controller/KpiController.java ruoyi-admin/src/main/java/com/ruoyi/kpi/service/KpiService.java ruoyi-admin/src/main/java/com/ruoyi/kpi/service/impl/KpiServiceImpl.java ruoyi-admin/src/test/java/com/ruoyi/kpi/service/impl/KpiServiceImplTest.java ruoyi-ui/src/api/kpi/kpi.js ruoyi-ui/src/views/kpi/plan/index.vue ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue git commit -m "feat: add dense warehouse floor plan" ``` Only perform this step when the user explicitly requests a Git commit. ### Task 4: Make the dense map viewport adaptive **Files:** - Modify: `ruoyi-ui/src/views/kpi/plan/index.vue` - Modify: `ruoyi-ui/src/views/kpi/plan/components/DenseCargoSpaceMap.vue` - Modify: `scripts/verify_dense_cargo_space_plan.py` - [x] **Step 1: Move floor actions into the existing search form** For warehouse 03, render `el-radio-group` floor buttons and a refresh button after the warehouse selector. Remove the dense-mode explanatory sentence. Pass only the selected floor and locations into the map component. ```vue ``` - [x] **Step 2: Remove the map header and column 25** Delete the warehouse eyebrow, title, subtitle, internal floor switch, and internal refresh action. Generate column labels from 24 down to 1, place data rows with `gridRow = 26 - theColumn`, and move the bottom 排 axis to row 26. ```javascript columnLabels() { return Array.from({ length: 24 }, (_, index) => 24 - index) } ``` - [x] **Step 3: Fit the full grid without internal scrolling** Use a fixed 13-column fraction grid and 24 adaptive rows. Set the viewport to `overflow: hidden`; compute the map row height from available viewport height with CSS `clamp()`, reduce summary/legend/footer vertical space, and allow cargo IDs to scale with `clamp()`. ```scss .dense-map__viewport { overflow: hidden; } .dense-grid { grid-template-columns: 36px repeat(13, minmax(0, 1fr)); grid-template-rows: 24px repeat(24, minmax(18px, 1fr)) 28px; width: 100%; min-width: 0; } ``` - [x] **Step 4: Rebuild and verify responsive behavior** Run `npm run build:prod`, then run `python scripts/verify_dense_cargo_space_plan.py`. Assert column 25 is absent, floor controls are in `.search-box`, the dense map has 259 nodes, and both `.dense-map__viewport` and `.dense-grid` have `scrollWidth <= clientWidth` and `scrollHeight <= clientHeight` at 1500×1050 and 1280×800 viewports.