warehouse-layout-enhancers.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. export interface WarehouseLayoutParsedLocation {
  2. floor: number
  3. x: number
  4. y: number
  5. depth: number
  6. }
  7. export interface WarehouseLayoutPosition {
  8. gridRow: number
  9. gridCol: number
  10. }
  11. interface LocalColumnAisleRule {
  12. afterColumn: number
  13. gapCols: number
  14. rows?: number[]
  15. rowRange?: [number, number]
  16. }
  17. interface GlobalColumnAisleRule {
  18. breakpoint: number
  19. excludeRows?: number[]
  20. excludeRowRange?: [number, number]
  21. }
  22. interface WarehouseLayoutEnhancer {
  23. supports: (level: number) => boolean
  24. apply: (
  25. currentPosition: WarehouseLayoutPosition,
  26. parsedLocation: WarehouseLayoutParsedLocation
  27. ) => WarehouseLayoutPosition
  28. }
  29. const firstFloorEnhancer: WarehouseLayoutEnhancer = {
  30. supports: (level) => level === 1,
  31. apply: (currentPosition, parsedLocation) => {
  32. let nextPosition = currentPosition
  33. const firstFloorRowAisleBreakpoints = [2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22]
  34. const firstFloorGlobalColumnAisles: GlobalColumnAisleRule[] = [
  35. { breakpoint: 1 },
  36. {
  37. breakpoint: 19,
  38. excludeRows: [8, 9, 10, 11]
  39. },
  40. { breakpoint: 26 }
  41. ]
  42. const firstFloorLocalColumnAisles: LocalColumnAisleRule[] = [
  43. {
  44. rowRange: [0, 8],
  45. afterColumn: 7,
  46. gapCols: 1
  47. },
  48. {
  49. rowRange: [11, 22],
  50. afterColumn: 7,
  51. gapCols: 1
  52. },
  53. {
  54. rows: [9, 10],
  55. afterColumn: 6,
  56. gapCols: 3
  57. },
  58. {
  59. rows: [9, 10],
  60. afterColumn: 10,
  61. gapCols: 1
  62. },
  63. {
  64. rows: [8, 11],
  65. afterColumn: 12,
  66. gapCols: 1
  67. },
  68. {
  69. rows: [8, 11],
  70. afterColumn: 17,
  71. gapCols: 1
  72. },
  73. {
  74. rows: [9, 10],
  75. afterColumn: 20,
  76. gapCols: 1
  77. },
  78. {
  79. rows: [8, 11],
  80. afterColumn: 24,
  81. gapCols: 1
  82. },
  83. {
  84. rows: [9, 10],
  85. afterColumn: 14,
  86. gapCols: 3
  87. }
  88. ]
  89. // 1 层增强规则:在指定列断点之间插入整列过道。
  90. firstFloorGlobalColumnAisles.forEach((rule) => {
  91. const excludedByRows = rule.excludeRows?.includes(parsedLocation.y) ?? false
  92. const excludedByRange = rule.excludeRowRange
  93. ? parsedLocation.y >= rule.excludeRowRange[0] && parsedLocation.y <= rule.excludeRowRange[1]
  94. : false
  95. if (!excludedByRows && !excludedByRange && parsedLocation.x >= rule.breakpoint) {
  96. nextPosition = {
  97. ...nextPosition,
  98. gridCol: nextPosition.gridCol + 1
  99. }
  100. }
  101. })
  102. // 1 层增强规则:在指定行断点之间插入整行过道。
  103. firstFloorRowAisleBreakpoints.forEach((breakpoint) => {
  104. if (parsedLocation.y >= breakpoint) {
  105. nextPosition = {
  106. ...nextPosition,
  107. gridRow: nextPosition.gridRow + 1
  108. }
  109. }
  110. })
  111. // 1 层增强规则:指定行内在某列右侧插入局部整列过道。
  112. firstFloorLocalColumnAisles.forEach((rule) => {
  113. const matchedRows = rule.rows?.includes(parsedLocation.y) ?? false
  114. const matchedRange = rule.rowRange
  115. ? parsedLocation.y >= rule.rowRange[0] && parsedLocation.y <= rule.rowRange[1]
  116. : false
  117. if ((matchedRows || matchedRange) && parsedLocation.x > rule.afterColumn) {
  118. nextPosition = {
  119. ...nextPosition,
  120. gridCol: nextPosition.gridCol + rule.gapCols
  121. }
  122. }
  123. })
  124. return nextPosition
  125. }
  126. }
  127. const LAYOUT_ENHANCERS: WarehouseLayoutEnhancer[] = [firstFloorEnhancer]
  128. export const applyWarehouseLayoutEnhancement = (
  129. level: number,
  130. parsedLocation: WarehouseLayoutParsedLocation,
  131. basePosition: WarehouseLayoutPosition
  132. ) => {
  133. return LAYOUT_ENHANCERS
  134. .filter((enhancer) => enhancer.supports(level))
  135. .reduce(
  136. (currentPosition, enhancer) => enhancer.apply(currentPosition, parsedLocation),
  137. basePosition
  138. )
  139. }