handy před 1 měsícem
rodič
revize
767943a78a

+ 18 - 7
src/components/WarehouseMap.vue

@@ -63,11 +63,11 @@
 <script setup lang="ts">
 import { computed, onBeforeUnmount, onMounted, ref, watch, type CSSProperties } from 'vue'
 import type { LocationResourceDataVO } from '../types'
+import { applyWarehouseLayoutEnhancement } from './warehouse-layout-enhancers'
 import {
-  applyWarehouseLayoutEnhancement,
   getWarehouseLayoutSpecialCells,
   type WarehouseLayoutSpecialCell
-} from './warehouse-layout-enhancers'
+} from './warehouse-layout-special-cells'
 
 interface Props {
   locations: LocationResourceDataVO[]
@@ -215,9 +215,11 @@ const parsedLocations = computed<GridCell[]>(() => {
     })
 })
 
+const specialCells = computed(() => getWarehouseLayoutSpecialCells(props.currentLevel))
+
 const specialCellMap = computed(() => {
   return new Map(
-    getWarehouseLayoutSpecialCells(props.currentLevel).map((cell) => [
+    specialCells.value.map((cell) => [
       `${cell.gridRow}-${cell.gridCol}`,
       cell
     ])
@@ -235,11 +237,20 @@ const locationMap = computed(() => {
 const gridBounds = computed(() => {
   if (parsedLocations.value.length === 0) return null
 
+  const allRows = [
+    ...parsedLocations.value.map((loc) => loc.parsed.gridRow),
+    ...specialCells.value.map((cell) => cell.gridRow)
+  ]
+  const allCols = [
+    ...parsedLocations.value.map((loc) => loc.parsed.gridCol),
+    ...specialCells.value.map((cell) => cell.gridCol)
+  ]
+
   return {
-    minX: Math.min(...parsedLocations.value.map((loc) => loc.parsed.gridRow)),
-    maxX: Math.max(...parsedLocations.value.map((loc) => loc.parsed.gridRow)),
-    minY: Math.min(...parsedLocations.value.map((loc) => loc.parsed.gridCol)),
-    maxY: Math.max(...parsedLocations.value.map((loc) => loc.parsed.gridCol))
+    minX: Math.min(...allRows),
+    maxX: Math.max(...allRows),
+    minY: Math.min(...allCols),
+    maxY: Math.max(...allCols)
   }
 })
 

+ 1 - 157
src/components/warehouse-layout-enhancers.ts

@@ -10,18 +10,6 @@ export interface WarehouseLayoutPosition {
   gridCol: number
 }
 
-export interface WarehouseLayoutWallCell {
-  gridRow: number
-  gridCol: number
-}
-
-export interface WarehouseLayoutSpecialCell {
-  gridRow: number
-  gridCol: number
-  type: 'wall' | 'elevator'
-  label?: string
-}
-
 type RowRange = readonly [number, number]
 
 interface RowScopedRule {
@@ -45,26 +33,11 @@ interface GlobalColumnAisleRule {
   excludeRowRange?: RowRange
 }
 
-interface VerticalWallBreakRule {
-  column: number
-  betweenRows: readonly [number, number]
-}
-
-interface ElevatorAreaRule {
-  leftColumn: number
-  rightColumn: number
-  upperRow: number
-  lowerRow: number
-  label: string
-}
-
 interface WarehouseLayoutRuleSet {
   rowAisleBreakpoints: readonly number[]
   globalColumnAisles: readonly GlobalColumnAisleRule[]
   localColumnAisles: readonly LocalColumnAisleRule[]
   localColumnShifts: readonly LocalColumnShiftRule[]
-  verticalWallBreaks: readonly VerticalWallBreakRule[]
-  elevatorAreas: readonly ElevatorAreaRule[]
 }
 
 const scopedRows = <T extends object>(rows: readonly number[], rule: T): T & Pick<RowScopedRule, 'rows'> => ({
@@ -89,29 +62,6 @@ const globalColumnAisle = (
   ...options
 })
 
-const verticalWallBreak = (
-  column: number,
-  upperRow: number,
-  lowerRow: number
-): VerticalWallBreakRule => ({
-  column,
-  betweenRows: [upperRow, lowerRow]
-})
-
-const elevatorArea = (
-  leftColumn: number,
-  rightColumn: number,
-  upperRow: number,
-  lowerRow: number,
-  label: string
-): ElevatorAreaRule => ({
-  leftColumn,
-  rightColumn,
-  upperRow,
-  lowerRow,
-  label
-})
-
 const FIRST_FLOOR_ROW_AISLE_BREAKPOINTS = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22] as const
 
 const FIRST_FLOOR_GLOBAL_COLUMN_AISLES = [
@@ -182,26 +132,11 @@ const FIRST_FLOOR_LOCAL_COLUMN_SHIFTS = [
   })
 ] as const
 
-const FIRST_FLOOR_VERTICAL_WALL_BREAKS = [
-  verticalWallBreak(0, 5, 6),
-  verticalWallBreak(0, 19, 20),
-  verticalWallBreak(6, 19, 20),
-  verticalWallBreak(13, 19, 20),
-  verticalWallBreak(20, 19, 20)
-] as const
-
-const FIRST_FLOOR_ELEVATOR_AREAS = [
-  elevatorArea(7, 9, 8, 11, '提升机'),
-  elevatorArea(18, 20, 8, 11, '提升机')
-] as const
-
 const FIRST_FLOOR_RULE_SET: WarehouseLayoutRuleSet = {
   rowAisleBreakpoints: FIRST_FLOOR_ROW_AISLE_BREAKPOINTS,
   globalColumnAisles: FIRST_FLOOR_GLOBAL_COLUMN_AISLES,
   localColumnAisles: FIRST_FLOOR_LOCAL_COLUMN_AISLES,
-  localColumnShifts: FIRST_FLOOR_LOCAL_COLUMN_SHIFTS,
-  verticalWallBreaks: FIRST_FLOOR_VERTICAL_WALL_BREAKS,
-  elevatorAreas: FIRST_FLOOR_ELEVATOR_AREAS
+  localColumnShifts: FIRST_FLOOR_LOCAL_COLUMN_SHIFTS
 }
 
 const RULE_SETS_BY_LEVEL: Readonly<Record<number, WarehouseLayoutRuleSet>> = {
@@ -292,79 +227,6 @@ const getRuleSet = (level: number) => {
   return RULE_SETS_BY_LEVEL[level]
 }
 
-const createSyntheticLocation = (
-  level: number,
-  column: number,
-  row: number
-): WarehouseLayoutParsedLocation => ({
-  floor: level,
-  x: column,
-  y: row,
-  depth: 1
-})
-
-const getEnhancedBasePosition = (
-  level: number,
-  ruleSet: WarehouseLayoutRuleSet,
-  column: number,
-  row: number
-) =>
-  applyRuleSet(
-    {
-      gridRow: row,
-      gridCol: column
-    },
-    createSyntheticLocation(level, column, row),
-    ruleSet
-  )
-
-const buildWallCells = (
-  level: number,
-  ruleSet: WarehouseLayoutRuleSet
-): WarehouseLayoutSpecialCell[] => {
-  return ruleSet.verticalWallBreaks.map((rule) => {
-    const upperRowPosition = getEnhancedBasePosition(level, ruleSet, rule.column, rule.betweenRows[0])
-
-    return {
-      type: 'wall',
-      gridRow: upperRowPosition.gridRow + 1,
-      gridCol: upperRowPosition.gridCol,
-      label: '墙'
-    }
-  })
-}
-
-const buildElevatorAreaCells = (
-  level: number,
-  ruleSet: WarehouseLayoutRuleSet
-): WarehouseLayoutSpecialCell[] => {
-  return ruleSet.elevatorAreas.flatMap((rule) => {
-    const upperLeft = getEnhancedBasePosition(level, ruleSet, rule.leftColumn, rule.upperRow)
-    const upperRight = getEnhancedBasePosition(level, ruleSet, rule.rightColumn, rule.upperRow)
-    const lowerLeft = getEnhancedBasePosition(level, ruleSet, rule.leftColumn, rule.lowerRow)
-    const rowStart = upperLeft.gridRow + 1
-    const rowEnd = lowerLeft.gridRow - 1
-    const colStart = upperLeft.gridCol
-    const colEnd = upperRight.gridCol
-    const centerRow = Math.floor((rowStart + rowEnd) / 2)
-    const centerCol = Math.floor((colStart + colEnd) / 2)
-    const cells: WarehouseLayoutSpecialCell[] = []
-
-    for (let gridRow = rowStart; gridRow <= rowEnd; gridRow++) {
-      for (let gridCol = colStart; gridCol <= colEnd; gridCol++) {
-        cells.push({
-          type: 'elevator',
-          gridRow,
-          gridCol,
-          label: gridRow === centerRow && gridCol === centerCol ? rule.label : undefined
-        })
-      }
-    }
-
-    return cells
-  })
-}
-
 export const applyWarehouseLayoutEnhancement = (
   level: number,
   parsedLocation: WarehouseLayoutParsedLocation,
@@ -377,21 +239,3 @@ export const applyWarehouseLayoutEnhancement = (
 
   return applyRuleSet(basePosition, parsedLocation, ruleSet)
 }
-
-export const getWarehouseLayoutSpecialCells = (level: number): WarehouseLayoutSpecialCell[] => {
-  const ruleSet = getRuleSet(level)
-  if (!ruleSet) {
-    return []
-  }
-
-  return [...buildWallCells(level, ruleSet), ...buildElevatorAreaCells(level, ruleSet)]
-}
-
-export const getWarehouseLayoutWallCells = (level: number): WarehouseLayoutWallCell[] => {
-  return getWarehouseLayoutSpecialCells(level)
-    .filter((cell): cell is WarehouseLayoutSpecialCell & { type: 'wall' } => cell.type === 'wall')
-    .map((cell) => ({
-      gridRow: cell.gridRow,
-      gridCol: cell.gridCol
-    }))
-}

+ 78 - 0
src/components/warehouse-layout-special-cells.ts

@@ -0,0 +1,78 @@
+export interface WarehouseLayoutWallCell {
+  gridRow: number
+  gridCol: number
+}
+
+export interface WarehouseLayoutSpecialCell {
+  gridRow: number
+  gridCol: number
+  type: 'wall' | 'elevator'
+  label?: string
+}
+
+const specialCell = (
+  gridRow: number,
+  gridCol: number,
+  type: WarehouseLayoutSpecialCell['type'],
+  label?: string
+): WarehouseLayoutSpecialCell => ({
+  gridRow,
+  gridCol,
+  type,
+  label
+})
+
+const specialArea = (
+  rowStart: number,
+  rowEnd: number,
+  colStart: number,
+  colEnd: number,
+  type: WarehouseLayoutSpecialCell['type'],
+  centerLabel?: string
+) => {
+  const centerRow = Math.floor((rowStart + rowEnd) / 2)
+  const centerCol = Math.floor((colStart + colEnd) / 2)
+  const cells: WarehouseLayoutSpecialCell[] = []
+
+  for (let gridRow = rowStart; gridRow <= rowEnd; gridRow++) {
+    for (let gridCol = colStart; gridCol <= colEnd; gridCol++) {
+      cells.push(
+        specialCell(
+          gridRow,
+          gridCol,
+          type,
+          centerLabel && gridRow === centerRow && gridCol === centerCol ? centerLabel : undefined
+        )
+      )
+    }
+  }
+
+  return cells
+}
+
+const SHARED_SPECIAL_CELLS: readonly WarehouseLayoutSpecialCell[] = [
+  specialCell(8, 0, 'wall', '墙'),
+  specialCell(29, 0, 'wall', '墙'),
+  specialCell(29, 7, 'wall', '墙'),
+  specialCell(29, 15, 'wall', '墙'),
+  specialCell(29, 23, 'wall', '墙'),
+  ...specialArea(13, 15, 8, 10, 'elevator', '提升机'),
+  ...specialArea(13, 15, 20, 22, 'elevator', '提升机')
+] as const
+
+export const getWarehouseLayoutSpecialCells = (level: number): WarehouseLayoutSpecialCell[] => {
+  if (!level) {
+    return []
+  }
+
+  return [...SHARED_SPECIAL_CELLS]
+}
+
+export const getWarehouseLayoutWallCells = (level: number): WarehouseLayoutWallCell[] => {
+  return getWarehouseLayoutSpecialCells(level)
+    .filter((cell): cell is WarehouseLayoutSpecialCell & { type: 'wall' } => cell.type === 'wall')
+    .map((cell) => ({
+      gridRow: cell.gridRow,
+      gridCol: cell.gridCol
+    }))
+}