瀏覽代碼

v0-20240106

May 1 天之前
父節點
當前提交
0bba23fae0
共有 81 個文件被更改,包括 6870 次插入15158 次删除
  1. 99 0
      README.md
  2. 146 488
      package-lock.json
  3. 0 1
      package.json
  4. 二進制
      src/assets/logo.png
  5. 二進制
      src/assets/map/rorate.jpg
  6. 二進制
      src/assets/map/shuttle_v0_canvas.png
  7. 二進制
      src/assets/simanc.jpg
  8. 二進制
      src/assets/simanc.png
  9. 0 131
      src/components/ArrowSelector.vue
  10. 131 0
      src/components/floor/index.vue
  11. 0 99
      src/components/flr/flr.vue
  12. 318 0
      src/components/grid/grid copy.vue
  13. 404 0
      src/components/grid/grid.vue
  14. 114 0
      src/components/grid/item/carrier.vue
  15. 352 0
      src/components/grid/mixin/cfg.js
  16. 2456 0
      src/components/grid/mixin/grid.js
  17. 160 0
      src/components/grid/port.vue
  18. 513 0
      src/components/grid/scss/grid.scss
  19. 122 0
      src/components/grid/scss/variables.scss
  20. 0 15
      src/components/map/GLB-GRID-CONST.js
  21. 0 1638
      src/components/map/GRID-CONST.js
  22. 0 445
      src/components/map/grid-canvas/cell-sel-panel.vue
  23. 0 3709
      src/components/map/grid-canvas/index.vue
  24. 0 52
      src/components/map/grid-canvas/variables-canvas.scss
  25. 0 210
      src/components/map/grid-svg/index.vue
  26. 0 56
      src/components/map/grid-svg/variables.scss
  27. 250 76
      src/components/tip/index.vue
  28. 0 0
      src/core/mixins/baseWareHouseId.js
  29. 0 0
      src/core/mixins/routerCache.js
  30. 0 0
      src/core/mixins/routerCacheForContentLayout.js
  31. 0 0
      src/core/mixins/sty.js
  32. 741 0
      src/core/mixins/ware-house.js
  33. 6 11
      src/global-cfg/global.js
  34. 7 6
      src/layout-content/ContentLayout.vue
  35. 6 0
      src/layout-content/CustomSearch.vue
  36. 2 2
      src/layout-content/core/dictService.js
  37. 2 3
      src/layout-content/mixins/dict.js
  38. 1 4
      src/layout-content/scss/layout-content.scss
  39. 1 1
      src/layout/components/AppMain.vue
  40. 0 1
      src/layout/components/Sidebar/Logo.vue
  41. 66 247
      src/layout/index.vue
  42. 0 93
      src/layout/index_yuanlai.vue
  43. 0 1
      src/main.js
  44. 0 149
      src/map-test/config.js
  45. 0 385
      src/map-test/dataSimulate.js
  46. 0 26
      src/mixins/map/canvas/gridCanvasMixin.js
  47. 0 3482
      src/mixins/map/gridBaseMixin.js
  48. 0 33
      src/mixins/map/gridViewMixin.js
  49. 0 56
      src/mixins/map/mapDataMixin.js
  50. 0 27
      src/mixins/map/renderStrategies/BaseRenderStrategy.js
  51. 0 20
      src/mixins/map/renderStrategies/RenderStrategyFactory.js
  52. 0 1106
      src/mixins/map/renderStrategies/SvgRenderStrategy.js
  53. 0 202
      src/mixins/map/threeDOri.js
  54. 0 90
      src/mixins/map/warehouseDataMixin.js
  55. 0 21
      src/mixins/map/warehouseRouteMixin.js
  56. 0 14
      src/mixins/socket/componentLevel/sockeHeart.js
  57. 0 33
      src/mixins/socket/componentLevel/socket.js
  58. 0 83
      src/mixins/socket/componentLevel/socketJs.js
  59. 1 13
      src/router/index.js
  60. 10 139
      src/styles/element-ui.scss
  61. 1 6
      src/styles/index.scss
  62. 220 145
      src/views/3d-orgin/index.vue
  63. 20 0
      src/views/3d/index.vue
  64. 35 0
      src/views/3d/show/index.vue
  65. 0 1162
      src/views/cfg/components/cfg-panel.vue
  66. 0 304
      src/views/cfg/components/cfg-table.vue
  67. 519 179
      src/views/cfg/index.vue
  68. 1 1
      src/views/materialconfig/index.vue
  69. 2 2
      src/views/materialcost/index.vue
  70. 2 2
      src/views/materialdetail/index.vue
  71. 1 1
      src/views/register/index.vue
  72. 0 40
      src/views/show/2-5D/V0/index.vue
  73. 0 42
      src/views/show/2-5D/V1/index.vue
  74. 0 34
      src/views/show/2D/index.vue
  75. 144 0
      src/views/show/index.vue
  76. 1 1
      src/views/specconfig/index.vue
  77. 1 1
      src/views/totalPrice/index.vue
  78. 1 1
      src/views/totalPriceCfg/index.vue
  79. 12 67
      src/views/warehouse/config.js
  80. 1 1
      src/views/warehouse/index.vue
  81. 1 1
      vue.config.js

+ 99 - 0
README.md

@@ -0,0 +1,99 @@
+# vue-admin-template
+
+English | [简体中文](./README-zh.md)
+
+> A minimal vue admin template with Element UI & axios & iconfont & permission control & lint
+
+**Live demo:** http://panjiachen.github.io/vue-admin-template
+
+
+**The current version is `v4.0+` build on `vue-cli`. If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-admin-template/tree/tag/3.11.0), it does not rely on `vue-cli`**
+
+<p align="center">
+  <b>SPONSORED BY</b>
+</p>
+<p align="center">
+   <a href="https://finclip.com?from=vue_element" title="FinClip" target="_blank">
+      <img height="200px" src="https://gitee.com/panjiachen/gitee-cdn/raw/master/vue%E8%B5%9E%E5%8A%A9.png" title="FinClip">
+   </a>
+</p>
+
+## Build Setup
+
+```bash
+# clone the project
+git clone https://github.com/PanJiaChen/vue-admin-template.git
+
+# enter the project directory
+cd vue-admin-template
+
+# install dependency
+npm install
+
+# develop
+npm run dev
+```
+
+This will automatically open http://localhost:9528
+
+## Build
+
+```bash
+# build for test environment
+npm run build:stage
+
+# build for production environment
+npm run build:prod
+```
+
+## Advanced
+
+```bash
+# preview the release environment effect
+npm run preview
+
+# preview the release environment effect + static resource analysis
+npm run preview -- --report
+
+# code format check
+npm run lint
+
+# code format check and auto fix
+npm run lint -- --fix
+```
+
+Refer to [Documentation](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) for more information
+
+## Demo
+
+![demo](https://github.com/PanJiaChen/PanJiaChen.github.io/blob/master/images/demo.gif)
+
+## Extra
+
+If you want router permission && generate menu by user roles , you can use this branch [permission-control](https://github.com/PanJiaChen/vue-admin-template/tree/permission-control)
+
+For `typescript` version, you can use [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
+
+## Related Project
+
+- [vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
+
+- [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
+
+- [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template)
+
+- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
+
+## Browsers support
+
+Modern browsers and Internet Explorer 10+.
+
+| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
+| --------- | --------- | --------- | --------- |
+| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
+
+## License
+
+[MIT](https://github.com/PanJiaChen/vue-admin-template/blob/master/LICENSE) license.
+
+Copyright (c) 2017-present PanJiaChen

File diff suppressed because it is too large
+ 146 - 488
package-lock.json


+ 0 - 1
package.json

@@ -17,7 +17,6 @@
     "axios": "0.18.1",
     "axios": "0.18.1",
     "copy-webpack-plugin": "^5.0.5",
     "copy-webpack-plugin": "^5.0.5",
     "core-js": "3.6.5",
     "core-js": "3.6.5",
-    "d3": "^5.16.0",
     "element-ui": "^2.15.14",
     "element-ui": "^2.15.14",
     "js-cookie": "2.2.0",
     "js-cookie": "2.2.0",
     "normalize.css": "7.0.0",
     "normalize.css": "7.0.0",

二進制
src/assets/logo.png


二進制
src/assets/map/rorate.jpg


二進制
src/assets/map/shuttle_v0_canvas.png


二進制
src/assets/simanc.jpg


二進制
src/assets/simanc.png


+ 0 - 131
src/components/ArrowSelector.vue

@@ -1,131 +0,0 @@
-<template>
-    <div :class="{ 'arrow-selector': !isIcon }" :style="cssVars">
-        <div class="arrow-grid">
-            <div class="arrow-item" v-for="direction in directions" :key="direction.type"
-                :class="{ active: isActive(direction.type), 'icon-only': isIcon }"
-                @click="handleSelect(direction.type)">
-                <svg viewBox="0 0 24 24" :width="isIcon ? '20' : '20'" :height="isIcon ? '20' : '20'">
-                    <g v-if="direction.type === 'up'">
-                        <path d="M12 2l-10 10h7v10h6V12h7z" :fill="isActive('up') ? activeColor : inactiveColor" />
-                    </g>
-                    <g v-if="direction.type === 'down'">
-                        <path d="M12 22l10-10h-7V2h-6v10H2z" :fill="isActive('down') ? activeColor : inactiveColor" />
-                    </g>
-                    <g v-if="direction.type === 'left'">
-                        <path d="M2 12l10-10v7h10v6H12v7z" :fill="isActive('left') ? activeColor : inactiveColor" />
-                    </g>
-                    <g v-if="direction.type === 'right'">
-                        <path d="M22 12l-10 10v-7H2v-6h10V2z" :fill="isActive('right') ? activeColor : inactiveColor" />
-                    </g>
-                    <g v-if="direction.type === 'bidirectional-h'">
-                        <path d="M2 12l8-8v5h4V4l8 8-8 8v-5h-4v5z"
-                            :fill="isActive('bidirectional-h') ? activeColor : inactiveColor" />
-                    </g>
-                    <g v-if="direction.type === 'bidirectional-v'">
-                        <path d="M12 2l8 8h-5v4h5l-8 8-8-8h5v-4H4z"
-                            :fill="isActive('bidirectional-v') ? activeColor : inactiveColor" />
-                    </g>
-                </svg>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-import scss from '@/components/map/grid-canvas/variables-canvas.scss'
-export default {
-    name: 'ArrowSelector',
-    props: {
-        isIcon: {
-            type: Boolean,
-            default: false
-        },
-        directions: {
-            type: Array,
-            default: () => [
-                { type: 'bidirectional-h' }]
-        },
-        value: {
-            type: String,
-            default: ''
-        },
-        activeColor: {
-            type: String,
-            default: scss.arrowColor
-        },
-        inactiveColor: {
-            type: String,
-            default: scss.arrowColor
-        }
-    },
-    emits: ['input'],
-    data() {
-        return {
-            localValue: this.value
-        }
-    },
-    computed: {
-        cssVars() {
-            return {
-                '--active-color': this.activeColor,
-                '--inactive-color': this.inactiveColor
-            }
-        }
-    },
-    methods: {
-        isActive(type) {
-            return this.localValue === type;
-        },
-        handleSelect(type) {
-            this.localValue = this.localValue === type ? '' : type;
-            this.$emit('input', this.localValue);
-        }
-    },
-    watch: {
-        value: {
-            handler(newValue) {
-                this.localValue = newValue;
-            },
-            immediate: true
-        }
-    }
-}
-</script>
-
-<style lang="scss" scoped>
-.arrow-selector {
-    .arrow-grid {
-        display: flex;
-
-        .arrow-item {
-            &:not(:last-child) {
-                margin-right: 3px;
-            }
-
-            border: 1px solid #e4e7ed;
-            padding: 2px;
-            cursor: pointer;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-
-            &:hover {
-                border-color: var(--active-color);
-                background-color: rgba(208, 32, 181, 0.1);
-            }
-
-            &.active {
-                border-color: var(--active-color);
-                background-color: rgba(208, 32, 181, 0.2);
-            }
-
-            &.icon-only {
-                border: none;
-                padding: 0;
-                margin: 0;
-                background: none;
-            }
-        }
-    }
-}
-</style>

+ 131 - 0
src/components/floor/index.vue

@@ -0,0 +1,131 @@
+<template>
+  <div v-if="floorNum" class="flr">
+    <div class="floor-p" :class="['floor-p-' + styType]" />
+    <ul ref="floorCon" class="floor-container">
+      <!-- @click="floorToggle(num)"  cursor-oper-->
+      <li
+        v-for="num in floorNum"
+        :key="num"
+        class="floor"
+        :class="{
+          active: activeFloor === num,
+          'cursor-oper': canBeClick,
+          'floor-1': styType === 1,
+          'active-1': activeFloor === num && styType === 1,
+        }"
+        @click="floorToggle(num)"
+      >
+        {{ num }}层
+      </li>
+    </ul>
+    <div
+      class="floor-p"
+      :class="['floor-p-' + styType]"
+      :style="{ height: floorPoHeight }"
+    />
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    styType: {
+      type: Number,
+      require: false,
+      default: 0
+    },
+    floorNum: {
+      type: Number,
+      require: false,
+      default: 1
+    },
+    activeFloorIn: {
+      type: Number,
+      require: false,
+      default: 1
+    },
+    canBeClick: {
+      type: Boolean,
+      require: false,
+      default: false
+    }
+  },
+  data() {
+    return {
+      floorPoHeight: '12px',
+      floorPoWid: '',
+      activeFloor: this.activeFloorIn
+    }
+  },
+  watch: {
+    activeFloorIn() {
+      this.activeFloor = this.activeFloorIn
+    }
+  },
+  mounted() {
+    const otherHeight =
+      (this.$refs.floorCon && this.$refs.floorCon.clientHeight) || 0 + 12
+    this.floorPoHeight = 'calc(100% - ' + otherHeight + 'px)'
+    this.floorPoWid =
+      (this.$refs.floorCon && this.$refs.floorCon.clientWidth) || 0 + 'px'
+  },
+  methods: {
+    floorToggle(num) {
+      if (!this.canBeClick) {
+        return
+      }
+      this.activeFloor = num
+      this.$emit('flr-chg', this.activeFloor)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+$lineSpeCo: #e8e8e8;
+$lineSpeWid: 1px;
+.flr {
+  height: 100%;
+  overflow: hidden;
+  .floor-p {
+    height: 12px;
+    border-right: $lineSpeWid solid $lineSpeCo;
+  }
+  .floor-p-1 {
+    border-right: none;
+  }
+  .floor-container {
+    padding: 0;
+    margin: 0;
+    .floor {
+      // font-size: 14px;
+      color: #909399;
+      text-align: center;
+      border-right: $lineSpeWid solid $lineSpeCo;
+      padding: 6px 6px;
+      line-height: 2;
+      // min-width: 20px;
+      // max-width: 50px;
+      // display:inline-block;
+    }
+    .floor-1 {
+      border-right: none;
+    }
+    .active {
+      color: #303133;
+      border-right: none;
+      border-top: $lineSpeWid solid $lineSpeCo;
+      border-bottom: $lineSpeWid solid $lineSpeCo;
+      border-left: $lineSpeWid solid $lineSpeCo;
+      // border-top-left-radius: 4px;
+      // border-bottom-left-radius: 4px;
+    }
+    .active-1 {
+      border-right: $lineSpeWid solid $lineSpeCo;
+      border-top: none;
+      border-bottom: none;
+      border-left: none;
+    }
+  }
+}
+</style>

+ 0 - 99
src/components/flr/flr.vue

@@ -1,99 +0,0 @@
-<template>
-    <div class="flr-container">
-        <div class="floor-list">
-            <div v-for="floor in floorList" :key="floor" :class="['floor-item', { active: curFlr === floor }]"
-                @click="handleFloorClick(floor)">
-                F{{ floor }}
-            </div>
-        </div>
-    </div>
-</template>
-
-<script>
-export default {
-    name: 'Flr',
-    props: {
-        curFlr: {  // 定义 props
-            type: Number,
-            default: 1
-        },
-        floors: {
-            type: Number,
-            default: 1
-        }
-    },
-    computed: {
-        floorList() {
-            return Array.from({ length: this.floors }, (_, index) => {
-                return this.floors - index
-            })
-        }
-    },
-    methods: {
-        handleFloorClick(floor) {
-            if (floor === this.curFlr) return
-            this.$emit('update:curFlr', floor)
-        }
-    }
-}
-</script>
-
-<style scoped>
-.flr-container {
-    display: flex;
-    justify-content: center;
-    align-items:flex-start;
-    /* padding: 6px 0; */
-}
-
-.floor-list {
-    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
-    display: flex;
-    flex-direction: column;
-    /* gap: 2px;
-    padding: 4px; */
-    /* background: #e6e6e6; */
-    /* border-radius: 4px; */
-    min-width: 24px;
-    flex: 0 0 24px;
-    overflow-y: scroll;
-    max-height: 100%;
-    scrollbar-width: none;
-}
-
-.floor-list::-webkit-scrollbar {
-    display: none;
-}
-
-.floor-item {
-    height: 24px;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
-    background: white;
-    font-size: 11px;
-    color: #333;
-    user-select: none;
-}
-
-.floor-item:hover {
-    background: #f5f5f5;
-}
-
-.floor-item.active {
-    background: #1890ff;
-    color: white;
-}
-
-/* 圆角处理 */
-.floor-item:first-child {
-    border-top-left-radius: 2px;
-    border-top-right-radius: 2px;
-}
-
-.floor-item:last-child {
-    border-bottom-left-radius: 2px;
-    border-bottom-right-radius: 2px;
-}
-</style>

+ 318 - 0
src/components/grid/grid copy.vue

@@ -0,0 +1,318 @@
+<template>
+  <div v-loading="loading" class="grid-container" :style="gridSty">
+    <div v-if="wCol && wCol">
+      <div v-for="(rowData, r) in dataDoubleArr" :key="r" class="g-row">
+        <div
+          v-for="(item, c) in rowData"
+          :key="c"
+          class="item"
+          :class="{
+            'item-xTrack':
+              !item.typeWH && item.sts === itemOperStatusCfg.xTrack,
+            'item-transport':
+              !item.typeWH && item.sts === itemOperStatusCfg.transport,
+            'item-unUse': !item.typeWH && item.sts === itemOperStatusCfg.unUse,
+            'item-lift': !item.typeWH && item.sts === itemOperStatusCfg.lift,
+            'ware-house-item': item.typeWH,
+          }"
+          :style="{
+            width: gridW,
+            height: gridH,
+          }"
+          @click="!item.typeWH && itemClick(item)"
+        >
+          <el-tooltip
+            effect="light"
+            :content="item.r + 1 + '行' + (item.c + 1) + '列'"
+            :disabled="!isShowRowColTip"
+            class="rowcol-tip"
+          >
+            <div
+              v-if="!item.typeWH"
+              class="item-container"
+              :class="{
+                'cursor-oper':
+                  itemOperStatus &&
+                  itemOperStatus !== 'default' &&
+                  itemOperStatus !== 'port' &&
+                  !itemStausMap[item.key],
+                'item-container-vertical': !isHorizontal,
+                'dis-vis':
+                  item.sts === itemOperStatusCfg.unUse ||
+                  item.sts === itemOperStatusCfg.xTrack ||
+                  item.sts === itemOperStatusCfg.lift ||
+                  item.sts === itemOperStatusCfg.transport,
+                'no-det': notShowDet,
+              }"
+            >
+              <template v-if="!notShowDet">
+                <!--railBound-1  -->
+                <div
+                  class="rail-bound-base"
+                  :class="{ 'rail-bound-base-vertical': !isHorizontal }"
+                />
+                <!-- rail-1 -->
+                <div
+                  class="rail-base"
+                  :class="{ 'rail-base-vertical': !isHorizontal }"
+                />
+                <!-- itemInter -->
+                <div
+                  class="item-inter-container"
+                  :class="{
+                    'item-inter-container-vertical': !isHorizontal,
+                  }"
+                >
+                  <template v-if="isShowAniObj">
+                    <div
+                      class="goods"
+                      :style="{
+                        visibility: item.hasGoods ? 'visible' : 'hidden',
+                      }"
+                    />
+                    <!-- visibility: item.hasCarrier ? 'visible' : 'hidden', -->
+                    <carrier
+                      :item="item"
+                      :is-horizontal="isHorizontal"
+                      :class="{ 'carrier-vertical': !isHorizontal }"
+                    />
+                  </template>
+                </div>
+                <div
+                  v-if="item.sts !== itemOperStatusCfg.xTrack"
+                  class="line-con"
+                  :class="{
+                    'line-con-vertical': !isHorizontal,
+                    'z-idx-down-1': item.hasCarrier,
+                  }"
+                >
+                  <div
+                    class="line line-go"
+                    :class="{
+                      'line-vertical': !isHorizontal,
+                      'line-go-vertical': !isHorizontal,
+                    }"
+                    :style="{
+                      visibility: item.lineGo ? 'visible' : 'hidden',
+                    }"
+                  />
+                  <div
+                    class="line line-back"
+                    :class="{
+                      'line-vertical': !isHorizontal,
+                      'line-back-vertical': !isHorizontal,
+                    }"
+                    :style="{
+                      visibility: item.lineBack ? 'visible' : 'hidden',
+                    }"
+                  />
+                </div>
+                <div
+                  v-if="item.sts === itemOperStatusCfg.xTrack"
+                  class="line-con"
+                  :class="{ 'z-idx-down-1': item.hasCarrier }"
+                >
+                  <template v-for="num in 4">
+                    <div
+                      :key="num"
+                      :class="[
+                        { 'line-xtrack': isHorizontal },
+                        { 'line-xtrack-vertical': !isHorizontal },
+                        'line-xtrack-' +
+                          (item.lineGo ? 'go-' : '') +
+                          item.lineType +
+                          '-' +
+                          num,
+                        'line-xtrack-' +
+                          (item.lineBack ? 'back-' : '') +
+                          item.lineType +
+                          '-' +
+                          num,
+                      ]"
+                      :style="{
+                        visibility:
+                          item.lineGo || item.lineBack ? 'visible' : 'hidden',
+                      }"
+                    />
+                  </template>
+                </div>
+                <!-- rail-2 -->
+                <div
+                  class="rail-base"
+                  :class="{ 'rail-base-vertical': !isHorizontal }"
+                />
+                <!--railBound-2  -->
+                <div
+                  class="rail-bound-base"
+                  :class="{ 'rail-bound-base-vertical': !isHorizontal }"
+                />
+              </template>
+              <template v-else>
+                <template v-if="isShowAniObj">
+                  <div
+                    class="goods-no-det"
+                    :style="{
+                      visibility: item.hasGoods ? 'visible' : 'hidden',
+                    }"
+                  />
+                  <div
+                    class="carrier-no-det"
+                    :style="{
+                      visibility: item.hasCarrier ? 'visible' : 'hidden',
+                    }"
+                  >
+                    <div
+                      class="goods-no-det-withc"
+                      :style="{
+                        visibility: item.carrierCatGoods ? 'visible' : 'hidden',
+                      }"
+                    />
+                  </div>
+                </template>
+              </template>
+            </div>
+          </el-tooltip>
+          <!-- 放在屏幕右边 -->
+          <!-- <div
+            v-if="!isShowRowColTip&&item.wColLast && item.r >= 0 && item.r < row"
+            class="indx-c indx-c-col-last"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-col-last-port': item.colLast }"
+          >
+            <span class="indx">{{ item.r + 1 }}</span>
+          </div> -->
+          <!-- 放在屏幕左边 -->
+          <div
+            v-if="
+              !isShowRowColTip && item.wColFirst && item.r >= 0 && item.r < row
+            "
+            class="indx-c indx-c-col-first"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-col-first-port': item.colFirst }"
+          >
+            <span class="indx">{{ item.r + 1 }}</span>
+          </div>
+          <!-- 放在屏幕下面 -->
+          <!-- <div
+            v-if="!isShowRowColTip&&item.wRowLast && item.c >= 0 && item.c < col"
+            class="indx-c indx-c-row-last"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-row-last-port': item.rowLast }"
+          >
+            <span class="indx">{{ item.c + 1 }}</span>
+          </div> -->
+          <!-- 放在屏幕上面 -->
+          <div
+            v-if="
+              !isShowRowColTip && item.wRowFirst && item.c >= 0 && item.c < col
+            "
+            class="indx-c indx-c-row-first"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-row-first-port': item.rowFirst }"
+          >
+            <span class="indx">{{ item.c + 1 }}</span>
+          </div>
+          <!-- port -->
+          <template
+            v-if="
+              isHorizontal && !item.typeWH && (item.rowFirst || item.rowLast)
+            "
+          >
+            <div
+              class="port-c z-idx-top-1"
+              :class="{
+                'port-c-h-start': item.rowFirst,
+                'port-c-h-end': item.rowLast,
+              }"
+              @click.stop="portItemClick(item)"
+            >
+              <i
+                v-if="item.rowFirst"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-paixu':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangshang': item.portType === 2,
+                  'icon-shuangxiangjiantou1': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+              <i
+                v-if="item.rowLast"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangshang':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-paixu': item.portType === 2,
+                  'icon-shuangxiangjiantou1': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+            </div>
+          </template>
+          <template
+            v-if="
+              !isHorizontal && !item.typeWH && (item.colFirst || item.colLast)
+            "
+          >
+            <div
+              class="port-c z-idx-top-1"
+              :class="{
+                'port-c-s-start': item.colFirst,
+                'port-c-s-end': item.colLast,
+              }"
+              @click.stop="portItemClick(item)"
+            >
+              <i
+                v-if="item.colFirst"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangyou':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangzuo': item.portType === 2,
+                  'icon-shuangxiangjiantou': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+              <i
+                v-if="item.colLast"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangzuo':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangyou': item.portType === 2,
+                  'icon-shuangxiangjiantou': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+            </div>
+          </template>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import grid from './mixin/grid'
+import carrier from './item/carrier.vue'
+export default {
+  components: { carrier },
+  mixins: [grid]
+}
+</script>
+<style lang="scss" scoped>
+@import "./scss/grid.scss";
+</style>

+ 404 - 0
src/components/grid/grid.vue

@@ -0,0 +1,404 @@
+<template>
+  <div v-loading="loading" class="grid-container" :style="gridSty">
+    <div v-if="wCol && wCol">
+      <div v-for="(rowData, r) in dataDoubleArr" :key="r" class="g-row">
+        <div
+          v-for="(item, c) in rowData"
+          :key="c"
+          class="item"
+          :class="{
+            'item-xTrack':
+              !item.typeWH && item.sts === itemOperStatusCfg.xTrack,
+            'item-transport': item.sts === itemOperStatusCfg.transport,
+            'item-unUse': !item.typeWH && item.sts === itemOperStatusCfg.unUse,
+            'item-park': !item.typeWH && item.sts === itemOperStatusCfg.park,
+            'item-charge': !item.typeWH && item.sts === itemOperStatusCfg.charge,
+            'item-lift': item.sts === itemOperStatusCfg.lift,
+            'item-standCol':
+              !item.typeWH && item.sts === itemOperStatusCfg.standCol,
+            'item-carriageway':
+              !item.typeWH && item.sts === itemOperStatusCfg.carriageway,
+            'ware-house-item': item.typeWH,
+          }"
+          :style="{
+            width: gridW,
+            height: gridH,
+            backgroundColor: getGlobalItemColor(item.sts, item.typeWH),
+          }"
+          :title="
+            !item.typeWH
+              ? (locProxy.indxOrientationRow ===
+                locProxyindxOrientationBottToTop
+                ? calculateReverseNumber(1, row, item.r + 1)
+                : item.r + 1) +
+                '行' +
+                (item.c + 1) +
+                '列'
+              : ''
+          "
+          @click="itemClick(item)"
+        >
+          <!-- <el-tooltip
+            effect="light"
+            :content="item.r + 1 + '行' + (item.c + 1) + '列'"
+            :disabled="!rowcolIndxFt"
+            class="rowcol-tip"
+            :open-delay="1000"
+          > -->
+          <div
+            v-if="!item.typeWH"
+            class="item-container"
+            :class="{
+              'cursor-oper':
+                itemOperStatus &&
+                itemOperStatus !== 'default' &&
+                itemOperStatus !== 'port' &&
+                !itemStausMap[item.key],
+              'item-container-vertical': !isHorizontal,
+              'dis-vis':
+                item.sts === itemOperStatusCfg.unUse ||
+                item.sts === itemOperStatusCfg.park ||
+                item.sts === itemOperStatusCfg.charge ||
+                item.sts === itemOperStatusCfg.xTrack ||
+                item.sts === itemOperStatusCfg.lift ||
+                item.sts === itemOperStatusCfg.transport ||
+                item.sts === itemOperStatusCfg.standCol ||
+                item.sts === itemOperStatusCfg.carriageway,
+              'no-det': notShowDet,
+            }"
+          >
+            <template v-if="!notShowDet">
+              <!--railBound-1  -->
+              <div
+                class="rail-bound-base"
+                :class="{ 'rail-bound-base-vertical': !isHorizontal }"
+                :style="{
+                  backgroundColor: getGlobalItemColor('rack', false),
+                }"
+              />
+              <!-- rail-1 -->
+              <div
+                class="rail-base"
+                :class="{ 'rail-base-vertical': !isHorizontal }"
+                :style="{
+                  backgroundColor: getGlobalItemColor('carriageway', false),
+                }"
+              />
+              <!-- itemInter -->
+              <div
+                class="item-inter-container"
+                :class="{
+                  'item-inter-container-vertical': !isHorizontal,
+                }"
+                :style="{
+                  backgroundColor: getGlobalItemColor('gridUnit', false),
+                }"
+              >
+                <template v-if="isShowAniObj">
+                  <div
+                    class="goods"
+                    :style="{
+                      visibility: item.hasGoods ? 'visible' : 'hidden',
+                      backgroundColor: getGlobalItemColor('goods', false),
+                    }"
+                  />
+                  <!-- visibility: item.hasCarrier ? 'visible' : 'hidden', -->
+                  <carrier
+                    :item="item"
+                    :is-horizontal="isHorizontal"
+                    :class="{ 'carrier-vertical': !isHorizontal }"
+                  />
+                </template>
+              </div>
+              <div
+                v-if="item.sts !== itemOperStatusCfg.xTrack"
+                class="line-con"
+                :class="{
+                  'line-con-vertical': !isHorizontal,
+                  'z-idx-down-1': item.hasCarrier,
+                }"
+              >
+                <div
+                  class="line line-go"
+                  :class="{
+                    'line-vertical': !isHorizontal,
+                    'line-go-vertical': !isHorizontal,
+                  }"
+                  :style="{
+                    visibility: item.lineGo ? 'visible' : 'hidden',
+                  }"
+                />
+                <div
+                  class="line line-back"
+                  :class="{
+                    'line-vertical': !isHorizontal,
+                    'line-back-vertical': !isHorizontal,
+                  }"
+                  :style="{
+                    visibility: item.lineBack ? 'visible' : 'hidden',
+                  }"
+                />
+              </div>
+              <div
+                v-if="item.sts === itemOperStatusCfg.xTrack"
+                class="line-con"
+                :class="{ 'z-idx-down-1': item.hasCarrier }"
+              >
+                <template v-for="num in 4">
+                  <div
+                    :key="num"
+                    :class="[
+                      { 'line-xtrack': isHorizontal },
+                      { 'line-xtrack-vertical': !isHorizontal },
+                      'line-xtrack-' +
+                        (item.lineGo ? 'go-' : '') +
+                        item.lineType +
+                        '-' +
+                        num,
+                      'line-xtrack-' +
+                        (item.lineBack ? 'back-' : '') +
+                        item.lineType +
+                        '-' +
+                        num,
+                    ]"
+                    :style="{
+                      visibility:
+                        item.lineGo || item.lineBack ? 'visible' : 'hidden',
+                    }"
+                  />
+                </template>
+              </div>
+              <!-- rail-2 -->
+              <div
+                class="rail-base"
+                :class="{ 'rail-base-vertical': !isHorizontal }"
+                :style="{
+                  backgroundColor: getGlobalItemColor('carriageway', false),
+                }"
+              />
+              <!--railBound-2  -->
+              <div
+                class="rail-bound-base"
+                :class="{ 'rail-bound-base-vertical': !isHorizontal }"
+                :style="{
+                  backgroundColor: getGlobalItemColor('rack', false),
+                }"
+              />
+            </template>
+            <template v-else>
+              <template v-if="isShowAniObj">
+                <div
+                  class="goods-no-det"
+                  :style="{
+                    visibility: item.hasGoods ? 'visible' : 'hidden',
+                  }"
+                />
+                <div
+                  class="carrier-no-det"
+                  :style="{
+                    visibility: item.hasCarrier ? 'visible' : 'hidden',
+                  }"
+                >
+                  <div
+                    class="goods-no-det-withc"
+                    :style="{
+                      visibility: item.carrierCatGoods ? 'visible' : 'hidden',
+                    }"
+                  />
+                </div>
+              </template>
+            </template>
+          </div>
+          <!-- </el-tooltip> -->
+          <!-- 序号放在屏幕右边 -->
+          <!-- <div
+            v-if="item.wColRightLast && item.r >= 0 && item.r < row"
+            class="indx-c indx-c-col-last"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-col-last-port': item.colLast }"
+          >
+            <span class="indx">{{ item.r + 1 }}</span>
+          </div> -->
+          <!-- 序号放在屏幕左边 -->
+          <div
+            v-if="item.wColFirst && item.r >= 0 && item.r < row"
+            class="indx-c indx-c-col-first z-idx-top-1"
+            :style="{
+              fontSize: portFontSize,
+              visibility: rowcolIndVis(item.r + 1),
+            }"
+            :class="{ 'indx-c-col-first-port': item.colFirst }"
+          >
+            <span class="indx">{{
+              locProxy.indxOrientationRow === locProxyindxOrientationBottToTop
+                ? calculateReverseNumber(1, row, item.r + 1)
+                : item.r + 1
+            }}</span>
+          </div>
+          <!-- 序号放在屏幕下面 -->
+          <!-- <div
+            v-if="item.wRowBottomLast && item.c >= 0 && item.c < col"
+            class="indx-c indx-c-row-last"
+            :style="{ fontSize: portFontSize }"
+            :class="{ 'indx-c-row-last-port': item.rowLast }"
+          >
+            <span class="indx">{{ item.c + 1 }}</span>
+          </div> -->
+          <!-- 序号放在屏幕上面 -->
+          <div
+            v-if="item.wRowFirst && item.c >= 0 && item.c < col"
+            class="indx-c indx-c-row-first z-idx-top-1"
+            :style="{
+              fontSize: portFontSize,
+              visibility: rowcolIndVis(item.c + 1),
+            }"
+            :class="{ 'indx-c-row-first-port': item.rowFirst }"
+          >
+            <span class="indx">{{ item.c + 1 }}</span>
+          </div>
+          <!-- port -->
+          <template
+            v-if="
+              isHorizontal &&
+                !item.typeWH &&
+                (item.rowFirst || item.rowLast) &&
+                itemOperStatus === itemOperStatusCfg.port
+            "
+          >
+            <div
+              class="port-c z-idx-top-1"
+              :class="{
+                'port-c-h-start': item.rowFirst,
+                'port-c-h-end': item.rowLast,
+              }"
+              @click.stop="portItemClick(item)"
+            >
+              <i
+                v-if="item.rowFirst"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-paixu':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangshang': item.portType === 2,
+                  'icon-shuangxiangjiantou1': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+              <i
+                v-if="item.rowLast"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangshang':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-paixu': item.portType === 2,
+                  'icon-shuangxiangjiantou1': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+            </div>
+          </template>
+          <template
+            v-if="
+              !isHorizontal &&
+                !item.typeWH &&
+                (item.colFirst || item.colLast) &&
+                itemOperStatus === itemOperStatusCfg.port
+            "
+          >
+            <div
+              class="port-c z-idx-top-1"
+              :class="{
+                'port-c-s-start': item.colFirst,
+                'port-c-s-end': item.colLast,
+              }"
+              @click.stop="portItemClick(item)"
+            >
+              <i
+                v-if="item.colFirst"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangyou':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangzuo': item.portType === 2,
+                  'icon-shuangxiangjiantou': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+              <i
+                v-if="item.colLast"
+                class="iconfont port"
+                :style="{ fontSize: portFontSize }"
+                :class="{
+                  'icon-xiangzuo':
+                    (item.portType === 0 &&
+                      itemOperStatus === itemOperStatusCfg.port) ||
+                    item.portType === 1,
+                  'icon-xiangyou': item.portType === 2,
+                  'icon-shuangxiangjiantou': item.portType === 3,
+                  'port-active': item.portType,
+                }"
+              />
+            </div>
+          </template>
+          <!-- 全局支架 -->
+          <template
+            v-if="
+              !item.typeWH &&
+                (item.rowFirst || item.rowLast || item.colFirst || item.colLast)
+            "
+          >
+            <div
+              v-if="item.rowFirst"
+              class="global-rack global-rack-top z-idx-top-1"
+              :style="{
+                backgroundColor: getGlobalItemColor('rack', false),
+              }"
+            />
+            <div
+              v-if="item.rowLast"
+              class="global-rack global-rack-bottom z-idx-top-1"
+              :style="{
+                backgroundColor: getGlobalItemColor('rack', false),
+              }"
+            />
+            <div
+              v-if="item.colFirst"
+              class="global-rack global-rack-left z-idx-top-1"
+              :style="{
+                backgroundColor: getGlobalItemColor('rack', false),
+              }"
+            />
+            <div
+              v-if="item.colLast"
+              class="global-rack global-rack-right z-idx-top-1"
+              :style="{
+                backgroundColor: getGlobalItemColor('rack', false),
+              }"
+            />
+          </template>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import grid from './mixin/grid'
+import carrier from './item/carrier.vue'
+export default {
+  components: { carrier },
+  mixins: [grid]
+}
+</script>
+<style lang="scss" scoped>
+@import "./scss/grid.scss";
+</style>

+ 114 - 0
src/components/grid/item/carrier.vue

@@ -0,0 +1,114 @@
+<template>
+  <div
+    class="carrier"
+    :style="{
+      visibility: item.hasCarrier ? 'visible' : 'hidden',
+    }"
+  >
+    <div
+      class="carrier-item"
+      :class="{ 'carrier-item-vertical': !isHorizontal }"
+    />
+    <div
+      class="carrier-main"
+      :class="{ 'carrier-main-vertical': !isHorizontal }"
+    >
+      <div
+        class="goods"
+        :style="{
+          visibility: item.carrierCatGoods ? 'visible' : 'hidden',
+        }"
+      />
+    </div>
+    <div
+      class="carrier-item"
+      :class="{ 'carrier-item-vertical': !isHorizontal }"
+    />
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    item: {
+      type: Object,
+      require: false,
+      default: () => { return {} }
+    },
+    baseInfo: {
+      type: Object,
+      require: true,
+      default: () => {}
+    },
+    isHorizontal: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      isShowGoods: false
+    }
+  },
+  methods: {
+    hasGoods() {
+      this.isShowGoods = true
+    },
+    noGoods() {
+      this.isShowGoods = false
+    },
+    setCarrierHere() {
+      this.display = true
+    },
+    removeCarrier() {
+      this.display = false
+      this.isShowGoods = false
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+@import "../scss/variables.scss";
+.carrier {
+  position: absolute;
+  width: calc(100% + #{$railW});
+  height: 100%;
+  display: flex;
+  // visibility: hidden;
+  background-color: $carrierColor;
+}
+.carrier-vertical {
+  flex-direction: column;
+  width: 100%;
+  height: calc(100% + #{$railW});
+}
+.carrier-main {
+  background-color: $carrierColor;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: calc(100% - #{$carrierBorderW}* 2);
+  height: 100%;
+  &-vertical {
+    width: 100%;
+    height: calc(100% - #{$carrierBorderW}* 2);
+  }
+  .goods {
+    position: absolute;
+    display: flex;
+    visibility: hidden;
+    background-color: $goodsColor;
+    width: $carrierGoodsW;
+    height: $carrierGoodsW;
+  }
+}
+.carrier-item {
+  width: $carrierBorderW;
+  height: $carrierBordeH;
+  background-color: $carrierItemColor;
+  &-vertical {
+    width: $carrierBordeH;
+    height: $carrierBorderW;
+  }
+}
+</style>

+ 352 - 0
src/components/grid/mixin/cfg.js

@@ -0,0 +1,352 @@
+export default {
+  animationActionMap: {
+    // end | track
+    horizontal: {
+      // -------------目的在上方 开始在下方 轨道在中间 start ----------------
+      '-,+|+|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '-,+|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '-,0|0|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '-,0|-|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,-|-|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '0,0|-|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+
+      '+,-|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '+,0|0|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,0|+|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '0,0|+|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '-,0|+|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,0|-|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '-,+|-|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,-|+|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      }
+      // -------------目的在上方 开始在下方 轨道在中间 start ----------------
+    },
+    // end | track
+    vertical: {
+      // -------------目的在上方 开始在下方 轨道在中间 start ----------------
+      '-,+|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '-,+|0|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '-,0|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '-,0|-|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '+,-|-|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '0,0|-|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+
+      '+,-|0|': {
+        r: function(num) {
+          return num + 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,0|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '+,0|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '0,0|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '-,0|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '+,0|-|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '0,+|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '0,+|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '0,+|-|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '0,-|0|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '0,-|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num - 1
+        }
+      },
+      '-,-|0|': {
+        r: function(num) {
+          return num - 1
+        },
+        c: function(num) {
+          return num
+        }
+      },
+      '+,-|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      },
+      '-,-|+|': {
+        r: function(num) {
+          return num
+        },
+        c: function(num) {
+          return num + 1
+        }
+      }
+      // -------------目的在上方 开始在下方 轨道在中间 start ----------------
+    },
+    // 值为田字格里面的样式  h s 1 2 3 4
+    xtrackLine: {
+      '-,0|0,+': '4',
+      '0,+|-,0': '1',
+      '+,0|+,0': 's',
+      '-,0|-,0': 's',
+      '0,+|+,0': '3',
+      '-,0|0,-': '3',
+      '0,-|-,0': '2'
+    },
+    numFlag: function(num) {
+      if (num > 0) {
+        return '+'
+      }
+      if (num < 0) {
+        return '-'
+      }
+      if (num === 0) {
+        return '0'
+      }
+    }
+  },
+  itemArr: [
+    'wareRackBound',
+    'rail',
+    'railRack',
+    'itemInter',
+    'railBound',
+    'goods',
+    'carrier',
+    'carrierItem',
+    'carrierMain',
+    'line'
+  ]
+  /**
+   * 一个单元格由如下组成
+   * 横向时横向组件
+   * wareRackBound(最边上才有)0.5%  根据实际情况,是否使用
+   * railBound 1%
+   * rail 1%
+   * itemInter 通过其他固定比例的数据计算出来
+   * rail 1%
+   * railBound 1%
+   * 横向时竖向组件
+   * palletSpe //当使用百分比作为 border-width 的单位时,结果可能不是整数像素值,这可能会导致在某些设备上出现模糊的边框效果。因此,在应用较细的边框时,建议使用像素或其他固定单位来确保边框的清晰度和一致性。
+   * palletSpe
+   * 线路组件
+   * line //使用固定像素
+   */
+  // gridLevelScaleMap: {
+  //   horizontal: {
+  //     railBoundW: '0.5%',
+  //     railBoundH: '100%',
+  //     railW: '1%',
+  //     railH: '100%',
+  //     itemInterW: '98%',
+  //     itemInterH: '100%',
+  //     wareRackBoundW: '0.5%',
+  //     wareRackBoundH: '100%',
+  //     lineW: '2px',
+  //     lineH: '100%',
+  //     palletSpeW: '1px',
+  //     palletSpeH: '1px'
+  //   }
+  // }
+}

+ 2456 - 0
src/components/grid/mixin/grid.js

@@ -0,0 +1,2456 @@
+import {
+  OrientationRacking,
+  OperType,
+  AnimationCfg,
+  OrientationRackingMap,
+  ItemMeasure,
+  ItemOperStatus,
+  ColorMap,
+  WareHouseSpace
+} from '@/global-cfg/global'
+import scss from '../scss/variables.scss'
+import cfg from './cfg'
+const idSep = '-'
+const cellStsMap = { 0: false, 1: true }
+/**
+ * 20230625 id目前使用支架r c
+ * **********待后台上发数据确认后,考虑使用配置策略************
+ * 策略包含
+ * 1-使用仓库wR wC 还是支架r c[在提交和获取后台数据时处理]
+ * 2-r c 坐标起点
+ * 3- r c 方向
+ * 关注 页面的数据哪些地方需要使用
+ * *************待处理
+ * 20230629 前后左右区相对屏幕的确认
+ */
+const locProxyIndxScopeWareHouse = 'Ware' // 以仓库整体坐标交互
+const locProxyindxOrientationBottToTop = 'BottomToTop' // 横向行的方向,从下到上
+const locProxyIndxScopeRack = 'Rack' // 以支架整体坐标交互
+// const locProxyindxOrientationTopToBottom = 'TopToBottom' // 横向行的方向,从上到下
+const locProxy = {
+  indxScope: locProxyIndxScopeWareHouse, // 使用仓库坐标还是支架坐标
+  indxFrom: 1, // 下标(包括行列)从几开 indxFrom: 0
+  indxOrientationRow: locProxyindxOrientationBottToTop // 行的方向 indxOrientationRow: 0 1屏幕从下到上 0 屏幕从上到下
+}
+const liftGenProxy = {
+  PROXY_SINGLE: 'single',
+  PROXY_SIX: 'six',
+  getProxy: function() {
+    // proxy:'single',//占1个位置  proxy:'single',//占6个位置
+    return this.PROXY_SINGLE
+  }
+}
+export default {
+  data() {
+    return {
+      locProxy: locProxy,
+      locProxyindxOrientationBottToTop: locProxyindxOrientationBottToTop,
+      shuttleMapPre: null, // 缓存各车辆上一个位置信息。在再次上发消息时,需要清空上一个状态
+      wsInfoData: null, // { cells: {}, shuttle: {}, left: {}, conveyor: {}} 根据此上发数据,cells数据会放到wsStsDataCells单独管理
+      wsStsDataCells: null,
+      whPath: null,
+      whCarriers: [],
+      whStores: [],
+      // aniLineMap: null,
+      warehouseId: null,
+      websocket: null,
+      rowcolIndxFt: 0,
+      showDet: false,
+      scaleM: null,
+      loading: false,
+      cfg: cfg,
+      scss: scss,
+      floor: 1,
+      itemOperStatusCfg: ItemOperStatus,
+      dataDoubleArr: [],
+      unUses: [], // 存储配置时点击数据 { r: 3, c: 1, is: true }
+      xTracks: [], // 存储配置时点击数据 平行于支架行,按轴向从1开始数量 //{id:,is:,r:,c:}
+      lifts: [], // 存储配置时点击数据 托盘按正轴向数量,行车道正轴向数量 {id: ,r:,c:,is: ,type:'11'(11,12,13,21,22,23)}
+      ports: [], // 存储配置时点击数据 存储配置时点击数据 {portType:''(0未设置1入口2出口),pos:'bottom'(bottom,top,left,right)}
+      transports: [], // 存储配置时点击数据 { r: 3, c: 1, is: true }
+      standCols: [], // 存储配置时点击数据
+      carriageways: [], // 存储配置时点击数据
+      parks: [], // 存储配置时点击数据
+      charges: [], // 存储配置时点击数据
+      itemStausMap: null,
+      itemStausStore: null,
+      itemOperStatus: '',
+      goodsDisArr: [],
+      lineShowArr: [],
+      animationMap: null,
+      carrierAnimationInfo: { start: null, end: null, next: null },
+      carrierTask: [],
+      animationTimer: null,
+      row: 0,
+      col: 0,
+      orientationRacking: OrientationRacking.HORIZONTAL,
+      front: WareHouseSpace.front, // 屏幕的上面,在行数的方向不同时需要关注
+      right: WareHouseSpace.right,
+      left: WareHouseSpace.left,
+      back: WareHouseSpace.back, // 屏幕的下面,在行数的方向不同时需要关注
+      wRow: 0, // 全局row
+      wCol: 0, // 全局col
+      gridW: '',
+      gridH: '',
+      portFontSize: ''
+    }
+  },
+  computed: {
+    // 计算 货位 和仓库格子颜色
+    getGlobalItemColor() {
+      return (itemSts, typeWH) => {
+        // 仓库颜色
+        if (typeWH && itemSts === ItemOperStatus.default) {
+          return this.scss.wareBgCo
+        }
+        if (ColorMap[itemSts] && itemSts !== ItemOperStatus.default) {
+          return this.scss[ColorMap[itemSts]]
+        }
+        if (!typeWH && itemSts === ItemOperStatus.default) {
+          return this.scss.gridUnit
+        }
+      }
+    },
+    railWidth() {
+      return ItemMeasure.scaleFormat(true, 'rail', 'width', false, this.scaleM)
+    },
+    isHorizontal() {
+      return this.orientationRacking === OrientationRacking.HORIZONTAL
+    },
+    idKey() {
+      return (r, c, type) => {
+        return r + idSep + c + idSep + this.floor + (type || '')
+      }
+    },
+    getRCFromKey() {
+      return (key) => {
+        const arr = key.split(idSep)
+        if (!arr || arr.length !== 3) {
+          return
+        }
+        const newArr = []
+        arr.forEach((numStr) => {
+          newArr.push(Number(numStr))
+        })
+        return newArr
+      }
+    },
+    trackIdKey() {
+      return (r, c, type) => {
+        return this.isHorizontal ? this.idKey(r, '') : this.idKey('', c)
+      }
+    },
+    gridSty() {
+      const styles = {}
+      if (!this.carrierRoadNum || !this.palletNum) {
+        styles.border = 'none'
+      }
+      return styles
+    },
+    isShowAniObj() {
+      return this.operType === OperType.animation
+    },
+    rowcolIndVis(num) {
+      return (num) => {
+        if (this.rowcolIndxFt < 5 && this.rowcolIndxFt !== 0) {
+          return num % 4 === 0 ? 'visible' : 'hidden'
+        }
+        if (this.rowcolIndxFt < 10 && this.rowcolIndxFt !== 0) {
+          return num % 2 === 0 ? 'visible' : 'hidden'
+        }
+        return 'visible'
+      }
+    }
+  },
+  props: {
+    operType: {
+      type: String,
+      default: OperType.default
+    },
+    palletWidth: {
+      type: Number,
+      require: false,
+      default: ItemMeasure.pallet.width
+    },
+    palletLen: {
+      type: Number,
+      require: false,
+      default: ItemMeasure.pallet.length
+    },
+    space: {
+      type: Number,
+      require: false,
+      default: ItemMeasure.space.length
+    }
+  },
+  mounted() {},
+  beforeDestroy() {
+    // 关闭 WebSocket 连接
+    if (this.websocket) {
+      this.websocket.close()
+    }
+  },
+  methods: {
+    // dataDoubleArr
+    getWRByR(r) {
+      if (r === undefined) {
+        return
+      }
+      return r + this.front
+    },
+    getWCByC(c) {
+      if (c === undefined) {
+        return
+      }
+      return c + this.left
+    },
+    calculateReverseNumber(startNum, row, idx) {
+      const reverseNumber = 2 * startNum + row - 1 - idx
+      return reverseNumber
+    },
+    /**
+     * 页面下标转业务下标
+     * 1-使用仓库坐标
+     * 2-下标从1开始
+     * 3-行从下至上
+     * 2023关注不维护wR wC,直接由 r c计算
+     * @param {*} item
+     * @returns
+     */
+    pageIdxToBusiIndx(item) {
+      if (!item || item.r === undefined || item.wR === undefined) {
+        return
+      }
+      // 行列序号是否需要处理增加或减少
+      if (locProxy.indxFrom) {
+        item.r = item.r + locProxy.indxFrom
+        item.c = item.c + locProxy.indxFrom
+      }
+      // 行序号在方向与页面序号不一致时处理
+      if (locProxy.indxOrientationRow === locProxyindxOrientationBottToTop) {
+        item.r = this.calculateReverseNumber(
+          locProxy.indxFrom,
+          this.row,
+          item.r
+        )
+      }
+      // 默认使用支架,使用仓库时需要转换
+      if (locProxy.indxScope === locProxyIndxScopeWareHouse) {
+        item.r = this.getWRByR(item.r)
+        item.c = this.getWCByC(item.c)
+      }
+      item.idKey = this.idKey(item.r, item.c)
+    },
+    /**
+     * 业务下标转页面下标(全部由r,c转换获取)
+     * 一般为后台上传数据时
+     * 1-使用仓库坐标
+     * 2-下标从1开始
+     * 3-行从下至上
+     * @param {*} item
+     * @returns
+     */
+    busiIndxToPageIdx(itemBusi, indxScopeCum) {
+      if (itemBusi.r === undefined) {
+        return
+      }
+      const indxScope = indxScopeCum || this.locProxy.indxScope
+      // 行序号在方向与页面序号不一致时处理
+      if (locProxy.indxOrientationRow === locProxyindxOrientationBottToTop) {
+        itemBusi.r = this.calculateReverseNumber(
+          locProxy.indxFrom,
+          indxScope === locProxyIndxScopeWareHouse ? this.wRow : this.row,
+          itemBusi.r // 使用支架时,这个为支架r,使用仓库时,这个为仓库r
+        )
+      }
+      // 行列序号是否需要处理增加或减少
+      if (locProxy.indxFrom) {
+        itemBusi.r = itemBusi.r - locProxy.indxFrom
+        itemBusi.c = itemBusi.c - locProxy.indxFrom
+      }
+      // 默认使用支架,使用仓库时需要转换,此时的itemBusi.r为仓库r
+      if (indxScope === locProxyIndxScopeWareHouse) {
+        itemBusi.rackR = itemBusi.r - this.front
+        itemBusi.rackC = itemBusi.c - this.left
+        itemBusi.r = itemBusi.rackR
+        itemBusi.c = itemBusi.rackC
+      }
+      return itemBusi
+    },
+    // 初始化货位所有状态为无货
+    floorCellsStsInitDis(floor) {
+      if (!this.dataDoubleArr || this.dataDoubleArr.length < 1) {
+        return
+      }
+      for (let i = 0; i < this.row; i++) {
+        for (let j = 0; j < this.col; j++) {
+          this.goodsHid(i, j)
+        }
+      }
+    },
+    // 初始化货位所有状态为指定状态
+    cellsStsInit(cells, floor) {
+      if (!cells || !this.dataDoubleArr || this.dataDoubleArr.length < 1) {
+        return
+      }
+      const procFlr = this.getProcFloor(floor, this.floor)
+      const index = procFlr - 1
+      const cellsSts = cells[index]
+      if (!cellsSts) {
+        return
+      }
+      const rows = Object.keys(cellsSts)
+      if (!rows || rows.length < 1) {
+        return
+      }
+      // 以后台返回数据为基准循环处理
+      rows.forEach((rowKey) => {
+        const dataArr = cellsSts[rowKey]
+        const rowNum = Number(rowKey)
+        for (let c = 0; c < dataArr.length; c++) {
+          // const rowInde = this.isHorizontal ? rowNum : c
+          // const colInde = this.isHorizontal ? c : rowNum
+          // const item = this.getItem(rowInde, colInde)
+          // const goodsSts = dataArr[c]
+          // item.hasGoods = cellStsMap[goodsSts]
+          this.setGoodsSts(rowNum, c, cellStsMap[dataArr[c]])
+        }
+      })
+    },
+    getProcFloor(flr1, flr2) {
+      if (flr1 !== undefined) {
+        return flr1
+      }
+      return flr2
+    },
+    /**
+     * 跟新缓存全量数据wsStsDataCells
+     * 跟新货位状态
+     * 20230617仅在数据上发时使用
+     * @param {*} cells
+     * @returns
+     */
+    cellsStsUpdate(cells) {
+      const cellKeys = Object.keys(cells)
+      if (
+        !cellKeys ||
+        cellKeys.length < 1 ||
+        !this.dataDoubleArr ||
+        this.dataDoubleArr.length < 1
+      ) {
+        return
+      }
+      for (let i = 0; i < cellKeys.length; i++) {
+        const key = cellKeys[i]
+        const [r, c, f] = this.getRCFromKey(key)
+        // 后台首次没有返回全量数据时,需要前台重新插入
+        if (!this.wsStsDataCells[f]) {
+          this.wsStsDataCells[f] = {}
+        }
+        if (!this.wsStsDataCells[f][r]) {
+          this.wsStsDataCells[f][r] = []
+        }
+        // 回填的时候,需要回填原始数据cells[key]
+        this.wsStsDataCells[f][r][c] = cells[key]
+        if (f !== this.floor) {
+          continue
+        }
+        // const finalR = this.isHorizontal ? r : c
+        // const finalC = this.isHorizontal ? c : r
+        // const item = this.getItem(finalR, finalC)
+        // 改变视图状态
+        // item.hasGoods = cellStsMap[cells[key]]
+        // 改变视图状态
+        this.setGoodsSts(r, c, cellStsMap[cells[key]])
+        // 缓存数据
+        // console.log(this.wsStsDataCells)
+        // console.log(r + '---' + c)
+      }
+      // cellKeys.forEach((key) => {
+
+      // })
+    },
+    /**
+     *初始化车辆颜色等基础信息
+     * @param {*} shuttleData 结构{sn1:{},sn2:{},sn3:{},}
+     */
+    shuttleInfoInit(shuttleData) {
+      const shuttleIds = Object.keys(shuttleData)
+      shuttleIds.forEach((key) => {
+        const data = shuttleData[key]
+        // this.clearShuttle(data, key)
+        const shuttle = this.showShuttle(data, key)
+        this.storeShuttle(shuttle, key)
+      })
+    },
+    // 1-是否存在上一辆车,则清除上一个状态。2-展示当前视图(当前层) 3-存储当前视图
+    // 视图缓存数据结构,参考WS上发时update时结构,新增对应的视图数据
+    shuttleStsUpdate(shuttleData) {
+      const shuttleIds = Object.keys(shuttleData)
+      shuttleIds.forEach((key) => {
+        const data = shuttleData[key]
+        this.clearShuttle(data, key)
+        const shuttle = this.showShuttle(data, key)
+        this.storeShuttle(shuttle, key)
+      })
+    },
+    /**
+     * 在切换楼层,将缓存在内存中的数据重新展示
+     * 不需要清除前一个与存储当前,仅再次渲染视图
+     * 在init时同步处理了
+     * @param {*} shuttleData
+
+    floorShuttleStsRefresh(shuttleData, floor) {
+      const data = shuttleData || this.shuttleMapPre
+      const shuttleIds = Object.keys(data)
+      shuttleIds.forEach((key) => {
+        this.showShuttle(data[key], key, floor)
+      })
+    },*/
+    /**
+     * 清除上一个车辆状态(车辆位置、车辆任务路线)
+     * @param {*} shuttleData
+     */
+    clearShuttle(shuttleData, shuttleKey) {
+      if (
+        this.shuttleMapPre &&
+        this.shuttleMapPre[shuttleKey] &&
+        this.shuttleMapPre[shuttleKey].viewData
+      ) {
+        this.carrierHid(null, null, this.shuttleMapPre[shuttleKey].viewData)
+      }
+      // 当前上发路线,跟上一条路线不一致时,清除上一条
+      if (
+        this.shuttleMapPre &&
+        this.shuttleMapPre[shuttleKey] &&
+        this.shuttleMapPre[shuttleKey].viewRouterDataArr &&
+        JSON.stringify(shuttleData.router) !==
+          this.shuttleMapPre[shuttleKey].viewRouterDataArrStr
+      ) {
+        const procArr = this.shuttleMapPre[shuttleKey].viewRouterDataArr
+        this.clearShuttleRouter(procArr)
+      }
+    },
+    /**
+     * 清除上一个路线
+     */
+    clearShuttleRouter(procArr, shuttleKey) {
+      for (let i = 0; i < procArr.length; i++) {
+        const pathItem = procArr[i]
+        this.lineHid(
+          null,
+          null,
+          AnimationCfg.routeType.go,
+          this.getLineType(pathItem, procArr[i - 1], procArr[i + 1]),
+          pathItem
+        )
+      }
+    },
+    /**
+     * 展示车辆视图信息[车辆、路线]。20230616目前只展示位置、是否托着货,其他TODOMM
+     * @param {*} shuttleData
+     * @param {*} shuttleKey
+     */
+    showShuttle(shuttleData, shuttleKey, floor) {
+      if (!shuttleData.addr) {
+        return
+      }
+      const retData = JSON.parse(JSON.stringify(shuttleData))
+      const arr = this.getRCFromKey(shuttleData.addr)
+      let r = arr[0]
+      let c = arr[1]
+      const f = arr[2]
+      // 测试20230922
+      // f = f - 1
+      // r = r - 16
+      // c = c - 34
+      const compuItem = this.busiIndxToPageIdx(
+        { r: r, c: c },
+        locProxyIndxScopeRack
+      )
+      r = compuItem.r
+      c = compuItem.c
+      console.log('R:' + r + 'C:' + c)
+      const procFlr = this.getProcFloor(floor, this.floor)
+      // 渲染当前层视图
+      // 不在本楼层也要缓存数据
+      retData['floorRealTime'] = f
+      if (procFlr !== f) {
+        return retData
+      }
+      // 车辆位置及是否有货
+      const item = this.setCarrierHere(r, c)
+      this.setCarrierCatGoodSts(r, c, shuttleData.load, item)
+      retData['viewData'] = item
+      // 车辆线路(跟当前显示路线不一致时,需要重新渲染)
+      // 上发数据结构['r-c-f']
+      if (
+        shuttleData.router &&
+        (!this.shuttleMapPre ||
+          JSON.stringify(shuttleData.router) !==
+            this.shuttleMapPre[shuttleKey].viewRouterDataArrStr)
+      ) {
+        const procArr = shuttleData.router
+        const routerShowArr = []
+        for (let i = 0; i < procArr.length; i++) {
+          const [r, c, f] = this.getRCFromKey(procArr[i])
+          const item = this.getItem(r, c)
+          routerShowArr.push(item)
+          if (procFlr !== f) {
+            continue
+          }
+          let preItem
+          if (procArr[i - 1]) {
+            const [preR, preC] = this.getRCFromKey(procArr[i - 1])
+            preItem = this.getItem(preR, preC)
+          }
+          let posItem
+          if (procArr[i + 1]) {
+            const [posR, posC] = this.getRCFromKey(procArr[i + 1])
+            posItem = this.getItem(posR, posC)
+          }
+          this.lineShow(
+            r,
+            c,
+            AnimationCfg.routeType.go,
+            this.getLineType(item, preItem, posItem)
+          )
+        }
+        retData.viewRouterDataArr = routerShowArr
+        retData.viewRouterDataArrStr = JSON.stringify(routerShowArr)
+      }
+      return retData
+    },
+    storeShuttle(shuttleData, shuttleKey) {
+      if (!this.shuttleMapPre) {
+        this.shuttleMapPre = {}
+      }
+      this.shuttleMapPre[shuttleKey] = shuttleData
+    },
+    /**
+     * 楼层初始化时,或切换楼层时,置空/初始化所有关联数据,重新加载所有关联数据
+     * cells,shuttle
+     */
+    floorDataInit(floor) {
+      this.floorCellsStsInitDis(floor)
+      this.cellsStsInit(this.wsStsDataCells, floor)
+      this.floorShuttleInit(floor)
+    },
+    /**
+     * 楼层初始化时,或切换楼层时,重新加载所有关联数据
+     * cells[重新初始化],shuttle[重新渲染缓存在本楼层的车辆]
+
+    floorDataRefresh(floor) {
+      this.cellsStsInit(this.wsStsDataCells, floor)
+      this.floorShuttleStsRefresh(floor)
+    },*/
+    /**
+     * 楼层初始化时/切换楼层时,车辆数据展示
+     */
+    floorShuttleInit(floor) {
+      if (!this.shuttleMapPre) {
+        return
+      }
+      const procFlr = this.getProcFloor(floor, this.floor)
+      const keys = Object.keys(this.shuttleMapPre)
+      keys.forEach((key) => {
+        if (
+          this.shuttleMapPre[key] &&
+          this.shuttleMapPre[key].floorRealTime === procFlr
+        ) {
+          // 只要在页面上展示了就要存起来
+          const shuttle = this.showShuttle(
+            this.shuttleMapPre[key],
+            key,
+            procFlr
+          )
+          this.storeShuttle(shuttle, key)
+        }
+        // 非本层数据展示时,设置为不展示
+        if (
+          this.shuttleMapPre[key] &&
+          this.shuttleMapPre[key].floorRealTime !== procFlr &&
+          this.shuttleMapPre[key].viewData &&
+          this.shuttleMapPre[key].viewData.hasCarrier
+        ) {
+          this.carrierHid(null, null, this.shuttleMapPre[key].viewData)
+        }
+        // 非本层数据展示时,设置为不展示
+        if (
+          this.shuttleMapPre[key] &&
+          this.shuttleMapPre[key].floorRealTime !== procFlr &&
+          this.shuttleMapPre[key].viewRouterDataArr
+        ) {
+          const procArr = this.shuttleMapPre[key].viewRouterDataArr
+          this.clearShuttleRouter(procArr)
+        }
+      })
+    },
+    socketCre() {
+      if (this.operType === 'animation' && !this.websocket) {
+        const hostName = window.location.hostname
+        // 创建WebSocket对象
+        this.websocket = new WebSocket('wss://' + hostName + ':443/ws')
+        // this.websocket = new WebSocket('wss://123.60.57.251/ws')
+
+        // 监听WebSocket事件
+        this.websocket.onopen = () => {
+          console.log('WebSocket已连接')
+        }
+
+        this.websocket.onmessage = (event) => {
+          console.log('收到消息:', event.data)
+          this.mesDo(event.data)
+        }
+
+        this.websocket.onclose = () => {
+          console.log('WebSocket已关闭')
+        }
+
+        this.websocket.onerror = (error) => {
+          console.log('WebSocket发生错误:', error)
+        }
+      }
+    },
+    mesDo(wsData) {
+      const resData = JSON.parse(wsData)
+      // 测试
+      // let resData = JSON.parse(wsData)
+      // resData = {
+      //   'action': 'init',
+      //   'data': {
+      //     'lift': {},
+      //     'shuttle': {
+      //       '2023092017474900': {
+      //         'addr': '21-35-2',
+      //         'battery': 89,
+      //         'error': {},
+      //         'floor': 2,
+      //         'load': false,
+      //         'lock': false,
+      //         'status': 'Unavailable',
+      //         'tid': '141'
+      //       }
+      //     }
+      //   }
+      // }
+      const { data, action } = resData
+      // 上发cells  shuttle left conveyor等设备新
+      // 缓存数据
+      // 并初始化设备信息(颜色等TODO)
+      if (action === 'init') {
+        this.floorDataInit()
+        this.wsInfoData = data
+        // 初始化时,货位信息的状态
+        if (data && data.cells) {
+          this.wsStsDataCells = data.cells
+          this.cellsStsInit(data.cells)
+        }
+        // 设置车辆的基础数据到视图数据中
+        if (data && data.shuttle) {
+          this.shuttleInfoInit(data.shuttle)
+        }
+      }
+      // 跟新cells  shuttle left conveyor等设备状态
+      if (action === 'update') {
+        if (data.cells) {
+          this.cellsStsUpdate(data.cells)
+        }
+        if (data.shuttle) {
+          this.shuttleStsUpdate(data.shuttle)
+        }
+      }
+    },
+    /**
+     *20230615以前解析逻辑
+     * @param {*} data
+     */
+    mesDoBefore(data) {
+      const resData = JSON.parse(data)
+      const { type, action } = resData
+      // if (type === 'carrier') {
+      //   this.refreshCarrier(resData, action)
+      //   this.cacheCarrier(resData, action)
+      // }
+      // if (type === 'store') {
+      //   this.refreshStore(resData, action)
+      //   this.cacheStore(resData, action)
+      // }
+      if (type === 'path') {
+        this.refreshPath(resData, action)
+        this.cachePath(resData, action)
+      }
+    },
+    refreshPath(resData, action) {
+      this.lineShowArrInit()
+      if (!resData || !resData.content) {
+        return
+      }
+      const info = resData.content && resData.content.path //
+      if (!info || info.length < 1) {
+        return
+      }
+      for (let i = 0; i < info.length; i++) {
+        const ele = info[i]
+        const { f, r, c } = ele
+        if (this.floor === f) {
+          // const routeType = AnimationCfg.routeType.go
+          // let routeType = AnimationCfg.routeType.go
+          // if (action === 'end') {
+          //   routeType = AnimationCfg.routeType.back
+          // }
+          if (action === 'start') {
+            this.lineShow(
+              r,
+              c,
+              AnimationCfg.routeType.go,
+              this.getLineType(info[i], info[i - 1], info[i + 1])
+            )
+          }
+        }
+      }
+    },
+    cachePath(resData, action) {
+      if (!resData || !resData.content) {
+        return
+      }
+      const pathArr = resData.content.path
+      if (!pathArr || pathArr.length < 1) {
+        return
+      }
+      let isHas = false
+      this.objInit(this.whPath)
+      const flr = pathArr[0].f
+      Object.keys(this.whPath).forEach((ele) => {
+        if (ele === flr) {
+          if (action === 'start') {
+            isHas = true
+            this.whPath[ele] = resData.content
+          }
+          if (action === 'end') {
+            this.whPath[ele] = null
+          }
+        }
+      })
+      if (!isHas && action === 'start') {
+        this.whPath[flr] = resData.content
+      }
+    },
+    objInit(whPath) {
+      if (whPath) {
+        return
+      }
+      this.whPath = {}
+    },
+    // refreshStore(resData, action) {
+    //   if (!resData || !resData.content) {
+    //     return
+    //   }
+    //   const info = resData.content
+    //   const [f, r, c] = info.pos
+    //   if (f === this.floor) {
+    //     const item = this.getItem(r, c)
+    //     item.hasGoods = info.hasPallet
+    //   }
+    // },
+    // cacheStore(resData, action) {
+    //   if (!resData || !resData.content) {
+    //     return
+    //   }
+    //   const info = resData.content
+    //   const [f, r, c] = info.pos
+    //   const whS = this.whStores && this.whStores[f]
+    //   if (whS) {
+    //     whS[r][c] = info.hasPallet
+    //   }
+    // },
+    // refreshCarrier(resData, action) {
+    //   if (!resData || !resData.content) {
+    //     return
+    //   }
+    //   const info = resData.content
+    //   // this.floorChg(info)
+    //   this.carrierParamInit(info, action)
+    // },
+    // cacheCarrier(resData, action) {
+    //   if (!resData || !resData.content) {
+    //     return
+    //   }
+    //   const info = resData.content
+    //   let isHas = false
+    //   for (let i = 0; i < this.whCarriers.length; i++) {
+    //     const itemWh = this.whCarriers[i]
+    //     if (itemWh.id === info.id) {
+    //       isHas = true
+    //       this.whCarriers[i] = info
+    //     }
+    //   }
+    //   if (!isHas) {
+    //     this.whCarriers.push(info)
+    //   }
+    // },
+    floorChg(info) {
+      if (!info || !info.pos) {
+        return
+      }
+      if (info.pos.f === this.floor) {
+        return
+      }
+      if (this.warehouseId === null) {
+        return
+      }
+      this.floor = info.pos.f
+      this.$emit('flr-chg', this.floor)
+      this.storesInit(this.whStores[this.floor ? this.floor : 1])
+      this.carriersInit(this.whCarriers)
+      // this.storesShowAsync(this.warehouseId)
+      // this.carriersShowAsync(this.warehouseId)
+    },
+    /**
+    floorInit() {
+      this.storesInit(this.whStores[this.floor ? this.floor : 0])
+      this.carriersInit(this.whCarriers)
+      this.pathInit(this.whPath)
+      // this.storesShowAsync(this.warehouseId)
+      // this.carriersShowAsync(this.warehouseId)
+    }, */
+    storesShow(warehouseId) {
+      this.getStores(warehouseId).then((res) => {
+        const resData = res.data
+        if (resData && resData.length > 0) {
+          // 全部缓存起来
+          this.whStores = resData
+          this.storesInit(this.whStores[this.floor ? this.floor : 1])
+          // this.storesInit(resData[this.floor ? this.floor : 0])
+        } else {
+          this.whStores = []
+        }
+      })
+    },
+    async storesShowAsync(warehouseId) {
+      const res = await this.getStores(warehouseId)
+      const resData = res.data
+      if (resData && resData.length > 0) {
+        this.storesInit(resData[this.floor ? this.floor : 1])
+      }
+    },
+    getStores(warehouseId) {
+      return this.$req({
+        url: '/warehouse/stores',
+        method: 'get',
+        params: {
+          warehouseId: warehouseId
+        }
+      })
+    },
+    carriersShow(warehouseId) {
+      this.getCarriers(warehouseId).then((res) => {
+        const resData = res.data
+        if (resData && resData.length > 0) {
+          // this.carriersInit(resData)
+          // 全部缓存起来
+          this.whCarriers = resData
+          this.carriersInit(this.whCarriers)
+        } else {
+          this.whCarriers = []
+        }
+      })
+    },
+    async carriersShowAsync(warehouseId) {
+      const res = await this.getCarriers(warehouseId)
+      const resData = res.data
+      if (resData && resData.length > 0) {
+        this.carriersInit(resData)
+      }
+    },
+    getCarriers(warehouseId) {
+      return this.$req({
+        url: '/shuttle/carriers',
+        method: 'get',
+        params: {
+          warehouseId: warehouseId
+        }
+      })
+    },
+    initData(cfgForm, itemData) {
+      this.notShowDet = cfgForm.notShowDet
+      this.orientationRacking = cfgForm.forward
+      this.row = cfgForm.row
+      this.col = cfgForm.column
+      this.front = cfgForm.front
+      this.right = cfgForm.right
+      this.left = cfgForm.left
+      this.back = cfgForm.back
+      this.wRow = this.getRowEndNum('ware')
+      this.wCol = this.getColEndNum('ware')
+      this.gridW = cfgForm.finalWidtPer + 'px'
+      this.gridH = cfgForm.finalHeightPer + 'px'
+      const ft = this.isHorizontal
+        ? (cfgForm.finalWidtPer ? cfgForm.finalWidtPer : 0) / 3
+        : (cfgForm.finalHeightPer ? cfgForm.finalHeightPer : 0) / 3
+      console.log(ft)
+      if (ft < 7) {
+        this.rowcolIndxFt = ft
+      } else {
+        this.rowcolIndxFt = 0
+      }
+      this.portFontSize = ft + 'px'
+      // 需要考证是否需要使用以下代码 0420
+      // const width = cfgForm.finalWidtPer + 'px'
+      // const length = cfgForm.finalHeightPer + 'px'
+      // this.gridW = this.isHorizontal ? width : length
+      // this.gridH = this.isHorizontal ? length : width
+      this.dataDoubleArr.length = 0
+      for (let i = 0; i < this.wRow; i++) {
+        const rowData = []
+        const rowFirst = i === this.front
+        const rowLast = i === this.front + this.row - 1
+        const rowPre1 = i === this.front - 1
+        const rowPos1 = i === this.front + this.row
+        const rowWare = i < this.front || i > this.front + this.row - 1
+        const wRowFirst = i === 0
+        const wRowLast = i === this.front + this.row + this.back - 1
+        // const intersectionBetWareRackRow = i >= this.front && i < this.front + this.row// 行方向,仓库和直接序号相交
+        for (let j = 0; j < this.wCol; j++) {
+          // const intersectionBetWareRackCol = j >= this.left && j < this.left + this.col// 列方向,仓库和直接序号相交
+          const colFirst = j === this.left
+          const colLast = j === this.left + this.col - 1
+          const wColFirst = j === 0
+          const wColLast = j === this.left + this.col + this.right - 1
+          const colPre1 = j === this.left - 1
+          const colPos1 = j === this.left + this.col
+          const colWare = j < this.left || j > this.left + this.col - 1
+          const wRKey = this.idKey(i, j)
+          const key = this.idKey(i - this.front, j - this.left)
+          // 是否是仓库对象
+          const isWareItem = rowWare || colWare
+          // 暂时不需要位置,根据r,c,横纵向等就能判断20230422
+          // let portPos = ''
+          // if (rowFirst && this.isHorizontal && !isWareItem) {
+          //   portPos = 'top'
+          // }
+          // if (rowLast && this.isHorizontal && !isWareItem) {
+          //   portPos = 'bottom'
+          // }
+          // if (colFirst && !this.isHorizontal && !isWareItem) {
+          //   portPos = 'left'
+          // }
+          // if (colLast && !this.isHorizontal && !isWareItem) {
+          //   portPos = 'right'
+          // }
+          rowData.push({
+            typeWH: isWareItem,
+            rowPre1,
+            rowPos1,
+            colPre1,
+            colPos1,
+            wRKey: wRKey,
+            wR: i,
+            wC: j,
+            key,
+            r: i - this.front,
+            c: j - this.left,
+            sts: ItemOperStatus.default,
+            rowFirst,
+            rowLast,
+            colFirst,
+            colLast,
+            wRowFirst,
+            wRowLast,
+            wColFirst,
+            wColLast,
+            // 20230621未使用到,注解起来(全局外支架,使用跟port一个样式实现方式[absoute,条件判断是否展示])
+            // wRowFrontNextRack: rowPre1 && intersectionBetWareRackCol, // 前区的紧挨支架的位置
+            // wRowBottomNextRack: rowPos1 && intersectionBetWareRackCol, // 后区紧挨支架的位置
+            // wColLeftNextRack: colPre1 && intersectionBetWareRackRow, // 左区紧挨支架的位置
+            // wColRightNextRack: colPos1 && intersectionBetWareRackRow, // 右区紧挨支架的位置
+            hasGoods: false,
+            hasCarrier: false,
+            carrierCatGoods: false,
+            lineGo: false,
+            lineBack: false,
+            lineType: this.isHorizontal ? 'h' : 's',
+            portType: 0 // 出入口类型。0未设置 1 入口  2出口 3出入口
+            // portPos: portPos //暂时不需要位置,根据r,c,横纵向等就能判断20230422
+          })
+        }
+        this.dataDoubleArr.push(rowData)
+      }
+      this.buildInit()
+      this.parseData(itemData)
+      // 基础数据加载完成后,再接收数据
+      this.socketCre()
+    },
+    storesInit(stores) {
+      if (!stores || stores.length < 0) {
+        return
+      }
+      for (let i = 0; i < stores.length; i++) {
+        const rowArr = stores[i]
+        for (let j = 0; j < rowArr.length; j++) {
+          const storeSts = rowArr[j]
+          // if (storeSts) {
+          const item = this.getItem(i, j)
+          item.hasGoods = !!storeSts
+          // }
+        }
+      }
+    },
+    // carriersInit(carriers) {
+    //   // 记录一层的数据
+    //   this.carrierMap = null
+    //   if (!carriers || carriers.length < 0) {
+    //     return
+    //   }
+    //   for (let i = 0; i < carriers.length; i++) {
+    //     this.carrierParamInit(carriers[i])
+    //   }
+    // },
+    /**
+     * 根据数据显示这一层数据
+     * @param {*} whPath
+
+    pathInit(whPath) {
+      if (!whPath || !whPath[this.floor]) {
+        this.refreshPath()
+        return
+      }
+      this.refreshPath(
+        { type: 'path', action: 'start', content: whPath[this.floor] },
+        'start'
+      )
+    }, */
+    // carrierParamInit(carrier, action = 'add') {
+    //   const pos = carrier.pos
+    //   if (pos.f !== this.floor) {
+    //     return
+    //   }
+    //   if (action === 'update') {
+    //     const preStsCarrier = this.carrierMap && this.carrierMap[carrier.id]
+    //     if (preStsCarrier) {
+    //       preStsCarrier.hasCarrier = false
+    //       preStsCarrier.carrierCatGoods = false
+    //       this.carrierMap[carrier.id] = null
+    //     }
+    //   }
+    //   const item = this.getItem(pos.r, pos.c)
+    //   item.hasCarrier = true
+    //   item.carrierCatGoods = carrier.hasPallet
+    //   item['carrierID'] = carrier.id
+    //   if (!this.carrierMap) {
+    //     this.carrierMap = {}
+    //   }
+    //   this.carrierMap[carrier.id] = item
+    // },
+    // carrierMapInit() {
+    //   if (!this.carrierMap) {
+    //     return
+    //   }
+    //   Object.keys(this.carrierMap).forEach((ele) => {
+    //     const carrier = this.carrierMap[ele]
+    //     if (carrier) {
+    //       carrier.hasCarrier = false
+    //       carrier.carrierCatGoods = false
+    //     }
+    //   })
+    //   this.carrierMap = null
+    // },
+    setScaleM(scale) {
+      this.scaleM = scale
+    },
+    /** parseData */
+    parseData(data) {
+      if (!data || data.length < 1) {
+        return
+      }
+      this.floor = data.floor || 1
+      this.xTracks = data.mainRoad ? JSON.parse(data.mainRoad) : []
+      this.xTracks.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.xTrack)
+      })
+      this.lifts = data.lift ? JSON.parse(data.lift) : []
+      this.lifts.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.lift)
+      })
+
+      this.ports = data.entrance ? JSON.parse(data.entrance) : []
+      this.ports.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.port)
+      })
+      this.transports = data.conveyor ? JSON.parse(data.conveyor) : []
+      this.transports.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.transport)
+      })
+      this.unUses = data.disable ? JSON.parse(data.disable) : []
+      this.unUses.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.unUse)
+      })
+      // 车位
+      this.parks = data.park ? JSON.parse(data.park) : []
+      this.parks.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.park)
+      })
+      // 充电位
+      this.charges = data.charge ? JSON.parse(data.charge) : []
+      this.charges.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.charge)
+      })
+      // 立柱
+      this.standCols = data.pillar ? JSON.parse(data.pillar) : []
+      this.standCols.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.standCol)
+      })
+      // 行车道
+      this.carriageways = data.drivingLane ? JSON.parse(data.drivingLane) : []
+      this.carriageways.forEach((element) => {
+        this.busiIndxToPageIdx(element)
+        element && this.itemStsInit(element, ItemOperStatus.carriageway)
+      })
+      this.storeAllCfg(this.itemOperStatus)
+    },
+    itemStsInit(element, status) {
+      if (!element) {
+        return
+      }
+      if (status === ItemOperStatus.port) {
+        const operItem = this.getItem(element.r, element.c)
+        operItem && (operItem.portType = element.portType)
+        return
+      }
+      if (!element.is) {
+        return
+      }
+      if (status === ItemOperStatus.xTrack) {
+        this.xTrackSet(element.is, element.r, element.c, status)
+        return
+      }
+      const operItem = this.getItem(element.r, element.c)
+      if (!operItem) {
+        return
+      }
+      operItem.sts = status
+      if (status === ItemOperStatus.lift) {
+        operItem.liftKey = element.liftKey
+      }
+    },
+    /** submit */
+    grtSubmitData(cfgForm) {
+      // 将非零件剔除
+      const xTracksParse = JSON.parse(JSON.stringify(this.xTracks))
+      const xTracks = xTracksParse.filter((ele) => {
+        return ele.is
+      })
+      xTracks.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const liftsParse = JSON.parse(JSON.stringify(this.lifts))
+      const lifts = liftsParse.filter((ele) => {
+        return ele.is
+      })
+      lifts.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const transportsParse = JSON.parse(JSON.stringify(this.transports))
+      const transports = transportsParse.filter((ele) => {
+        return ele.is
+      })
+      transports.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const unUsesParse = JSON.parse(JSON.stringify(this.unUses))
+      const unUses = unUsesParse.filter((ele) => {
+        return ele.is
+      })
+      unUses.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const parksParse = JSON.parse(JSON.stringify(this.parks))
+      const parks = parksParse.filter((ele) => {
+        return ele.is
+      })
+      parks.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const chargesParse = JSON.parse(JSON.stringify(this.charges))
+      const charges = chargesParse.filter((ele) => {
+        return ele.is
+      })
+      charges.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const portsParse = JSON.parse(JSON.stringify(this.ports))
+      const ports = portsParse.filter((ele) => {
+        return ele.portType
+      })
+      ports.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const standColsParse = JSON.parse(JSON.stringify(this.standCols))
+      const stands = standColsParse.filter((ele) => {
+        return ele.is
+      })
+      stands.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const carriagewaysParse = JSON.parse(JSON.stringify(this.carriageways))
+      const carriageways = carriagewaysParse.filter((ele) => {
+        return ele.is
+      })
+      carriageways.forEach((ele) => {
+        this.pageIdxToBusiIndx(ele)
+      })
+      const data = Object.assign({}, cfgForm, {
+        floors: [
+          {
+            floor: this.floor,
+            mainRoad: JSON.stringify(xTracks),
+            lift: JSON.stringify(lifts),
+            entrance: JSON.stringify(ports),
+            conveyor: JSON.stringify(transports),
+            disable: JSON.stringify(unUses),
+            park: JSON.stringify(parks),
+            charge: JSON.stringify(charges),
+            pillar: JSON.stringify(stands),
+            drivingLane: JSON.stringify(carriageways)
+          }
+        ]
+      })
+      console.log(JSON.stringify(data))
+      return data
+    },
+    /** set start */
+    // 构建时初始化操作
+    buildInit() {
+      this.floor = 1
+      this.itemOperStatus = ''
+      this.itemStausMap = {}
+      this.itemStausStore = {}
+      for (const item of ItemOperStatus.arr) {
+        const flag = item + 's'
+        if (this[flag] && this[flag].length > 0) {
+          this[flag] = []
+        }
+      }
+      this.setAllItemInitDefault()
+    },
+    /**
+     * 删除上一操作未保存数据
+     * 保存当前未操作前数据
+     * 设置当前操作状态
+     * arr: ['unUse', 'xTrack'(整行特殊分支逻辑处理), 'lift', 'port'(表格外特殊分支逻辑处理), 'transport'],
+     * @param {*} status
+     */
+    setItemOperStatus(status) {
+      // console.log('点击了操作按钮' + status)
+      // 清除时机,点击安纽,上一次的操作非deafult
+      if (
+        status !== ItemOperStatus.default &&
+        this.itemOperStatus &&
+        this.itemOperStatus !== ItemOperStatus.default
+      ) {
+        this.removeCfg(this.itemOperStatus)
+      }
+      // 保存实际,点击确认配置按钮
+      if (
+        status === ItemOperStatus.default &&
+        this.itemOperStatus &&
+        this.itemOperStatus !== ItemOperStatus.default
+      ) {
+        // 在default时,保存
+        this.storeCfg(this.itemOperStatus)
+      }
+      // console.log(
+      //   'this.itemStausStore::' + JSON.stringify(this.itemStausStore)
+      // )
+      this.itemOperStatus = status
+      // 计算互斥操作,每次点击都跟新到最新
+      this.disOper(status)
+      // if (status === ItemOperStatus.port) {
+      //   this.portsInit()
+      // }
+    },
+    disOper(status) {
+      this.itemStatusMapInit()
+      const operingStatus = status || this.itemOperStatus
+      for (const oper of ItemOperStatus.arr) {
+        if (operingStatus === oper || operingStatus === ItemOperStatus.port) {
+          continue
+        }
+        if (oper === ItemOperStatus.xTrack) {
+          for (const item of this.xTracks) {
+            if (!item.is) {
+              continue
+            }
+            this.itemStatusMapSetInit()
+            const procNum = this.isHorizontal ? this.col : this.row
+            for (let i = 0; i < procNum; i++) {
+              const idFlag = this.isHorizontal
+                ? this.idKey(item.r, i)
+                : this.idKey(i, item.c)
+              this.itemStausMap[idFlag] = idFlag
+            }
+          }
+        }
+        const list = this[oper + 's']
+        if (!list) {
+          return
+        }
+        for (const item of list) {
+          if (item.is) {
+            this.itemStatusMapSetInit(oper)
+            this.itemStatusMapSet(item)
+          }
+        }
+      }
+      // console.log('huchi::' + JSON.stringify(this.itemStausMap))
+    },
+    removeCfg(status) {
+      const flag = status + 's'
+      if (this.itemStausStore && this.itemStausStore[flag]) {
+        this[flag] = JSON.parse(JSON.stringify(this.itemStausStore[flag]))
+        // 同步最新的数据到数据 this[flag]可能是空数组,或者其他状态
+        this.setAllItemInit(status)
+        for (let i = 0; i < this[flag].length; i++) {
+          const operItem = this[flag][i]
+          const dataItem = this.getItem(operItem.r, operItem.c)
+          dataItem.sts = operItem.is ? status : ItemOperStatus.default
+          if (status === ItemOperStatus.port) {
+            dataItem.portType = operItem.portType
+          }
+          if (status === ItemOperStatus.xTrack) {
+            this.xTrackSet(operItem.is, operItem.r, operItem.c, status)
+          }
+        }
+      } else {
+        this[flag].length = 0
+        this.setAllItemInit(status)
+      }
+    },
+    // 没有可操作的对象时
+    setAllItemInit(status) {
+      for (let i = 0; i < this.wRow; i++) {
+        for (let j = 0; j < this.wCol; j++) {
+          const operData = this.getItem(i, j, 'ware')
+          if (operData.sts === status) {
+            operData.sts = ItemOperStatus.default
+            operData.portType = 0
+          }
+        }
+      }
+    },
+    setAllItemInitDefault() {
+      for (let i = 0; i < this.wRow; i++) {
+        for (let j = 0; j < this.wCol; j++) {
+          const operData = this.getItem(i, j, 'ware')
+          operData.sts = ItemOperStatus.default
+        }
+      }
+    },
+    storeCfg(status) {
+      if (!this.itemStausStore) {
+        this.itemStausStore = {}
+      }
+      const flag = status + 's'
+      this.itemStausStore[flag] = JSON.parse(JSON.stringify(this[flag]))
+      // console.log('itemStausStore::' + JSON.stringify(this.itemStausStore))
+    },
+    storeAllCfg() {
+      for (const item of ItemOperStatus.arr) {
+        this.storeCfg(item)
+      }
+    },
+    /**
+     * 无ports数据时,初始化port
+     * @param {*} cfging
+     */
+    // portsInit() {
+    //   if (!this.ports) {
+    //     this.ports = []
+    //   }
+    //   if (this.ports[0].length < 1 && this.isHorizontal) {
+    //     for (let i = 1; i <= this.col; i++) {
+    //       this.ports[0].push({
+    //         type: 0,
+    //         portType: 0,
+    //         pos: 'bottom',
+    //         c: i
+    //       })
+    //       this.ports[1].push({
+    //         type: 1,
+    //         portType: 0,
+    //         pos: 'top',
+    //         c: i
+    //       })
+    //     }
+    //   }
+    //   if (this.ports[2].length < 1 && !this.isHorizontal) {
+    //     for (let i = 1; i <= this.row; i++) {
+    //       this.ports[2].push({
+    //         type: 2,
+    //         portType: 0,
+    //         pos: 'left',
+    //         r: i
+    //       })
+    //       this.ports[3].push({
+    //         type: 3,
+    //         portType: 0,
+    //         pos: 'right',
+    //         r: i
+    //       })
+    //     }
+    //   }
+    //   console.log(JSON.stringify(this.ports))
+    // },
+    resetItemOperStatus() {
+      this.buildInit()
+    },
+    itemStatusMapInit() {
+      this.itemStausMap = {}
+    },
+    itemStatusMapSetInit() {
+      if (!this.itemStausMap) {
+        this.itemStausMap = {}
+      }
+    },
+    itemStatusMapSet(ele) {
+      const idFlag = this.idKey(ele.r, ele.c)
+      this.itemStausMap[idFlag] = idFlag
+      const trackKey = this.trackIdKey(ele.r, ele.c)
+      this.itemStausMap[trackKey] = trackKey
+    },
+    itemStatusMapConfirm(ele, oper) {
+      if (oper && this.itemStausMap[oper]) {
+        const idFlag = this.idKeyWhenBusi(ele.r, ele.c)
+        this.itemStausMap[oper][idFlag] = idFlag
+      }
+    },
+    itemClick(item) {
+      // 非支架单元格且不是设置梯子或者transport
+      if (
+        item.typeWH &&
+        !(
+          this.itemOperStatus === ItemOperStatus.lift ||
+          this.itemOperStatus === ItemOperStatus.transport
+        )
+      ) {
+        return
+      }
+      // 既不是xtrack上设置轨道又不存在itemOperStatus或者itemOperStatus为default或者port时不处理
+      if (
+        !this.isProcUnseWhenXTrack(item) &&
+        (!this.itemOperStatus ||
+          this.itemOperStatus === ItemOperStatus.default ||
+          this.itemOperStatus === ItemOperStatus.port)
+      ) {
+        return
+      }
+      // console.log('点击了格子')
+      // 此处时支架的行号,按照网页坐标y轴向下
+      const r = item.r
+      const c = item.c
+      const key = item.key
+      /** 互斥操作
+       * xtrack上设置不可用时,不是互斥关系
+       */
+      if (this.itemStausMap[key] && !this.isProcUnseWhenXTrack(item)) {
+        // console.log('shi huchi de')
+        return
+      }
+      if (this.itemOperStatus === ItemOperStatus.xTrack) {
+        const trackKey = this.trackIdKey(r, c)
+        if (this.itemStausMap[trackKey]) {
+          return
+        }
+      }
+      // 各项点击操作
+      const operItem = item
+      if (this.itemOperStatus === ItemOperStatus.xTrack) {
+        this.xTrack(r, c, key, operItem)
+        return
+      }
+      // 提升机
+      if (
+        this.itemOperStatus === ItemOperStatus.lift &&
+        liftGenProxy.getProxy() === liftGenProxy.PROXY_SIX
+      ) {
+        const liftData = this.liftValidateAndGet(operItem)
+        if (!liftData) {
+          return
+        }
+        // 同步单元格状态
+        this.liftInitData(liftData)
+        // 操作同步组件数据的数组
+        liftData.forEach((ele) => {
+          this.itemClickCommonDo(ele.key, ele.r, ele.c, ele)
+        })
+        // console.log(
+        //   'itemClickData' + JSON.stringify(this[this.itemOperStatus + 's'])
+        // )
+        return
+      }
+
+      this.itemClickCommonDo(key, r, c, operItem)
+      // console.log(
+      //   'itemClickData' + JSON.stringify(this[this.itemOperStatus + 's'])
+      // )
+    },
+    isProcUnseWhenXTrack(item) {
+      let isXtrack = false
+      for (let i = 0; i < this.xTracks.length; i++) {
+        const ele = this.xTracks[i]
+        const key = ele.key
+        const [r, c] = key.split('-')
+        const xtrackNumString = this.isHorizontal ? r : c
+        const xtrackNum = parseInt(xtrackNumString)
+        isXtrack = this.isHorizontal
+          ? xtrackNum === item.r
+          : xtrackNum === item.c
+        if (isXtrack) {
+          break
+        }
+      }
+      const ret = this.itemOperStatus === ItemOperStatus.unUse && isXtrack
+      return ret
+    },
+    /**
+     * 对当前被点击格子目标状态的数组,进行遍历,确认最终状态
+     * 特殊情况,当目标状态时不可用时且被点击的格子是轨道上的,状态应该被重置为轨道状态
+     * @param {*} key
+     * @param {*} r
+     * @param {*} c
+     * @param {*} operItem  当前被点击的格子
+     * @returns
+     */
+    itemClickCommonDo(key, r, c, operItem) {
+      const operListFlag = this.itemOperStatus + 's'
+      const dataList = this[operListFlag]
+      if (!dataList) {
+        this[operListFlag] = []
+      }
+      const list = this[operListFlag]
+      if (list.length < 1) {
+        this[operListFlag].push({
+          key: key,
+          r: r,
+          c: c,
+          wR: operItem.wR,
+          wC: operItem.wC,
+          is: true,
+          liftKey: operItem.liftKey
+        })
+        operItem.sts = this.itemOperStatus
+        return
+      }
+      let isHas
+      for (const element of list) {
+        if (element.r === r && element.c === c) {
+          element.is = !element.is
+          element.liftKey = element.is ? operItem.liftKey : ''
+          isHas = true
+          operItem.sts = this.commonSetStsWhenHasSet(element)
+          operItem.liftKey = element.is ? operItem.liftKey : ''
+          break
+        }
+      }
+      if (!isHas) {
+        this[operListFlag].push({
+          key: key,
+          r: r,
+          c: c,
+          wR: operItem.wR,
+          wC: operItem.wC,
+          is: true,
+          liftKey: operItem.liftKey
+        })
+        operItem.sts = this.itemOperStatus
+      }
+    },
+    commonSetStsWhenHasSet(element) {
+      let sts = element.is ? this.itemOperStatus : ItemOperStatus.default
+      if (!element.is && this.isProcUnseWhenXTrack(element)) {
+        sts = ItemOperStatus.xTrack
+      }
+      return sts
+    },
+    portItemClick(item) {
+      // console.log('点击了port')
+      if (this.itemOperStatus !== ItemOperStatus.port) {
+        return
+      }
+      let pt = item.portType + 1
+      if (pt >= 4) {
+        pt = 0
+      }
+      item.portType = pt
+      if (!this.ports) {
+        this.ports = []
+      }
+      let isHas = false
+      for (const element of this.ports) {
+        if (item.r === element.r && item.c === element.c) {
+          element.portType = pt
+          isHas = true
+        }
+      }
+      const added = JSON.parse(JSON.stringify(item))
+      if (!isHas) {
+        this.ports.push(added)
+      }
+    },
+    /**
+     * 3行车道2货位列梯子,校验空间,及初始化liftKey
+     * 点击位置将在点击位置左侧和右侧,及下侧生成梯子,没有报错
+     * 关注边界
+     * 考虑了横纵向
+     * 返回的数组为二维数组中数据
+     * 20230625开放非支架位置也可配置
+     * @param {*} operItem
+     */
+    liftValidateAndGet(operItem) {
+      const r = operItem.wR
+      const c = operItem.wC
+      const liftKey = operItem.liftKey
+      if (liftKey) {
+        // 横向数据
+        const rowArr = []
+        const colMaxNum = c + 2 >= this.wCol ? this.wCol - 1 : c + 2
+        const colMinNum = c - 2 < 0 ? 0 : c - 2
+        for (let i = colMinNum; i < colMaxNum + 1; i++) {
+          const dataItem = this.getItem(r, i, 'ware')
+          if (dataItem.liftKey === liftKey) {
+            rowArr.push(dataItem)
+          }
+        }
+        // console.log(JSON.stringify(rowArr))
+        const colArr = []
+        // 纵向数据
+        for (let j = 0; j < rowArr.length; j++) {
+          const rowItem = rowArr[j]
+          const rowC = rowItem.wC
+          const row2Min = rowItem.wR - 2 >= 0 ? rowItem.wR - 2 : 0
+          const row2Max =
+            rowItem.wR + 2 < this.wRow ? rowItem.wR + 2 : this.wRow - 1
+          for (let k = row2Min; k <= row2Max; k++) {
+            const it = this.getItem(k, rowC, 'ware')
+            if (it.liftKey === liftKey) {
+              colArr.push(it)
+            }
+          }
+        }
+
+        // console.log(JSON.stringify(colArr))
+        return [...colArr]
+      }
+      const carrierRoadNum = this.isHorizontal ? this.wCol : this.wRow
+      const palletNum = this.isHorizontal ? this.wRow : this.wCol
+      if (palletNum < 2 || carrierRoadNum < 3) {
+        this.$message({
+          message: '梯子需要占用3行车道2货位,空间不足!',
+          type: 'warning'
+        })
+        return
+      }
+      // 确定行车道数据
+      const liftCarrierRoadItem = operItem
+      const liftCarrierRoadArr = []
+      const palletArr = []
+      if (this.isHorizontal) {
+        if (c - 1 < 0) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置左侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        if (c + 1 >= this.wCol) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置右侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        if (r + 1 >= this.wRow) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置下侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        const roadPre = this.getItem(r, c - 1, 'ware')
+        if (!roadPre || roadPre.sts !== ItemOperStatus.default) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置左侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        liftCarrierRoadArr.push(roadPre)
+        liftCarrierRoadArr.push(liftCarrierRoadItem)
+        const roadPost = this.getItem(r, c + 1, 'ware')
+        if (!roadPost || roadPost.sts !== ItemOperStatus.default) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置右侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        liftCarrierRoadArr.push(roadPost)
+        for (let i = 0; i < liftCarrierRoadArr.length; i++) {
+          const ele = liftCarrierRoadArr[i]
+          const c = ele.wC
+          const item = this.getItem(r + 1, c, 'ware')
+          if (!item || item.sts !== ItemOperStatus.default) {
+            this.$message({
+              message: '梯子占用3行行车道,2行货位;点击位置下侧空间不足!',
+              type: 'warning'
+            })
+            return
+          }
+          palletArr.push(item)
+        }
+      } else {
+        if (r - 1 < 0) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置上侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        if (r + 1 >= this.wRow) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置下侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        if (c + 1 >= this.wCol) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置左侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        const roadPre = this.getItem(r - 1, c, 'ware')
+        if (!roadPre || roadPre.sts !== ItemOperStatus.default) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置上侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        liftCarrierRoadArr.push(roadPre)
+        liftCarrierRoadArr.push(liftCarrierRoadItem)
+        const roadPost = this.getItem(r + 1, c, 'ware')
+        if (!roadPost || roadPost.sts !== ItemOperStatus.default) {
+          this.$message({
+            message: '梯子占用3行行车道,2行货位;点击位置下侧空间不足!',
+            type: 'warning'
+          })
+          return
+        }
+        liftCarrierRoadArr.push(roadPost)
+        for (let i = 0; i < liftCarrierRoadArr.length; i++) {
+          const ele = liftCarrierRoadArr[i]
+          const c = ele.wC
+          const item = this.getItem(ele.r, c + 1, 'ware')
+          if (!item || item.sts !== ItemOperStatus.default) {
+            this.$message({
+              message: '梯子占用3行行车道,2行货位;点击位置左侧空间不足!',
+              type: 'warning'
+            })
+            return
+          }
+          palletArr.push(item)
+        }
+      }
+
+      const keyArr = [...liftCarrierRoadArr, ...palletArr]
+      const map = { r: {}, c: {}}
+      keyArr.forEach((ele) => {
+        map.r[ele.r] = ele.r
+        map.c[ele.c] = ele.c
+      })
+      const key = JSON.stringify(map)
+      keyArr.forEach((ele) => {
+        ele['liftKey'] = key
+      })
+      return keyArr
+    },
+    liftInitData(liftData) {
+      liftData.forEach((ele) => {
+        ele.sts =
+          ele.sts === ItemOperStatus.lift
+            ? ItemOperStatus.default
+            : ItemOperStatus.lift
+        ele.liftKey = ele.sts === ItemOperStatus.lift ? ele.liftKey : ''
+      })
+    },
+    xTrack(r, c, key, operItem) {
+      for (const track of this.xTracks) {
+        if (
+          (this.isHorizontal && r === track.r) ||
+          (!this.isHorizontal && c === track.c)
+        ) {
+          track.is = !track.is
+          this.xTrackSet(track.is, r, c)
+          return true
+        }
+      }
+      const trackKey = this.trackIdKey(r, c)
+      this.xTracks.push({
+        key: trackKey,
+        r: r,
+        c: c,
+        wR: operItem.wR,
+        wC: operItem.wC,
+        is: true
+      })
+      this.xTrackSet(true, r, c)
+      return true
+    },
+    /**
+     * 传入的r,c为支架的 r c
+     * @param {*} is
+     * @param {*} r
+     * @param {*} c
+     * @param {*} status
+     */
+    xTrackSet(is, r, c, status) {
+      if (this.isHorizontal) {
+        const rowData = this.getRowData(r)
+        const colS = this.getColStNum()
+        const colE = this.getColEndNum()
+        for (let i = colS; i < colE; i++) {
+          const operItem = this.getColData(rowData, i, 'ware')
+          operItem.sts = is
+            ? status || this.itemOperStatus
+            : ItemOperStatus.default
+        }
+      } else {
+        const rowS = this.getRowStNum()
+        const rowE = this.getRowEndNum()
+        const wC = this.getWC(c)
+        for (let i = rowS; i < rowE; i++) {
+          const operItem = this.getItem(i, wC, 'ware')
+          operItem.sts = is
+            ? status || this.itemOperStatus
+            : ItemOperStatus.default
+        }
+      }
+    },
+    /** set end */
+    /**
+     * 获取元素并设置指定值
+     * @param {*} r
+     * @param {*} c
+     * @param {*} val
+     * @param {*} flag
+     * @param {*} type
+     */
+    getItem(r, c, type = 'rack') {
+      let rowIndex = r + this.front
+      let colIndex = c + this.left
+      if (type === 'ware') {
+        rowIndex = r
+        colIndex = c
+      }
+      const ele =
+        this.dataDoubleArr[rowIndex] && this.dataDoubleArr[rowIndex][colIndex]
+      return ele
+    },
+    // 通过支架c找仓库全局c
+    getWC(c) {
+      return c + this.left
+    },
+    // 通过支架r找仓库全局r
+    getWR(r) {
+      return r + this.front
+    },
+    // 通过支架c找仓库全局c
+    getRackC(c) {
+      return c - this.left
+    },
+    // 通过支架r找仓库全局r
+    getRackR(r) {
+      return r - this.front
+    },
+    getRowData(r, c, type = 'rack') {
+      let rowIndex = r + this.front
+      if (type === 'ware') {
+        rowIndex = r
+      }
+      const ele = this.dataDoubleArr[rowIndex]
+      return ele
+    },
+    getRowStNum(type = 'rack') {
+      let rowIndex = this.front
+      if (type === 'ware') {
+        rowIndex = 0
+      }
+      return rowIndex
+    },
+    getRowEndNum(type = 'rack') {
+      let rowIndex = this.front + this.row
+      if (type === 'ware') {
+        rowIndex = this.front + this.row + this.back
+      }
+      return rowIndex
+    },
+    getColStNum(type = 'rack') {
+      let colIndex = this.left
+      if (type === 'ware') {
+        colIndex = 0
+      }
+      return colIndex
+    },
+    getColEndNum(type = 'rack') {
+      let colIndex = this.left + this.col
+      if (type === 'ware') {
+        colIndex = this.left + this.col + this.right
+      }
+      return colIndex
+    },
+    /**
+     * 行数据下区列数据
+     * @param {*} r
+     * @param {*} c
+     * @param {*} type
+     * @returns
+     */
+    getColData(rowData, c, type = 'rack') {
+      let colIndex = c + this.left
+      if (type === 'ware') {
+        colIndex = c
+      }
+      const ele = rowData[colIndex]
+      return ele
+    },
+    setItem(ele, val, flag) {
+      ele && (ele[flag] = val)
+      return ele
+    },
+    goodsInit() {
+      for (const ele of this.goodsDisArr) {
+        const r = ele[0]
+        const c = ele[1]
+        const item = this.getItem(r, c)
+        if (item.sts === ItemOperStatus.default) {
+          this.setItem(item, true, 'hasGoods')
+        }
+      }
+      // console.log(JSON.stringify(this.dataDoubleArr))
+    },
+    lineShowArrInit() {
+      this.lineShowArr.forEach((ele) => {
+        ele.lineGo = false
+        ele.lineBack = false
+        ele.lineType = this.isHorizontal ? 'h' : 's'
+      })
+      this.lineShowArr.length = 0
+    },
+    /** animation start  */
+    animationTest() {
+      this.actionInit()
+      if (this.hasGoods() && this.xTracks && this.xTracks[0]) {
+        this.action()
+      }
+    },
+    /**
+     * 检查当前支架上是否还有货物
+     * @returns
+     */
+    hasGoods() {
+      for (const ele of this.goodsDisArr) {
+        const r = ele[0]
+        const c = ele[1]
+        const item = this.getItem(r, c)
+        if (item.hasGoods) {
+          return true
+        }
+      }
+    },
+    /**
+     * 1-同步当前仓库货物状态
+     * 2-初始化任务的开始结束点
+     */
+    actionInit() {
+      // 初始化货物
+      this.goodsInit()
+      // 初始化线路
+      this.lineShowArrInit()
+      // 初始化任务信息,确认首个任务起点终点
+      const sR = this.carrierTask[0][0]
+      const sC = this.carrierTask[0][1]
+      const eR = this.carrierTask[1][0]
+      const eC = this.carrierTask[1][1]
+      this.carrierAnimationInfo.start = {
+        key: this.idKey(sR, sC),
+        r: sR,
+        c: sC
+      }
+      this.carrierAnimationInfo.end = { key: this.idKey(eR, eC), r: eR, c: eC }
+    },
+    action() {
+      this.$nextTick(() => {
+        this.animationTimerDes()
+        this.animationTimer = setInterval(() => {
+          this.animationSimulation(this.carrierAnimationInfo)
+        }, AnimationCfg.action().timeInter)
+      })
+    },
+    /**
+     * 销毁定时器
+     */
+    animationTimerDes() {
+      if (this.animationTimer) {
+        clearInterval(this.animationTimer)
+        this.animationTimer = null
+      }
+    },
+    /**
+     * 根据carrierAnimationInfo信息推断当前车和货的状态
+     * start 任务开始位置 end 任务结束位置
+     * @param {*} carrierAnimationInfo
+     */
+    animationSimulation(carrierAnimationInfo) {
+      // console.log('任务开始了')
+      // 分任务开始时
+      if (!carrierAnimationInfo.next) {
+        this.setAnimationDestInfo(carrierAnimationInfo)
+        this.setCurAnimation(carrierAnimationInfo, {
+          key: carrierAnimationInfo.start.key,
+          r: carrierAnimationInfo.start.r,
+          c: carrierAnimationInfo.start.c
+        })
+      }
+      this.chgPreItemStatus(carrierAnimationInfo)
+      this.chgCurItemStatus(carrierAnimationInfo)
+      this.setPreAnimation(carrierAnimationInfo)
+      this.setNextAnimation(carrierAnimationInfo)
+    },
+    /**
+     * 大任务下的小任务,处于开始位置时
+     * 1-查找下一个小任务的终点
+     * 2-没有下一个小任务时,若循环播放,初始化货物,寻找下一个小任务终点
+     * @param {*} carrierAnimationInfo
+     */
+    setAnimationDestInfo(carrierAnimationInfo) {
+      let isHasDest = false
+      for (let r = this.row - 1; r >= 0; r--) {
+        for (let c = this.col - 1; c >= 0; c--) {
+          const item = this.getItem(r, c)
+          if (item.hasGoods) {
+            this.startPosInit(carrierAnimationInfo, r, c)
+            isHasDest = true
+            break
+          }
+        }
+      }
+      /** 没有货时 */
+      if (!isHasDest) {
+        if (this.getIsRestart()) {
+          this.actionInit()
+          carrierAnimationInfo.next = null
+          this.setAnimationDestInfo(carrierAnimationInfo)
+        }
+      }
+      // console.log('分任务开始位置' + JSON.stringify(carrierAnimationInfo))
+    },
+    /**
+     * 修改上一状态
+     * 1-不显示车
+     * @param {*} carrierAnimationInfo
+     * @returns
+     */
+    chgPreItemStatus(carrierAnimationInfo) {
+      if (!carrierAnimationInfo.prev) {
+        return
+      }
+      const item = this.getItem(
+        carrierAnimationInfo.prev.r,
+        carrierAnimationInfo.prev.c
+      )
+      item.hasCarrier = false
+      item.carrierCatGoods = false
+    },
+    setCarrierHere(r, c, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      eleProc.hasCarrier = true
+      return eleProc
+    },
+    carrierCatGood(r, c, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      eleProc.carrierCatGoods = true
+      return eleProc
+    },
+    setCarrierCatGoodSts(r, c, val, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      eleProc.carrierCatGoods = val
+      return eleProc
+    },
+    carrierHid(r, c, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      if (eleProc.hasCarrier) {
+        eleProc.hasCarrier = false
+      }
+      if (eleProc.carrierCatGoods) {
+        eleProc.carrierCatGoods = false
+      }
+      return eleProc
+    },
+    goodsHid(r, c, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      if (eleProc.hasGoods) {
+        eleProc.hasGoods = false
+      }
+    },
+    goodsShow(r, c, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      if (!eleProc.hasGoods) {
+        eleProc.hasGoods = true
+      }
+    },
+    setGoodsSts(r, c, val, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      eleProc.hasGoods = val
+    },
+    lineShow(r, c, routeType, lineType) {
+      const ele = this.getItem(r, c)
+      if (routeType === AnimationCfg.routeType.back) {
+        ele.lineBack = true
+      }
+      if (routeType === AnimationCfg.routeType.go) {
+        ele.lineGo = true
+      }
+      if (ele.sts === ItemOperStatus.xTrack && lineType) {
+        ele.lineType = lineType
+      }
+      this.lineShowArr.push(ele)
+    },
+    lineHid(r, c, routeType, lineType, ele) {
+      const eleProc = ele || this.getItem(r, c)
+      if (routeType === AnimationCfg.routeType.back && eleProc.lineBack) {
+        eleProc.lineBack = false
+      }
+      if (routeType === AnimationCfg.routeType.go && eleProc.lineGo) {
+        eleProc.lineGo = false
+      }
+      if (ele.sts === ItemOperStatus.xTrack && lineType) {
+        eleProc.lineType = lineType
+      }
+      return eleProc
+    },
+    /**
+     * 改变当前位置状态
+     * @param {*} carrierAnimationInfo
+     * @returns
+     */
+    chgCurItemStatus(carrierAnimationInfo) {
+      const currentObj = carrierAnimationInfo.current
+      if (!currentObj) {
+        return
+      }
+      // 1-显示车
+
+      const r = currentObj.r
+      const c = currentObj.c
+      this.setCarrierHere(r, c)
+      const carrierCatching = currentObj.carrierCatching
+      const goodsDis = currentObj.goodsDis
+
+      // 有货状态
+      if (carrierCatching) {
+        this.carrierCatGood(r, c)
+      }
+      if (goodsDis) {
+        this.goodsHid(r, c)
+      }
+      this.lineShow(
+        r,
+        c,
+        carrierAnimationInfo.routeType,
+        this.getXTrackLineType(carrierAnimationInfo)
+      )
+      // 当前状态预处理
+      // 当处于分任务的结束位置时
+      if (
+        r === carrierAnimationInfo.end.r &&
+        c === carrierAnimationInfo.end.c
+      ) {
+        this.endPosInit(carrierAnimationInfo)
+      }
+      // 当处于分任务开始位置,且是回来时
+      if (
+        r === carrierAnimationInfo.start.r &&
+        c === carrierAnimationInfo.start.c &&
+        carrierAnimationInfo.routeType === AnimationCfg.routeType.back
+      ) {
+        this.startPosCurrInit(carrierAnimationInfo)
+      }
+    },
+    /**
+     * 分任务中下个位置信息处理
+     * @param {*} carrierAnimationInfo
+     * @returns
+     */
+    setNextAnimation(carrierAnimationInfo) {
+      if (!carrierAnimationInfo.current) {
+        return
+      }
+      const nRC = this.getNextRC(carrierAnimationInfo)
+      const nR = nRC.r
+      const nC = nRC.c
+      const next = {
+        key: this.idKey(nR, nC),
+        r: nR,
+        c: nC,
+        carrierCatching: carrierAnimationInfo.prev.carrierCatching,
+        goodsDis: false
+      }
+      this.setRouteTypeAndCurrInfo(carrierAnimationInfo, next)
+      carrierAnimationInfo.next = next
+      carrierAnimationInfo.current = next
+    },
+    /**
+     * 当在xtrak上时,路线计算 h s 1 2 3 4
+     * @param {} carrierAnimationInfo
+     */
+    getXTrackLineType(carrierAnimationInfo) {
+      const r = carrierAnimationInfo.current.r
+      const c = carrierAnimationInfo.current.c
+      const ele = this.getItem(r, c)
+      if (ele.sts !== ItemOperStatus.xTrack || !carrierAnimationInfo.prev) {
+        return
+      }
+
+      const preR = carrierAnimationInfo.prev.r
+      const preC = carrierAnimationInfo.prev.c
+      const nRC = this.getNextRC(carrierAnimationInfo)
+      if (!nRC) {
+        return
+      }
+      const postR = nRC.r
+      const postC = nRC.c
+      const toR = r - preR
+      const toC = c - preC
+      const toPosR = postR - r
+      const toPosC = postC - c
+      const map = this.cfg.animationActionMap
+      // const keyFlag =
+      //   OrientationRackingMap[this.orientationRacking] + 'XtrackLine'
+      const keyFlag = 'xtrackLine'
+      const keyFlagBusi =
+        map.numFlag(toR) +
+        ',' +
+        map.numFlag(toC) +
+        '|' +
+        map.numFlag(toPosR) +
+        ',' +
+        map.numFlag(toPosC)
+      const result = map[keyFlag][keyFlagBusi]
+      if (!result) {
+        console.log(r + ',' + c + '--' + 'NOXtrackLineKey::' + keyFlagBusi)
+        return
+      }
+      return result
+    },
+    /**
+     * 根据起始\当前\目标位置计算路线 h s 1 2 3 4
+     * @param {*} current
+     * @param {*} pre
+     * @returns
+     */
+    getLineType(current, pre, next) {
+      console.log(current, pre, next)
+      const { r, c } = current
+      const ele = this.getItem(r, c)
+      if (ele.sts !== ItemOperStatus.xTrack || !pre || !next) {
+        return
+      }
+      const { r: preR, c: preC } = pre
+      const { r: postR, c: postC } = next
+      const toR = r - preR
+      const toC = c - preC
+      const toPosR = postR - r
+      const toPosC = postC - c
+      const map = this.cfg.animationActionMap
+      // const keyFlag =
+      //   OrientationRackingMap[this.orientationRacking] + 'XtrackLine'
+      const keyFlag = 'xtrackLine'
+      const keyFlagBusi =
+        map.numFlag(toR) +
+        ',' +
+        map.numFlag(toC) +
+        '|' +
+        map.numFlag(toPosR) +
+        ',' +
+        map.numFlag(toPosC)
+      const result = map[keyFlag][keyFlagBusi]
+      if (!result) {
+        console.log(r + ',' + c + '--' + 'NOXtrackLineKey::' + keyFlagBusi)
+        return
+      }
+      return result
+    },
+    /**
+     * 下个位置状态预处理
+     * 1-分任务的终点位置时,设置搬货
+     * @param {*} carrierAnimationInfo
+     * @param {*} next
+     */
+    setRouteTypeAndCurrInfo(carrierAnimationInfo, next) {
+      next.carrierCatching = carrierAnimationInfo.prev.carrierCatching
+      if (
+        next.r === carrierAnimationInfo.end.r &&
+        next.c === carrierAnimationInfo.end.c
+      ) {
+        next.carrierCatching = true
+        next.goodsDis = true
+      }
+    },
+    /**
+     * 车在起点时,初始化操作.
+     * end 完整分任务的终点
+     * dest 实时目的地
+     * @param {*} carrierAnimationInfo
+     * @param {*} r
+     * @param {*} c
+     */
+    startPosInit(carrierAnimationInfo, r, c) {
+      const idKey = this.idKey(r, c)
+      carrierAnimationInfo.end = { key: idKey, r: r, c: c }
+      carrierAnimationInfo.dest = { key: idKey, r: r, c: c }
+      carrierAnimationInfo.routeType = AnimationCfg.routeType.go
+      // 初始化线路
+      this.lineShowArrInit()
+    },
+    startPosCurrInit(carrierAnimationInfo) {
+      carrierAnimationInfo.next = null
+      carrierAnimationInfo.current = null
+      carrierAnimationInfo.routeType = AnimationCfg.routeType.go
+    },
+    /**
+     * 处于分任务结束位置时
+     * 1-改变分任务目标位置
+     * 2-改变当前路线类型
+     * @param {*} carrierAnimationInfo
+     */
+    endPosInit(carrierAnimationInfo) {
+      carrierAnimationInfo.dest = JSON.parse(
+        JSON.stringify(carrierAnimationInfo.start)
+      )
+      carrierAnimationInfo.routeType = AnimationCfg.routeType.back
+    },
+    getNextRC(carrierAnimationInfo) {
+      const current = carrierAnimationInfo.current
+      const curR = current.r
+      const curC = current.c
+      const toDestR = carrierAnimationInfo.dest.r - curR
+      const toXtrack = this.isHorizontal
+        ? this.xTracks[0].r - curR
+        : this.xTracks[0].c - curC
+      const toDestC = carrierAnimationInfo.dest.c - curC
+      const map = this.cfg.animationActionMap
+      const keyFlag = OrientationRackingMap[this.orientationRacking]
+      const keyFlagBusi =
+        map.numFlag(toDestR) +
+        ',' +
+        map.numFlag(toDestC) +
+        '|' +
+        map.numFlag(toXtrack) +
+        '|'
+      const doFlag = map[keyFlag][keyFlagBusi]
+      if (!doFlag) {
+        // console.log('NOkeyFlagBusi::' + keyFlagBusi)
+        return { r: curR, c: curC }
+      }
+      // console.log('keyFlagBusi::' + keyFlagBusi)
+      const nextR = doFlag.r(curR)
+      const nextC = doFlag.c(curC)
+      // console.log('nextR::' + nextR)
+      // console.log('nextC::' + nextC)
+      return { r: nextR, c: nextC }
+    },
+    /**
+     * 初始位置时,设置当前操作信息
+     * @param {*} carrierAnimationInfo
+     * @param {*} obj
+     */
+    setCurAnimation(carrierAnimationInfo, obj) {
+      carrierAnimationInfo.current = obj
+    },
+    setPreAnimation(carrierAnimationInfo) {
+      carrierAnimationInfo.prev = JSON.parse(
+        JSON.stringify(carrierAnimationInfo.current)
+      )
+    },
+    /** 是否循环开始 */
+    getIsRestart() {
+      return true
+    },
+    /** animation end  */
+    /** set Val start  */
+    setOrientationRacking(orientationRacking) {
+      this.orientationRacking = orientationRacking
+    },
+    setCarrierRoadNum(carrierRoadNum) {
+      this.carrierRoadNum = carrierRoadNum
+    },
+    setPalletNum(palletNum) {
+      this.palletNum = palletNum
+    },
+    // setBaseInfo(orientationRacking, palletNum, carrierRoadNum) {
+    //   this.orientationRacking = orientationRacking
+    //   this.palletNum = palletNum
+    //   this.carrierRoadNum = carrierRoadNum
+    // },
+    setGoodsDisArr(goodsDisArr) {
+      this.goodsDisArr = goodsDisArr
+    },
+    setCcarrierTask(carrierTask) {
+      this.carrierTask = carrierTask
+    },
+    setXTracks(xTrack) {
+      this.xTracks.push(xTrack)
+    },
+    setLifts(lift) {
+      this.lifts.push(lift)
+    },
+    /**
+     * 页面点击楼层时,触发
+     * @param {} floor
+     */
+    flrChg(floor) {
+      // 重新渲染楼层数据:1-清空当前楼层数据2-加载指定层数据
+      if (this.floor !== floor) {
+        this.floorDataInit(floor)
+      }
+      this.floor = floor
+    },
+    /**
+    // 设置层数,初始化层数为第一层0
+    setFlrBefore(floor) {
+      // 清空当前楼层数据
+      if (this.floor !== floor) {
+        this.carrierMapInit()
+      }
+      this.floor = floor
+      this.floorInit()
+    }, */
+    setWHId(id) {
+      this.warehouseId = id
+    }
+    /** set Val end  */
+  },
+  destroyed() {
+    this.animationTimerDes()
+  }
+}

+ 160 - 0
src/components/grid/port.vue

@@ -0,0 +1,160 @@
+<template>
+  <div
+    class="item-container"
+    :class="{
+      'item-container-vertical': !isHorizontal,
+    }"
+  >
+    <!-- rail-1 -->
+    <div
+      :style="{
+        width: baseInfo.railW,
+        height: baseInfo.railH,
+      }"
+      :class="{
+        'rail-vertical': !isHorizontal,
+      }"
+    />
+    <div
+      class="item-inter-container"
+      :class="{ 'item-inter-container-vertical': !isHorizontal }"
+    >
+      <!-- railRack-1 -->
+      <div
+        :style="{
+          width: baseInfo.railRackW,
+          height: baseInfo.railRackH,
+        }"
+      />
+      <div class="port-item-inter" :style="portItemInterSty">
+        <i class="iconfont arrow" :class="portCls" />
+      </div>
+      <!-- railRack-2 -->
+      <div
+        :style="{
+          width: baseInfo.railRackW,
+          height: baseInfo.railRackH,
+        }"
+      />
+    </div>
+    <!-- rail-2 -->
+    <div
+      :style="{
+        width: baseInfo.railW,
+        height: baseInfo.railH,
+      }"
+    />
+    <!--railBound  -->
+    <div
+      v-if="railBoundShowNL(r, c)"
+      :style="{
+        width: baseInfo.railBoundW,
+        height: baseInfo.railBoundH,
+      }"
+    />
+  </div>
+</template>
+
+<script>
+import { OrientationRackingMap, OrientationRacking } from '@/global-cfg/global'
+const portTypeClsMap = {
+  horizontal: {
+    '00': 'icon-xiangshang',
+    '01': 'icon-xiangshang arrow-active',
+    '02': 'icon-paixu arrow-active',
+    10: 'icon-paixu',
+    11: 'icon-paixu arrow-active',
+    12: 'icon-xiangshang arrow-active'
+  },
+  vertical: {
+    20: 'icon-xiangyou',
+    21: 'icon-xiangyou arrow-active',
+    22: 'icon-xiangzuo arrow-active',
+    30: 'icon-xiangzuo',
+    31: 'icon-xiangzuo arrow-active',
+    32: 'icon-xiangyou arrow-active'
+  }
+}
+export default {
+  props: {
+    type: {
+      type: Number,
+      default: 0
+    },
+    itemOperStatus: {
+      type: String,
+      default: ''
+    },
+    orientationRacking: {
+      type: Number,
+      default: OrientationRacking.HORIZONTAL
+    },
+    isHorizontal: {
+      type: Boolean,
+      default: true
+    },
+    r: {
+      type: Number,
+      default: 0
+    },
+    c: {
+      type: Number,
+      default: 0
+    },
+    railBoundShowNL: {
+      type: Function,
+      default: () => {}
+    },
+    baseInfo: {
+      type: Object,
+      require: true,
+      default: () => {
+        return {}
+      }
+    },
+    portHeight: {
+      type: String,
+      default: '32px'
+    },
+    portTypeIn: {
+      type: Number,
+      default: 0
+    }
+  },
+  data() {
+    return {
+      portType: this.portTypeIn
+    }
+  },
+  computed: {
+    portItemInterSty() {
+      if (this.type === 0 || this.type === 1) {
+        return {
+          width: this.baseInfo.itemInterW,
+          height: this.portHeight
+        }
+      }
+      if (this.type === 2 || this.type === 3) {
+        return {
+          width: this.portHeight,
+          height: this.baseInfo.itemInterH
+        }
+      }
+      return {}
+    },
+    portCls() {
+      return portTypeClsMap[OrientationRackingMap[this.orientationRacking]][
+        this.type + '' + this.portType
+      ]
+    }
+  },
+  watch: {
+    portTypeIn(value) {
+      this.portType = value
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+@import "./scss/grid.scss";
+</style>

+ 513 - 0
src/components/grid/scss/grid.scss

@@ -0,0 +1,513 @@
+@import "./variables.scss";
+
+.grid-container {
+  // position: absolute;
+  // border: $rackingColor $rackingContainrWid solid; //外框架额外加了2px样式
+  background-color: $itemBgColor;
+
+  .g-row {
+    display: flex;
+
+    .item {
+      position: relative;
+      background: $gridUnitColor;
+
+      .port-c {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        // 横向 上面
+        &-h-start {
+          left: 0;
+          top: -100%;
+        }
+
+        &-h-end {
+          left: 0;
+          bottom: -100%;
+        }
+
+        &-s-start {
+          top: 0;
+          left: -100%;
+        }
+
+        &-s-end {
+          top: 0;
+          right: -100%;
+        }
+
+        .port {
+          font-size: $portW;
+          color: $portColorDis;
+
+          &-vertical {
+            width: $portH;
+            height: $portW;
+          }
+
+          &-active {
+            color: $portColor;
+          }
+        }
+      }
+
+      .indx-c {
+        position: absolute;
+        width: 100%;
+        height: 100%;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+
+        .indx {
+          color: #909399;
+        }
+
+        &-col-first {
+          top: 0;
+          left: -100%;
+
+          &-port {
+            left: -200%;
+          }
+        }
+
+        &-col-last {
+          top: 0;
+          right: -100%;
+
+          &-port {
+            right: -200%;
+          }
+        }
+
+        &-row-last {
+          left: 0;
+          bottom: -100%;
+
+          &-port {
+            bottom: -200%;
+          }
+        }
+
+        &-row-first {
+          // writing-mode: vertical-rl;
+          // text-orientation: mixed;
+          left: 0;
+          top: -100%;
+
+          &-port {
+            top: -200%;
+          }
+        }
+      }
+
+      .no-det {
+        // border: 0.5px solid $railColor;
+        border-left: 0.5px solid $railColor;
+        border-right: 0.5px solid $railColor;
+        border-top: 0.5px solid $palletSpeCo;
+        border-bottom: 0.5px solid $palletSpeCo;
+      }
+
+      .item-container {
+        overflow: hidden;
+        display: flex;
+        position: relative;
+        justify-content: center;
+        align-items: center;
+        width: 100%;
+        height: 100%;
+
+        &-vertical {
+          flex-direction: column;
+        }
+
+        .goods-no-det {
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          background-color: $goodsColor;
+        }
+
+        .carrier-no-det {
+          position: absolute;
+          width: 100%;
+          height: 100%;
+          background-color: $carrierItemColor;
+          display: flex;
+          justify-content: center;
+          align-items: center;
+
+          .goods-no-det-withc {
+            position: absolute;
+            width: 60%;
+            height: 60%;
+            background-color: $goodsColor;
+            visibility: hidden;
+          }
+        }
+
+        .line-con {
+          display: flex;
+          flex-wrap: wrap;
+          position: absolute;
+          width: 100%;
+          height: 100%;
+
+          &-vertical {
+            flex-direction: column;
+          }
+
+          .line {
+            visibility: hidden;
+            width: 50%;
+            height: 100%;
+
+            &-vertical {
+              width: 100%;
+              height: 50%;
+            }
+          }
+
+          .line-go {
+            border-right: $lineW solid $lineGoColor;
+
+            &-vertical {
+              border-right: none;
+              border-bottom: $lineW solid $lineGoColor;
+            }
+          }
+
+          .line-back {
+            border-left: $lineW solid $lineBackColor;
+
+            &-vertical {
+              border-left: none;
+              border-top: $lineW solid $lineBackColor;
+            }
+          }
+
+          .line-xtrack {
+            flex-basis: 50%;
+            height: 50%;
+          }
+
+          .line-xtrack-vertical {
+            flex-basis: 50%;
+            height: 50%;
+          }
+
+          .line-xtrack:nth-child(1),
+          .line-xtrack:nth-child(2) {
+            height: calc(50% - #{$lineW})
+          }
+
+          .line-xtrack:nth-child(3),
+          .line-xtrack:nth-child(4) {
+            height: calc(50% + #{$lineW})
+          }
+
+          .line-xtrack-go {
+
+            // 路线的定制 从后台推送出来的数据都使用go类型20230516
+            // -line type - 定位四个方块 从上到下,从左到右 1 2 3 4 &-h(样式)-1田字格里第几个方块
+            &-h-1 {
+              border-bottom: $lineW solid $lineGoColor;
+            }
+
+            &-h-2 {
+              border-bottom: $lineW solid $lineGoColor;
+            }
+
+            &-s-1 {
+              border-right: $lineW solid $lineGoColor;
+            }
+
+            &-s-3 {
+              border-right: $lineW solid $lineGoColor;
+            }
+
+            &-1-1 {
+              border-right: $lineW solid $lineGoColor;
+              border-bottom: $lineW solid $lineGoColor;
+            }
+
+            // &-2-2 {
+            //   border-left: $lineW solid $lineGoColor;
+            //   border-bottom: $lineW solid $lineGoColor;
+            // }
+
+            &-2-1 {
+              border-right: $lineW solid $lineGoColor;
+            }
+
+            &-2-2 {
+              border-bottom: $lineW solid $lineGoColor;
+            }
+
+            // &-3-3 {
+            //   border-right: $lineW solid $lineGoColor;
+            //   border-top: $lineW solid $lineGoColor;
+            // }
+            &-3-1 {
+              border-bottom: $lineW solid $lineGoColor;
+            }
+
+            &-3-3 {
+              border-right: $lineW solid $lineGoColor;
+            }
+
+            &-4-3 {
+              border-right: $lineW solid $lineGoColor;
+            }
+
+            &-4-2 {
+              border-bottom: $lineW solid $lineGoColor;
+            }
+          }
+
+          // -line type h s 1 2 3 4 - 定位四个方块 从上到下,从左到右 1 2 3 4
+          .line-xtrack-back {
+            &-1-2 {
+              border-left: $lineW solid $lineBackColor;
+            }
+
+            &-1-3 {
+              border-top: $lineW solid $lineBackColor;
+            }
+
+            &-h-3 {
+              border-top: $lineW solid $lineBackColor;
+            }
+
+            &-h-4 {
+              border-top: $lineW solid $lineBackColor;
+            }
+
+            &-s-2 {
+              border-left: $lineW solid $lineBackColor;
+            }
+
+            &-s-4 {
+              border-left: $lineW solid $lineBackColor;
+            }
+
+
+
+            &-2-2 {
+              border-left: $lineW solid $lineBackColor;
+              border-bottom: $lineW solid $lineBackColor;
+            }
+
+            // &-3-3 {
+            //   border-right: $lineW solid $lineBackColor;
+            //   border-top: $lineW solid $lineBackColor;
+            // }
+
+            &-3-1 {
+              border-bottom: $lineW solid $lineBackColor;
+            }
+
+            &-3-4 {
+              border-left: $lineW solid $lineBackColor;
+            }
+
+            &-4-4 {
+              border-left: $lineW solid $lineBackColor;
+              border-top: $lineW solid $lineBackColor;
+            }
+          }
+
+        }
+
+        .ware-rack-bound-base {
+          background-color: $wareRackBoundBgColor;
+        }
+
+        .rail-bound-base {
+          width: $railBoundW;
+          height: $railBoundH;
+          background-color: $railBoundBgColor;
+
+          &-vertical {
+            width: $railBoundH;
+            height: $railBoundW;
+          }
+        }
+
+        .rail-base {
+          width: $railW;
+          height: $railH;
+          background-color: $railColor;
+
+          &-vertical {
+            width: $railH;
+            height: $railW;
+          }
+        }
+
+        .rail-xTrack {
+          background-color: $xTrackBgColor;
+        }
+
+        .rail-transport {
+          background-color: $transportRailBgc;
+        }
+
+        .rail-unUse {
+          background-color: $unUseColor;
+        }
+
+        .rail-lift {
+          background-color: $liftColor;
+        }
+
+        .rail-bound-xTrack {
+          background-color: $xTrackBgColor;
+        }
+
+        .item-inter-container {
+          position: relative;
+          display: flex;
+          flex-direction: column;
+          justify-content: center;
+          align-items: center;
+          width: calc(100% - #{$railW}*2 - #{$railBoundW}*2);
+          height: $itemInterH;
+          background-color: $gridUnitColor;
+          border-top: 0.5px dashed $palletSpeCo;
+          border-bottom: 0.5px dashed $palletSpeCo;
+
+          &-vertical {
+            width: $itemInterH;
+            height: calc(100% - #{$railW}*2 - #{$railBoundW}*2);
+            flex-direction: row;
+            border-top: none;
+            border-bottom: none;
+            border-left: 0.5px dashed $palletSpeCo;
+            border-right: 0.5px dashed $palletSpeCo;
+          }
+
+          .railRack-base {
+            background-color: $rackingColor;
+          }
+
+          .rail-rack-xTrack {
+            background-color: $railColor;
+          }
+
+          .goods {
+            position: absolute;
+            display: flex;
+            visibility: hidden;
+            background-color: $goodsColor;
+            width: $goodsW;
+            height: $goodsH;
+          }
+
+          .itemInter-xTrack {
+            background-color: $xTrackBgColor;
+          }
+
+          .itemInter-transport {
+            background-color: $transportColor;
+          }
+
+          .itemInter-unUse {
+            background-color: $unUseColor;
+          }
+
+          .itemInter-lift {
+            background-color: $liftColor;
+          }
+        }
+
+        // .item-inter-container-vertical {
+        //   flex-direction: row;
+        // }
+      }
+
+      .dis-vis {
+        visibility: hidden;
+      }
+
+      .global-rack {
+        position: absolute;
+        background-color: $rackingColor;
+      }
+
+      .global-rack-top {
+        height: $rackingGlobalWid;
+        width: 100%;
+        top: -#{$rackingGlobalWid};
+        left: 0;
+      }
+
+      .global-rack-bottom {
+        height: $rackingGlobalWid;
+        width: 100%;
+        bottom: -#{$rackingGlobalWid};
+        left: 0;
+      }
+
+      .global-rack-left {
+        height: 100%;
+        width: $rackingGlobalWid;
+        top: 0;
+        left:-#{$rackingGlobalWid};
+      }
+
+      .global-rack-right {
+        height: 100%;
+        width: $rackingGlobalWid;
+        top: 0;
+        right:-#{$rackingGlobalWid};
+      }
+
+      // item样式结尾
+    }
+
+    .ware-house-item {
+      background-color: $wareBgCo;
+      border: $wareUnitBorderCo $wareUnitBorderWid solid;
+    }
+
+    .item-xTrack {
+      background-color: $xTrackBgColor;
+    }
+
+    .item-transport {
+      background-color: $transportRailBgc;
+      border: none;
+    }
+
+    .item-unUse {
+      background-color: $unUseColor;
+    }
+
+    .item-lift {
+      background-color: $liftColor;
+      border: none;
+    }
+
+    .item-standCol {
+      background-color: $standColColor;
+    }
+
+    .item-carriageway {
+      background-color: $carriagewayColor;
+    }
+    .item-park {
+      background-color: $parkColor;
+    }
+    .item-charge {
+      background-color: $chargeColor;
+    }
+  }
+}

+ 122 - 0
src/components/grid/scss/variables.scss

@@ -0,0 +1,122 @@
+$palletWid: 30px;
+$palletLen: 24px;
+$carrierWid: 26px;
+$carrierLen: 32px;
+$railInterval: 2px;
+$railIntervalColor: RED;
+$railWid: 3.5px;
+$railColor: #edf8e2;
+$railStyle: solid;
+$rackingWid: 1px;
+$rackingColor: #5a62c6;//#5a62c6
+$rackingContainrWid: 2px;
+$itemBgColor: #84a17c;
+$gridUnitColor: #84a17c;
+$xTrackBgColor: #9db498;
+$xTrackDisplay: none;
+$xTrackRowWid: 100%;
+$xTrackColHeight: $palletLen + $railInterval;
+// $liftColor: #6e716b;
+$liftColor: #F9C45A;
+$liftBorderColor: #b4c6ac;
+$liftBorderWidth: $rackingWid * 3;
+$wareRackBoundBgColor: #84a17c;
+// $railBoundBgColor: #84a17c;
+$railBoundBgColor: #5a62c6;//使用支架颜色
+$carrierColor: #a8aaa9;
+$carrierItemColor: #2c97c4;
+$carrierMainBorderColor: #635b62;
+$goodsColor: #936844;
+$unUseColor: #e8e8e8;
+$portColor: #55b352;
+$portHeight: 32px;
+$portPos: -38px;
+$portColorDis: #555;
+// $transportColor:#804000;
+$transportColor: rgba(#804000, 0.45);
+// $transportRailBgc: #804000;
+$transportRailBgc: #A7518E;
+$palletSpeCo: #b3c2b3;
+$lineGoColor: gray;
+$lineBackColor: gray;
+//横向时数据
+// $railBoundW: 1.5%;
+$railBoundW: 1px;
+$railBoundH: 100%;
+// $railW: 3%;
+$railW: 2.5px;
+$railH: 100%;
+// $itemInterW: '98%';基于其他计算
+$itemInterH: 100%;
+$wareRackBoundW: 0.5%;
+$wareRackBoundH: 100%;
+$lineW: 3px;
+$lineH: 100%;
+$palletSpeW: 1px;
+$palletSpeH: 1px;
+$goodsW: 100%;
+$goodsH: 100%;
+$carrierGoodsW: 80%;
+$carrierGoodsH: 80%;
+$carrierBorderW: 5%;
+$carrierBordeH: 100%;
+$wareBgCo: #e8e8e8;
+$portW: 60%;
+$portH: 100%;
+$standColColor: #87cefa;
+$carriagewayColor: #98fb98;
+$wareUnitBorderCo: #fff;
+$wareUnitBorderWid: 1px;
+$rackingGlobalWid: 2px;
+$chargeColor:green;
+$parkColor:blue;
+:export {
+  palletWid: $palletWid;
+  palletLen: $palletLen;
+  carrierWid: $carrierWid;
+  carrierLen: $carrierLen;
+  railInterval: $railInterval;
+  railWid: $railWid;
+  railStyle: $railStyle;
+  rackingWid: $rackingWid;
+  rackingContainrWid: $rackingContainrWid;
+  itemBgColor: $itemBgColor;
+  gridUnitColor: $gridUnitColor;
+  rackingColor: $rackingColor;
+  chargeColor:$chargeColor;
+  parkColor:$parkColor;
+  railColor: $railColor;
+  xTrackBgColor: $xTrackBgColor;
+  railIntervalColor: $railIntervalColor;
+  xTrackDisplay: $xTrackDisplay;
+  xTrackRowWid: $xTrackRowWid;
+  xTrackColHeight: $xTrackColHeight;
+  liftColor: $liftColor;
+  liftBorderColor: $liftBorderColor;
+  liftBorderWidth: $liftBorderWidth;
+  wareRackBoundBgColor: $wareRackBoundBgColor;
+  railBoundBgColor: $railBoundBgColor;
+  carrierColor: $carrierColor;
+  carrierItemColor: $carrierItemColor;
+  carrierMainBorderColor: $carrierMainBorderColor;
+  goodsColor: $goodsColor;
+  unUseColor: $unUseColor;
+  portColor: $portColor;
+  portHeight: $portHeight;
+  portPos: $portPos;
+  portColorDis: $portColorDis;
+  transportColor: $transportColor;
+  transportRailBgc: $transportRailBgc;
+  palletSpeCo: $palletSpeCo;
+  lineGoColor: $lineGoColor;
+  lineBackColor: $lineBackColor;
+  railW: $railW;
+  wareBgCo: $wareBgCo;
+  portW: $portW;
+  portH: $portH;
+  standColColor: $standColColor;
+  carriagewayColor: $carriagewayColor;
+  wareUnitBorderCo: $wareUnitBorderCo;
+  wareUnitBorderWid: $wareUnitBorderWid;
+  rackingGlobalWid: $rackingGlobalWid;
+}

+ 0 - 15
src/components/map/GLB-GRID-CONST.js

@@ -1,15 +0,0 @@
-import {
-  COMMON_CONST,
-  LOCTYPE,
-  ITEM_ATTRIBUTE_TYPE,
-  ITEMSTATUS,
-  getCFG,
-} from "@/components/map/GRID-CONST";
-
-window.GRID_CONST = {
-  getCFG,
-  COMMON_CONST,
-  LOCTYPE,
-  ITEM_ATTRIBUTE_TYPE,
-  ITEMSTATUS,
-};

+ 0 - 1638
src/components/map/GRID-CONST.js

@@ -1,1638 +0,0 @@
-import scss from "./grid-svg/variables.scss";
-import scssCanvas from "./grid-canvas/variables-canvas.scss";
-export function getScss(type) {
-  if (type === "canvas") {
-    return scssCanvas;
-  } else {
-    return scss;
-  }
-}
-export const COMMON_CONST = {
-  idSep: "-",
-  MAIN_TRACK_DIR: {
-    DEFAULT: 0,
-    // 支架的方向
-    HORIZONTAL: 0, // 横
-    VERTICAL: 1, // 纵
-  },
-};
-export const LOCTYPE = {
-  default: "default",
-  rack: "rack",
-  around: "around",
-};
-export const ITEM_ATTRIBUTE_TYPE = {
-  storageLoc: "storageLoc",
-  dev: "dev",
-  sysSet: "sysSet",
-};
-export const ITEMSTATUS = {
-  default: "default",
-  storageLoc: "storageLoc",
-  shuttle: "shuttle",
-  path: "path",
-  pathHasDrived: "pathHasDrived",
-  xTrack: "xTrack",
-  xTrackEx: "xTrackEx",
-  carriageway: "carriageway",
-  lift: "lift",
-  unExist: "unExist",
-  unUse: "unUse",
-  charge: "charge",
-  entranceAndExit: "entranceAndExit",
-  park: "park",
-  transport: "transport",
-  pillar: "pillar",
-  goods: "goods",
-};
-
-export const getCFG = (type) => {
-  const scss = getScss(type);
-  return {
-    baseItemStsArr: [
-      {
-        key: "default",
-        name: "默认", //用于给默认样式
-        displayControl: {
-          isNotShowInCfg: true, // 不在任何配置中显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.default],
-          borderColor: scss["borderColor"],
-          lineWidth: 1,
-        },
-      },
-      {
-        key: "shuttle",
-        name: "四向车",
-        displayControl: {
-          isNotShowInCfg: true, // 不在任何配置中显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.shuttle],
-        },
-      },
-      {
-        key: "path",
-        name: "路线",
-        displayControl: {
-          isNotShowInCfg: true, // 不在任何配置中显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.path],
-          lineWidth: 2,
-        },
-      },
-      {
-        key: "pathHasDrived",
-        name: "路线",
-        displayControl: {
-          isNotShowInCfg: true, // 不在任何配置中显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.pathHasDrived],
-          lineWidth: 2,
-        },
-      },
-      {
-        key: "goods",
-        name: "货物",
-        displayControl: {
-          isNotShowInCfg: true, // 不在任何配置中显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.goods],
-          lineWidth: 1,
-        },
-      },
-      {
-        key: "xTrack",
-        name: "主轨道",
-        disableSwitchIsByFloor: true,
-        handleMouseMove: function (e) {
-          return false;
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.xTrack],
-        },
-        cfgTable: {
-          isNotApplyToOtherFloor: true,
-          isNotApplyToTotalRow: true,
-          isNotApplyToTotalCol: true,
-          columnsCfgArr: function (formData) {
-            if (!formData.mainTrackDir) {
-              return [
-                {
-                  prop: "r",
-                  label: "行",
-                  type: "number",
-                  template: true,
-                  inputProps: {
-                    type: "number",
-                    placeholder: "",
-                  },
-                },
-              ];
-            } else {
-              return [
-                {
-                  prop: "c",
-                  label: "列",
-                  type: "number",
-                  template: true,
-                  inputProps: {
-                    placeholder: "",
-                    type: "number",
-                    maxWidth: 100,
-                  },
-                },
-              ];
-            }
-          },
-          toPageDataFun: function (formData) {
-            let res = [];
-            if (formData[ITEMSTATUS.xTrack]) {
-              formData[ITEMSTATUS.xTrack].forEach((item) => {
-                let ele = { c: undefined, r: undefined, f: undefined };
-                if (!item.mainTrackDir) {
-                  ele.r = item;
-                } else {
-                  ele.c = item;
-                }
-                res.push(ele);
-              });
-            }
-            return res;
-          },
-          toBackDataFun: function (formData, cfgTableData) {
-            let res = [];
-            if (cfgTableData.length > 0) {
-              cfgTableData.forEach((item) => {
-                if (!formData.mainTrackDir) {
-                  res.push(item.r);
-                } else {
-                  res.push(item.c);
-                }
-              });
-            }
-            return res;
-          },
-        },
-        cellSelPanel: {
-          procItemDataFun: function (that) {
-            const uniqueRowsOrCols = that.getUniqueRowsOrCols();
-            return that.getOperItemsForLine(uniqueRowsOrCols);
-          },
-        },
-      },
-      {
-        key: "xTrackEx",
-        name: "拓展主轨道",
-        sty: {
-          fillColor: scss[ITEMSTATUS.xTrack],
-        },
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-      },
-      {
-        key: "carriageway",
-        backKey: "yTrack",
-        name: "行车道",
-        sty: {
-          fillColor: scss[ITEMSTATUS.carriageway],
-        },
-      },
-      {
-        key: "lift",
-        name: "提升机",
-        disableSwitchIsByFloor: true,
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.lift],
-        },
-        cfgTable: {
-          isNotApplyToOtherFloor: true,
-          isNotApplyToTotalRow: true,
-          isNotApplyToTotalCol: true,
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "max_floor",
-                label: "最大层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "rS",
-                label: "起始行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "rE",
-                label: "结束行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "cS",
-                label: "起始列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "cE",
-                label: "结束列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-      },
-      {
-        key: "unUse",
-        // backKey: 'unUse',
-        name: "不可用",
-        sty: {
-          fillColor: scss[ITEMSTATUS.unUse],
-        },
-      },
-      {
-        key: "unExist",
-        // backKey: 'unExist',
-        name: "不存在",
-        sty: {
-          fillColor: scss[ITEMSTATUS.unExist],
-        },
-      },
-      {
-        key: "park",
-        name: "停车位",
-        sty: {
-          fillColor: scss[ITEMSTATUS.park],
-        },
-      },
-      {
-        key: "charge",
-        name: "充电桩",
-        backKey: "charger",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.dev,
-        sty: {
-          fillColor: scss[ITEMSTATUS.charge],
-          width: 6,
-        },
-        cfgTable: {
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "f",
-                label: "层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-        drawFun: function (that, col) {
-          const ctx = that.ctx;
-          ctx.save();
-
-          // 设置填充颜色
-          ctx.fillStyle = this.sty.fillColor;
-
-          // 获取坐标
-          const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-            that.calculateCoordinates(col);
-
-          // 计算矩形的宽度和位置
-          const width = x2 - x1;
-          const rectHeight = this.sty.width || 6; // 使用配置的宽度,默认为6
-
-          // 在顶部绘制矩形
-          ctx.fillRect(x1, y1, width, rectHeight);
-
-          ctx.restore();
-          return true;
-        },
-        drawFunSvg: function (that, col) {
-          const group = that.createSvgElement("g");
-
-          // 获取坐标和倾斜角度
-          const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-            that.component.calculateCoordinates(col);
-          const angle = that.component.includedAngle || 90;
-          const angleInRadians = (angle * Math.PI) / 180;
-
-          // 计算充电桩的高度
-          const rectHeight = this.sty.width || 6;
-
-          // 计算平行四边形的四个顶点
-          // a点和b点就是原始的x1,y1和x2,y2
-          const ax = x1;
-          const ay = y1;
-          const bx = x2;
-          const by = y2;
-
-          // 计算单元格的倾斜向量
-          const cellVectorX = x4 - x1;
-          const cellVectorY = y4 - y1;
-          const cellLength = Math.sqrt(
-            cellVectorX * cellVectorX + cellVectorY * cellVectorY
-          );
-
-          // 计算单位向量
-          const unitVectorX = cellVectorX / cellLength;
-          const unitVectorY = cellVectorY / cellLength;
-
-          // 使用单元格的倾斜方向计算偏移量
-          const offsetX = rectHeight * unitVectorX;
-          const offsetY = rectHeight * unitVectorY;
-
-          // 计算c点和d点
-          const dx = ax + offsetX;
-          const dy = ay + offsetY;
-          const cx = bx + offsetX;
-          const cy = by + offsetY;
-
-          // 创建平行四边形
-          const rect = that.createSvgElement("polygon", {
-            points: `${ax},${ay} ${bx},${by} ${cx},${cy} ${dx},${dy}`,
-            fill: this.sty.fillColor,
-            stroke: "none",
-          });
-
-          group.appendChild(rect);
-          that.mainGroup.appendChild(group);
-          return true;
-        },
-      },
-      {
-        key: "transport",
-        backKey: "conveyor",
-        name: "输送机",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.dev,
-        sty: {
-          fillColor: scss[ITEMSTATUS.transport],
-          borderColor: scss[ITEMSTATUS.transport + "BorderColor"],
-          borderWidth: 4,
-        },
-        cfgTable: {
-          isNotApplyToOtherFloor: true,
-          isNotApplyToTotalRow: true,
-          isNotApplyToTotalCol: true,
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "f",
-                label: "层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "rS",
-                label: "起始行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "rE",
-                label: "结束行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "cS",
-                label: "起始列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "cE",
-                label: "结束列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-        drawFun: function (that, col) {
-          const ctx = that.ctx;
-          ctx.save();
-
-          // 设置填充和边框颜色
-          ctx.fillStyle = this.sty.fillColor;
-          ctx.strokeStyle = this.sty.borderColor;
-
-          const borderWidth = this.sty.borderWidth;
-          const offset = borderWidth / 2;
-
-          // 获取外部轮廓坐标
-          const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-            that.calculateCoordinates(col);
-
-          // 计算内部偏移量
-          const dx =
-            ((x2 - x1) * offset) / Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
-          const dy =
-            ((y2 - y1) * offset) / Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
-
-          // 计算内部轮廓坐标
-          const ix1 = x1 + dx;
-          const iy1 = y1 + dy;
-          const ix2 = x2 - dx;
-          const iy2 = y2 + dy;
-          const ix3 = x3 - dx;
-          const iy3 = y3 - dy;
-          const ix4 = x4 + dx;
-          const iy4 = y4 - dy;
-
-          // 绘制主体形状
-          ctx.beginPath();
-          ctx.moveTo(ix1, iy1);
-          ctx.lineTo(ix2, iy2);
-          ctx.lineTo(ix3, iy3);
-          ctx.lineTo(ix4, iy4);
-          ctx.closePath();
-          ctx.fill();
-
-          // 绘制左边框
-          ctx.beginPath();
-          ctx.lineWidth = borderWidth;
-          ctx.moveTo(ix1, iy1);
-          ctx.lineTo(ix4, iy4);
-          ctx.stroke();
-
-          // 绘制右边框
-          ctx.beginPath();
-          ctx.moveTo(ix2, iy2);
-          ctx.lineTo(ix3, iy3);
-          ctx.stroke();
-
-          ctx.restore();
-          return true;
-        },
-
-        drawFunSvg: function (that, col) {
-          const group = that.createSvgElement("g");
-
-          // 获取坐标和计算偏移量
-          const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-            that.component.calculateCoordinates(col);
-          const borderWidth = this.sty.borderWidth || 4;
-          const offset = borderWidth / 2;
-
-          // 计算倾斜角度
-          const angle = that.component.includedAngle || 90;
-          const angleInRadians = (angle * Math.PI) / 180;
-
-          // 根据倾斜角度调整右侧偏移量,使视觉效果一致
-          const rightOffset = offset / Math.sin(angleInRadians);
-
-          // 计算内部轮廓坐标
-          const ix1 = x1 + offset;
-          const iy1 = y1;
-          const ix2 = x2 - rightOffset;
-          const iy2 = y2;
-          const ix3 = x3 - rightOffset;
-          const iy3 = y3;
-          const ix4 = x4 + offset;
-          const iy4 = y4;
-
-          // 创建外部轮廓(左侧平行四边形)
-          const leftPolygon = that.createSvgElement("polygon", {
-            points: `${x1},${y1} ${ix1},${iy1} ${ix4},${iy4} ${x4},${y4}`,
-            fill: this.sty.borderColor,
-            stroke: "none",
-          });
-
-          // 创建外部轮廓(右侧平行四边形)
-          const rightPolygon = that.createSvgElement("polygon", {
-            points: `${x2},${y2} ${ix2},${iy2} ${ix3},${iy3} ${x3},${y3}`,
-            fill: this.sty.borderColor,
-            stroke: "none",
-          });
-
-          // 应用偏移量到所有多边形
-          [leftPolygon, rightPolygon].forEach((polygon) => {
-            const points = polygon.getAttribute("points");
-            const offsetPoints = points
-              .split(" ")
-              .map((point) => {
-                const [x, y] = point.split(",");
-                return `${parseFloat(x)},${parseFloat(y)}`;
-              })
-              .join(" ");
-            polygon.setAttribute("points", offsetPoints);
-          });
-          group.appendChild(leftPolygon); // 左边框
-          group.appendChild(rightPolygon); // 右边框
-
-          that.mainGroup.appendChild(group);
-          return true;
-        },
-        getTheTargetStsWhenCfg: function (that, ele) {
-          if (ele.statusList && Array.isArray(ele.statusList)) {
-            // 检查 statusList 中是否存在 this.key 的状态
-            const existingStatus = ele.statusList.find(
-              (item) => item.status === this.key
-            );
-            return existingStatus ? "" : this.key;
-          }
-          return this.key;
-        },
-      },
-      {
-        key: "entranceAndExit",
-        name: "出入口",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.sysSet,
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        paramInfoArr: [
-          {
-            type: "radio",
-            defaultVal: "",
-            paramKeyVal: "type",
-            options: [
-              { label: "出入口", value: "" },
-              { label: "出口", value: "exit" },
-              { label: "入口", value: "entrance" },
-            ],
-          },
-        ],
-        paramToMergeObj: {
-          type: "",
-          arrowFlow: 0,
-        },
-        sty: {
-          arrowFillColor: scss["arrowColor"],
-          arrowStrokeColor: scss["arrowColor"],
-          arrowLineWidth: 1,
-        },
-        getTheTargetStsWhenCfg: function (that, ele) {
-          if (ele.statusList && Array.isArray(ele.statusList)) {
-            // 检查 statusList 中是否存在 this.key 的状态
-            const existingStatus = ele.statusList.find(
-              (item) => item.status === this.key
-            );
-            const isDisItemSts =
-              existingStatus &&
-              (!that.paramToMergeObj.type ||
-                (existingStatus.paramToMergeObj &&
-                  existingStatus.paramToMergeObj.arrowFlow === 1));
-            return isDisItemSts ? "" : this.key;
-          }
-          return this.key;
-        },
-        handleDoubleClick: function (e) {
-          return false;
-        },
-        handleMouseMove: function (e) {
-          return false;
-        },
-        drawFun: function (that, col) {
-          let arrowType;
-          const isHorizontal = that.isHorizontal();
-          const angle = that.rotationAngleType || 0;
-          // mergeObj.type = 'exit' //TEST
-          if (col.type === "exit") {
-            if (isHorizontal) {
-              switch (angle) {
-                case 0:
-                  arrowType = "down";
-                  break;
-                case 1:
-                  arrowType = "left";
-                  break;
-                case 2:
-                  arrowType = "up";
-                  break;
-                case 3:
-                  arrowType = "right";
-                  break;
-              }
-            } else {
-              switch (angle) {
-                case 0:
-                  arrowType = "left";
-                  break;
-                case 1:
-                  arrowType = "up";
-                  break;
-                case 2:
-                  arrowType = "right";
-                  break;
-                case 3:
-                  arrowType = "down";
-                  break;
-              }
-            }
-          } else if (col.type === "entrance") {
-            if (isHorizontal) {
-              switch (angle) {
-                case 0:
-                  arrowType = "up";
-                  break;
-                case 1:
-                  arrowType = "right";
-                  break;
-                case 2:
-                  arrowType = "down";
-                  break;
-                case 3:
-                  arrowType = "left";
-                  break;
-              }
-            } else {
-              switch (angle) {
-                case 0:
-                  arrowType = "right";
-                  break;
-                case 1:
-                  arrowType = "down";
-                  break;
-                case 2:
-                  arrowType = "left";
-                  break;
-                case 3:
-                  arrowType = "up";
-                  break;
-              }
-            }
-          } else {
-            // 双向箭头的情况保持不变
-            if (angle === 1 || angle === 3) {
-              arrowType = isHorizontal ? "bidirectional-h" : "bidirectional-v";
-            } else {
-              arrowType = isHorizontal ? "bidirectional-v" : "bidirectional-h";
-            }
-          }
-          if (col.type && col.arrowFlow === 1) {
-            const reverseMap = {
-              up: "down",
-              down: "up",
-              left: "right",
-              right: "left",
-            };
-            arrowType = reverseMap[arrowType] || arrowType;
-          }
-          that.ctx.fillStyle = this.sty.arrowFillColor;
-          that.ctx.strokeStyle = this.sty.arrowStrokeColor;
-          that.ctx.lineWidth = this.sty.arrowLineWidth;
-          const coordinates = that.calculateCoordinates(col);
-          drawArrow(that.ctx, coordinates, arrowType);
-          return "entranceAndExit-drawFun";
-        },
-        drawFunSvg: function (that, col) {
-          const group = that.createSvgElement("g");
-          let arrowType;
-          const isHorizontal = that.component.isHorizontal();
-          const angle = that.component.rotationAngleType || 0;
-
-          // 确定箭头类型
-          if (col.type === "exit") {
-            if (isHorizontal) {
-              switch (angle) {
-                case 0:
-                  arrowType = "down";
-                  break;
-                case 1:
-                  arrowType = "left";
-                  break;
-                case 2:
-                  arrowType = "up";
-                  break;
-                case 3:
-                  arrowType = "right";
-                  break;
-              }
-            } else {
-              switch (angle) {
-                case 0:
-                  arrowType = "left";
-                  break;
-                case 1:
-                  arrowType = "up";
-                  break;
-                case 2:
-                  arrowType = "right";
-                  break;
-                case 3:
-                  arrowType = "down";
-                  break;
-              }
-            }
-          } else if (col.type === "entrance") {
-            if (isHorizontal) {
-              switch (angle) {
-                case 0:
-                  arrowType = "up";
-                  break;
-                case 1:
-                  arrowType = "right";
-                  break;
-                case 2:
-                  arrowType = "down";
-                  break;
-                case 3:
-                  arrowType = "left";
-                  break;
-              }
-            } else {
-              switch (angle) {
-                case 0:
-                  arrowType = "right";
-                  break;
-                case 1:
-                  arrowType = "down";
-                  break;
-                case 2:
-                  arrowType = "left";
-                  break;
-                case 3:
-                  arrowType = "up";
-                  break;
-              }
-            }
-          } else {
-            if (angle === 1 || angle === 3) {
-              arrowType = isHorizontal ? "bidirectional-h" : "bidirectional-v";
-            } else {
-              arrowType = isHorizontal ? "bidirectional-v" : "bidirectional-h";
-            }
-          }
-
-          if (col.type && col.arrowFlow === 1) {
-            const reverseMap = {
-              up: "down",
-              down: "up",
-              left: "right",
-              right: "left",
-            };
-            arrowType = reverseMap[arrowType] || arrowType;
-          }
-
-          // 获取坐标
-          const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-            that.component.calculateCoordinates(col);
-          const centerX = (x1 + x2 + x3 + x4) / 4;
-          const centerY = (y1 + y2 + y3 + y4) / 4;
-          const width = Math.max(x2 - x1, x3 - x4);
-          const height = Math.max(y4 - y1, y3 - y2);
-
-          // 基准尺寸
-          const BASE_SIZE = {
-            arrowWidth: 16, // 减小箭头宽度,使其更协调
-            arrowLength: 10, // 减小箭头长度,保持比例
-            bodyThickness: 6, // 减小主体厚度,使其更精致
-          };
-
-          // 计算缩放比例
-          const minDimension = Math.min(width, height);
-          const scale = minDimension / 30; // 调整基准缩放比例
-
-          const arrowWidth = BASE_SIZE.arrowWidth * scale;
-          const arrowLength = BASE_SIZE.arrowLength * scale;
-          const bodyThickness = BASE_SIZE.bodyThickness * scale;
-
-          // 创建箭头路径
-          let pathData = "";
-          switch (arrowType) {
-            case "bidirectional-h": {
-              const bodyWidth = Math.min(width * 0.5, width - 2 * arrowLength);
-              pathData = `
-                M ${centerX - bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY + bodyThickness / 2}
-                L ${centerX - bodyWidth / 2} ${centerY + bodyThickness / 2}
-                Z
-                M ${centerX - bodyWidth / 2} ${centerY - arrowWidth / 2}
-                L ${centerX - bodyWidth / 2 - arrowLength} ${centerY}
-                L ${centerX - bodyWidth / 2} ${centerY + arrowWidth / 2}
-                Z
-                M ${centerX + bodyWidth / 2} ${centerY - arrowWidth / 2}
-                L ${centerX + bodyWidth / 2 + arrowLength} ${centerY}
-                L ${centerX + bodyWidth / 2} ${centerY + arrowWidth / 2}
-                Z
-              `;
-              break;
-            }
-            case "bidirectional-v": {
-              const bodyHeight = Math.min(
-                height * 0.5,
-                height - 2 * arrowLength
-              );
-              pathData = `
-                M ${centerX - bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY + bodyHeight / 2}
-                L ${centerX - bodyThickness / 2} ${centerY + bodyHeight / 2}
-                Z
-                M ${centerX - arrowWidth / 2} ${centerY - bodyHeight / 2}
-                L ${centerX} ${centerY - bodyHeight / 2 - arrowLength}
-                L ${centerX + arrowWidth / 2} ${centerY - bodyHeight / 2}
-                Z
-                M ${centerX - arrowWidth / 2} ${centerY + bodyHeight / 2}
-                L ${centerX} ${centerY + bodyHeight / 2 + arrowLength}
-                L ${centerX + arrowWidth / 2} ${centerY + bodyHeight / 2}
-                Z
-              `;
-              break;
-            }
-            case "down": {
-              const bodyHeight = height * 0.5;
-              pathData = `
-                M ${centerX - bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY + bodyHeight / 2}
-                L ${centerX + arrowWidth / 2} ${centerY + bodyHeight / 2}
-                L ${centerX} ${Math.min(
-                centerY + bodyHeight / 2 + arrowLength,
-                y4
-              )}
-                L ${centerX - arrowWidth / 2} ${centerY + bodyHeight / 2}
-                L ${centerX - bodyThickness / 2} ${centerY + bodyHeight / 2}
-                Z
-              `;
-              break;
-            }
-            case "left": {
-              const bodyWidth = width * 0.5;
-              pathData = `
-                M ${centerX - bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY + bodyThickness / 2}
-                L ${centerX - bodyWidth / 2} ${centerY + bodyThickness / 2}
-                Z
-                M ${centerX - bodyWidth / 2} ${centerY - arrowWidth / 2}
-                L ${Math.max(
-                  centerX - bodyWidth / 2 - arrowLength,
-                  x1
-                )} ${centerY}
-                L ${centerX - bodyWidth / 2} ${centerY + arrowWidth / 2}
-                Z
-              `;
-              break;
-            }
-            case "up": {
-              const bodyHeight = height * 0.5;
-              pathData = `
-                M ${centerX - bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY - bodyHeight / 2}
-                L ${centerX + bodyThickness / 2} ${centerY + bodyHeight / 2}
-                L ${centerX - bodyThickness / 2} ${centerY + bodyHeight / 2}
-                Z
-                M ${centerX - arrowWidth / 2} ${centerY - bodyHeight / 2}
-                L ${centerX} ${Math.max(
-                centerY - bodyHeight / 2 - arrowLength,
-                y1
-              )}
-                L ${centerX + arrowWidth / 2} ${centerY - bodyHeight / 2}
-                Z
-              `;
-              break;
-            }
-            case "right": {
-              const bodyWidth = width * 0.5;
-              pathData = `
-                M ${centerX - bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY - bodyThickness / 2}
-                L ${centerX + bodyWidth / 2} ${centerY - arrowWidth / 2}
-                L ${Math.min(
-                  centerX + bodyWidth / 2 + arrowLength,
-                  x2
-                )} ${centerY}
-                L ${centerX + bodyWidth / 2} ${centerY + arrowWidth / 2}
-                L ${centerX + bodyWidth / 2} ${centerY + bodyThickness / 2}
-                L ${centerX - bodyWidth / 2} ${centerY + bodyThickness / 2}
-                Z
-              `;
-              break;
-            }
-          }
-
-          // 创建SVG路径元素
-          const path = that.createSvgElement("path", {
-            d: pathData,
-            fill: this.sty.arrowFillColor,
-            stroke: "none", // 移除描边,使外观更清晰
-            transform: `rotate(${that.component.includedAngle}, ${centerX}, ${centerY})`, // 添加旋转变换
-          });
-
-          group.appendChild(path);
-          that.mainGroup.appendChild(group);
-          return "entranceAndExit-drawFunSvg";
-        },
-        cfgTable: {
-          toBackDataFun: function (formData, cfgTableData) {
-            let res = [];
-            if (cfgTableData.length > 0) {
-              cfgTableData.forEach((item) => {
-                if (item.type !== "exit" && item.type !== "entrance") {
-                  item.type = "";
-                  res.push(item);
-                }
-              });
-            }
-            return res;
-          },
-        },
-      },
-      {
-        key: "storageLoc",
-        name: "货位",
-        noToBackData: true,
-        displayControl: {
-          isNotShowInCfgPanel: true, // 不在按钮配置面板显示
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.storageLoc],
-        },
-      },
-      {
-        key: "digitalInput",
-        name: "光电",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.dev,
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        cfgTable: {
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "f",
-                label: "层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-        drawFun: function (that, col) {
-          return true;
-        },
-      },
-      {
-        key: "narrowGate",
-        name: "限宽门",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.dev,
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        cfgTable: {
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "f",
-                label: "层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-        drawFun: function (that, col) {
-          return true;
-        },
-      },
-      {
-        key: "codeScanners",
-        name: "扫码器",
-        backKey: "codeScanner",
-        itemAttributeType: ITEM_ATTRIBUTE_TYPE.dev,
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        cfgTable: {
-          columnsCfgArr: function (formData) {
-            return [
-              {
-                prop: "did",
-                label: "did",
-                template: true,
-              },
-              {
-                prop: "c",
-                label: "列",
-                type: "number",
-                template: true,
-                inputProps: {
-                  placeholder: "",
-                  type: "number",
-                },
-              },
-              {
-                prop: "r",
-                label: "行",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-              {
-                prop: "f",
-                label: "层",
-                type: "number",
-                template: true,
-                inputProps: {
-                  type: "number",
-                  placeholder: "",
-                },
-              },
-            ];
-          },
-        },
-        drawFun: function (that, col) {
-          return true;
-        },
-      },
-      {
-        key: LOCTYPE.around,
-        LOCTYPE: LOCTYPE.around,
-        name: "货架外围", //用于给默认样式
-        locType: LOCTYPE.around,
-        noToBackData: true,
-        disableSwitchIsByFloor: true,
-        sty: {
-          btnStyle: {
-            noIcon: true,
-          },
-          fillColor: scss[LOCTYPE.around],
-          // numSty:{
-          //     cellNumFontColor:'white'
-          // }
-        },
-        paramInfoArr: [
-          {
-            type: "input",
-            defaultVal: "",
-            paramKeyVal: "up",
-            dataType: "number",
-            label: "上",
-            rules: [
-              {
-                type: "number",
-                min: 0,
-                message: "请输入大于等于0的整数",
-                trigger: "blur",
-              },
-            ],
-          },
-          {
-            type: "input",
-            defaultVal: "",
-            paramKeyVal: "down",
-            dataType: "number",
-            label: "下",
-            rules: [
-              {
-                type: "number",
-                min: 0,
-                message: "请输入大于等于0的整数",
-                trigger: "blur",
-              },
-            ],
-          },
-          {
-            type: "input",
-            defaultVal: "",
-            paramKeyVal: "left",
-            label: "左",
-            dataType: "number",
-            rules: [
-              {
-                type: "number",
-                min: 0,
-                message: "请输入大于等于0的整数",
-                trigger: "blur",
-              },
-            ],
-          },
-          {
-            type: "input",
-            defaultVal: "",
-            paramKeyVal: "right",
-            label: "右",
-            dataType: "number",
-            rules: [
-              {
-                type: "number",
-                min: 0,
-                message: "请输入大于等于0的整数",
-                trigger: "blur",
-              },
-            ],
-          },
-        ],
-        // 添加合并参数对象
-        paramToMergeObj: {
-          up: undefined,
-          down: undefined,
-          left: undefined,
-          right: undefined,
-        },
-        updateFormDataAround: function (formData) {
-          if (!formData.around) {
-            formData.around = {};
-          }
-          Object.keys(this.paramToMergeObj).forEach((key) => {
-            formData.around[key] = this.paramToMergeObj[key];
-          });
-        },
-        validateWheConfirmCfg: function (formData, that) {
-          // 从this.paramToMergeObj获取参数
-          if (!this.paramToMergeObj) {
-            console.warn("paramToMergeObj is missing");
-            return true;
-          }
-
-          // 获取旋转角度
-          const rotation = formData.rotation || 0;
-
-          // 计算实际的起始行列
-          let rowStart, colStart;
-
-          switch (rotation) {
-            case 0: // 0度
-              rowStart = this.paramToMergeObj.down || 0;
-              colStart = this.paramToMergeObj.left || 0;
-              break;
-            case 1: // 90度
-              rowStart = this.paramToMergeObj.left || 0;
-              colStart = this.paramToMergeObj.up || 0;
-              break;
-            case 2: // 180度
-              rowStart = this.paramToMergeObj.up || 0;
-              colStart = this.paramToMergeObj.right || 0;
-              break;
-            case 3: // 270度
-              rowStart = this.paramToMergeObj.right || 0;
-              colStart = this.paramToMergeObj.down || 0;
-              break;
-            default:
-              rowStart = this.paramToMergeObj.down || 0;
-              colStart = this.paramToMergeObj.left || 0;
-          }
-
-          // 检查是否在有效范围内
-          if (rowStart < 0 || rowStart > formData.rowStart) {
-            switch (rotation) {
-              case 0: // 0度
-                that.$message.error(
-                  "下侧增加的外围数量超出仓库范围!请调整rowStart或外围下侧数量"
-                );
-                break;
-              case 1: // 90度
-                that.$message.error(
-                  "左侧增加的外围数量超出仓库范围!请调整rowStart或外围左侧数量"
-                );
-                break;
-              case 2: // 180度
-                that.$message.error(
-                  "上侧增加的外围数量超出仓库范围!请调整rowStart或外围上侧数量"
-                );
-                break;
-              case 3: // 270度
-                that.$message.error(
-                  "右侧增加的外围数量超出仓库范围!请调整rowStart或外围右侧数量"
-                );
-                break;
-              default:
-                that.$message.error(
-                  "下侧增加的外围数量超出仓库范围!请调整rowStart或外围下侧数量"
-                );
-                break;
-            }
-            return true;
-          }
-          if (colStart < 0 || colStart > formData.colStart) {
-            switch (rotation) {
-              case 0: // 0度
-                that.$message.error(
-                  "左侧增加的外围数量超出仓库范围!请调整colStart或外围左侧数量"
-                );
-                break;
-              case 1: // 90度
-                that.$message.error(
-                  "上侧增加的外围数量超出仓库范围!请调整colStart或外围上侧数量"
-                );
-                break;
-              case 2: // 180度
-                that.$message.error(
-                  "右侧增加的外围数量超出仓库范围!请调整colStart或外围右侧数量"
-                );
-                break;
-              case 3: // 270度
-                that.$message.error(
-                  "下侧增加的外围数量超出仓库范围!请调整colStart或外围下侧数量"
-                );
-                break;
-              default:
-                that.$message.error(
-                  "左侧增加的外围数量超出仓库范围!请调整colStart或外围左侧数量"
-                );
-                break;
-            }
-            return true;
-          }
-          return false;
-        },
-        confirmCfg: function (formData, that) {
-          if (!this.paramToMergeObj) {
-            return;
-          }
-          this.updateFormDataAround(formData);
-          that.$emit("operCfg", {
-            operType: "chgAroundBasicInfo",
-            operItemStsObj: this,
-            formData,
-          });
-        },
-        cancelCfg: function (formData, that) {
-          this.paramToMergeObj = JSON.parse(
-            JSON.stringify(this.paramToMergeObjStore)
-          );
-          this.updateFormDataAround(formData);
-          that.$emit("operCfg", {
-            operType: "chgAroundBasicInfo",
-            operItemStsObj: this,
-            formData,
-          });
-        },
-        resetCfg: function (formData, that) {
-          this.paramToMergeObj.left = 0;
-          this.paramToMergeObj.right = 0;
-          this.paramToMergeObj.up = 0;
-          this.paramToMergeObj.down = 0;
-          this.paramToMergeObjStore = JSON.parse(
-            JSON.stringify(this.paramToMergeObj)
-          );
-          this.updateFormDataAround(formData);
-          that.$emit("operCfg", {
-            operType: "chgAroundBasicInfo",
-            operItemStsObj: this,
-            formData,
-          });
-        },
-        handleClick: function (e) {
-          return false;
-        },
-        handleDoubleClick: function (e) {
-          return false;
-        },
-        handleMouseMove: function (e) {
-          return false;
-        },
-      },
-      {
-        key: "exStorage",
-        name: "外围货位",
-        displayControl: {
-          isNotShowInCfgCellSel: true,
-        },
-        sty: {
-          fillColor: scss[ITEMSTATUS.storageLoc],
-        },
-      },
-    ],
-    cellSty: {
-      cellLen: 20,
-      cellWidth: 52,
-      cellNumFont: "12px Arial",
-      cellNumFontColor: "#333333",
-      widthForFlrNum1: 18,
-      cellXOffset: 4,
-      widthColInd2: 24,
-      cellYOffset: 14,
-      cellMinLen: 12,
-      cellMaxLen: 40,
-      rackIdxNumOffsetLen: 24,
-      rackIdxNumFont: "12px Arial",
-      rackIdxNumFontColor: "#666",
-      rackIdxNumSideYPadding: 8, //考虑文字居中渲染
-      rackIdxNumSideXPadding: 0,
-    },
-  };
-};
-/**
- * 绘制箭头
- * @param {CanvasRenderingContext2D} ctx - Canvas上下文
- * @param {Object} coordinates - 坐标点对象 { x1, y1, x2, y2, x3, y3, x4, y4 }
- * @param {string} type - 箭头类型:'bidirectional-h','bidirectional-v','right','left','up','down'
- */
-function drawArrow(ctx, coordinates, type) {
-  const { x1, y1, x2, y2, x3, y3, x4, y4 } = coordinates;
-  const centerX = (x1 + x2 + x3 + x4) / 4;
-  const centerY = (y1 + y2 + y3 + y4) / 4;
-  const width = Math.max(x2 - x1, x3 - x4);
-  const height = Math.max(y4 - y1, y3 - y2);
-
-  // 调整基准尺寸,使其更适合小格子
-  const BASE_SIZE = {
-    arrowWidth: 24, // 减小箭头宽度
-    arrowLength: 12, // 减小箭头长度
-    bodyThickness: 10, // 减小主体厚度
-  };
-
-  // 计算缩放比例,确保箭头完整显示
-  const minDimension = Math.min(width, height);
-  const scale = minDimension / 40; // 移除最小值限制,让箭头始终按比例缩放
-
-  const arrowWidth = BASE_SIZE.arrowWidth * scale;
-  const arrowLength = BASE_SIZE.arrowLength * scale;
-  const bodyThickness = BASE_SIZE.bodyThickness * scale;
-
-  switch (type) {
-    case "bidirectional-h": {
-      const bodyWidth = Math.min(width * 0.4, width - 2 * arrowLength);
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY + bodyThickness / 2);
-      ctx.lineTo(centerX - bodyWidth / 2, centerY + bodyThickness / 2);
-
-      // 左侧箭头
-      ctx.moveTo(centerX - bodyWidth / 2, centerY - arrowWidth / 2);
-      ctx.lineTo(centerX - bodyWidth / 2 - arrowLength, centerY);
-      ctx.lineTo(centerX - bodyWidth / 2, centerY + arrowWidth / 2);
-
-      // 右侧箭头
-      ctx.moveTo(centerX + bodyWidth / 2, centerY - arrowWidth / 2);
-      ctx.lineTo(centerX + bodyWidth / 2 + arrowLength, centerY);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY + arrowWidth / 2);
-      break;
-    }
-
-    case "bidirectional-v": {
-      const bodyHeight = Math.min(height * 0.4, height - 2 * arrowLength);
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY + bodyHeight / 2);
-      ctx.lineTo(centerX - bodyThickness / 2, centerY + bodyHeight / 2);
-
-      // 上箭头
-      ctx.moveTo(centerX - arrowWidth / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX, centerY - bodyHeight / 2 - arrowLength);
-      ctx.lineTo(centerX + arrowWidth / 2, centerY - bodyHeight / 2);
-
-      // 下箭头
-      ctx.moveTo(centerX - arrowWidth / 2, centerY + bodyHeight / 2);
-      ctx.lineTo(centerX, centerY + bodyHeight / 2 + arrowLength);
-      ctx.lineTo(centerX + arrowWidth / 2, centerY + bodyHeight / 2);
-      break;
-    }
-    case "down": {
-      const bodyHeight = height * 0.4;
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY + bodyHeight / 2);
-      ctx.lineTo(centerX + arrowWidth / 2, centerY + bodyHeight / 2);
-      // 箭头
-      ctx.lineTo(centerX, Math.min(centerY + bodyHeight / 2 + arrowLength, y4)); // 确保不超出底部边界
-      ctx.lineTo(centerX - arrowWidth / 2, centerY + bodyHeight / 2);
-      ctx.lineTo(centerX - bodyThickness / 2, centerY + bodyHeight / 2);
-      break;
-    }
-
-    case "left": {
-      const bodyWidth = width * 0.4;
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY + bodyThickness / 2);
-      ctx.lineTo(centerX - bodyWidth / 2, centerY + bodyThickness / 2);
-      // 箭头
-      ctx.moveTo(centerX - bodyWidth / 2, centerY - arrowWidth / 2);
-      ctx.lineTo(Math.max(centerX - bodyWidth / 2 - arrowLength, x1), centerY); // 确保不超出左侧边界
-      ctx.lineTo(centerX - bodyWidth / 2, centerY + arrowWidth / 2);
-      break;
-    }
-
-    case "up": {
-      const bodyHeight = height * 0.4;
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX + bodyThickness / 2, centerY + bodyHeight / 2);
-      ctx.lineTo(centerX - bodyThickness / 2, centerY + bodyHeight / 2);
-      // 箭头
-      ctx.moveTo(centerX - arrowWidth / 2, centerY - bodyHeight / 2);
-      ctx.lineTo(centerX, Math.max(centerY - bodyHeight / 2 - arrowLength, y1)); // 确保不超出顶部边界
-      ctx.lineTo(centerX + arrowWidth / 2, centerY - bodyHeight / 2);
-      break;
-    }
-
-    case "right": {
-      const bodyWidth = width * 0.4;
-      ctx.beginPath();
-      // 主体矩形
-      ctx.moveTo(centerX - bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY - bodyThickness / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY - arrowWidth / 2);
-      ctx.lineTo(Math.min(centerX + bodyWidth / 2 + arrowLength, x2), centerY); // 确保不超出右侧边界
-      ctx.lineTo(centerX + bodyWidth / 2, centerY + arrowWidth / 2);
-      ctx.lineTo(centerX + bodyWidth / 2, centerY + bodyThickness / 2);
-      ctx.lineTo(centerX - bodyWidth / 2, centerY + bodyThickness / 2);
-      break;
-    }
-  }
-
-  ctx.closePath();
-  ctx.fill();
-}
-
-/**
- * 根据条件返回相应的 SCSS 对象
- * @param {string} type - 类型参数,用于决定返回哪个 SCSS 对象
- * @returns {object} - 返回相应的 SCSS 对象
- */

+ 0 - 445
src/components/map/grid-canvas/cell-sel-panel.vue

@@ -1,445 +0,0 @@
-<template>
-  <div class="cell-sel-panel">
-    <div class="section section-title-con">
-      <div class="section-title">
-        {{
-          selectedItemArr && selectedItemArr[0]
-            ? selectedItemArr[0].backC + "列"
-            : ""
-        }}
-        <br />
-        {{
-          selectedItemArr && selectedItemArr[0]
-            ? selectedItemArr[0].backR + "行"
-            : ""
-        }}
-        <br />
-        {{
-          selectedItemArr && selectedItemArr[0]
-            ? selectedItemArr[0].flrNum + "层"
-            : ""
-        }}
-      </div>
-      <div
-        class="custom-switch"
-        :class="{
-          'is-checked': isByFloor,
-          'is-disabled': disableSwitchIsByFloor,
-        }"
-        @click="toggleSwitch"
-      >
-        <div class="switch-core">
-          <div class="switch-button"></div>
-          <span class="switch-text">应用到<br />其他层</span>
-        </div>
-      </div>
-    </div>
-    <template v-for="section in cfgItemArr">
-      <div
-        class="section"
-        v-if="section.itemArr && section.itemArr.length > 0"
-        :key="section.type"
-      >
-        <div class="section-title">{{ section.title }}</div>
-        <div class="type-grid">
-          <div
-            class="type-con"
-            :class="{ 'is-selected': item.cfgTableSts }"
-            v-for="item in section.itemArr"
-            :key="item.key"
-            @click="onCellSelItemClick(section, item)"
-          >
-            <div
-              v-if="item.key === ITEMSTATUS.entranceAndExit"
-              class="cfg-table-sts-icon"
-            >
-              <ArrowSelector :isIcon="true" />
-            </div>
-            <div
-              v-else-if="item.key === ITEMSTATUS.charge"
-              class="cfg-table-sts-icon"
-            >
-              <div class="cube-container">
-                <div class="cube-charge"></div>
-              </div>
-            </div>
-            <div
-              v-else-if="item.key === ITEMSTATUS.transport"
-              class="cfg-table-sts-icon"
-            >
-              <div class="cube-container">
-                <div class="cube-transport"></div>
-                <div class="cube-transport"></div>
-              </div>
-            </div>
-            <div
-              v-else
-              class="color-box"
-              :style="{
-                backgroundColor: (item.sty && item.sty.fillColor) || '#fff',
-              }"
-            ></div>
-            <span>{{ item.name }}</span>
-          </div>
-        </div>
-        <div
-          class="selected-item-detail"
-          v-if="isTheSelItemDet('entranceAndExit', section)"
-        >
-          <div class="entrance-param">
-            <span class="entrance-param-title">类型:</span>
-            <el-radio-group
-              class="el-radio-group-cum"
-              v-model="entranceType"
-              @change="onEntranceTypeChange"
-            >
-              <el-radio
-                v-for="item in entranceTypeOptions"
-                :key="item.value"
-                :label="item.value"
-                >{{ item.label }}</el-radio
-              >
-            </el-radio-group>
-          </div>
-          <div class="entrance-param">
-            <span class="entrance-param-title">方向:</span>
-            <ArrowSelector
-              v-model="selectedDirection"
-              :directions="directions"
-            />
-          </div>
-        </div>
-      </div>
-    </template>
-  </div>
-</template>
-
-<script>
-import ArrowSelector from "@/components/ArrowSelector.vue";
-import {
-  getCFG,
-  ITEM_ATTRIBUTE_TYPE,
-  ITEMSTATUS,
-  LOCTYPE,
-} from "@/components/map//GRID-CONST";
-
-export default {
-  name: "CellSelPanel",
-  props: {
-    selectedItemArr: {
-      type: Array,
-      default: [],
-    },
-    renderType: {
-      type: String,
-      default: 'canvas',
-    },
-  },
-  watch: {
-    selectedItemArr(newVal) {
-      this.resetCfgItemArr();
-      if (newVal.length === 0) {
-        return;
-      }
-      const theFirstItem = newVal[0];
-      for (let i = 0; i < this.cfgItemArr.length; i++) {
-        const section = this.cfgItemArr[i];
-        for (let j = 0; j < section.itemArr.length; j++) {
-          const item = section.itemArr[j];
-          if (item.key === theFirstItem.status) {
-            section.status = theFirstItem.status;
-            item.cfgTableSts = theFirstItem.status;
-          }
-          const stsArr = theFirstItem.statusList;
-          if (stsArr) {
-            for (let k = 0; k < stsArr.length; k++) {
-              const stsItem = stsArr[k];
-              if (stsItem.status === item.key) {
-                item.cfgTableSts = stsItem.status;
-              }
-            }
-          }
-        }
-      }
-    },
-  },
-  components: {
-    ArrowSelector,
-  },
-  data() {
-    return {
-      ITEMSTATUS,
-      isByFloor: false,
-      hasEntrance: false,
-      entranceType: "",
-      cfgItemArr: [
-        { title: "货位类型", type: "storageLoc", status: "", itemArr: [] },
-        { title: "设备", type: "dev", status: "", itemArr: [] },
-        { title: "系统配置", type: "sysSet", status: "", itemArr: [] },
-      ],
-      selectedDirection: "bidirectional-v",
-      directions: [{ type: "bidirectional-h" }, { type: "bidirectional-v" }],
-      entranceTypeOptions: [],
-      disableSwitchIsByFloor: false,
-    };
-  },
-  created() {
-    this.initBaseItemStsArr();
-  },
-  methods: {
-    isTheSelItemDet(itemKey, sectionIn) {
-      for (let i = 0; i < this.cfgItemArr.length; i++) {
-        const section = this.cfgItemArr[i];
-        if (section !== sectionIn) {
-          continue;
-        }
-        for (let j = 0; j < section.itemArr.length; j++) {
-          const item = section.itemArr[j];
-          if (item.key === itemKey) {
-            return item.cfgTableSts;
-          }
-        }
-      }
-      return false;
-    },
-    resetCfgItemArr(section = null) {
-      const sections = section ? [section] : this.cfgItemArr;
-      sections.forEach((sec) => {
-        sec.status = "";
-        sec.itemArr.forEach((item) => {
-          item.cfgTableSts = "";
-        });
-      });
-    },
-    toggleSwitch() {
-      if (this.disableSwitchIsByFloor) {
-        return;
-      }
-      this.isByFloor = !this.isByFloor;
-      this.$emit("changeIsByFloor", this.isByFloor);
-    },
-    initBaseItemStsArr() {
-      for (let i = 0; i < getCFG(this.renderType).baseItemStsArr.length; i++) {
-        const item = getCFG(this.renderType).baseItemStsArr[i];
-        if (
-          (item.displayControl && item.displayControl.isNotShowInCfg) ||
-          (item.displayControl && item.displayControl.isNotShowInCfgCellSel)
-        ) {
-          continue;
-        }
-        item["cfgTableSts"] = false;
-        if (item.itemAttributeType === ITEM_ATTRIBUTE_TYPE.sysSet) {
-          this.cfgItemArr[2].itemArr.push(item);
-        } else if (item.itemAttributeType === ITEM_ATTRIBUTE_TYPE.dev) {
-          this.cfgItemArr[1].itemArr.push(item);
-        } else {
-          this.cfgItemArr[0].itemArr.push(item);
-        }
-        if (item.key === ITEMSTATUS.entranceAndExit) {
-          const paramInfoArr = item.paramInfoArr;
-          for (let i = 0; i < paramInfoArr.length; i++) {
-            const paramItem = paramInfoArr[i];
-            if (paramItem.paramKeyVal === "type") {
-              this.entranceTypeOptions = paramItem.options;
-            }
-          }
-          this.onEntranceTypeChange(this.entranceTypeOptions);
-        }
-      }
-    },
-    onEntranceTypeChange(val) {
-      if (val === "entrance" || val === "exit") {
-        this.directions = [
-          { type: "up" },
-          { type: "down" },
-          { type: "left" },
-          { type: "right" },
-        ];
-      } else {
-        this.directions = [
-          { type: "bidirectional-h" },
-          { type: "bidirectional-v" },
-        ];
-      }
-    },
-    onCellSelItemClick(section, itemCfgInfo) {
-      this.procIsByFloorSts(itemCfgInfo);
-      if (section.type === ITEM_ATTRIBUTE_TYPE.storageLoc) {
-        this.resetCfgItemArr(section);
-        section.status = itemCfgInfo.key;
-        itemCfgInfo.cfgTableSts = itemCfgInfo.key;
-        this.$emit("onCellSelItemClick", itemCfgInfo, itemCfgInfo.cfgTableSts);
-        return;
-      }
-      if (!itemCfgInfo.cfgTableSts) {
-        itemCfgInfo.cfgTableSts = itemCfgInfo.key;
-      } else {
-        itemCfgInfo.cfgTableSts = "";
-      }
-      this.$emit("onCellSelItemClick", itemCfgInfo, itemCfgInfo.cfgTableSts);
-    },
-    procIsByFloorSts(itemCfgInfo) {
-      this.disableSwitchIsByFloor = itemCfgInfo.disableSwitchIsByFloor;
-      if (this.disableSwitchIsByFloor) {
-        this.isByFloor = false;
-      }
-    },
-  },
-};
-</script>
-<style lang="scss">
-.custom-switch {
-  cursor: pointer;
-  display: inline-block;
-
-  .switch-core {
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
-    position: relative;
-    background-color: #13ce66;
-    border-radius: 2px;
-    transition: all 0.3s;
-    display: flex;
-    align-items: center;
-    padding: 4px;
-
-    .switch-button {
-      position: absolute;
-      width: 16px;
-      height: 20px;
-      border-radius: 2px;
-      background-color: white;
-      box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
-      transition: all 0.3s;
-    }
-
-    .switch-text {
-      color: #fff;
-      font-size: 11px;
-      margin-left: 20px;
-      transition: all 0.3s;
-    }
-  }
-
-  &.is-checked {
-    .switch-core {
-      background-color: #999;
-    }
-  }
-
-  &.is-disabled {
-    cursor: not-allowed;
-  }
-}
-</style>
-<style lang="scss" scoped>
-@import "@/components/map/grid-canvas/variables-canvas.scss";
-$space: 6px;
-
-.cell-sel-panel {
-  font-size: 12px;
-  padding: 0 4px;
-  background: #fff;
-  box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1);
-  height: fit-content;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-
-  .section-title-con {
-    display: flex;
-    flex-direction: row;
-    justify-content: space-between;
-    align-items: center;
-  }
-
-  .section {
-    padding: $space 0;
-    border-bottom: 1px solid #e4e7ed;
-    // box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-
-    .section-title {
-      font-weight: 1000;
-      color: #333;
-      padding: 0 0 $space 0;
-    }
-
-    .type-grid {
-      display: grid;
-      grid-template-columns: repeat(3, 1fr); // 三等分
-      gap: 2px; // 统一设置间距
-
-      .type-con {
-        display: flex;
-        align-items: center;
-        padding-top: 4px;
-        border: 2px solid #e4e7ed;
-        border-radius: 2px;
-        cursor: pointer;
-        transition: all 0.3s;
-        flex-direction: column;
-        line-height: 2;
-
-        .color-box {
-          width: 12px;
-          height: 12px;
-          // border-radius: 3px;
-          // margin-bottom: 4px;
-          // border: 1px solid #dcdfe6;
-        }
-
-        span {
-          color: #606266;
-        }
-
-        &.is-selected {
-          border-color: #13ce66;
-          box-shadow: 0 2px 8px rgba(19, 206, 102, 0.2);
-          transform: translateY(0px);
-        }
-
-        &:hover {
-          border-color: #85e2b0;
-          box-shadow: 0 2px 2px rgba(19, 206, 102, 0.1);
-        }
-      }
-    }
-
-    .entrance-title-con {
-      display: flex;
-      align-items: center;
-    }
-
-    .entrance-param {
-      display: flex;
-      flex-direction: column;
-      align-items: flex-start;
-      line-height: 1.5;
-      margin-top: $space;
-    }
-
-    .section-title-entrance {
-      padding: 0;
-      margin-right: $space;
-    }
-  }
-}
-
-.cube-container {
-  display: flex;
-  justify-content: space-between;
-  width: 18px;
-  height: 12px;
-  align-items: center;
-}
-
-.cube-charge {
-  width: 100%; // 修改为占满容器宽度
-  height: 3px; // 保持与 Canvas 绘制时相同的高度
-  background-color: $charge;
-}
-
-.cube-transport {
-  width: 3px; // 正方体的宽度
-  height: 12px; // 正方体的高度
-  background-color: $transportBorderColor; // 正方体的颜色
-  // box-shadow: 0 0 10px rgba(0, 0, 0, 0.5); // 添加阴影效果
-}
-</style>

+ 0 - 3709
src/components/map/grid-canvas/index.vue

@@ -1,3709 +0,0 @@
-<template>
-  <div ref="wareHouseArea" v-loading="canvasLoading" class="ware-house-area">
-    <canvas
-      ref="canvas"
-      :width="canvasWidth"
-      :height="canvasHeight"
-      style="user-select: none"
-      @mousedown="handleMouseDown"
-      @mousemove="handleMouseMove"
-      @mouseup="handleMouseUp"
-      @dblclick="handleDoubleClick"
-      @click="handleClick"
-      @contextmenu.prevent="handleContextMenu"
-    />
-    <div
-      v-show="
-        hoveredInfo.hoveredRowIndex !== null &&
-        hoveredInfo.hoveredColIndex !== null
-      "
-      class="overlay"
-    >
-      <template v-if="hoveredSid"> 设备编号: {{ hoveredSid }} <br /> </template>
-      <template v-if="hoveredInfo.hoveredFloorIndex !== null">
-        当前层: {{ hoveredInfo.hoveredFloorIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredColIndex !== null">
-        当前列: {{ hoveredInfo.hoveredColIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredRowIndex !== null">
-        当前行: {{ hoveredInfo.hoveredRowIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredItemStsName !== null">
-        类型: {{ hoveredInfo.hoveredItemStsName }}<br />
-      </template>
-      <template v-if="hoveredPalletCode">
-        <span :style="{ color: 'black', fontWeight: 'bold' }">
-          托盘码: {{ hoveredPalletCode }}
-        </span>
-        <br />
-      </template>
-    </div>
-    <!-- 20250101 先注解
-    <img
-      v-if="!isCfgSty"
-      title="旋转90度"
-      class="img-btn"
-      :src="imageBtnSrc"
-      :style="imageBtnStyle"
-      alt="旋转"
-      @click="rotateBtn"
-    /> -->
-    <div
-      :class="['cell-sel-panel-wrapper', panelPositionClass]"
-      @dblclick.stop="togglePanelPosition"
-    >
-      <CellSelPanel
-        :selectedItemArr="selectedItemArr"
-        v-show="cellSelPanelVisible"
-        class="cell-sel-panel-con"
-        @changeIsByFloor="setCfgIsByFloor"
-        @onCellSelItemClick="onCellSelItemClick"
-      />
-    </div>
-    <div
-      v-show="showContextMenu"
-      class="context-menu-grid"
-      :style="{
-        left: contextMenuPosition.x + 'px',
-        top: contextMenuPosition.y + 'px',
-      }"
-    >
-      <ul>
-        <!-- <li @click="saveCanvasAsImage">保存为图片</li> -->
-        <li @click="handleMenuClick('chgPalletCode')">修改托盘码</li>
-        <!-- <li @click="handleMenuClick('option3')">选项3</li> -->
-      </ul>
-    </div>
-    <el-dialog
-      :visible.sync="showChgPalletCodeDia"
-      title="修改托盘码"
-      width="60%"
-      class="pallet-code-dialog"
-    >
-      <el-form :model="chgPalletCodeDiaData" label-width="100px">
-        <!-- <el-form-item label="当前层">
-          <el-input v-model="chgPalletCodeDiaData.f" disabled />
-        </el-form-item>
-        <el-form-item label="当前列">
-          <el-input v-model="chgPalletCodeDiaData.c" disabled />
-        </el-form-item>
-        <el-form-item label="当前行">
-          <el-input v-model="chgPalletCodeDiaData.r" disabled />
-        </el-form-item> -->
-        <el-form-item label="坐标">
-          {{ chgPalletCodeDiaData.f }}-{{ chgPalletCodeDiaData.c }}-{{
-            chgPalletCodeDiaData.r
-          }}
-        </el-form-item>
-        <el-form-item label="托盘码">
-          <el-input v-model="chgPalletCodeDiaData.pallet_code" />
-        </el-form-item>
-      </el-form>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="showChgPalletCodeDia = false">取 消</el-button>
-        <el-button type="primary" @click="submitChgPalletCode">确 定</el-button>
-      </span>
-    </el-dialog>
-  </div>
-</template>
-<script>
-import shuttleLogImg from "@/assets/map/shuttle_v0_canvas.png";
-import {
-  COMMON_CONST,
-  ITEMSTATUS,
-  LOCTYPE,
-  ITEM_ATTRIBUTE_TYPE,
-  getCFG,
-  getScss,
-} from "@/components/map//GRID-CONST";
-import CellSelPanel from "./cell-sel-panel.vue";
-export default {
-  props: {
-    mapOperModel: {
-      type: String,
-      default: "cfg",
-    },
-    isShowNumInCell: {
-      type: Boolean,
-      default: false,
-    },
-    isShowHoverInfo: {
-      type: Boolean,
-      default: true,
-    },
-    includedAngle: {
-      type: Number,
-      default: 90,
-    },
-    isShowAllFlr: {
-      type: Boolean,
-      default: false,
-    },
-    isShowRackIndxNum: {
-      type: Boolean,
-      default: false,
-    },
-    containerWidth: {
-      type: Number,
-      default: 0,
-    },
-    containerHeight: {
-      type: Number,
-      default: 0,
-    },
-    operFloor: {
-      type: Number,
-      default: 1,
-    },
-  },
-  components: {
-    CellSelPanel,
-  },
-  data() {
-    return {
-      showChgPalletCodeDia: false,
-      chgPalletCodeDiaData: {
-        warehouse_id: null,
-        f: null,
-        c: null,
-        r: null,
-        pallet_code: null,
-      },
-      showContextMenu: false,
-      contextMenuPosition: {
-        x: 0,
-        y: 0,
-      },
-      selectedItemArr: null,
-      canvasWidth: 0,
-      canvasHeight: 0,
-      canvasLoading: false,
-      hoveredInfo: {
-        hoveredRowIndex: null,
-        hoveredColIndex: null,
-        hoveredFloorIndex: null,
-        hoveredItemStsName: null,
-      },
-      hoveredPalletCode: "",
-      hoveredSid: "",
-      imageBtnSrc: require("@/assets/map/rorate.jpg"), // 引入图片
-      isPanelOnRight: true, // 控制面板位置的状态
-    };
-  },
-  computed: {
-    cellSelPanelVisible() {
-      return this.selectedItemArr && this.selectedItemArr.length > 0;
-    },
-    isCfgSty() {
-      return this.mapOperModel === "cfg";
-    },
-    imageBtnStyle() {
-      return {
-        transform: `rotate(${this.rotationAngleType * 90}deg)`,
-        width: "28px", // 控制图片宽度为18px,高度会自动调整以保持图片比例
-        height: "auto",
-        transition: "transform 0.5s", // 使旋转有动画效果
-      };
-    },
-    rCFStrToArr() {
-      return (key) => {
-        const arr = key.split(COMMON_CONST.idSep);
-        if (!arr || arr.length !== 3) {
-          return;
-        }
-        const newArr = [];
-        arr.forEach((numStr) => {
-          newArr.push(Number(numStr));
-        });
-        return newArr;
-      };
-    },
-    panelPositionClass() {
-      return this.isPanelOnRight ? "panel-right" : "panel-left";
-    },
-  },
-  watch: {
-    operFloor: {
-      handler(newVal, oldVal) {
-        if (newVal !== oldVal) {
-          this.flrChg();
-        }
-      },
-      immediate: false,
-    },
-    isShowNumInCell: {
-      handler(newVal, oldVal) {
-        if (newVal !== oldVal) {
-          this.clearSelItemArr();
-          this.initData(this.storeData, true);
-        }
-      },
-      immediate: false,
-      deep: true,
-    },
-    mapOperModel(newVal) {
-      this.canBeSelected = newVal === "cfg";
-    },
-    selectedItemArr(newVal) {
-      if (
-        newVal &&
-        newVal.length > 0 &&
-        (newVal[0].backC === undefined || newVal[0].backR === undefined)
-      ) {
-        this.pageIdxToBusiIndx(newVal[0], this.rotationAngleType);
-      }
-    },
-  },
-  created() {
-    this.initComponentParam();
-    this.initShuttleImg();
-    /*  if (!this.isGetDataFromOut) {
-      this.canvasLoading = true;
-      this.$nextTick(() => {
-        this.getWareHouseData()
-          .then((res) => {
-            this.canvasLoading = false;
-            this.initData(res);
-          })
-          .catch(() => {
-            this.canvasLoading = false;
-          });
-      });
-    } */
-    this.initSysBaseData();
-  },
-
-  mounted() {
-    // 点击其他区域关闭菜单
-    document.addEventListener("click", this.closeContextMenu);
-  },
-
-  beforeDestroy() {
-    document.removeEventListener("click", this.closeContextMenu);
-  },
-  methods: {
-    submitChgPalletCode() {
-      this.$req({
-        url: "/wcs/api/map/cell/set/pallet",
-        method: "post",
-        data: this.chgPalletCodeDiaData,
-      })
-        .then((res) => {
-          this.$message.success("修改托盘码成功");
-          this.showChgPalletCodeDia = false;
-        })
-        .catch((err) => {
-          console.error("修改托盘码失败:", err);
-        });
-    },
-    handleContextMenu(e) {
-      e.preventDefault();
-      const ele = this.getCurrentMouseCellEle(e);
-      this.curEvent = e;
-      if (!ele) {
-        return;
-      }
-      // 记录右键点击位置
-      this.contextMenuPosition = {
-        x: e.clientX,
-        y: e.clientY,
-      };
-      this.showContextMenu = true;
-    },
-
-    closeContextMenu() {
-      this.showContextMenu = false;
-    },
-
-    handleMenuClick(option) {
-      // 处理菜单选项点击
-      switch (option) {
-        case "chgPalletCode":
-          this.chgPalletCode(this.curEvent);
-          break;
-        case "option3":
-          // 处理选项3
-          break;
-      }
-      this.closeContextMenu();
-    },
-    chgPalletCode(e) {
-      const ele = this.getCurrentMouseCellEle(e);
-      if (!ele) {
-        return;
-      }
-      const backEle = this.pageIdxToBusiIndx(
-        { f: ele.flrNum, c: ele.colIndex, r: ele.rowIndex },
-        this.rotationAngleType
-      );
-      const afterGetPalletCodeDo = () => {
-        /*  if (!this.hoveredPalletCode) {
-          this.$message.error("当前位置没有托盘!");
-          return;
-        } */
-        this.showChgPalletCodeDia = true;
-        this.chgPalletCodeDiaData = {
-          warehouse_id: this.wareHouseId,
-          f: backEle.f,
-          c: backEle.c,
-          r: backEle.r,
-          pallet_code: this.hoveredPalletCode,
-        };
-      };
-      this.showPalletCode(backEle, afterGetPalletCodeDo);
-    },
-    togglePanelPosition() {
-      this.isPanelOnRight = !this.isPanelOnRight;
-    },
-    onCellSelItemClick(itemCfgInfo, cfgTableSts) {
-      let operItems = this.selectedItemArr;
-      if (
-        itemCfgInfo.cellSelPanel &&
-        itemCfgInfo.cellSelPanel.procItemDataFun
-      ) {
-        operItems = itemCfgInfo.cellSelPanel.procItemDataFun(this);
-      }
-      this.itemStsInitBatch(operItems, cfgTableSts, itemCfgInfo.key);
-      this.drawCanvas();
-      this.$emit("grid-canvas-save", this.getCfgData());
-    },
-    getUniqueRowsOrCols() {
-      const key = this.isHorizontal() ? "rowIndex" : "colIndex";
-      const uniqueIndices = [
-        ...new Set(this.selectedItemArr.map((item) => item[key])),
-      ];
-      // 返回符合条件的一个元素
-      return uniqueIndices.map((index) => {
-        return this.selectedItemArr.find((item) => item[key] === index);
-      });
-    },
-    initComponentParam() {
-      this.scssVariables = getScss("canvas");
-      this.canBeSelected = false;
-      this.isCfgByFloor = false;
-      this.mouseSts = "";
-      this.cfgOperingItem = "";
-      this.rowStart = 0;
-      this.colStart = 0;
-      this.rowStartOri = 0;
-      this.colStartOri = 0;
-      this.showSty = process.env.VUE_APP_SHOW_STYLE; // show[展示模式] cfg[配置模式]//TESTMM1113
-      // this.showSty = 'show'; // show[展示模式] cfg[配置模式]
-      this.expandRowNum = 0;
-      this.expandColNum = 0;
-      this.expandRowStart = 0;
-      this.expandColStart = 0;
-      this.converyAround = [];
-      this.conveyorAroundMap = {};
-      this.wareHouseId = null;
-      this.wareHouseName = null;
-      this.flrFromSty = "bTOt"; // 楼层显示-从下到上 bTOt 从上到下 tTOb
-      // this.operFloor = 1;
-      this.totalFlr = 1;
-      this.shuttleImg = null;
-      this.totalPageFlr = 0; // 页面共有几层楼层
-      this.thetaInRadians = (90 * Math.PI) / 180;
-      this.flrHorizontalTotalHangLen = 0; // 单层横向悬空长度
-      this.flrHorizontalShowType = "many"; // 横向空间层显示类型,'one' 'many'
-      this.flrHorizontalTotalLen = 0; // 每层横向总长度
-      this.flrVehTotalLen = 0; // 每层纵向总长度
-      this.flrHorizontalLen = 0; // 每层横向向总长度
-      this.flrHorizontalSpace = 10; // 层横向间距
-      this.flrVehSpace = 10; // 层纵向间距
-      this.totalHorizontalFlrPer = 0; // 横向放置层的数量
-      this.rotationAngleType = 0; // 原始0,1-顺时针旋转90度,2-顺时针旋转180度,3-顺时针旋转270度,4-顺时针旋转360度(状态同原始)
-      this.front = 0; // 屏幕的上面,在行数的方向不同时需要关注
-      this.right = 0;
-      this.left = 0;
-      this.back = 0; // 屏幕的下面,在行数的方向不同时需要关注
-      this.isShowing = false;
-      this.clickCount = 0;
-      this.clickTimeout = null;
-      this.rotationAngle = 0;
-      this.ctx = null;
-      this.canvas = null;
-      this.animationFrameId = null;
-      this.scale = 1;
-      this.startDrag = { x: 0, y: 0 };
-      this.offset = { x: 0, y: 0 };
-      this.pageFloorGridDataObj = {}; // 存储页面数据,与页面显示对象一一对应。旋转时,改变数据位置内容 不放在data中,不适用双向绑定
-      this.storePageFloorGridDataObj = null;
-      this.storeData = null;
-      this.shuttleVisObj = {}; // 车辆数据(基础数据、线路、页面位置信息)
-      this.goodsVisObj = {}; // 货物数据
-      this.pageRow = 0; // 维护的所有格子的行数
-      this.pageCol = 0; // 维护的所有格子的列数
-      this.rackRow = 0;
-      this.rackCol = 0;
-      this.wareRow = 0;
-      this.wareCol = 0;
-      this.cellWidth = 0; // 四边形横向边长度
-      this.cellLen = 0; // 四边形纵向边长度
-      this.verticalCellHeight = 0; // 四边形横向边间距离
-      this.horizontalPointOffset = 0; // 四边形左下角水平方向的偏移
-      this.warehousPageCfg = {
-        rowOffsetX: 0, // 在第一列左侧预留的宽度,需计算使得整个仓库位于视口中间位置
-        colOffsetY: 0, // 在第一行上方预留的高度,需计算使得整个仓库位于视口中间位置
-      };
-      this.aroundInfo = {}; // 配置时,外围扩展信息
-    },
-    setIsAni(isAni) {
-      this.isAni = isAni;
-    },
-    initSysBaseData() {
-      this.initItemStsMap();
-    },
-    initItemStsMap() {
-      this.itemStsMap = {};
-      for (const itemType of getCFG("canvas").baseItemStsArr) {
-        /*         if (itemType.isNotCellData) {
-                  continue
-                } */
-        this.itemStsMap[itemType.key] = itemType;
-      }
-    },
-    saveCanvasAsImage() {
-      if (!this.isCfgSty) {
-        return;
-      }
-      const canvas = this.$refs.canvas;
-      const image = canvas
-        .toDataURL("image/png")
-        .replace("image/png", "image/octet-stream");
-      const link = document.createElement("a");
-      link.href = image;
-      const fileName = this.wareHouseName
-        ? `${this.wareHouseName}_楼层${this.operFloor}.png`
-        : `仓库_楼层${this.operFloor}.png`;
-      link.download = fileName;
-      link.click();
-    },
-    /*     flrChg(flr) {
-      this.operFloor = flr;
-      this.initData(this.storeData);
-    }, */
-    flrChg(flr) {
-      // this.operFloor = flr;
-      this.clearSelItemArr();
-      this.drawCanvas();
-    },
-    setFlr(flr) {
-      this.operFloor = flr;
-    },
-    initShuttleImg() {
-      if (this.shuttleImg) return; // 避免重复加载
-
-      const img = new Image();
-      img.onload = () => {
-        this.shuttleImg = img;
-        // 图片加载完成后重新渲染
-        this.drawCanvas();
-      };
-      img.onerror = (err) => {
-        console.error("Failed to load shuttle image:", err);
-      };
-      img.src = shuttleLogImg;
-    },
-    rotateBtn() {
-      const storeRotationType = localStorage.getItem("rotationAngleType") || 0;
-      const storeNum = parseInt(storeRotationType);
-      let rotationFinal = storeNum + 1;
-      if (rotationFinal > 3) {
-        // 当达到360度时重置
-        rotationFinal = 0;
-      }
-      localStorage.setItem("rotationAngleType", rotationFinal);
-      this.initData(this.storeData);
-    },
-    getWareHouseData() {
-      return this.$req({
-        url: "/wcs/api/map/get/" + this.wareHouseId || window.glbMapId,
-        method: "post",
-      });
-    },
-    rotateGridData(pageFloorGridDataObj, rotationAngleType = 0) {
-      let result = [];
-      const rows = pageFloorGridDataObj.length;
-      const cols = pageFloorGridDataObj[0].length;
-
-      switch (rotationAngleType) {
-        case 0: // 不旋转
-          result = pageFloorGridDataObj;
-          break;
-        case 1: // 90度顺时针旋转
-          for (let col = 0; col < cols; col++) {
-            const newRow = [];
-            for (let row = rows - 1; row >= 0; row--) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        case 2: // 180度顺时针旋转
-          for (let row = rows - 1; row >= 0; row--) {
-            const newRow = [];
-            for (let col = cols - 1; col >= 0; col--) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        case 3: // 270度顺时针旋转或90度逆时针旋转
-          for (let col = cols - 1; col >= 0; col--) {
-            const newRow = [];
-            for (let row = 0; row < rows; row++) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        default:
-          result = pageFloorGridDataObj;
-      }
-
-      return result;
-    },
-    resetData() {
-      this.rackRow = 0;
-      this.rackCol = 0;
-      this.pageRow = 0;
-      this.pageCol = 0;
-      this.pageFloorGridDataObj = {};
-      this.storePageFloorGridDataObj = null;
-      this.storeData = null;
-      this.ctx &&
-        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-    },
-    /*
-    this.pageFloorGridDataObj对应页面整个数据。
-    每个最底层元素,持有从后台数据转换而来的数据信息。
-    关键动作:后台数据转前台页面数据。
-    */
-    initData(res, isInitAllFlrData) {
-      this.resetData();
-      if (!res) {
-        return;
-      }
-      const data = res.row;
-      if (!data) {
-        // this.resetData();
-        return;
-      }
-      this.storeData = res;
-      try {
-        this.canvasLoading = true;
-        this.assignment(data); // 后台基础数据赋值
-        this.initCfg(data);
-        if (this.isNotDo()) {
-          this.canvasLoading = false;
-          return;
-        }
-        this.pageFloorGridDataObj = this.initFloorGridData(
-          this.pageFloorGridDataObj,
-          isInitAllFlrData
-        );
-        this.parseOperItemData(data, isInitAllFlrData); // 依赖this.pageFloorGridDataObj
-        this.initCfgBefRender();
-        this.storePageFloorGridDataObj = JSON.parse(
-          JSON.stringify(this.pageFloorGridDataObj)
-        );
-        // Vue更新视图后再执行drawCanvas(),从而确保在更改画布大小后正确渲染内容
-        this.$nextTick(() => {
-          this.drawCanvas();
-          this.canvasLoading = false;
-        });
-      } catch (error) {
-        console.error(error);
-        this.canvasLoading = false;
-      }
-    },
-    parseOperItemData(data, isInitAllFlrData) {
-      const dataIn = JSON.parse(JSON.stringify(data));
-      const keys = Object.keys(this.pageFloorGridDataObj);
-      for (const flrNumStr of keys) {
-        const flrNum = Number(flrNumStr);
-        if (
-          !this.isShowAllFlr &&
-          flrNum !== this.operFloor &&
-          !isInitAllFlrData
-        ) {
-          continue;
-        }
-        for (let itemType of getCFG("canvas").baseItemStsArr) {
-          const dataKey = itemType.backKey || itemType.key;
-          const itemStatusKey = itemType.key;
-          const itemsDataArr = dataIn[dataKey] ? dataIn[dataKey] : []; // 配置项数组【"mainRoad":[1,2],"lift":[{"f":1,"c":1,"r":1}],】
-          if (!Array.isArray(itemsDataArr)) {
-            continue;
-          }
-          if (!itemsDataArr || itemsDataArr.length === 0) {
-            continue;
-          }
-          const newItemsDataArr = JSON.parse(JSON.stringify(itemsDataArr));
-          newItemsDataArr.forEach((elementIn) => {
-            if (itemStatusKey === ITEMSTATUS.xTrack) {
-              const mainRoadDirNum = this.isHorizontal()
-                ? this.pageCol
-                : this.pageRow; // 主巷道方向行数
-              for (let j = 0; j < mainRoadDirNum; j++) {
-                let element = {};
-                if (this.isHorizontal()) {
-                  element.r = elementIn;
-                  element.c = j + this.colStartOri;
-                } else {
-                  element.r = j + this.rowStartOri;
-                  element.c = elementIn;
-                }
-                this.busiIndxToPageIdx(element, this.rotationAngleType);
-                const item = this.getTheItem(element.r, element.c, flrNum);
-                // const item = this.getTheItem(this.isHorizontal() ? idx : j, this.isHorizontal() ? j : idx, flrNum);
-                if (item?.type !== LOCTYPE.around) {
-                  this.itemStsInit(item, itemStatusKey);
-                }
-              }
-            } else if (
-              itemStatusKey === ITEMSTATUS.lift ||
-              flrNum === elementIn.f
-            ) {
-              //适配了非1楼无梯子数据也需要渲染
-
-              if (
-                elementIn.rE !== undefined ||
-                elementIn.rS !== undefined ||
-                elementIn.cE !== undefined ||
-                elementIn.cS !== undefined
-              ) {
-                this.procManyRowOrCol(elementIn, itemStatusKey, flrNum);
-              } else {
-                this.busiIndxToPageIdx(elementIn, this.rotationAngleType);
-                const item = this.getTheItem(elementIn.r, elementIn.c, flrNum);
-                this.itemStsInit(item, itemStatusKey);
-              }
-            }
-          });
-        }
-      }
-    },
-    getCfgData() {
-      const result = {};
-      const xTrackMap = new Set();
-      const isHorizontal = this.isHorizontal();
-
-      // 初始化结果对象
-      Object.keys(this.itemStsMap).forEach((key) => {
-        const itemType = this.itemStsMap[key];
-        if (!itemType.noToBackData) {
-          const backKey = itemType.backKey || key;
-          result[backKey] = [];
-        }
-      });
-
-      // 处理单个状态对象
-      const processStatus = (ele, status, flrNum) => {
-        const itemTypeEle = this.itemStsMap[status];
-        if (
-          !itemTypeEle ||
-          (itemTypeEle.displayControl &&
-            itemTypeEle.displayControl.isNotShowInCfg)
-        )
-          return;
-
-        const backKey = itemTypeEle.backKey || status;
-        if (!backKey) return;
-
-        if (!result[backKey]) {
-          result[backKey] = [];
-        }
-
-        const eleBack = this.buildElementBack(ele, flrNum);
-
-        if (itemTypeEle.key === ITEMSTATUS.xTrack) {
-          const trackValue = isHorizontal ? eleBack.r : eleBack.c;
-          xTrackMap.add(trackValue);
-        } else {
-          result[backKey].push(eleBack);
-        }
-      };
-
-      // 遍历楼层数据
-      for (let flrNum = 1; flrNum <= this.totalFlr; flrNum++) {
-        const flrData =
-          this.pageFloorGridDataObj[flrNum] || this.pageFloorGridDataObj[1];
-        if (!flrData) continue;
-
-        // 处理每层的网格数据
-        Object.values(flrData).forEach((pageCArr) => {
-          pageCArr.forEach((ele) => {
-            const itemType = this.itemStsMap[ele.status];
-            if (itemType && !itemType.noToBackData) {
-              if (ele.status) {
-                processStatus(ele, ele.status, flrNum);
-              }
-            }
-
-            // 处理状态列表
-            if (ele.statusList?.length) {
-              ele.statusList.forEach((statusObj) => {
-                const itemType = this.itemStsMap[statusObj.status];
-                if (itemType && !itemType.noToBackData) {
-                  if (statusObj.status) {
-                    processStatus(ele, statusObj.status, flrNum);
-                  }
-                }
-              });
-            }
-          });
-        });
-      }
-
-      // 处理xTrack数据
-      if (xTrackMap.size > 0) {
-        result[this.itemStsMap["xTrack"].key] = Array.from(xTrackMap)
-          .map(Number)
-          .sort((a, b) => a - b);
-      }
-
-      return result;
-    },
-    buildElementBack(ele, flrNum) {
-      const eleBack = { ...ele };
-      if (ele.backR !== undefined && ele.backC !== undefined) {
-        return {
-          ...eleBack,
-          f: flrNum,
-          c: ele.backC,
-          r: ele.backR,
-        };
-      }
-
-      const backEle = this.pageIdxToBusiIndx(
-        ele,
-        this.rotationAngleType,
-        true,
-        false
-      );
-      return {
-        ...eleBack,
-        f: flrNum,
-        c: backEle.backC,
-        r: backEle.backR,
-      };
-    },
-    procManyRowOrCol(elementIn, itemStatusKey, flrNum) {
-      const rStart = elementIn.rS ?? elementIn.r;
-      const rEnd = elementIn.rE ?? elementIn.r;
-      const cStart = elementIn.cS ?? elementIn.c;
-      const cEnd = elementIn.cE ?? elementIn.c;
-
-      // 遍历行
-      if (rStart <= rEnd) {
-        for (let i = rStart; i <= rEnd; i++) {
-          // 遍历列
-          if (cStart <= cEnd) {
-            for (let j = cStart; j <= cEnd; j++) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          } else {
-            for (let j = cStart; j >= cEnd; j--) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          }
-        }
-      } else {
-        for (let i = rStart; i >= rEnd; i--) {
-          // 遍历列
-          if (cStart <= cEnd) {
-            for (let j = cStart; j <= cEnd; j++) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          } else {
-            for (let j = cStart; j >= cEnd; j--) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          }
-        }
-      }
-    },
-    procLiftBackData(itemStatusKey, flrNum, i, elementIn) {
-      let liftEle = { r: i, c: elementIn.c };
-      const canNotBeClick = i === elementIn.r ? false : true;
-      this.busiIndxToPageIdx(liftEle, this.rotationAngleType);
-      const item = this.getTheItem(liftEle.r, liftEle.c, flrNum);
-      this.itemStsInit(item, itemStatusKey);
-      if (canNotBeClick) {
-        item.canNotBeClick = canNotBeClick;
-      }
-    },
-    initAroundConveyor(dataIn) {
-      if (!dataIn || !dataIn.around) {
-        this.converyAround = [];
-        return;
-      }
-      const chainConveyor = dataIn.around.chainConveyor || [];
-      const rollerConveyor = dataIn.around.rollerConveyor || [];
-      // 合并 chainConveyor 和 rollerConveyor,并去重
-      const aroundConveyor = [];
-      const uniqueSet = new Set();
-      const palletizer = dataIn.around.palletizer || [];
-
-      // 获取最大和最小的 r, c 值
-      let maxR = -Infinity;
-      let maxC = -Infinity;
-      let minR = Infinity;
-      let minC = Infinity;
-
-      const processItem = (item) => {
-        maxR = Math.max(maxR, item.r);
-        maxC = Math.max(maxC, item.c);
-        minR = Math.min(minR, item.r);
-        minC = Math.min(minC, item.c);
-        const key = `${item.r}-${item.c}-${item.f}`;
-        if (!uniqueSet.has(key)) {
-          uniqueSet.add(key);
-          aroundConveyor.push(item);
-        }
-      };
-
-      [...chainConveyor, ...rollerConveyor].forEach(processItem);
-      palletizer.forEach((item) => {
-        if (Array.isArray(item.for2D)) {
-          item.for2D.forEach(processItem);
-        }
-      });
-      // 计算行列范围
-      const rowRange = {
-        start: this.rowStart,
-        end: this.rackRow + this.rowStart - 1,
-      };
-      const colRange = {
-        start: this.colStart,
-        end: this.rackCol + this.colStart - 1,
-      };
-
-      // 计算行列差异
-      const calculateDiff = (min, max, range) => ({
-        min: min - range.start,
-        max: max - range.end,
-      });
-
-      const rowDiff = calculateDiff(minR, maxR, rowRange);
-      const colDiff = calculateDiff(minC, maxC, colRange);
-
-      // 计算需要扩展的行数和列数
-      const calculateExpansion = (diff) =>
-        Math.max(0, -diff.min) + Math.max(0, diff.max);
-
-      this.expandRowNum = calculateExpansion(rowDiff);
-      this.expandColNum = calculateExpansion(colDiff);
-      if (rowDiff.min < 0) {
-        this.expandRowStart = Math.abs(rowDiff.min);
-        this.rowStart = this.rowStart + rowDiff.min;
-      }
-      if (colDiff.min < 0) {
-        // 当小于0时,行列序号集体加
-        this.expandColStart = Math.abs(colDiff.min);
-        this.colStart = this.colStart + colDiff.min;
-      }
-      this.converyAround = aroundConveyor;
-    },
-    itemIsStackable(itemStsCfgInfo) {
-      return (
-        itemStsCfgInfo.itemAttributeType === ITEM_ATTRIBUTE_TYPE.dev ||
-        itemStsCfgInfo.itemAttributeType === ITEM_ATTRIBUTE_TYPE.sysSet
-      );
-    },
-    /**
-     * 将数据值同步到现有页面数据中
-     */
-    itemStsInit(element, itemStatus, theOperingKey) {
-      if (!element) {
-        return;
-      }
-      const stackableItemKey = itemStatus || theOperingKey;
-      const itemStsCfgInfo = this.itemStsMap[stackableItemKey];
-      if (itemStsCfgInfo && this.itemIsStackable(itemStsCfgInfo)) {
-        if (!element.statusList) {
-          element.statusList = [];
-        }
-        if (!itemStatus) {
-          const index = element.statusList.findIndex(
-            (item) => item.status === theOperingKey
-          );
-          if (index > -1) {
-            element.statusList.splice(index, 1);
-          }
-        } else {
-          if (!element.statusList.find((item) => item.status === itemStatus)) {
-            element.statusList.push({ status: itemStatus });
-          }
-        }
-      } else {
-        const stsInfo = this.getItemStsInfo(itemStatus, element.type);
-        element["status"] = stsInfo.status;
-        element["fillColor"] =
-          stsInfo.fillColor || this.scssVariables.gridFillColor;
-        element["borderColor"] =
-          stsInfo.borderColor || this.scssVariables.gridBorderColor;
-        element["lineWidth"] =
-          stsInfo.lineWidth || this.scssVariables.gridLineWidth;
-      }
-    },
-    /**
-     * 页面下标转业务下标【页面坐标原点在左上角,实际二维码坐标[坐标原点据旋转]】
-     *
-     * 1-页面坐标考转为二维码坐标[坐标原点据旋转]。
-     * 2-将不带预留位坐标[即现场的物理视觉坐标]转为业务坐标[二维码(从0开始)]
-     *rotationAngleType=0【未旋转】时实际二维码坐标原点在左下
-     *rotationAngleType=1【旋转90】时实际二维码坐标原点在左上
-     * rotationAngleType=2【旋转180】时实际二维码坐标原点在右上
-     * rotationAngleType=3【旋转270】时实际二维码坐标原点在右下
-     *  @param {*} item
-     * @returns
-     */
-    pageIdxToBusiIndx(
-      item,
-      rotationAngleType = 0,
-      isNotChgEle = false,
-      isLog = false
-    ) {
-      const rIsNum = typeof item.r === "number";
-      const cIsNum = typeof item.c === "number";
-      if (!rIsNum && !cIsNum) {
-        return;
-      }
-      const pageR = item.r;
-      const pageC = item.c;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "正在处理-页面坐标 c:",
-          pageC,
-          "r:",
-          pageR
-        );
-      }
-      const { rotatedY_R, rotatedX_C } = this.rotateCoordinates(
-        pageR,
-        pageC,
-        rotationAngleType,
-        "toBack"
-      );
-      const isNumRoR = typeof rotatedY_R === "number";
-      const isNumRoC = typeof rotatedX_C === "number";
-      const backR = isNumRoR && this.transformIndex(rotatedY_R, "r", "toBack");
-      const backC = isNumRoC && this.transformIndex(rotatedX_C, "c", "toBack");
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "加上预留位的坐标 c:",
-          backC,
-          "r:",
-          backR
-        );
-      }
-      item.backR = backR;
-      item.backC = backC;
-      if (isNotChgEle) {
-        return { backR, backC };
-      }
-      item.r = backR;
-      item.c = backC;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "处理完成-业务坐标 c:",
-          item.c,
-          "r:",
-          item.r
-        );
-      }
-      return item;
-    },
-    /**
-     * 业务下标转页面下标【页面坐标原点在左上角,实际二维码坐标原点在左下,旋转后实际二维码坐标原点发生改变】
-     * 后台上传数据时
-     * 1-将业务坐标转为不带预留位坐标[即现场的物理视觉坐标]
-     * 2-根据二维码坐标原点为页面坐标。
-     * rotationAngleType=0【未旋转】时实际二维码坐标原点在左下
-     *rotationAngleType=1【旋转90】时实际二维码坐标原点在左上
-     * rotationAngleType=2【旋转180】时实际二维码坐标原点在右上
-     * rotationAngleType=3【旋转270】时实际二维码坐标原点在右下
-     * @param {*} itemBusi 后台数据
-     * @returns
-     */
-    busiIndxToPageIdx(itemBusi, rotationAngleType = 0, isLog = false) {
-      const rIsNum = typeof itemBusi.r === "number";
-      const cIsNum = typeof itemBusi.c === "number";
-      if (!rIsNum && !cIsNum) {
-        return;
-      }
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "正在处理-业务坐标 c:",
-          itemBusi.c,
-          "r:",
-          itemBusi.r
-        );
-      }
-      const pageR = rIsNum && this.transformIndex(itemBusi.r, "r", "toPage");
-      const pageC = cIsNum && this.transformIndex(itemBusi.c, "c", "toPage");
-      if (isLog) {
-        console.log("去除预留的坐标c:", pageC, "r:", pageR);
-      }
-      const { rotatedY_R, rotatedX_C } = this.rotateCoordinates(
-        pageR,
-        pageC,
-        rotationAngleType,
-        "toPage",
-        isLog
-      );
-      const finalR = rotatedY_R;
-      const finalC = rotatedX_C;
-      itemBusi.r = finalR;
-      itemBusi.c = finalC;
-      itemBusi.pageR = finalR;
-      itemBusi.pageC = finalC;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "处理完成-页面坐标 c:",
-          itemBusi.c,
-          "r:",
-          itemBusi.r
-        );
-      }
-      return itemBusi;
-    },
-    /**
-     * 在计算反转的坐标时,需要区分是后台数据,还是前台数据在反转
-     * @param oriR
-     * @param oriC
-     * @param rotationAngleType
-     * @param rotateC_Road
-     * @param rotateR_good
-     */
-    rotateCoordinates(r, c, rotationAngleType, dir = "toPage", isLog) {
-      const rowNum = dir === "toPage" ? this.busiRowOri : this.pageRow;
-      const colNum = dir === "toPage" ? this.busiColOri : this.pageCol;
-      const reverseR = this.calcRevNum(rowNum - 1, r);
-      const reverseC = this.calcRevNum(colNum - 1, c);
-      if (isLog) {
-        console.log(
-          "坐标c:",
-          c,
-          "r:",
-          r,
-          "反转后对应的坐标c:",
-          reverseC,
-          "r:",
-          reverseR
-        );
-      }
-      let rotatedY_R, rotatedX_C;
-      switch (rotationAngleType) {
-        case 0: // 现实坐标不动(左下角坐标原点)。页面X轴(c)取c,页面Y轴(r)取reverseR
-          rotatedY_R = reverseR;
-          rotatedX_C = c;
-          break;
-        case 1: // 现实坐标原点在左上。页面X轴(c)取r,页面Y轴(r)取c
-          rotatedY_R = c;
-          rotatedX_C = r;
-          break;
-        case 2: // 现实坐标原点在右上。页面X轴(c)取reverseC,页面Y轴(r)取r
-          rotatedY_R = r;
-          rotatedX_C = reverseC;
-          break;
-        case 3: // 现实坐标在右下。页面X轴(c)取reverseC,页面Y轴(r)取reverseR
-          rotatedY_R = reverseC;
-          rotatedX_C = reverseR;
-          break;
-        default: // 同 case 0
-          rotatedY_R = reverseR;
-          rotatedX_C = c;
-      }
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          dir === "toPage" ? "业务c:" : "页面c:",
-          c,
-          "r:",
-          r,
-          dir === "toPage" ? "页面c:" : "业务c:",
-          reverseC,
-          "r:",
-          reverseR
-        );
-      }
-      return { rotatedY_R, rotatedX_C };
-    },
-    transformIndex(idx, type = "r", direction = "toPage") {
-      const startValue = type === "r" ? this.rowStart : this.colStart;
-      const numericIdx = Number(idx);
-      if (isNaN(numericIdx)) {
-        throw new Error("idx must be a number or convertible to a number");
-      }
-      return direction === "toPage"
-        ? numericIdx - startValue
-        : numericIdx + startValue;
-    },
-    /**
-     *
-     * 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17反转位置17,16,15,14...
-     * 根据起始位置和总数计算反转后的位置
-     */
-    calcRevNum(row, idx) {
-      const reverseNumber = row - idx;
-      return reverseNumber;
-    },
-    /**
-     *
-     * 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17反转位置17,16,15,14...
-     * 根据起始位置和总数计算反转后的位置
-     */
-    consiPIdxSt(num, startNum, offset) {
-      if (!startNum || startNum === 0) {
-        return num;
-      }
-      return num + offset;
-    },
-    isNotDo() {
-      if (!this.rackRow || !this.rackCol || !this.pageRow || !this.pageCol) {
-        return true;
-      }
-      return false;
-    },
-    isHorizontal() {
-      return this.orientationRacking === COMMON_CONST.MAIN_TRACK_DIR.HORIZONTAL;
-    },
-    assignment(data) {
-      if (!data) {
-        this.resetData();
-        return;
-      }
-      this.wareHouseId = data.id;
-      this.orientationRacking =
-        data.forward || COMMON_CONST.MAIN_TRACK_DIR.DEFAULT;
-      // this.rackRow = this.isHorizontal() ? data.row : data.col
-      // this.rackCol = this.isHorizontal() ? data.col : data.row
-      this.rackRow = data.row;
-      this.rackCol = data.col;
-      if (!this.rackRow || !this.rackCol) {
-        this.resetData();
-        return;
-      }
-      this.front = data.front;
-      this.right = data.right;
-      this.left = data.left;
-      this.back = data.back;
-      /* 页面总楼层 */
-      this.totalFlr = data.floor;
-      this.rowStart = data.rowStart || 0;
-      this.colStart = data.colStart || 0;
-      this.rowStartOri = data.rowStart || 0;
-      this.colStartOri = data.colStart || 0;
-      if (this.isCfgSty) {
-        this.rotationAngleType = data.rotation || 0;
-        this.aroundInfo = data.around || {};
-        this.procRowColStartWhenCfg(data);
-      } else {
-        const storeRotationType = localStorage.getItem("rotationAngleType");
-        const storeNum =
-          (storeRotationType !== undefined && storeRotationType !== null
-            ? storeRotationType
-            : data.rotation || 0) || 0;
-        this.rotationAngleType = parseInt(storeNum);
-      }
-    },
-    procRowColStartWhenCfg(data) {
-      const { down = 0, left = 0, up = 0, right = 0 } = this.aroundInfo || {};
-      switch (this.rotationAngleType) {
-        case 0: // 原始方向,左下角为原点
-          this.rowStart = data.rowStart - down;
-          this.colStart = data.colStart - left;
-          this.rowStartOri = data.rowStart - down;
-          this.colStartOri = data.colStart - left;
-          break;
-        case 1: // 顺时针90度,左上角为原点
-          this.rowStart = data.rowStart - left;
-          this.colStart = data.colStart - up;
-          this.rowStartOri = data.rowStart - left;
-          this.colStartOri = data.colStart - up;
-          break;
-        case 2: // 顺时针180度,右上角为原点
-          this.rowStart = data.rowStart - up;
-          this.colStart = data.colStart - right;
-          this.rowStartOri = data.rowStart - up;
-          this.colStartOri = data.colStart - right;
-          break;
-        case 3: // 顺时针270度,右下角为原点
-          this.rowStart = data.rowStart - right;
-          this.colStart = data.colStart - down;
-          this.rowStartOri = data.rowStart - right;
-          this.colStartOri = data.colStart - down;
-          break;
-      }
-    },
-    mesDo(wsData) {
-      if (!wsData) {
-        return;
-      }
-      if (!this.pageFloorGridDataObj) {
-        return "isNotReady";
-      }
-      this.setIsAni(true);
-      let dataIn;
-      if (typeof wsData === "string") {
-        dataIn = JSON.parse(wsData);
-      } else {
-        dataIn = JSON.parse(JSON.stringify(wsData));
-      }
-      const { data, action } = dataIn;
-      this.animationProc(action, data);
-    },
-    animationProc(action, data) {
-      if (action === "init") {
-        if (data && data.cells) {
-          this.cellsStsInit(data.cells);
-        }
-      } else if (action === "update") {
-        if (data && data.cells) {
-          this.cellsStsUpdate(data.cells);
-        }
-      }
-
-      // 设置车辆的基础数据到视图数据中
-      if (data && data.shuttle) {
-        this.shuttleInfoRefresh(data.shuttle);
-      }
-      if (data && data.plc_conveyor) {
-        this.conveyorInfoUp(data.plc_conveyor);
-      }
-    },
-    conveyorInfoUp(conveyorData) {
-      // 将this.conveyorAroundMap中所有值设置为0
-      Object.keys(this.conveyorAroundMap).forEach((key) => {
-        this.conveyorAroundMap[key] = 0;
-      });
-      for (let i = 0; i < conveyorData.length; i++) {
-        const conveyor = conveyorData[i];
-        const idKey = this.idKey(conveyor);
-        let item = (conveyor.items && conveyor.items[0]) || 0;
-        item = parseInt(item);
-        if (!item) {
-          item = (conveyor.items && conveyor.items[1]) || 0;
-        }
-        this.conveyorAroundMap[idKey] = parseInt(item);
-      }
-    },
-    idKey(ele) {
-      return `${ele.f}${COMMON_CONST.idSep}${ele.c}${COMMON_CONST.idSep}${ele.r}`;
-    },
-    /**
-     * 存储每次上发得车辆数据
-     * @param {*} shuttleData 结构{sn1:{},sn2:{},sn3:{},}
-     */
-    shuttleInfoRefresh(shuttleData) {
-      if (!shuttleData || shuttleData.length === 0) {
-        return;
-      }
-      for (let i = 0; i < shuttleData.length; i++) {
-        const data = shuttleData[i];
-        const shuttleKey = data.sid;
-        if (!this.shuttleVisObj[shuttleKey]) {
-          this.shuttleVisObj[shuttleKey] = {};
-        }
-        this.shuttleVisObj[shuttleKey]["baseInfo"] = data;
-      }
-    },
-    // 初始化货位所有状态为指定状态,直接修改floorGridDoubleArr数据
-    /**
-     *{
-  "data": {
-    "1"-层: {
-      "4"-列: [0-行, 1, 9, 0, 1, 9, 0, 1],
-      "5": [0, 1, 9, 0, 1, 9, 0, 1]
-    },
-    "2": {
-      "6": [0, 1, 9, 0, 1, 9, 0, 1],
-      "7": [0, 1, 9, 0, 1, 9, 0, 1]
-    }
-  }
-  }
-     *
-     */
-    cellsStsInit(cells) {
-      this.goodsVisObj = {};
-      if (!cells || !this.pageFloorGridDataObj) {
-        return;
-      }
-
-      for (const flr in cells) {
-        // if (!this.pageFloorGridDataObj[flr]) {
-        //   continue
-        // }
-        const cellsFloorSts = cells[flr];
-        const cols = Object.keys(cellsFloorSts);
-        if (!cols || cols.length < 1) {
-          return;
-        }
-
-        cols.forEach((colKey) => {
-          const dataArr = cellsFloorSts[colKey];
-          const colNum = Number(colKey);
-
-          for (let rowNum = 0; rowNum < dataArr.length; rowNum++) {
-            if (dataArr[rowNum]) {
-              // 计算key值,格式为"1-1-1"
-              const addrKey = `${flr}${COMMON_CONST.idSep}${colNum}${COMMON_CONST.idSep}${rowNum}`;
-              this.goodsVisObj[addrKey] = dataArr[rowNum];
-            }
-          }
-        });
-      }
-    },
-    cellsStsUpdate(cells) {
-      if (!cells || !this.pageFloorGridDataObj) {
-        return;
-      }
-      cells.forEach((cell) => {
-        const idKey = `${cell.f}${COMMON_CONST.idSep}${cell.c}${COMMON_CONST.idSep}${cell.r}`;
-        this.goodsVisObj[idKey] = cell.items;
-      });
-    },
-    initFloorGridData(pageFloorGridDataObj, isInitAllFlrData) {
-      if (!this.totalFlr) {
-        return;
-      }
-      pageFloorGridDataObj = {};
-      for (let i = 1; i <= this.totalFlr; i++) {
-        if (!this.isShowAllFlr && this.operFloor !== i && !isInitAllFlrData) {
-          continue;
-        }
-        pageFloorGridDataObj[i] = this.initGridDoubleArr([], i);
-      }
-      return pageFloorGridDataObj;
-    },
-    getTheItem(r, c, f) {
-      return (
-        this.pageFloorGridDataObj[f] &&
-        this.pageFloorGridDataObj[f][r] &&
-        this.pageFloorGridDataObj[f][r][c]
-      );
-    },
-    getTheItemStore(r, c, f) {
-      return (
-        this.storePageFloorGridDataObj[f] &&
-        this.storePageFloorGridDataObj[f][r] &&
-        this.storePageFloorGridDataObj[f][r][c]
-      );
-    },
-    resetPageRowCol() {
-      const rowNum = this.isCfgSty
-        ? (this.aroundInfo.up || 0) + (this.aroundInfo.down || 0)
-        : this.expandRowNum;
-      const colNum = this.isCfgSty
-        ? (this.aroundInfo.left || 0) + (this.aroundInfo.right || 0)
-        : this.expandColNum;
-      this.busiRowOri = this.rackRow + rowNum;
-      this.busiColOri = this.rackCol + colNum;
-      if (this.rotationAngleType === 0 || this.rotationAngleType === 2) {
-        this.pageRow = this.rackRow + rowNum;
-        this.pageCol = this.rackCol + colNum;
-      }
-      if (this.rotationAngleType === 1 || this.rotationAngleType === 3) {
-        this.pageRow = this.rackCol + colNum;
-        this.pageCol = this.rackRow + rowNum;
-      }
-    },
-    initCfg(data) {
-      this.initAroundConveyor(JSON.parse(JSON.stringify(data)));
-      this.resetPageRowCol();
-      if (this.isNotDo()) {
-        return;
-      }
-      this.calculateBoundInfo(this.rotationAngleType, this.isCfgSty);
-      this.refreshCanvasSize();
-      // if (this.isCfgSty) {
-      // this.initRackBoundInfoWhenCfg(this.rotationAngleType)
-      // this.refreshCanvasSizeWhenCfg()
-      // } else {
-      // this.initRackBoundInfo(this.rotationAngleType)
-      // this.refreshCanvasSize()
-      // }
-    },
-    refreshCanvasSize() {
-      // const clientWidth =
-      //   this.$refs.wareHouseArea.clientWidth ||
-      //   this.$refs.wareHouseArea.parentNode.clientWidth; // 当v-show为false,第一次展示时容器为0,此时使用父元素的长宽
-      // const clientHeight =
-      //   this.$refs.wareHouseArea.clientHeight ||
-      //   this.$refs.wareHouseArea.parentNode.clientHeight; // 当v-show为false,第一次展示时容器为0,此时使用父元素的长宽
-      const containerWidth =
-        this.containerWidth - getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-      const containerHeight =
-        this.containerHeight - getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-      console.log(containerHeight, containerWidth);
-      this.thetaInRadians = (this.includedAngle * Math.PI) / 180;
-      const mathSin = Math.sin(this.thetaInRadians);
-      const mathCos = Math.cos(this.thetaInRadians);
-      const mathTan = Math.tan(this.thetaInRadians);
-      if (this.isShowNumInCell) {
-        if (this.isTheRotationAngleType()) {
-          this.cellLen = getCFG("canvas").cellSty.cellLen;
-          this.cellWidth = getCFG("canvas").cellSty.cellWidth;
-        } else {
-          this.cellLen = getCFG("canvas").cellSty.cellWidth;
-          this.cellWidth = getCFG("canvas").cellSty.cellLen;
-        }
-      } else {
-        const horizontalCellWidth = containerWidth / this.pageCol; // horizontalCellWidth为横向四边形占用的总空间
-        const pageFlr = !this.isShowAllFlr ? 1 : this.totalFlr;
-        const verticalCellHeight =
-          (containerHeight - (pageFlr - 1) * this.flrVehSpace) /
-          (this.pageRow * pageFlr); //verticalCellHeight为竖向四边形占用的总空间
-        const verticalEdgeLen = verticalCellHeight / mathSin;
-        let cellLen = Math.min(verticalEdgeLen, horizontalCellWidth);
-        if (cellLen < 12) {
-          cellLen = 12;
-        }
-        if (cellLen > 40) {
-          cellLen = 40;
-        }
-        // 使用余弦函数偏移量
-        let offset = !this.isShowAllFlr ? 0 : cellLen * mathCos;
-        let isComNum = false;
-        while (
-          offset * this.pageRow + cellLen * this.pageCol >
-          containerWidth
-        ) {
-          cellLen -= 0.3;
-          isComNum = true;
-          // 使用正弦函数计算偏移量
-          offset = cellLen * mathCos;
-          if (cellLen < 10) {
-            break;
-          }
-        }
-        if (isComNum) {
-          cellLen += 0.3;
-        }
-        this.cellLen = cellLen;
-        this.cellWidth = cellLen;
-      }
-
-      // 根据 cellWidth  cellLen 重新计算参数
-      this.verticalCellHeight = this.cellLen * mathSin;
-      // 向右倾斜
-      this.horizontalPointOffset = !this.isShowAllFlr
-        ? 0
-        : -this.cellLen * mathCos;
-
-      // 2.1 计算this.flrVehTotalLen值
-      this.flrVehTotalLen = this.verticalCellHeight * this.pageRow;
-
-      // 2.2 计算this.flrHorizontalTotalHangLen
-
-      this.flrHorizontalTotalHangLen = !this.isShowAllFlr
-        ? 0
-        : this.flrVehTotalLen / mathTan;
-      // 2.3 计算this.flrHorizontalLen
-      this.flrHorizontalLen = this.cellWidth * this.pageCol;
-
-      // 2.4 计算this.flrHorizontalTotalLen
-      this.flrHorizontalTotalLen =
-        this.flrHorizontalLen + this.flrHorizontalTotalHangLen;
-
-      // 2.5 计算this.totalHorizontalFlrPer
-      let flrPer = Math.floor(
-        (containerWidth + this.flrHorizontalSpace) / this.flrHorizontalTotalLen
-      );
-      flrPer = flrPer || 1;
-      this.totalHorizontalFlrPer = !this.isShowAllFlr ? 1 : flrPer;
-      const { currentPageFloorNum } = this.calcCurPageFloor(
-        this.totalFlr,
-        this.totalHorizontalFlrPer,
-        "tTOb"
-      );
-      this.totalPageFlr = !this.isShowAllFlr ? 1 : currentPageFloorNum;
-      // 3-根据最终的 cellWidth 和 cellLen 计算画布大小
-      this.canvasWidth =
-        containerWidth + getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-      this.canvasHeight =
-        containerHeight + getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-    },
-    /**
-     *  初始化 rowOffsetX 和 colOffsetY
-     *
-     */
-    initCfgBefRender() {
-      const lenInfo = this.getCavasAreaLen(this.pageFloorGridDataObj);
-      const renderTotalWidth =
-        lenInfo.widthX + getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-
-      // const renderTotalHeight = lenInfo.heightY
-      const renderTotalHeight =
-        this.pageRow * this.verticalCellHeight * this.totalPageFlr +
-        (this.totalPageFlr - 1) * this.flrVehSpace;
-      const inclineLeftX = lenInfo.minX < 0 ? Math.abs(lenInfo.minX) : 0; // 倾斜到左侧时,对左侧不可见部分进行偏移
-      // const inclineTopY = lenInfo.minY < 0 ? Math.abs(lenInfo.minY) : 0
-      let XOffset = 0;
-      if (this.canvasWidth > renderTotalWidth) {
-        // 总的canvas宽度需要根据整个货架最大x-最小x
-        XOffset = (this.canvasWidth - renderTotalWidth) / 2;
-        // this.canvasWidth = this.canvasWidth + XOffset + inclineLeftX
-      } else {
-        this.canvasWidth = renderTotalWidth;
-      }
-      let YOffset = 0;
-      if (this.canvasHeight > renderTotalHeight) {
-        // 总的canvas高度,没有Y向偏移,直接+YOffset
-        YOffset = (this.canvasHeight - renderTotalHeight) / 2;
-        // this.canvasHeight = this.canvasHeight + YOffset
-      } else {
-        this.canvasHeight = renderTotalHeight;
-      }
-      this.warehousPageCfg.rowOffsetX =
-        inclineLeftX + XOffset + getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-      this.warehousPageCfg.colOffsetY =
-        YOffset + getCFG("canvas").cellSty.rackIdxNumOffsetLen;
-    },
-    /**
-     * pageFloorGridDataObj的数据结构为{层:[[ele,ele2],[],[]]}
-     * ele的结构为{type: 'gridUnit', status: 'default', fillColor: '#fff', borderColor: '#000', lineWidth: 1, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0, x4: 0, y4: 0}
-     * 循环每一层数据,取出第一行第一个元素、最后一个元素;最后一行第一个元素、最后一个元素,计算出最大x和最小x,最大y和最小y
-     * 根据最大x和最小x,最大y和最小y计算出画布的宽和高
-     */
-    getCavasAreaLen(pageFloorGridDataObj) {
-      // 初始化最大和最小 x、y 值
-      let minX = Infinity;
-      let maxX = -Infinity;
-      let minY = Infinity;
-      let maxY = -Infinity;
-
-      // 遍历每一层的数据
-      for (const floorData of Object.values(pageFloorGridDataObj)) {
-        // 获取第一行和最后一行的元素
-        const firstRowFirstEle = floorData[0][0];
-        const firstRowLastEle = floorData[0][floorData[0].length - 1];
-        const lastRowFirstEle = floorData[floorData.length - 1][0];
-        const lastRowLastEle =
-          floorData[floorData.length - 1][
-            floorData[floorData.length - 1].length - 1
-          ];
-
-        // 更新最大和最小 x、y 值
-        minX = Math.min(
-          minX,
-          firstRowFirstEle.x1,
-          firstRowLastEle.x2,
-          lastRowFirstEle.x1,
-          lastRowLastEle.x2
-        );
-        maxX = Math.max(
-          maxX,
-          firstRowFirstEle.x1,
-          firstRowLastEle.x2,
-          lastRowFirstEle.x1,
-          lastRowLastEle.x2
-        );
-        minY = Math.min(
-          minY,
-          firstRowFirstEle.y1,
-          firstRowLastEle.y2,
-          lastRowFirstEle.y1,
-          lastRowLastEle.y2
-        );
-        maxY = Math.max(
-          maxY,
-          firstRowFirstEle.y1,
-          firstRowLastEle.y2,
-          lastRowFirstEle.y1,
-          lastRowLastEle.y2
-        );
-      }
-
-      // 计算画布的宽度和高度
-      const canvasWidth = maxX - minX;
-      const canvasHeight = maxY - minY;
-
-      return { widthX: canvasWidth, heightY: canvasHeight, minX, minY };
-    },
-    initGridDoubleArr(gridDoubleArr, curFlrNum) {
-      const { currentPageFloorNum, positionInPageFloorNum } =
-        this.calcCurPageFloor(curFlrNum, this.totalHorizontalFlrPer);
-      for (let rowIndex = 0; rowIndex < this.pageRow; rowIndex++) {
-        const row = [];
-        for (let colIndex = 0; colIndex < this.pageCol; colIndex++) {
-          const itemType = this.getItemType(rowIndex, colIndex);
-          const ele = {
-            rowIndex,
-            colIndex,
-            flrNum: curFlrNum,
-            r: rowIndex,
-            c: colIndex,
-            pageR: rowIndex,
-            pageC: colIndex,
-            type: itemType,
-            status: "",
-            fillColor: "",
-            borderColor: "",
-            lineWidth: 0,
-          };
-          const pos = this.getCellPos(
-            rowIndex,
-            colIndex,
-            currentPageFloorNum,
-            positionInPageFloorNum
-          );
-          Object.assign(ele, pos);
-          this.itemStsInit(ele, "");
-
-          row.push(ele);
-        }
-        gridDoubleArr.push(row);
-      }
-      return gridDoubleArr;
-    },
-    /**
-     * currentPageFloorNum 处于页面的哪一层
-     * positionInPageFloorNum处于具体层的具体行号
-     * 根据rcf计算位置信息
-     */
-    getCellPos(
-      rowIndex,
-      colIndex,
-      currentPageFloorNum,
-      positionInPageFloorNum
-    ) {
-      const { x1, y1 } = this.calcPoint1(
-        rowIndex,
-        colIndex,
-        currentPageFloorNum,
-        positionInPageFloorNum
-      );
-      const x2 = x1 + this.cellWidth;
-      const x3 = x2 + this.horizontalPointOffset;
-      const x4 = x3 - this.cellWidth;
-      const y2 = y1;
-      const y3 = y2 + this.verticalCellHeight;
-      const y4 = y3;
-      return { x1, y1, x2, y2, x3, y3, x4, y4 };
-    },
-    calcCurPageFloor(curFlrNum, totalHorizontalFlrPer, flrFromSty) {
-      const finalFlrFromSty = flrFromSty || this.flrFromSty;
-      // 确保curFlrNum和totalHorizontalFlrPer都是有效的数字
-      if (
-        typeof curFlrNum !== "number" ||
-        typeof totalHorizontalFlrPer !== "number" ||
-        totalHorizontalFlrPer <= 0
-      ) {
-        console.error("Invalid input");
-        return;
-      }
-      if (!this.isShowAllFlr) {
-        return {
-          currentPageFloorNum: 1,
-          positionInPageFloorNum: 1,
-        };
-      }
-      // 计算当前编号货架层属于第几层
-      let currentPageFloorNum = Math.ceil(curFlrNum / totalHorizontalFlrPer);
-      // if (this.flrFromSty === 'bTOt') {
-      //   currentPageFloorNum =
-      //     this.totalPageFlr - Math.ceil(curFlrNum / totalHorizontalFlrPer) + 1 // 从下往上计算层数
-      // } else {
-      //   currentPageFloorNum = Math.ceil(curFlrNum / totalHorizontalFlrPer) // 从上往下计算层数
-      // }
-
-      // 计算当前货架层是所在层中的第几块
-      const positionInPageFloorNum =
-        curFlrNum % totalHorizontalFlrPer === 0
-          ? totalHorizontalFlrPer
-          : curFlrNum % totalHorizontalFlrPer;
-      if (finalFlrFromSty !== "bTOt") {
-        // 返回当前层及该层中的位置
-        return {
-          currentPageFloorNum,
-          positionInPageFloorNum,
-        };
-      }
-      currentPageFloorNum = this.totalPageFlr - currentPageFloorNum + 1;
-      return {
-        currentPageFloorNum,
-        positionInPageFloorNum,
-      };
-    },
-    /**
-     * rowIndex,行序号
-      colIndex,列序号
-      currentPageFloorNum,页面上属于第几行
-      positionInPageFloorNum 在页面行中属于第几个
-     */
-    calcPoint1(
-      rowIndex,
-      colIndex,
-      currentPageFloorNum,
-      positionInPageFloorNum
-    ) {
-      const flrVehTotalLen =
-        this.verticalCellHeight * (this.pageRow - rowIndex);
-      const flrHorizontalTotalHangLen =
-        flrVehTotalLen / Math.tan(this.thetaInRadians);
-      const x1 =
-        (positionInPageFloorNum - 1) *
-          (this.flrHorizontalTotalLen + this.flrHorizontalSpace) +
-        flrHorizontalTotalHangLen +
-        colIndex * this.cellWidth;
-      const y1 =
-        (currentPageFloorNum - 1) * (this.flrVehTotalLen + this.flrVehSpace) +
-        rowIndex * this.verticalCellHeight;
-      return { x1, y1 };
-    },
-    /**
-     * 1-[0,0][this.rackCol+this.expandColStart,0][this.rackCol+this.expandColStart,this.rackRow+this.expandRowStart][0,this.rackRow+this.expandRowStart]转换到页面后货架边界的四个顶点。
-     * 2-确认rowIndexIn colIndexIn是否在四个顶点范围内
-     * @param rowIndexIn 页面序号
-     * @param colIndexIn 页面序号
-     * @param rotationAngleType
-     */
-    getItemType(rowIndexIn, colIndexIn) {
-      const minR = this.rackBoundInfo.minR;
-      const maxR = this.rackBoundInfo.maxR;
-      const minC = this.rackBoundInfo.minC;
-      const maxC = this.rackBoundInfo.maxC;
-      if (!this.isCfgSty) {
-        if (
-          rowIndexIn >= minR &&
-          rowIndexIn <= maxR &&
-          colIndexIn >= minC &&
-          colIndexIn <= maxC
-        ) {
-          return LOCTYPE.rack;
-        } else {
-          return LOCTYPE.default;
-        }
-      }
-      // 判断是否在货架区域内
-      if (
-        rowIndexIn >= minR &&
-        rowIndexIn <= maxR &&
-        colIndexIn >= minC &&
-        colIndexIn <= maxC
-      ) {
-        return LOCTYPE.rack;
-      }
-      const {
-        minR: aroundMinR,
-        maxR: aroundMaxR,
-        minC: aroundMinC,
-        maxC: aroundMaxC,
-      } = this.aroundBoundInfo;
-      // 判断是否在外围区域内
-      if (
-        rowIndexIn >= aroundMinR &&
-        rowIndexIn <= aroundMaxR &&
-        colIndexIn >= aroundMinC &&
-        colIndexIn <= aroundMaxC
-      ) {
-        return LOCTYPE.around;
-      }
-      return LOCTYPE.default;
-    },
-    calculateBoundInfo(rotationAngleType, includeAround) {
-      const around = this.aroundInfo || {};
-      const { up = 0, down = 0, left = 0, right = 0 } = around;
-
-      const innerOffset = includeAround ? { r: down, c: left } : { r: 0, c: 0 };
-      const outerOffset = includeAround
-        ? { r: down + up, c: left + right }
-        : { r: 0, c: 0 };
-
-      const vertices = this.getVertices(innerOffset, outerOffset);
-
-      vertices.forEach((vertex) => {
-        this.busiIndxToPageIdx(vertex, rotationAngleType);
-      });
-
-      const rackBoundInfo = this.getBoundInfo(vertices.slice(0, 4));
-      const aroundBoundInfo = includeAround
-        ? this.getBoundInfo(vertices.slice(4))
-        : null;
-
-      this.rackBoundInfo = rackBoundInfo;
-      if (includeAround) {
-        this.aroundBoundInfo = aroundBoundInfo;
-      }
-
-      return includeAround ? aroundBoundInfo : rackBoundInfo;
-    },
-
-    getVertices(innerOffset, outerOffset) {
-      const innerVertex1 = {
-        r: this.rowStartOri + innerOffset.r,
-        c: this.colStartOri + innerOffset.c,
-      };
-      const innerVertex2 = {
-        r: this.rackRow + this.rowStartOri + innerOffset.r - 1,
-        c: this.colStartOri + innerOffset.c,
-      };
-      const innerVertex3 = {
-        r: this.rackRow + this.rowStartOri + innerOffset.r - 1,
-        c: this.rackCol + this.colStartOri + innerOffset.c - 1,
-      };
-      const innerVertex4 = {
-        r: this.rowStartOri + innerOffset.r,
-        c: this.rackCol + this.colStartOri + innerOffset.c - 1,
-      };
-
-      const outerVertex1 = { r: this.rowStartOri, c: this.colStartOri };
-      const outerVertex2 = {
-        r: this.rackRow + this.rowStartOri + outerOffset.r - 1,
-        c: this.colStartOri,
-      };
-      const outerVertex3 = {
-        r: this.rackRow + this.rowStartOri + outerOffset.r - 1,
-        c: this.rackCol + this.colStartOri + outerOffset.c - 1,
-      };
-      const outerVertex4 = {
-        r: this.rowStartOri,
-        c: this.rackCol + this.colStartOri + outerOffset.c - 1,
-      };
-
-      return [
-        innerVertex1,
-        innerVertex2,
-        innerVertex3,
-        innerVertex4,
-        outerVertex1,
-        outerVertex2,
-        outerVertex3,
-        outerVertex4,
-      ];
-    },
-
-    getBoundInfo(vertices) {
-      const minR = Math.min(...vertices.map((v) => v.r));
-      const maxR = Math.max(...vertices.map((v) => v.r));
-      const minC = Math.min(...vertices.map((v) => v.c));
-      const maxC = Math.max(...vertices.map((v) => v.c));
-
-      return { minR, maxR, minC, maxC };
-    },
-    getItemStsInfo(itemStatus, type) {
-      if (!itemStatus) {
-        if (type === LOCTYPE.rack) {
-          itemStatus = ITEMSTATUS.storageLoc;
-        } else {
-          itemStatus = type;
-        }
-      }
-      const defaultStyle = this.itemStsMap[ITEMSTATUS.default].sty;
-      const itemStyle = this.itemStsMap[itemStatus]?.sty || {};
-
-      return {
-        status: itemStatus,
-        fillColor: itemStyle.fillColor || defaultStyle.fillColor,
-        borderColor: itemStyle.borderColor || defaultStyle.borderColor,
-        lineWidth: itemStyle.lineWidth || defaultStyle.lineWidth,
-      };
-    },
-    updateMapTransform() {
-      this.ctx.setTransform(
-        this.scale,
-        0,
-        0,
-        this.scale,
-        this.offset.x,
-        this.offset.y
-      );
-    },
-    /**
-     * 设置是否展示,匹配跟3D一起展示的情景
-     */
-    setIsShowing(isShow) {
-      this.isShowing = isShow;
-      if (this.isShowing) {
-        this.aniDraw();
-      } else {
-        this.stopAniDraw();
-      }
-    },
-    drawCanvas() {
-      const canvas = this.$refs.canvas;
-      if (!canvas) {
-        return;
-      }
-
-      if (!this.pageFloorGridDataObj) {
-        return;
-      }
-      const keys = Object.keys(this.pageFloorGridDataObj);
-      if (!keys || keys.length < 1) {
-        return;
-      }
-      const ctx = canvas.getContext("2d");
-      this.ctx = ctx;
-      this.canvas = canvas;
-
-      // 清除整个 Canvas
-      ctx.clearRect(0, 0, canvas.width, canvas.height);
-
-      // 保存当前状态
-      ctx.save();
-
-      ctx.scale(this.scale, this.scale);
-
-      // 绘制货架
-      this.drawGrid(ctx);
-      this.drawGoods(ctx, this.goodsVisObj);
-      this.drawGoods(ctx, this.conveyorAroundMap);
-      // 绘制线路
-      this.drawPath();
-      // 绘制车辆 车辆数据已经是页面序号
-      // 暂不开放 20240301
-      // this.drawRackIndx(ctx)
-      if (this.isShowAllFlr) {
-        this.drawFlrNum(ctx);
-      }
-      this.drawSelItemArr(ctx);
-      this.drawRackIndxNum(ctx);
-      this.drawShuttle(ctx);
-      // 恢复状态
-      ctx.restore();
-      this.aniDraw();
-    },
-    getRackIndxNum(e) {
-      const canvas = this.$refs.canvas;
-      const rect = canvas.getBoundingClientRect();
-
-      // 获取鼠标点击的坐标
-      let x = (e.clientX - rect.left - this.offset.x) / this.scale;
-      let y = (e.clientY - rect.top - this.offset.y) / this.scale;
-
-      const SIDE_PADDING = getCFG("canvas").cellSty.idxNumSidePadding || 4;
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-
-      if (!firstFloorData || firstFloorData.length === 0) {
-        return null;
-      }
-
-      // 检查是否点击了行号区域
-      if (firstFloorData[0] && firstFloorData[0][0]) {
-        for (let rowIndex = 0; rowIndex < firstFloorData.length; rowIndex++) {
-          if (firstFloorData[rowIndex] && firstFloorData[rowIndex][0]) {
-            const firstCell = firstFloorData[rowIndex][0];
-            const { x1, y1, y4 } = this.calculateCoordinates(firstCell);
-            const centerY = y1 + (y4 - y1) / 2;
-
-            // 检查点击是否在行号区域内
-            if (
-              x >= x1 - getCFG("canvas").cellSty.rackIdxNumOffsetLen &&
-              x <=
-                x1 -
-                  getCFG("canvas").cellSty.rackIdxNumOffsetLen +
-                  SIDE_PADDING * 4 &&
-              y >= centerY - 10 &&
-              y <= centerY + 10
-            ) {
-              // 转换回业务索引
-              // const backEle = this.pageIdxToBusiIndx(
-              //   { r: rowIndex, c: 0 },
-              //   this.rotationAngleType,
-              //   true,
-              //   false
-              // )
-              return {
-                type: "row",
-                index: rowIndex,
-              };
-            }
-          }
-        }
-      }
-
-      // 检查是否点击了列号区域
-      if (firstFloorData[0]) {
-        for (
-          let colIndex = 0;
-          colIndex < firstFloorData[0].length;
-          colIndex++
-        ) {
-          if (firstFloorData[0][colIndex]) {
-            const firstCell = firstFloorData[0][colIndex];
-            const { x1, x2, y1 } = this.calculateCoordinates(firstCell);
-            const centerX = x1 + (x2 - x1) / 2;
-
-            // 检查点击是否在列号区域内
-            if (
-              y >=
-                y1 -
-                  getCFG("canvas").cellSty.rackIdxNumOffsetLen -
-                  SIDE_PADDING * 2 &&
-              y <= y1 - SIDE_PADDING &&
-              x >= centerX - 15 &&
-              x <= centerX + 15
-            ) {
-              // 转换回业务索引
-              // const backEle = this.pageIdxToBusiIndx(
-              //   { r: 0, c: colIndex },
-              //   this.rotationAngleType,
-              //   true,
-              //   false
-              // )
-              return {
-                type: "col",
-                index: colIndex,
-              };
-            }
-          }
-        }
-      }
-      return null;
-    },
-    drawRackIndxNum(ctx) {
-      if (!this.isShowRackIndxNum) {
-        return;
-      }
-      const SIDE_PADDING_X = getCFG("canvas").cellSty.rackIdxNumSideXPadding;
-      const SIDE_PADDING_Y = getCFG("canvas").cellSty.rackIdxNumSideYPadding;
-      const FONT = getCFG("canvas").cellSty.rackIdxNumFont || "12px Arial";
-      const DEFAULT_COLOR =
-        getCFG("canvas").cellSty.rackIdxNumFontColor || "#666666";
-      const HIGHLIGHT_BG = "#CCE6FF"; // 中等蓝色背景
-      const HIGHLIGHT_TEXT = "#000000"; // 纯黑色文字
-      const HIGHLIGHT_FONT = "bold 12px Arial";
-
-      // 基础文本样式设置
-      ctx.font = FONT;
-      ctx.fillStyle = DEFAULT_COLOR;
-      ctx.textBaseline = "middle";
-
-      // 获取选中项
-      const firstSelectedItem = this.selectedItemArr?.[0] || null;
-      const highlightRow = firstSelectedItem?.rowIndex;
-      const highlightCol = firstSelectedItem?.colIndex;
-
-      // 获取当前楼层数据
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-      if (!firstFloorData?.length) return;
-
-      // 绘制行号
-      this.drawRowNumbers(ctx, firstFloorData, highlightRow, {
-        SIDE_PADDING_X,
-        DEFAULT_COLOR,
-        FONT,
-        HIGHLIGHT_BG,
-        HIGHLIGHT_TEXT,
-        HIGHLIGHT_FONT,
-      });
-
-      // 绘制列号
-      this.drawColumnNumbers(ctx, firstFloorData, highlightCol, {
-        SIDE_PADDING_Y,
-        DEFAULT_COLOR,
-        FONT,
-        HIGHLIGHT_BG,
-        HIGHLIGHT_TEXT,
-        HIGHLIGHT_FONT,
-      });
-    },
-
-    // 抽取行号绘制逻辑
-    drawRowNumbers(ctx, firstFloorData, highlightRow, styles) {
-      for (let rowIndex = 0; rowIndex < firstFloorData.length; rowIndex++) {
-        const firstCell = firstFloorData[rowIndex]?.[0];
-        if (!firstCell) continue;
-
-        const { x1, y1, y4 } = this.calculateCoordinates(firstCell);
-        const backEle = this.pageIdxToBusiIndx(
-          { r: rowIndex, c: 0 },
-          this.rotationAngleType,
-          false,
-          false
-        );
-        const formattedRowNum = backEle.backR.toString();
-
-        // 计算行高度和垂直中心位置
-        const rowHeight = y4 - y1;
-        const centerY = y1 + rowHeight / 2;
-
-        // 计算文本框的位置和尺寸
-        const textX =
-          x1 -
-          getCFG("canvas").cellSty.rackIdxNumOffsetLen +
-          styles.SIDE_PADDING_X;
-        const textWidth =
-          getCFG("canvas").cellSty.rackIdxNumOffsetLen -
-          styles.SIDE_PADDING_X * 2;
-
-        // 高亮处理
-        if (rowIndex === highlightRow) {
-          // 绘制高亮背景,确保背景框与文本区域对齐
-          this.drawHighlightBackground(
-            ctx,
-            textX - styles.SIDE_PADDING_X,
-            y1,
-            textWidth + styles.SIDE_PADDING_X * 2,
-            rowHeight,
-            styles.HIGHLIGHT_BG
-          );
-          ctx.fillStyle = styles.HIGHLIGHT_TEXT;
-          ctx.font = styles.HIGHLIGHT_FONT;
-        } else {
-          ctx.fillStyle = styles.DEFAULT_COLOR;
-          ctx.font = styles.FONT;
-        }
-
-        // 设置文本对齐方式
-        ctx.textAlign = "center";
-        ctx.textBaseline = "middle";
-
-        // 在计算出的中心位置绘制文本
-        ctx.fillText(
-          formattedRowNum,
-          textX + textWidth / 2, // 文本框的水平中心
-          centerY // 单元格的垂直中心
-        );
-      }
-    },
-
-    // 抽取列号绘制逻辑
-    drawColumnNumbers(ctx, firstFloorData, highlightCol, styles) {
-      const firstRow = firstFloorData[0];
-      if (!firstRow) return;
-
-      for (let colIndex = 0; colIndex < firstRow.length; colIndex++) {
-        const firstCell = firstRow[colIndex];
-        if (!firstCell) continue;
-
-        const { x1, x2, y1 } = this.calculateCoordinates(firstCell);
-        const backEle = this.pageIdxToBusiIndx(
-          { r: 0, c: colIndex },
-          this.rotationAngleType,
-          false,
-          false
-        );
-        const formattedColNum = backEle.backC.toString();
-
-        // 计算列宽度和水平中心位置
-        const colWidth = x2 - x1;
-        const centerX = x1 + colWidth / 2;
-
-        // 计算文本框的位置和尺寸
-        const textY =
-          y1 -
-          getCFG("canvas").cellSty.rackIdxNumOffsetLen +
-          styles.SIDE_PADDING_Y;
-        const textHeight =
-          getCFG("canvas").cellSty.rackIdxNumOffsetLen -
-          styles.SIDE_PADDING_Y * 2;
-
-        // 高亮处理
-        if (colIndex === highlightCol) {
-          // 绘制高亮背景,确保背景框与文本区域对齐
-          this.drawHighlightBackground(
-            ctx,
-            x1, // 起始x坐标
-            y1 - getCFG("canvas").cellSty.rackIdxNumOffsetLen, // 起始y坐标
-            colWidth, // 宽度
-            getCFG("canvas").cellSty.rackIdxNumOffsetLen, // 高度
-            styles.HIGHLIGHT_BG,
-            false
-          );
-          ctx.fillStyle = styles.HIGHLIGHT_TEXT;
-          ctx.font = styles.HIGHLIGHT_FONT;
-        } else {
-          ctx.fillStyle = styles.DEFAULT_COLOR;
-          ctx.font = styles.FONT;
-        }
-
-        // 设置文本对齐方式
-        ctx.textAlign = "center";
-        ctx.textBaseline = "middle";
-
-        // 在计算出的中心位置绘制文本
-        ctx.fillText(
-          formattedColNum,
-          centerX,
-          textY + textHeight / 2 // 文本框的垂直中心
-        );
-      }
-    },
-
-    // 抽取高亮背景绘制逻辑
-    // 修改高亮背景绘制逻辑
-    drawHighlightBackground(ctx, x, y, width, height, color) {
-      const padding = 2; // 背景内边距
-      ctx.fillStyle = color;
-      ctx.fillRect(
-        x + padding, // 左边加padding
-        y + padding, // 上边加padding
-        width - padding * 2, // 减去左右padding
-        height - padding * 2 // 减去上下padding
-      );
-    },
-    drawSelItemArr(ctx) {
-      if (!this.selectedItemArr || this.selectedItemArr.length < 1) {
-        return;
-      }
-
-      // 按照行列排序selectedItemArr
-      const sortedItems = [...this.selectedItemArr].sort((a, b) => {
-        if (a.flrNum !== b.flrNum) return a.flrNum - b.flrNum;
-        if (a.rowIndex !== b.rowIndex) return a.rowIndex - b.rowIndex;
-        return a.colIndex - b.colIndex;
-      });
-
-      // 绘制边框
-      sortedItems.forEach((item) => {
-        const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-          this.calculateCoordinates(item);
-
-        // 检查四个方向是否有相邻元素
-        const hasLeft = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex &&
-            other.colIndex === item.colIndex - 1
-        );
-        const hasRight = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex &&
-            other.colIndex === item.colIndex + 1
-        );
-        const hasTop = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex - 1 &&
-            other.colIndex === item.colIndex
-        );
-        const hasBottom = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex + 1 &&
-            other.colIndex === item.colIndex
-        );
-
-        // 绘制主边框
-        ctx.beginPath();
-        ctx.strokeStyle = "#409EFF"; // 主边框颜色
-        ctx.lineWidth = 2;
-
-        // 只绘制没有相邻元素的边
-        if (!hasTop) {
-          ctx.moveTo(x1, y1);
-          ctx.lineTo(x2, y2);
-        }
-        if (!hasRight) {
-          ctx.moveTo(x2, y2);
-          ctx.lineTo(x3, y3);
-        }
-        if (!hasBottom) {
-          ctx.moveTo(x3, y3);
-          ctx.lineTo(x4, y4);
-        }
-        if (!hasLeft) {
-          ctx.moveTo(x4, y4);
-          ctx.lineTo(x1, y1);
-        }
-        ctx.stroke();
-
-        // 绘制外发光效果
-        ctx.beginPath();
-        ctx.strokeStyle = "rgba(64, 158, 255, 0.3)"; // 半透明的边框颜色
-        ctx.lineWidth = 4;
-
-        if (!hasTop) {
-          ctx.moveTo(x1, y1 - 1);
-          ctx.lineTo(x2, y2 - 1);
-        }
-        if (!hasRight) {
-          ctx.moveTo(x2 + 1, y2);
-          ctx.lineTo(x3 + 1, y3);
-        }
-        if (!hasBottom) {
-          ctx.moveTo(x3, y3 + 1);
-          ctx.lineTo(x4, y4 + 1);
-        }
-        if (!hasLeft) {
-          ctx.moveTo(x4 - 1, y4);
-          ctx.lineTo(x1 - 1, y1);
-        }
-        ctx.stroke();
-      });
-    },
-    drawGoods(ctx, drawObj) {
-      const goodsAddrArr = Object.keys(drawObj);
-      if (!goodsAddrArr || goodsAddrArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < goodsAddrArr.length; i++) {
-        const addr = goodsAddrArr[i];
-        const [f, c, r] = this.rCFStrToArr(addr);
-        if (!this.pageFloorGridDataObj[f] || !drawObj[addr]) {
-          continue;
-        }
-        const compuItem = this.busiIndxToPageIdx(
-          { r: r, c: c },
-          this.rotationAngleType
-        );
-        const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-        if (ele) {
-          const newItem = JSON.parse(JSON.stringify(ele));
-          this.itemStsInit(newItem, ITEMSTATUS.goods);
-          // 绘制车辆,部分参数不使用
-          this.parallelogramDraw(ctx, newItem);
-        }
-      }
-    },
-    drawFlrNum(ctx) {
-      Object.keys(this.pageFloorGridDataObj).forEach((flrNum) => {
-        const { currentPageFloorNum, positionInPageFloorNum } =
-          this.calcCurPageFloor(Number(flrNum), this.totalHorizontalFlrPer);
-        const pos = this.getCellPos(
-          0,
-          0,
-          currentPageFloorNum,
-          positionInPageFloorNum
-        );
-        const x1 = pos.x1 - this.flrHorizontalTotalHangLen;
-        const y1 = pos.y1 + this.flrVehTotalLen / 2;
-        const x = this.calculateCoordinate(x1, "x");
-        const y = this.calculateCoordinate(y1, "y");
-        // 设置文本样式 (可选)
-        ctx.font = "12px Arial"; // 可以根据需要调整字体大小和类型
-        ctx.fillStyle = "gray"; // 文本颜色
-
-        // 在x1, y1位置书写文字,内容为 flrNum + '层'
-        ctx.fillText(flrNum + "层", x, y);
-      });
-    },
-    drawRackIndx(ctx) {
-      if (!this.isShowAllFlr) {
-        ctx.font = "12px Arial";
-        ctx.fillStyle = "white";
-        for (let colIndex = 0; colIndex < this.rackCol; colIndex++) {
-          const x = this.calculateCoordinate(colIndex * this.cellWidth, "x");
-          ctx.fillText(colIndex + 1, x + 5, 15);
-        }
-
-        for (let rowIndex = 0; rowIndex < this.rackRow; rowIndex++) {
-          const y = this.calculateCoordinate(rowIndex * this.cellLen, "y");
-          ctx.fillText(rowIndex + 1, 5, y + 15);
-        }
-      }
-    },
-    aniDraw() {
-      if (!this.isAni) {
-        this.stopAniDraw();
-        return;
-      }
-      this.animationFrameId = requestAnimationFrame(this.drawCanvas);
-    },
-    stopAniDraw() {
-      if (this.animationFrameId) {
-        cancelAnimationFrame(this.animationFrameId);
-        this.animationFrameId = null;
-      }
-    },
-    drawGrid(ctx) {
-      this.drawFloorGirdDoubleArr(this.pageFloorGridDataObj, ctx);
-    },
-    drawPath() {
-      /* test
-      this.shuttleVisObj = {
-        1: {
-          baseInfo: {
-            sid: "1",
-            f: 2,
-            r: 17,
-            c: 15,
-            items: "00", // 表示载货状态,第一位是货物,第二位是托盘
-            steps: [
-              { f: 2, r: 17, c: 13 },
-              { f: 2, r: 17, c: 14 },
-              { f: 2, r: 17, c: 15 },
-              { f: 2, r: 17, c: 16 },
-              { f: 2, r: 17, c: 17 },
-            ],
-            step_index: 2,
-          },
-        },
-        2: {
-          baseInfo: {
-            sid: "2",
-            f: 1,
-            r: 18,
-            c: 39,
-            items: "00", // 只载托盘无货物
-            steps: [
-              { f: 1, r: 18, c: 37 },
-              { f: 1, r: 18, c: 38 },
-              { f: 1, r: 18, c: 39 },
-              { f: 1, r: 18, c: 40 },
-              { f: 1, r: 18, c: 41 },
-            ],
-            step_index: 3,
-          },
-        },
-      }; */
-      const shuttleArr = Object.keys(this.shuttleVisObj);
-      if (!shuttleArr || shuttleArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < shuttleArr.length; i++) {
-        const shuttleKey = shuttleArr[i];
-        const shuttle = this.shuttleVisObj[shuttleKey];
-        if (
-          !shuttle ||
-          !shuttle.baseInfo ||
-          !shuttle.baseInfo.steps ||
-          shuttle.baseInfo.steps.length < 1
-        ) {
-          continue;
-        }
-        const step_index = shuttle.baseInfo.step_index;
-        const steps = shuttle.baseInfo.steps;
-        const pathArr = [];
-        const pathArrBef = [];
-        for (let j = 0; j < steps.length; j++) {
-          const stepItem = steps[j];
-          const f = stepItem.f;
-          const r = stepItem.r;
-          const c = stepItem.c;
-          const compuItem = this.busiIndxToPageIdx(
-            { r: r, c: c },
-            this.rotationAngleType
-          );
-          const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-          if (!ele) {
-            continue;
-          }
-
-          if (j < step_index) {
-            pathArrBef.push(this.getCellCenterPos(ele));
-          } else if (j === step_index) {
-            pathArrBef.push(this.getCellCenterPos(ele));
-            pathArr.push(this.getCellCenterPos(ele));
-          } else {
-            pathArr.push(this.getCellCenterPos(ele));
-          }
-        }
-        // const pathColors = this.itemTypeProxy?.shuttle?.pathColors?.[shuttleKey];
-        // const passedColor = pathColors?.passed || 'rgb(200, 200, 200)'; // 已经过路径的颜色,默认灰色
-        // const toPassColor = pathColors?.toPass || PAGECFG_CONST.ITEMSTATUS.path.fillColor;
-
-        // 获取当前仓库的穿梭车颜色配置
-        const warehouseColors =
-          window.warehouseShuttleColors?.[this.wareHouseId];
-        const shuttleColors = warehouseColors?.[shuttleKey];
-
-        // 使用全局存储的颜色,如果没有则使用默认值
-        const passedColor =
-          shuttleColors?.path_passed_color || this.scssVariables.pathHasDrived;
-        const toPassColor =
-          shuttleColors?.path_color || this.scssVariables.path;
-        if (pathArr.length > 1) {
-          this.drawLineByArr(pathArr, toPassColor);
-        }
-        if (pathArrBef.length > 1) {
-          // this.startBlinkInter();
-          this.drawLineByArr(pathArrBef, passedColor);
-        }
-      }
-    },
-    startBlinkInter() {
-      if (this.blinkInter) {
-        return;
-      }
-      this.blinkInter = setInterval(() => {
-        this.isBlink = !this.isBlink;
-      }, 1000);
-    },
-    stopBlinkInter() {
-      if (this.blinkInter) {
-        clearInterval(this.blinkInter);
-        this.blinkInter = null;
-      }
-    },
-    /**
-     * 根据pathArr绘制线条
-     */
-    drawLineByArr(pathArr, fillColor) {
-      const ctx = this.ctx;
-      ctx.strokeStyle =
-        fillColor || this.itemStsMap[ITEMSTATUS.path].sty.fillColor;
-      ctx.lineWidth = this.itemStsMap[ITEMSTATUS.path].sty.lineWidth;
-      ctx.beginPath();
-      ctx.moveTo(
-        this.calculateCoordinate(pathArr[0].x, "x"),
-        this.calculateCoordinate(pathArr[0].y, "y")
-      );
-      for (let i = 1; i < pathArr.length; i++) {
-        ctx.lineTo(
-          this.calculateCoordinate(pathArr[i].x, "x"),
-          this.calculateCoordinate(pathArr[i].y, "y")
-        );
-      }
-      ctx.stroke();
-    },
-    /**
-     * ele结构为{r: 1, c: 1, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0, x4: 0, y4: 0, type: "warehouse", status: "default", fillColor: "white", borderColor: "black", lineWidth: 1}
-     * 根据ele上四个点的坐标获取四边形的中心点坐标
-     */
-    getCellCenterPos(ele) {
-      const x = (ele.x1 + ele.x2 + ele.x3 + ele.x4) / 4;
-      const y = (ele.y1 + ele.y2 + ele.y3 + ele.y4) / 4;
-      return { x, y };
-    },
-    // shuttle渲染数据this.shuttleVisObj
-    drawShuttle(ctx) {
-      // console.log(JSON.stringify(this.shuttleVisObj))
-      // TESTMM1113OVER
-      /* this.shuttleVisObj = {
-        test: {
-          baseInfo: {
-            f: 1,
-            c: 11,
-            r: 11,
-            sid: "1",
-            items: "00",
-            steps: [
-              { f: 1, c: 1, r: 1 },
-              { f: 1, c: 2, r: 1 },
-            ],
-            step_index: 1,
-          },
-        },
-      }; */
-      const shuttleArr = Object.keys(this.shuttleVisObj);
-      if (!shuttleArr || shuttleArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < shuttleArr.length; i++) {
-        const key = shuttleArr[i];
-        const shuttle = this.shuttleVisObj[key];
-        const baseInfo = shuttle.baseInfo;
-        // const [f, c, r] = this.rCFStrToArr(baseInfo.addr)
-        const f = baseInfo.f;
-        const c = baseInfo.c;
-        const r = baseInfo.r;
-        if (!this.isShowAllFlr && f !== this.operFloor) {
-          continue;
-        }
-        const compuItem = this.busiIndxToPageIdx(
-          { r: r, c: c },
-          this.rotationAngleType
-        );
-        const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-        if (ele) {
-          const locShuttle = JSON.parse(JSON.stringify(ele));
-          this.itemStsInit(locShuttle, ITEMSTATUS.shuttle);
-          locShuttle["type"] = ITEMSTATUS.shuttle;
-          if (
-            ele.status === ITEMSTATUS.goods ||
-            (ele.status === ITEMSTATUS.default && ele.type === LOCTYPE.rack)
-          ) {
-            const backEle = this.pageIdxToBusiIndx(
-              { f: ele.flrNum, c: ele.colIndex, r: ele.rowIndex },
-              this.rotationAngleType
-            );
-            const id = this.idKey(backEle);
-            if (this.goodsVisObj[id] || this.conveyorAroundMap[id]) {
-              locShuttle.isUnderGood = true;
-            }
-          }
-          if (this.isShowShuttleSid) {
-            locShuttle.sid = baseInfo.sid;
-          }
-          // 绘制车辆,部分参数不使用
-          this.parallelogramDrawShuttle(ctx, locShuttle);
-          const goodTypeStr = baseInfo.items && baseInfo.items[0];
-          const goodType = goodTypeStr && parseInt(goodTypeStr);
-          const palletTypeStr = baseInfo.items && baseInfo.items[1];
-          const palletType = goodTypeStr && parseInt(palletTypeStr);
-          if (goodType || palletType) {
-            const goodsPageEle = this.getParallelogramByPageEle(ele);
-            this.itemStsInit(goodsPageEle, ITEMSTATUS.goods);
-            goodsPageEle.borderColor =
-              this.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-            this.parallelogramDraw(ctx, goodsPageEle);
-          }
-        }
-      }
-    },
-    /**
-     * pageEle结构为{r: 1, c: 1, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0, x4: 0, y4: 0, type: "warehouse", status: "default", fillColor: "white", borderColor: "black", lineWidth: 1}
-     * pageEle是一个菱形
-     * @param pageEle 原始元素
-     * @param style 绘制样式 'small'(默认小正方形) | 'full'(扁平化效果,上下留空,左右扩展)
-     * 返回与pageEle结构一致的四个点坐标
-     */
-    getParallelogramByPageEle(pageEle, style = "full") {
-      // 获取pageEle的中心点坐标
-      const centerX = (pageEle.x1 + pageEle.x2 + pageEle.x3 + pageEle.x4) / 4;
-      const centerY = (pageEle.y1 + pageEle.y2 + pageEle.y3 + pageEle.y4) / 4;
-
-      if (style === "full") {
-        // 计算原始高度和宽度
-        const originalHeight = pageEle.y4 - pageEle.y1;
-        const originalWidth = pageEle.x2 - pageEle.x1;
-
-        // 设置上下留空的比例(可以调整这个值来改变留空大小)
-        const verticalPadding = originalHeight * 0.1; // 上下各留20%的空间
-
-        // 设置左右扩展的比例(可以调整这个值来改变扩展大小)
-        const horizontalExtend = originalWidth * 0.1; // 左右各扩展10%
-
-        // 计算新的坐标
-        const x1 = pageEle.x1 - horizontalExtend;
-        const y1 = pageEle.y1 + verticalPadding;
-        const x2 = pageEle.x2 + horizontalExtend;
-        const y2 = pageEle.y2 + verticalPadding;
-        const x3 = pageEle.x3 + horizontalExtend;
-        const y3 = pageEle.y3 - verticalPadding;
-        const x4 = pageEle.x4 - horizontalExtend;
-        const y4 = pageEle.y4 - verticalPadding;
-
-        return { ...pageEle, x1, y1, x2, y2, x3, y3, x4, y4 };
-      } else {
-        // 小正方形样式保持不变
-        const sideLength = Math.min(
-          Math.abs(pageEle.x1 - centerX),
-          Math.abs(pageEle.x2 - centerX),
-          Math.abs(pageEle.x3 - centerX),
-          Math.abs(pageEle.x4 - centerX)
-        );
-
-        const x1 = centerX - sideLength / 2;
-        const y1 = centerY - sideLength / 2;
-        const x2 = centerX + sideLength / 2;
-        const y2 = centerY - sideLength / 2;
-        const x3 = centerX + sideLength / 2;
-        const y3 = centerY + sideLength / 2;
-        const x4 = centerX - sideLength / 2;
-        const y4 = centerY + sideLength / 2;
-
-        return { ...pageEle, x1, y1, x2, y2, x3, y3, x4, y4 };
-      }
-    },
-    drawFloorGirdDoubleArr(pageFloorGridDataObj, ctx) {
-      const flrNums = Object.keys(pageFloorGridDataObj);
-      for (let i = 0; i < flrNums.length; i++) {
-        if (this.drawFlrConditon(flrNums[i])) {
-          continue;
-        }
-        const flrNum = flrNums[i];
-        const gridDoubleArr = pageFloorGridDataObj[flrNum];
-        this.drawGirdDoubleArr(gridDoubleArr, ctx, flrNum);
-      }
-      // for (let i = 1; i <= this.totalFlr; i++) {
-      //   const gridDoubleArr = pageFloorGridDataObj[i]
-      //   this.drawGirdDoubleArr(gridDoubleArr, ctx)
-      // }
-    },
-    drawFlrConditon(flrNum) {
-      if (this.isCfgSty && flrNum != this.operFloor) {
-        return true;
-      }
-    },
-    drawGirdDoubleArr(gridDoubleArr, ctx, flrNum) {
-      gridDoubleArr.forEach((row, rowIndex) => {
-        row.forEach((col, colIndex) => {
-          this.parallelogramDraw(ctx, col);
-          // 按状态列表顺序依次绘制
-          if (col.statusList && col.statusList.length > 0) {
-            col.statusList.forEach((statusObj) => {
-              const drawConfig = {
-                ...col,
-                ...statusObj, // 传入当前要绘制的状态
-              };
-              this.parallelogramDraw(ctx, drawConfig);
-            });
-          }
-        });
-      });
-    },
-    parallelogramDraw(ctx, col, fillColor) {
-      const cumDraw = this.itemCumFunDo(col, "drawFun");
-      if (cumDraw) {
-        return;
-      }
-      this.parallelogramDrawCommon(ctx, col, fillColor);
-      this.parallelogramDrawNum(ctx, col);
-    },
-    itemCumFunDo(ele, funName) {
-      const operItemSts = ele.status;
-      if (
-        this.itemStsMap[operItemSts] &&
-        this.itemStsMap[operItemSts][funName]
-      ) {
-        return this.itemStsMap[operItemSts][funName](this, ele);
-      }
-    },
-    parallelogramDrawCommon(ctx, col, fillColor) {
-      ctx.fillStyle = fillColor || col.fillColor;
-      ctx.strokeStyle = col.borderColor;
-      ctx.lineWidth = col.lineWidth;
-      ctx.beginPath();
-      const { x1, y1, x2, y2, x3, y3, x4, y4 } = this.calculateCoordinates(col);
-      ctx.moveTo(x1, y1);
-      ctx.lineTo(x2, y2);
-      ctx.lineTo(x3, y3);
-      ctx.lineTo(x4, y4);
-      ctx.closePath();
-      ctx.fill();
-      ctx.stroke();
-    },
-    parallelogramDrawNum(ctx, col) {
-      if (!this.isShowNumInCell) {
-        return;
-      }
-      if (col.type === LOCTYPE.around) {
-        return;
-      }
-      const { flrNum, rowIndex, colIndex } = col;
-      if (
-        !(
-          flrNum === undefined ||
-          rowIndex === undefined ||
-          colIndex === undefined
-        )
-      ) {
-        let backR = col.backR;
-        let backC = col.backC;
-        if (backR === undefined || backC === undefined) {
-          const backEle = this.pageIdxToBusiIndx(
-            col,
-            this.rotationAngleType,
-            true,
-            false
-          );
-          backR = backEle.backR;
-          backC = backEle.backC;
-        }
-        const formattedFlrNum = flrNum.toString().padStart(2, "0");
-        const formattedRowIndex = backR.toString().padStart(3, "0");
-        const formattedColIndex = backC.toString().padStart(3, "0");
-        const itemNumSty =
-          this.itemStsMap[col.status] &&
-          this.itemStsMap[col.status].sty &&
-          this.itemStsMap[col.status].sty.numSty;
-        ctx.font =
-          (itemNumSty && itemNumSty.cellNumFont) ||
-          getCFG("canvas").cellSty.cellNumFont;
-        ctx.fillStyle =
-          (itemNumSty && itemNumSty.cellNumFontColor) ||
-          getCFG("canvas").cellSty.cellNumFontColor;
-        let offsetX1Fixed =
-          (itemNumSty && itemNumSty.cellXOffset) ||
-          getCFG("canvas").cellSty.cellXOffset;
-        let loc1FlrNum = 0;
-        /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-          loc1FlrNum += getCFG('canvas').cellSty.widthForFlrNum1;
-        } */
-        const offsetX2 = offsetX1Fixed + loc1FlrNum;
-        const loc2ColInd = getCFG("canvas").cellSty.widthColInd2;
-        const offsetX3 = offsetX2 + loc2ColInd;
-        const { x1, y1 } = this.calculateCoordinates(col);
-        if (this.isTheRotationAngleType()) {
-          /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-            ctx.fillText(
-              formattedFlrNum,
-              x1 + offsetX1Fixed,
-              y1 + getCFG('canvas').cellSty.cellYOffset
-            );
-          } */
-          ctx.fillText(
-            formattedColIndex,
-            x1 + offsetX2,
-            y1 + getCFG("canvas").cellSty.cellYOffset
-          );
-          ctx.fillText(
-            formattedRowIndex,
-            x1 + offsetX3,
-            y1 + getCFG("canvas").cellSty.cellYOffset
-          );
-        } else {
-          ctx.save();
-          ctx.translate(x1, y1);
-          ctx.rotate(Math.PI / 2);
-          /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-            ctx.fillText(formattedFlrNum, offsetX1Fixed, -4);
-          } */
-          ctx.fillText(formattedColIndex, offsetX2, -4);
-          ctx.fillText(formattedRowIndex, offsetX3, -4);
-          ctx.restore();
-        }
-      }
-    },
-    parallelogramDrawShuttle(ctx, col) {
-      if (!this.shuttleImg || !this.shuttleImg.src) {
-        console.warn("Shuttle image not loaded");
-        return;
-      }
-
-      this.parallelogramDraw(ctx, col);
-      const { x1, y1, x2, y2, x3, y3, x4, y4 } = col;
-      // 计算四边形的宽度和高度
-      const width = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
-      const height = Math.sqrt((x3 - x2) ** 2 + (y3 - y2) ** 2);
-      ctx.save();
-      ctx.setTransform(
-        (x2 - x1) / width,
-        (y2 - y1) / width,
-        (x3 - x2) / height,
-        (y3 - y2) / height,
-        this.calculateCoordinate(x1, "x"),
-        this.calculateCoordinate(y1, "y")
-      );
-      ctx.drawImage(this.shuttleImg, 0, 0, width, height);
-      ctx.restore();
-      if (col.sid) {
-        // 设置文字样式
-        ctx.font = "bold 18px Arial"; // 加粗并增大字号
-        ctx.textAlign = "center";
-        ctx.textBaseline = "middle"; // 确保文字垂直居中
-
-        // 计算文字位置
-        const textX =
-          col.x1 * this.scale +
-          this.warehousPageCfg.rowOffsetX +
-          (col.x3 * this.scale +
-            this.warehousPageCfg.rowOffsetX -
-            (col.x1 * this.scale + this.warehousPageCfg.rowOffsetX)) /
-            2;
-        const textY =
-          col.y1 * this.scale +
-          this.warehousPageCfg.colOffsetY +
-          (col.y3 * this.scale +
-            this.warehousPageCfg.colOffsetY -
-            (col.y1 * this.scale + this.warehousPageCfg.colOffsetY)) /
-            2;
-        // 添加文字描边效果
-        ctx.strokeStyle = "#FFFFFF"; // 白色描边
-        ctx.lineWidth = 3; // 描边宽度
-        ctx.strokeText(col.sid, textX, textY);
-
-        // 绘制文字主体
-        ctx.fillStyle = "#000000"; // 黑色文字
-        ctx.fillText(col.sid, textX, textY);
-      }
-      if (col.isUnderGood) {
-        // 获取cell状态的填充色
-        const cellFillColor = this.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-        // 将颜色转换为带50%透明度的颜色
-        const cellFillColorHalf = cellFillColor + "80";
-        /* // 将颜色转换为带70%透明度的颜色
-        const cellFillColorWithOpacity = cellFillColor + 'B3'
-        // 将颜色转换为带30%透明度的颜色
-        const cellFillColorWithOpacity30 = cellFillColor + '4D' */
-        this.parallelogramDraw(ctx, col, cellFillColorHalf);
-      }
-    },
-    isTheRotationAngleType() {
-      if (this.rotationAngleType === 0 || this.rotationAngleType === 2) {
-        return true;
-      }
-    },
-    // 绘制每条边
-    drawEdge(ctx, fromX, fromY, toX, toY, edgeProps) {
-      ctx.beginPath();
-      ctx.moveTo(fromX, fromY);
-      ctx.lineTo(toX, toY);
-      ctx.strokeStyle = edgeProps.color;
-      ctx.lineWidth = edgeProps.width;
-      ctx.stroke();
-    },
-    handleWheel(e) {
-      // 清除画布
-      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-
-      const delta = e.deltaY > 0 ? -0.1 : 0.1; // 根据滚动方向调整缩放因子
-      this.scale += delta;
-      this.scale = Math.max(0.1, Math.min(3, this.scale)); // 限制缩放范围 0.1-3
-
-      this.updateMapTransform();
-      // this.$nextTick(() => {
-      this.drawCanvas();
-      // })
-    },
-    handleMouseDown(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      e.preventDefault();
-      this.mouseStartDragLoc = { x: e.clientX, y: e.clientY };
-      this.mouseSts = "down";
-      this.currentHoverEle = null;
-      this.clearSelItemArr();
-    },
-    handleMouseUp(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      e.preventDefault();
-      this.mouseEndDragLoc = { x: e.clientX, y: e.clientY };
-      this.refreshMouseDownInfo("up");
-    },
-    refreshMouseDownInfo(mouseSts) {
-      this.mouseSts = mouseSts;
-      if (
-        Math.abs(this.mouseEndDragLoc.x - this.mouseStartDragLoc.x) > 5 ||
-        Math.abs(this.mouseEndDragLoc.y - this.mouseStartDragLoc.y) > 5
-      ) {
-        this.isDragMove = true;
-      } else {
-        this.isDragMove = false;
-      }
-    },
-    mouseHoveredNothing(isClearSelItemArr) {
-      isClearSelItemArr && this.clearSelItemArr();
-      this.handleMouseHoverInfo(null);
-      this.drawCanvas();
-    },
-    clearSelItemArr() {
-      this.selectedItemArr = [];
-    },
-    handleMouseMove(e) {
-      e.preventDefault();
-      const ele = this.getCurrentMouseCellEle(e, this.operFloor);
-      if (!ele) {
-        this.mouseHoveredNothing();
-        return;
-      }
-      const theCellIsChg =
-        !this.currentHoverEle ||
-        ele.rowIndex !== this.currentHoverEle.rowIndex ||
-        ele.colIndex !== this.currentHoverEle.colIndex ||
-        ele.flrNum !== this.currentHoverEle.flrNum;
-      if (theCellIsChg) {
-        if (this.mouseSts === "down") {
-          this.procSelItemArr(e, ele, "mouseMove");
-        }
-        this.hoveredPalletCode = "";
-        this.hoveredSid = "";
-        const showHoverInfo =
-          this.isShowHoverInfo && this.isTheGoodLocCell(ele);
-        if (showHoverInfo) {
-          this.handleMouseHoverInfo(ele);
-        } else {
-          this.handleMouseHoverInfo(null);
-        }
-      }
-      this.currentHoverEle = ele;
-    },
-    isMouseActionDo(e, mouseActionFun) {
-      if (
-        this.itemStsMap[this.cfgOperingItem] &&
-        this.itemStsMap[this.cfgOperingItem][mouseActionFun]
-      ) {
-        const isDo = this.itemStsMap[this.cfgOperingItem][mouseActionFun](e);
-        if (isDo === false) {
-          return false;
-        }
-      }
-      return true;
-    },
-    isTheGoodLocCell(ele) {
-      if (ele.status) {
-        return true;
-      }
-      return false;
-    },
-    handleClick(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      if (this.isDragMove) {
-        return;
-      }
-      this.clearSelItemArr();
-      this.procSelItemArr(e, null, "click");
-    },
-    procSelItemArr(e, currentEleIn, mouseActionType) {
-      // 1. 初始化选中数组
-      if (!this.selectedItemArr) {
-        this.selectedItemArr = [];
-      }
-      // 2. 获取当前选中元素
-      const currentEle =
-        currentEleIn || this.getCurrentMouseCellEle(e, this.operFloor);
-
-      // 3. 处理无选中元素的情况
-      if (!currentEle) {
-        return this.handleNoCurrentElement(e, mouseActionType);
-      }
-
-      // 4. 处理单个元素的选中/取消选中
-      this.selElement(currentEle);
-
-      // 5. 重绘画布
-      this.drawCanvas();
-    },
-
-    // 处理无选中元素的情况
-    handleNoCurrentElement(e, mouseActionType) {
-      const rackIndxNumEle = this.getRackIndxNum(e);
-      if (rackIndxNumEle && mouseActionType === "click") {
-        this.handleRackIndexClick(rackIndxNumEle);
-        return;
-      }
-      this.mouseHoveredNothing(true);
-    },
-
-    // 处理货架索引点击
-    handleRackIndexClick(rackIndxNumEle) {
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-      if (!firstFloorData) return;
-
-      // 根据类型处理行或列
-      if (rackIndxNumEle.type === "row") {
-        this.handleRowSelection(rackIndxNumEle, firstFloorData);
-      } else if (rackIndxNumEle.type === "col") {
-        this.handleColumnSelection(rackIndxNumEle, firstFloorData);
-      }
-
-      this.drawCanvas();
-    },
-
-    // 处理行选择
-    handleRowSelection(rackIndxNumEle, firstFloorData) {
-      const rowCells = this.getCells(firstFloorData[0].length, (colIndex) =>
-        this.getTheItem(rackIndxNumEle.index, colIndex, this.operFloor)
-      );
-
-      this.toggleCellsSelection(rowCells, "rowIndex", rackIndxNumEle.index);
-    },
-
-    // 处理列选择
-    handleColumnSelection(rackIndxNumEle, firstFloorData) {
-      const colCells = this.getCells(firstFloorData.length, (rowIndex) =>
-        this.getTheItem(rowIndex, rackIndxNumEle.index, this.operFloor)
-      );
-
-      this.toggleCellsSelection(colCells, "colIndex", rackIndxNumEle.index);
-    },
-
-    // 获取单元格数组
-    getCells(length, getCellFn) {
-      const cells = [];
-      for (let i = 0; i < length; i++) {
-        const cell = getCellFn(i);
-        if (cell) cells.push(cell);
-      }
-      return cells;
-    },
-
-    // 切换单元格选择状态
-    toggleCellsSelection(cells, indexType, indexValue) {
-      const allSelected = this.areAllCellsSelected(cells);
-
-      if (allSelected) {
-        // 取消选中
-        this.selectedItemArr = this.selectedItemArr.filter(
-          (item) =>
-            item[indexType] !== indexValue || item.flrNum !== this.operFloor
-        );
-      } else {
-        // 选中新单元格
-        cells.forEach((cell) => {
-          if (!this.isCellSelected(cell)) {
-            this.selectedItemArr.push(cell);
-          }
-        });
-      }
-    },
-
-    // 检查所有单元格是否已选中
-    areAllCellsSelected(cells) {
-      return cells.every((cell) => this.isCellSelected(cell));
-    },
-
-    // 检查单个单元格是否已选中
-    isCellSelected(cell) {
-      return this.selectedItemArr.some(
-        (item) =>
-          item.rowIndex === cell.rowIndex &&
-          item.colIndex === cell.colIndex &&
-          item.flrNum === cell.flrNum
-      );
-    },
-
-    // 切换单个元素的选中状态
-    selElement(currentEle) {
-      const existingIndex = this.selectedItemArr.findIndex(
-        (item) =>
-          item.rowIndex === currentEle.rowIndex &&
-          item.colIndex === currentEle.colIndex &&
-          item.flrNum === currentEle.flrNum
-      );
-      if (existingIndex === -1) {
-        this.selectedItemArr.push(currentEle);
-      }
-    },
-    itemStsInitBatch(operItems, theTargetSts, theOperingKey) {
-      if (!this.isCfgByFloor) {
-        const flrNumArr = Object.keys(this.pageFloorGridDataObj);
-        flrNumArr.forEach((flrNum) => {
-          operItems.forEach((operItem) => {
-            if (operItem.flrNum == flrNum) {
-              this.procItemStsWhenCfg(operItem, theTargetSts, theOperingKey);
-            } else {
-              const newOperItem = this.getTheItem(
-                operItem.rowIndex,
-                operItem.colIndex,
-                flrNum
-              );
-              this.procItemStsWhenCfg(newOperItem, theTargetSts, theOperingKey);
-            }
-          });
-        });
-      } else {
-        operItems.forEach((operItem) => {
-          this.procItemStsWhenCfg(operItem, theTargetSts, theOperingKey);
-        });
-      }
-    },
-    procItemStsWhenCfg(operItem, theTargetSts, theOperingKey) {
-      const theFinalSts = theTargetSts;
-      this.itemStsInit(operItem, theFinalSts, theOperingKey);
-    },
-    getOperItemsForLine(arr) {
-      const isHorizontal = this.isHorizontal();
-      const totalNum = isHorizontal ? this.pageCol : this.pageRow;
-      const operItems = [];
-      for (const ele of arr) {
-        const fixIndx = isHorizontal ? ele.rowIndex : ele.colIndex;
-        for (let i = 0; i < totalNum; i++) {
-          const rowIndex = isHorizontal ? fixIndx : i;
-          const colIndex = isHorizontal ? i : fixIndx;
-          const operItem = this.getTheItem(rowIndex, colIndex, ele.flrNum);
-          if (operItem && operItem.type !== LOCTYPE.around) {
-            operItems.push(operItem);
-          }
-        }
-      }
-      return operItems;
-    },
-    getTheTargetStsWhenCfg(ele) {
-      if (!this.cfgOperingItem) {
-        return;
-      }
-      if (
-        this.itemStsMap[this.cfgOperingItem] &&
-        this.itemStsMap[this.cfgOperingItem].getTheTargetStsWhenCfg
-      ) {
-        return this.itemStsMap[this.cfgOperingItem].getTheTargetStsWhenCfg(
-          this,
-          ele
-        );
-      }
-      const theSts = ele.status;
-      let theStoreSts = this.getTheStoreSts(ele);
-      if (theStoreSts === this.cfgOperingItem) {
-        theStoreSts = ITEMSTATUS.default;
-      }
-      const theTargetSts =
-        theSts === this.cfgOperingItem ? theStoreSts : this.cfgOperingItem;
-      return theTargetSts;
-    },
-    getTheStoreSts(ele) {
-      const theStoreEle = this.getTheItemStore(
-        ele.rowIndex,
-        ele.colIndex,
-        ele.flrNum
-      );
-      return theStoreEle.status;
-    },
-    handleDoubleClick(e) {
-      if (this.mapOperModel !== "selPointForOrder") {
-        return;
-      }
-      e.preventDefault();
-      e.stopPropagation();
-      const ele = this.getCurrentMouseCellEle(e);
-      if (!ele) {
-        return;
-      }
-      if (ele.status === ITEMSTATUS.unUse || ele.canNotBeClick) {
-        this.canBeSelected &&
-          this.$message({
-            message: "当前位置不可用,不可作为选点被选中!",
-            type: "warning",
-          });
-        return;
-      }
-      if (!this.isTheGoodLocCell(ele)) {
-        return;
-      }
-      const backEle = this.pageIdxToBusiIndx(
-        { f: ele.flrNum, c: ele.colIndex, r: ele.rowIndex },
-        this.rotationAngleType
-      );
-      this.showPalletCode(backEle);
-      if (this.canBeSelected) {
-        this.$emit("cellDoubleClick", backEle);
-      }
-    },
-    /* 双击选中整行,再次双击取消选中整行;
-      shift + 双击选中整列,再次双击取消选中整列;
-    */
-    /* handleDoubleClickWhenCfg(e) {
-      const selType = e.shiftKey ? 'col' : 'row'
-      this.toggleCfgOperingItem(e, selType)
-      this.drawCanvas()
-    }, */
-    showPalletCode(ele) {
-      this.$req({
-        url: "/wcs/api/map/cell/get/pallet",
-        method: "post",
-        data: {
-          warehouse_id: this.wareHouseId || window.glbMapId,
-          f: parseInt(ele.f),
-          c: parseInt(ele.c),
-          r: parseInt(ele.r),
-        },
-      })
-        .then((res) => {
-          this.hoveredPalletCode = (res.row && res.row.pallet_code) || "";
-          if (this.hoveredPalletCode) {
-            navigator.clipboard
-              .writeText(this.hoveredPalletCode)
-              .then(() => {
-                this.$message.success("托盘码已复制到剪贴板");
-              })
-              .catch((err) => {
-                console.error("复制失败:", err);
-              });
-          }
-        })
-        .catch((err) => {
-          console.error("获取托盘码失败:", err);
-        });
-    },
-    handleThreeClick(event) {
-      clearTimeout(this.clickTimeout);
-      this.clickCount++;
-
-      this.clickTimeout = setTimeout(() => {
-        this.clickCount = 0;
-      }, 1000);
-
-      if (this.clickCount === 3) {
-        this.rotationAngle = this.rotationAngle + 90;
-        if (this.rotationAngle === 360) {
-          this.rotationAngle = 0;
-        }
-        this.drawCanvas();
-        this.clickCount = 0;
-      }
-    },
-    rotateCanvas() {
-      this.ctx.save();
-      // 如果需要旋转角度,则进行旋转
-      if (this.rotationAngle !== 0) {
-        const centerX = this.canvas.width / 2;
-        const centerY = this.canvas.height / 2;
-        this.ctx.translate(centerX, centerY);
-        this.ctx.rotate((Math.PI / 180) * this.rotationAngle);
-        this.ctx.translate(-centerX, -centerY);
-      }
-      this.ctx.restore();
-    },
-    /**
-     * rowIndex 货架渲染后页面行号 从0 开的
-     * colIndex 货架渲染后页面列号 从 0 开始
-     * floor  从0 开始
-     * 根据点击点获取,所在行列(整体序号)。this.horizontalPointOffset大于0小于0分情况考虑。y向根据夹角和x位置,确认y所在的位置范围
-     * 关注scale
-     */
-    getMousePosition(event, operFlrNum) {
-      const canvas = this.$refs.canvas;
-      const rect = canvas.getBoundingClientRect();
-      const scaleX = this.scale;
-      const scaleY = this.scale;
-
-      // 获取鼠标点击的坐标
-      let x = event.clientX - rect.left;
-      let y = event.clientY - rect.top;
-
-      // 考虑 rowOffsetX 和 colOffsetY
-      x -= this.warehousPageCfg.rowOffsetX / scaleX;
-      y -= this.warehousPageCfg.colOffsetY / scaleY;
-
-      // 考虑缩放和平移
-      x = (x - this.offset.x) / this.scale;
-      y = (y - this.offset.y) / this.scale;
-
-      const keys = Object.keys(this.pageFloorGridDataObj);
-      for (const i of keys) {
-        const indxEle = this.getRowColIndx(x, y, this.pageFloorGridDataObj[i]);
-        if (indxEle.rowIndex !== undefined && indxEle.colIndex !== undefined) {
-          const rowIndex = indxEle.rowIndex;
-          const colIndex = indxEle.colIndex;
-          // const floor = i - 1
-          // const ele = this.getTheItem(rowIndex, colIndex, i)
-          // ele.flrNum = i
-          return { rowIndex, colIndex, flrNum: operFlrNum || i };
-        }
-      }
-    },
-    getRowColIndx(x, y, gridDoubleArr) {
-      // 考虑缩放和平移
-      x = (x - this.offset.x) / this.scale;
-      y = (y - this.offset.y) / this.scale;
-      let rowIndex, colIndex;
-      const horizontalPointOffset = Math.abs(this.horizontalPointOffset);
-      for (let i = 0; i < gridDoubleArr.length; i++) {
-        for (let j = 0; j < gridDoubleArr[i].length; j++) {
-          const cell = gridDoubleArr[i][j];
-          const offsetPointX = cell.x1 + this.cellWidth - horizontalPointOffset;
-          // 最小的cell.x1 + this.horizontalPointOffset 最大点cell.x1 + this.cellWidth
-          const isWithinParallelogramLessOffset =
-            x >= cell.x1 + this.horizontalPointOffset &&
-            x <= cell.x1 + this.cellWidth &&
-            y >= cell.y1 &&
-            y <= cell.y4;
-          if (!this.horizontalPointOffset && isWithinParallelogramLessOffset) {
-            rowIndex = i;
-            colIndex = j;
-            return { rowIndex, colIndex };
-          }
-
-          const isWithinParallelogramMoreOffset =
-            x >= cell.x1 &&
-            x <= cell.x1 + this.cellWidth + this.horizontalPointOffset &&
-            y >= cell.y1 &&
-            y <= cell.y4;
-          if (
-            this.horizontalPointOffset < 0 &&
-            isWithinParallelogramLessOffset
-          ) {
-            if (
-              x >= cell.x1 &&
-              x <= offsetPointX &&
-              y >= cell.y1 &&
-              y <= cell.y4
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-
-            let len;
-            if (x < cell.x1) {
-              len = Math.abs(cell.x1 - x);
-            }
-            if (x > offsetPointX) {
-              len = cell.x1 + this.cellWidth - x;
-            }
-            const angle = this.includedAngle;
-            const theYLen = len * Math.tan(angle * (Math.PI / 180));
-            const yLen = y - cell.y1;
-            if (
-              (x < cell.x1 && yLen > theYLen) ||
-              (x > offsetPointX && yLen < theYLen)
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-          }
-          if (
-            this.horizontalPointOffset > 0 &&
-            isWithinParallelogramMoreOffset
-          ) {
-            if (
-              x >= offsetPointX &&
-              x <= cell.x1 + this.cellWidth &&
-              y >= cell.y1 &&
-              y <= cell.y4
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-
-            let len;
-            if (x > cell.x1 && x < offsetPointX) {
-              len = Math.abs(cell.x1 - x);
-            }
-            if (x > cell.x1 + this.cellWidth) {
-              len = x - cell.x1 - this.cellWidth;
-            }
-            const angle = 180 - this.includedAngle;
-            const theYLen = len * Math.tan(angle * (Math.PI / 180));
-            const yLen = y - cell.y1;
-            if (
-              (x > cell.x1 && x < offsetPointX && yLen < theYLen) ||
-              (x > cell.x1 + this.cellWidth && yLen > theYLen)
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-          }
-        }
-        if (rowIndex !== undefined) {
-          break; // Exit the outer loop if we found a match
-        }
-      }
-      return { rowIndex, colIndex };
-    },
-    handleMouseHoverInfo(ele) {
-      if (!ele) {
-        this.hoveredInfo = {
-          hoveredRowIndex: null,
-          hoveredColIndex: null,
-          hoveredFloorIndex: null,
-          hoveredItemStsName: null,
-        };
-        this.hoveredPalletCode = "";
-        this.hoveredSid = "";
-        return;
-      }
-      const itemStatus = ele.status;
-      const itemStatusName = itemStatus
-        ? this.itemStsMap[itemStatus].name
-        : null;
-      const itemBui = this.pageIdxToBusiIndx(
-        { r: ele.rowIndex, c: ele.colIndex },
-        this.rotationAngleType
-      );
-      const hoveredRowIndex = itemBui ? itemBui.r : null;
-      const hoveredColIndex = itemBui ? itemBui.c : null;
-
-      this.hoveredInfo.hoveredItemStsName = itemStatusName;
-      this.hoveredInfo.hoveredFloorIndex = ele.flrNum;
-      this.hoveredInfo.hoveredRowIndex = hoveredRowIndex;
-      this.hoveredInfo.hoveredColIndex = hoveredColIndex;
-      this.hoveredSid = this.checkShuttleExist(
-        ele.flrNum,
-        hoveredColIndex,
-        hoveredRowIndex
-      );
-    },
-    checkShuttleExist(f, c, r) {
-      // 参数校验
-      if (
-        typeof f !== "number" ||
-        typeof c !== "number" ||
-        typeof r !== "number"
-      ) {
-        return "";
-      }
-
-      // 遍历所有穿梭车
-      for (const shuttleId in this.shuttleVisObj) {
-        const shuttle = this.shuttleVisObj[shuttleId];
-
-        // 检查baseInfo是否存在
-        if (!shuttle.baseInfo) {
-          continue;
-        }
-
-        // 比较坐标
-        if (
-          shuttle.baseInfo.f === f &&
-          shuttle.baseInfo.c === c &&
-          shuttle.baseInfo.r === r
-        ) {
-          return shuttle.baseInfo.sid;
-        }
-      }
-
-      return "";
-    },
-    getCurrentMouseCellEle(event, operFlrNum) {
-      const theMousePosition = this.getMousePosition(event, operFlrNum);
-      if (!theMousePosition) {
-        return;
-      }
-      const ele = this.getTheItem(
-        theMousePosition.rowIndex,
-        theMousePosition.colIndex,
-        theMousePosition.flrNum
-      );
-      return ele;
-    },
-    setOperingCfgItem(setOperingCfgItem) {
-      this.cfgOperingItem = setOperingCfgItem.key;
-      this.isCfgByFloor = setOperingCfgItem.isByFloor;
-      this.paramToMergeObj = setOperingCfgItem.paramToMergeObj;
-      this.storePageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.pageFloorGridDataObj)
-      );
-    },
-    cancelCfg() {
-      this.operCfgInit();
-      this.pageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.storePageFloorGridDataObj)
-      );
-      this.drawCanvas();
-    },
-    resetCfg() {
-      this.resetTheItemAllCfg(
-        this.storePageFloorGridDataObj,
-        this.cfgOperingItem
-      );
-      this.operCfgInit();
-      this.pageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.storePageFloorGridDataObj)
-      );
-      this.drawCanvas();
-    },
-    operCfgInit() {
-      this.cfgOperingItem = "";
-      this.paramToMergeObj = null;
-      this.isCfgByFloor = undefined;
-    },
-    resetTheItemAllCfg(pageFloorGridDataObj, itemType) {
-      if (!itemType) {
-        return;
-      }
-      Object.keys(pageFloorGridDataObj).forEach((flrNum) => {
-        pageFloorGridDataObj[flrNum].forEach((row) => {
-          row.forEach((cellData) => {
-            if (cellData.status === itemType) {
-              this.itemStsInit(cellData, ITEMSTATUS.default);
-            }
-            if (cellData.statusList) {
-              cellData.statusList.forEach((statusObj) => {
-                if (statusObj.status === itemType) {
-                  this.itemStsInit(cellData, "", itemType);
-                }
-              });
-            }
-          });
-        });
-      });
-    },
-    setCfgIsByFloor(isCfgByFloor) {
-      this.isCfgByFloor = isCfgByFloor;
-    },
-    calculateCoordinates(col) {
-      const coordinates = {
-        x1: this.calculateCoordinate(col.x1, "x"),
-        y1: this.calculateCoordinate(col.y1, "y"),
-        x2: this.calculateCoordinate(col.x2, "x"),
-        y2: this.calculateCoordinate(col.y2, "y"),
-        x3: this.calculateCoordinate(col.x3, "x"),
-        y3: this.calculateCoordinate(col.y3, "y"),
-        x4: this.calculateCoordinate(col.x4, "x"),
-        y4: this.calculateCoordinate(col.y4, "y"),
-      };
-
-      return coordinates;
-    },
-    calculateCoordinate(value, type) {
-      const offset =
-        type === "x"
-          ? this.warehousPageCfg.rowOffsetX
-          : this.warehousPageCfg.colOffsetY;
-
-      return value * this.scale + offset;
-    },
-  },
-};
-</script>
-
-<style lang="scss">
-.ware-house-area {
-  // background-color: #f5f5f5;//与不存在保持一致
-  // position: relative;
-  // flex: 1;
-  // box-sizing: border-box;
-  // overflow: auto;
-  .cell-sel-panel-wrapper {
-    position: absolute;
-    top: 0;
-    z-index: 100;
-
-    &.panel-left {
-      left: 244px;
-    }
-
-    &.panel-right {
-      right: 24px;
-    }
-  }
-
-  .cell-sel-panel-con {
-    width: 100%;
-    height: 100%;
-  }
-}
-
-canvas {
-  display: block;
-}
-
-.overlay {
-  user-select: none;
-  position: absolute;
-  top: auto;
-  left: 10px;
-  bottom: 0px;
-  right: auto;
-  font-size: 12px;
-  background-color: rgba(255, 255, 255, 0.8);
-  padding: 2px;
-  // border: 1px solid gray;
-  overflow: hidden;
-}
-
-.bottom-right {
-  top: auto;
-  left: auto;
-  bottom: 0px;
-  right: 10px;
-}
-
-.bottom-left {
-  top: auto;
-  left: 10px;
-  bottom: 0px;
-  right: auto;
-}
-
-// canvas {
-//   cursor: grab;
-// }
-canvas:active {
-  cursor: grabbing;
-}
-
-.img-btn {
-  user-select: none;
-  position: fixed;
-  top: 48px;
-  right: 12px;
-}
-
-.img-btn-2 {
-  position: fixed;
-  top: 48px;
-  right: 56px;
-  // right: 16px;
-}
-.pallet-code-dialog {
-  width: 60% !important;
-  min-width: 400px !important;
-  max-width: 800px !important;
-  margin: 0 auto 0 !important;
-}
-</style>

+ 0 - 52
src/components/map/grid-canvas/variables-canvas.scss

@@ -1,52 +0,0 @@
-$gridFillColor: #e6e6e6;
-$gridBorderColor: white;
-$gridLineWidth: 1;
-$default: #e6e6e6;
-$storageLoc: #e6e6e6;
-$xTrack: #008000cc;
-$carriageway: #4ba64bcc;
-$shuttle: #a8aaa9;
-$path: #FFB676;
-$pathHasDrived: #D69A5A;
-$pathHasDrivedColor: #D69A5A; //#FFD700 //#FFC876
-$shuttleBodyColor: red;
-$lift: #e74c3ccc;
-$unExist: #f5f5f5;//与容器背景色保持一致
-$unUse: #BFBFBF;
-$charge: #f1c40f;
-$entranceAndExit: #e6e6e6;
-$park: #3498db;
-// $transport: rgba(128, 64, 0, 0.45);
-$transport: rgba(255, 255, 255, 0);
-$transportBorderColor: #804000;
-$pillar: #0000ffcc;
-// $around: #c8e6c9;
-$around: #c8e6c9;
-$arrowColor: rgba(208, 32, 181, 0.6);
-$goods: #926844;
-:export {
-  gridFillColor: $gridFillColor;
-  gridBorderColor: $gridBorderColor;
-  gridLineWidth: $gridLineWidth;
-  default: $default;
-  storageLoc: $storageLoc;
-  shuttle: $shuttle;
-  path: $path;
-  pathHasDrived: $pathHasDrived;
-  pathHasDrivedColor: $pathHasDrivedColor;
-  shuttleBodyColor: $shuttleBodyColor;
-  xTrack: $xTrack;
-  carriageway: $carriageway;
-  lift: $lift;
-  unExist: $unExist;
-  unUse: $unUse;
-  charge: $charge;
-  entranceAndExit: $entranceAndExit;
-  park: $park;
-  transport: $transport;
-  transportBorderColor: $transportBorderColor;
-  pillar: $pillar;
-  around: $around;
-  arrowColor: $arrowColor;
-  goods: $goods;
-}

+ 0 - 210
src/components/map/grid-svg/index.vue

@@ -1,210 +0,0 @@
-<template>
-  <div
-    ref="wareHouseArea"
-    class="svg-container"
-    :style="{ background: scssVariables.default }"
-    v-loading="canvasLoading"
-  >
-    <div class="toolbar">
-      <img
-        title="旋转90度"
-        :src="imageBtnSrc"
-        :style="imageBtnStyle"
-        alt="旋转"
-        @click="rotateBtn"
-      />
-      <button size="small" @click="saveViewState" class="save-view-btn">
-        保存视角
-      </button>
-    </div>
-    <div
-      v-show="
-        hoveredInfo.hoveredRowIndex !== null &&
-        hoveredInfo.hoveredColIndex !== null
-      "
-      class="overlay"
-    >
-      <template v-if="hoveredSid"> 设备编号: {{ hoveredSid }} <br /> </template>
-      <template v-if="hoveredInfo.hoveredFloorIndex !== null">
-        当前层: {{ hoveredInfo.hoveredFloorIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredColIndex !== null">
-        当前列: {{ hoveredInfo.hoveredColIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredRowIndex !== null">
-        当前行: {{ hoveredInfo.hoveredRowIndex }}<br />
-      </template>
-      <template v-if="hoveredInfo.hoveredItemStsName !== null">
-        类型: {{ hoveredInfo.hoveredItemStsName }}<br />
-      </template>
-      <template v-if="hoveredPalletCode">
-        <span :style="{ color: 'black', fontWeight: 'bold' }">
-          托盘码: {{ hoveredPalletCode }}
-        </span>
-        <br />
-      </template>
-    </div>
-    <div
-      :class="['cell-sel-panel-wrapper', panelPositionClass]"
-      @dblclick.stop="togglePanelPosition"
-    >
-      <CellSelPanel
-        :selectedItemArr="selectedItemArr"
-        v-show="cellSelPanelVisible"
-        class="cell-sel-panel-con"
-        @changeIsByFloor="setCfgIsByFloor"
-        @onCellSelItemClick="onCellSelItemClick"
-      />
-    </div>
-    <div
-      v-show="showContextMenu"
-      class="context-menu-grid"
-      :style="{
-        position: 'fixed',
-        left: `${contextMenuPosition.x}px`,
-        top: `${contextMenuPosition.y}px`,
-        transform: 'translate(0, 0)',
-      }"
-    >
-      <ul>
-        <!-- <li @click="saveCanvasAsImage">保存为图片</li> -->
-        <li @click="handleMenuClick('chgPalletCode')">修改托盘码</li>
-        <li @click="handleMenuClick('copyPalletCode')">复制托盘码</li>
-      </ul>
-    </div>
-    <el-dialog
-      :visible.sync="showChgPalletCodeDia"
-      title="修改托盘码"
-      width="60%"
-      class="pallet-code-dialog"
-    >
-      <el-form :model="chgPalletCodeDiaData" label-width="100px">
-        <el-form-item label="坐标">
-          {{ chgPalletCodeDiaData.f }}-{{ chgPalletCodeDiaData.c }}-{{
-            chgPalletCodeDiaData.r
-          }}
-        </el-form-item>
-        <el-form-item label="托盘码">
-          <el-input v-model="chgPalletCodeDiaData.pallet_code" />
-        </el-form-item>
-      </el-form>
-      <span slot="footer" class="dialog-footer">
-        <el-button @click="showChgPalletCodeDia = false">取 消</el-button>
-        <el-button type="primary" @click="submitChgPalletCode">确 定</el-button>
-      </span>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import gridBaseMixin from "@/mixins/map/gridBaseMixin";
-export default {
-  name: "GridSvg",
-  mixins: [gridBaseMixin],
-};
-</script>
-
-<style lang="scss" scoped>
-.svg-container {
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-}
-
-.toolbar {
-  position: absolute;
-  top: 10px;
-  right: 10px;
-  z-index: 100;
-  display: flex;
-  gap: 8px;
-  align-items: center;
-
-  img {
-    width: 24px;
-    height: 24px;
-    cursor: pointer;
-    transition: all 0.3s;
-
-    &:hover {
-      opacity: 0.8;
-    }
-  }
-
-  .save-view-btn {
-    background-color: #4caf50;
-    border: none;
-    color: #fff;
-    padding: 5px;
-    border-radius: 3px;
-    margin: 0;
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); // 添加轻微阴影
-    transition: all 0.2s ease-in-out; // 优化过渡效果
-    &:hover {
-      background-color: #45a049; // 稍微暗一点的悬停色
-      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
-    }
-    &:active {
-      background-color: #3d8b40; // 点击时的颜色
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    }
-  }
-}
-
-.overlay {
-  position: absolute;
-  bottom: 0;
-  left: 10px;
-  background-color: rgba(255, 255, 255, 0.8);
-  padding: 5px;
-  font-size: 12px;
-  pointer-events: none;
-}
-
-.cell-sel-panel-wrapper {
-  position: absolute;
-  top: 0;
-  z-index: 100;
-
-  &.panel-right {
-    right: 24px;
-  }
-
-  &.panel-left {
-    left: 244px;
-  }
-}
-
-.context-menu-grid {
-  position: fixed;
-  background: white;
-  border: 1px solid #dcdfe6;
-  border-radius: 4px;
-  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-  padding: 5px 0;
-  z-index: 1000;
-  margin-top: 2px;
-  margin-left: 2px;
-
-  ul {
-    list-style: none;
-    margin: 0;
-    padding: 0;
-
-    li {
-      padding: 8px 16px;
-      cursor: pointer;
-      font-size: 14px;
-      color: #606266;
-      white-space: nowrap;
-
-      &:hover {
-        background-color: #f5f7fa;
-      }
-    }
-  }
-}
-</style>

+ 0 - 56
src/components/map/grid-svg/variables.scss

@@ -1,56 +0,0 @@
-$gridFillColor: #F0F5FA;
-$gridBorderColor: #dcdcdc;
-$gridLineWidth: 1;
-$default: white;
-$storageLoc: #F0F5FA;
-$xTrack: white;
-$carriageway: white;
-$selGridBorderColor: #336FEC;
-$flrBottomLineColor: #030303;
-$offsetBackGroundColor: #f5f5f5;
-$shuttle: #3498db;
-$path: #FFB676;
-$pathHasDrived: #D69A5A;
-$shuttleBodyColor: red;
-$lift: #FFB676;
-$unExist: $default;//与容器背景色保持一致
-$unUse: #e8e8e8;
-$charge: #f1c40f;
-$entranceAndExit: #F0F5FA;
-$park: #3498db;
-// $transport: rgba(128, 64, 0, 0.45);
-$transport: rgba(255, 255, 255, 0);
-$transportBorderColor: #804000;
-$pillar: #0000ffcc;
-// $around: #c8e6c9;
-$around: #c8e6c9;
-$arrowColor: rgba(208, 32, 181, 0.6);
-$goods: #4CAF50;
-:export {
-  gridFillColor: $gridFillColor;
-  gridBorderColor: $gridBorderColor;
-  gridLineWidth: $gridLineWidth;
-  default: $default;
-  storageLoc: $storageLoc;
-  shuttle: $shuttle;
-  offsetBackGroundColor: $offsetBackGroundColor;
-  path: $path;
-  pathHasDrived: $pathHasDrived;
-  shuttleBodyColor: $shuttleBodyColor;
-  xTrack: $xTrack;
-  carriageway: $carriageway;
-  lift: $lift;
-  unExist: $unExist;
-  unUse: $unUse;
-  charge: $charge;
-  entranceAndExit: $entranceAndExit;
-  park: $park;
-  transport: $transport;
-  transportBorderColor: $transportBorderColor;
-  flrBottomLineColor: $flrBottomLineColor;
-  pillar: $pillar;
-  around: $around;
-  arrowColor: $arrowColor;
-  goods: $goods;
-  selGridBorderColor: $selGridBorderColor;
-}

+ 250 - 76
src/components/tip/index.vue

@@ -6,12 +6,12 @@
       class="tip"
       class="tip"
       :class="{ 'tip-c-row-item': direction === 'h' }"
       :class="{ 'tip-c-row-item': direction === 'h' }"
     >
     >
-      <!-- title="点击修改配色"
-        @click="showColorPickerFun(item)" -->
       <div
       <div
-        v-if="!item.cusmSty"
+        v-if="!item.icon"
         class="content"
         class="content"
+        title="点击修改配色"
         :style="{ backgroundColor: item.bgc }"
         :style="{ backgroundColor: item.bgc }"
+        @click="showColorPickerFun(item)"
       >
       >
         <div v-show="item.showColorPicker" class="color-pos">
         <div v-show="item.showColorPicker" class="color-pos">
           <el-color-picker
           <el-color-picker
@@ -22,38 +22,13 @@
           />
           />
         </div>
         </div>
       </div>
       </div>
-      <i
-        v-else-if="item.cusmSty === 'icon'"
-        :class="item.icon"
-        :style="{ color: item.color }"
-      />
-      <div
-        v-else-if="item.cusmSty === 'bgImg'"
-        class="content"
-        :style="{
-          backgroundColor: item.bgc,
-          backgroundImage: 'url(' + require('@/assets/simanc.png') + ')',
-          backgroundSize: 'contain',
-          backgroundPosition: 'center',
-          backgroundRepeat: 'no-repeat'
-        }"
-      />
-      <!-- 当cusmSty === 'line',显示一条线,居中显示 -->
-      <div
-        v-else-if="item.cusmSty === 'line'"
-        class="content"
-        :style="{
-          backgroundColor: item.bgc,
-          height: '4px',
-          position: 'relative'
-        }"
-      />
+      <i v-else :class="item.icon" :style="{ color: item.color }" />
       <span
       <span
         class="title"
         class="title"
         :class="{ 'tip-c-row-item-title': direction === 'h' }"
         :class="{ 'tip-c-row-item-title': direction === 'h' }"
       >{{ item.title }}</span>
       >{{ item.title }}</span>
     </div>
     </div>
-    <!-- <div
+    <div
       v-if="isShowCarrier"
       v-if="isShowCarrier"
       class="tip"
       class="tip"
       :class="{ 'tip-c-row-item': direction === 'h' }"
       :class="{ 'tip-c-row-item': direction === 'h' }"
@@ -70,14 +45,16 @@
         class="title"
         class="title"
         :class="{ 'tip-c-row-item-title': direction === 'h' }"
         :class="{ 'tip-c-row-item-title': direction === 'h' }"
       >四向车</span>
       >四向车</span>
-    </div> -->
+    </div>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import scss from '@/components/map/grid-canvas/variables-canvas.scss'
-import { ItemOperStatus, ColorMap } from '@/components/map//GRID-CONST'
+import scss from '@/components/grid/scss/variables.scss'
+import carrier from '@/components/grid/item/carrier.vue'
+import { ItemOperStatus, ColorMap } from '@/global-cfg/global'
 export default {
 export default {
+  components: { carrier },
   props: {
   props: {
     type: {
     type: {
       type: String,
       type: String,
@@ -112,8 +89,8 @@ export default {
     }
     }
   },
   },
   mounted() {
   mounted() {
-    // this.getScssStore()
-    // this.setScssVal()
+    this.getScssStore()
+    this.setScssVal()
     this.itemArr = this.getItem()
     this.itemArr = this.getItem()
   },
   },
   methods: {
   methods: {
@@ -152,59 +129,256 @@ export default {
       this.setScssStore()
       this.setScssStore()
     },
     },
     getItem() {
     getItem() {
-      // 辅助函数,用于创建条目对象
-      const createItem = (item, extraProps = {}) => {
-        const bgc =
-          (this.scssStoreObj && this.scssStoreObj[ColorMap[item.itemType]]) ||
-          this.scss[ColorMap[item.itemType]]
-        item['bgc'] = bgc
-        return item
+      if (this.type === 'ani') {
+        return [
+          {
+            key: 'wareHouseUnit',
+            title: '仓库',
+            itemType: ItemOperStatus.wareHouseUnit,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.wareHouseUnit]]) ||
+              this.scss[ColorMap[ItemOperStatus.wareHouseUnit]],
+            showColorPicker: false
+          },
+          {
+            key: 2,
+            title: '主轨道',
+            itemType: ItemOperStatus.xTrack,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.xTrack]]) ||
+              this.scss[ColorMap[ItemOperStatus.xTrack]],
+            showColorPicker: false
+          },
+          {
+            key: 1,
+            title: '不可用',
+            itemType: ItemOperStatus.unUse,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.unUse]]) ||
+              this.scss[ColorMap[ItemOperStatus.unUse]],
+            showColorPicker: false
+          },
+          {
+            key: 3,
+            title: '提升机',
+            itemType: ItemOperStatus.lift,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.unUse]]) ||
+              this.scss[ColorMap[ItemOperStatus.unUse]],
+            showColorPicker: false
+          },
+          {
+            key: 4,
+            title: '出入口',
+            color: this.scss.portColor,
+            icon: 'iconfont icon-shuangxiangjiantou1 port-active',
+            showColorPicker: false
+          },
+          {
+            key: 5,
+            title: '输送机',
+            itemType: ItemOperStatus.transport,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.transport]]) ||
+              this.scss[ColorMap[ItemOperStatus.transport]],
+            showColorPicker: false
+          },
+          {
+            key: 6,
+            title: '货位',
+            itemType: ItemOperStatus.gridUnit,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.gridUnit]]) ||
+              this.scss[ColorMap[ItemOperStatus.gridUnit]],
+            showColorPicker: false
+          },
+          {
+            key: 7,
+            title: '立柱',
+            itemType: ItemOperStatus.standCol,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.standCol]]) ||
+              this.scss[ColorMap[ItemOperStatus.standCol]],
+            showColorPicker: false
+          },
+          {
+            key: 8,
+            title: '行车道',
+            itemType: ItemOperStatus.carriageway,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.carriageway]]) ||
+              this.scss[ColorMap[ItemOperStatus.carriageway]],
+            showColorPicker: false
+          },
+          {
+            key: 9,
+            title: '货物',
+            itemType: ItemOperStatus.goods,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.goods]]) ||
+              this.scss[ColorMap[ItemOperStatus.goods]],
+            showColorPicker: false
+          },
+          {
+            key: 'park',
+            title: '停车位',
+            itemType: ItemOperStatus.rack,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.park]]) ||
+              this.scss[ColorMap[ItemOperStatus.park]],
+            showColorPicker: false
+          },
+          {
+            key: 'charge',
+            title: '充电位',
+            itemType: ItemOperStatus.charge,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.charge]]) ||
+              this.scss[ColorMap[ItemOperStatus.charge]],
+            showColorPicker: false
+          },
+          {
+            key: 'rack',
+            title: '支架',
+            itemType: ItemOperStatus.rack,
+            bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.rack]]) ||
+              this.scss[ColorMap[ItemOperStatus.rack]],
+            showColorPicker: false
+          }
+        ]
       }
       }
-
-      // 定义基础条目列表
-      const baseItems = [
+      return [
+        {
+          key: 'wareHouseUnit',
+          title: '仓库',
+          itemType: ItemOperStatus.wareHouseUnit,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.wareHouseUnit]]) ||
+            this.scss[ColorMap[ItemOperStatus.wareHouseUnit]],
+          showColorPicker: false
+        },
+        {
+          key: 2,
+          title: '主轨道',
+          itemType: ItemOperStatus.xTrack,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.xTrack]]) ||
+            this.scss[ColorMap[ItemOperStatus.xTrack]],
+          showColorPicker: false
+        },
         {
         {
-          key: 'storageSpot',
+          key: 1,
+          title: '不可用',
+          itemType: ItemOperStatus.unUse,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.unUse]]) ||
+            this.scss[ColorMap[ItemOperStatus.unUse]],
+          showColorPicker: false
+        },
+        {
+          key: 3,
+          title: '提升机',
+          itemType: ItemOperStatus.lift,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.lift]]) ||
+            this.scss[ColorMap[ItemOperStatus.lift]],
+          showColorPicker: false
+        },
+        {
+          key: 4,
+          title: '出入口',
+          color: this.scss.portColor,
+          icon: 'iconfont icon-shuangxiangjiantou1 port-active',
+          showColorPicker: false
+        },
+        {
+          key: 5,
+          title: '输送机',
+          itemType: ItemOperStatus.transport,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.transport]]) ||
+            this.scss[ColorMap[ItemOperStatus.transport]],
+          showColorPicker: false
+        },
+        {
+          key: 6,
           title: '货位',
           title: '货位',
-          itemType: ItemOperStatus.gridUnit
+          itemType: ItemOperStatus.gridUnit,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.gridUnit]]) ||
+            this.scss[ColorMap[ItemOperStatus.gridUnit]],
+          showColorPicker: false
         },
         },
-        { key: 'goods', title: '货物', itemType: ItemOperStatus.goods },
         {
         {
-          key: 'carrier',
-          cusmSty: 'bgImg',
-          title: '四向车',
-          itemType: ItemOperStatus.carrier
+          key: 7,
+          title: '立柱',
+          itemType: ItemOperStatus.standCol,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.standCol]]) ||
+            this.scss[ColorMap[ItemOperStatus.standCol]],
+          showColorPicker: false
         },
         },
-        { key: 'mainTrack', title: '主轨道', itemType: ItemOperStatus.xTrack },
         {
         {
-          key: 'driveway',
+          key: 8,
           title: '行车道',
           title: '行车道',
-          itemType: ItemOperStatus.carriageway
+          itemType: ItemOperStatus.carriageway,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.carriageway]]) ||
+            this.scss[ColorMap[ItemOperStatus.carriageway]],
+          showColorPicker: false
         },
         },
-        { key: 'elevator', title: '提升机', itemType: ItemOperStatus.lift },
-        // { key: 'entranceExit', cusmSty:'icon',title: '出入口', itemType: null, extraProps: { color: this.scss.portColor, icon: 'iconfont icon-shuangxiangjiantou1 port-active' }},
         {
         {
-          key: 'conveyor',
-          title: '输送机',
-          itemType: ItemOperStatus.transport
+          key: 'park',
+          title: '停车位',
+          itemType: ItemOperStatus.rack,
+          bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.park]]) ||
+              this.scss[ColorMap[ItemOperStatus.park]],
+          showColorPicker: false
         },
         },
-/*         { key: 'pillar', title: '立柱', itemType: ItemOperStatus.standCol },
-        { key: 'parkingSpot', title: '停车位', itemType: ItemOperStatus.park }, */
         {
         {
-          key: 'chargingSpot',
+          key: 'charge',
           title: '充电位',
           title: '充电位',
-          itemType: ItemOperStatus.charge
+          itemType: ItemOperStatus.charge,
+          bgc:
+              (this.scssStoreObj &&
+                this.scssStoreObj[ColorMap[ItemOperStatus.charge]]) ||
+              this.scss[ColorMap[ItemOperStatus.charge]],
+          showColorPicker: false
         },
         },
-        { key: 'unavailable', title: '不可用', itemType: ItemOperStatus.unUse },
-        { key: 'entrance', title: '出入口', itemType: ItemOperStatus.entrance },
-        { key: 'path', title: '路线', itemType: ItemOperStatus.path, cusmSty: 'line' }
-        // { key: 'rack', title: '支架', itemType: ItemOperStatus.rack }
+        {
+          key: 'rack',
+          title: '支架',
+          itemType: ItemOperStatus.rack,
+          bgc:
+            (this.scssStoreObj &&
+              this.scssStoreObj[ColorMap[ItemOperStatus.rack]]) ||
+            this.scss[ColorMap[ItemOperStatus.rack]],
+          showColorPicker: false
+        }
       ]
       ]
-
-      // 使用map函数和createItem辅助函数创建最终的条目数组
-      return baseItems.map((item) =>
-        createItem(item, item.extraProps || {})
-      )
     }
     }
   }
   }
 }
 }
@@ -249,7 +423,7 @@ export default {
   justify-content: center;
   justify-content: center;
   align-items: center;
   align-items: center;
   flex-direction: column;
   flex-direction: column;
-  font-size: 14px;
+  font-size: 8px;
   color: #909399;
   color: #909399;
   &-row {
   &-row {
     flex-direction: row;
     flex-direction: row;
@@ -262,8 +436,8 @@ export default {
     padding: 8px 0;
     padding: 8px 0;
     .content {
     .content {
       position: relative; //选择器使用
       position: relative; //选择器使用
-      width: 16px; //跟颜色显示框统一
-      height: 16px; //跟颜色显示框统一
+      width: 12px; //跟颜色显示框统一
+      height: 12px; //跟颜色显示框统一
     }
     }
     .title {
     .title {
       margin-top: 2px;
       margin-top: 2px;

+ 0 - 0
src/mixins/baseWareHouseId.js → src/core/mixins/baseWareHouseId.js


+ 0 - 0
src/mixins/routerCache.js → src/core/mixins/routerCache.js


+ 0 - 0
src/mixins/routerCacheForContentLayout.js → src/core/mixins/routerCacheForContentLayout.js


+ 0 - 0
src/mixins/sty.js → src/core/mixins/sty.js


+ 741 - 0
src/core/mixins/ware-house.js

@@ -0,0 +1,741 @@
+import Grid from '@/components/grid/grid.vue'
+import Floor from '@/components/floor/index.vue'
+import Tip from '@/components/tip/index.vue'
+import {
+  ItemMeasure,
+  Scale,
+  OrientationRacking,
+  ItemOperStatus,
+  WareHouseSpace
+} from '@/global-cfg/global'
+// import { fullscreenToggel, listenfullscreen } from '@/utils/util'
+import { fullscreenToggel } from '@/utils/util'
+import { mapGetters } from 'vuex'
+import routerCache from '@/core/mixins/routerCache.js'
+
+const mes = {
+  doRealTime: { words: '请实时保存您的操作空间!' },
+  unUse: { words: '单击选择不可用空间,再次单击取消选择!' },
+  xTrack: { words: '单击选择主轨道,再次单击取消选择!' },
+  lift: {
+    words:
+      '梯子占用3行行车道,2行货位,单击选择梯子中心位置,将在点击位置行车道两侧和下侧或右侧生成梯子;再次单击梯子取消选择!'
+  },
+  port: {
+    words:
+      '单击一次选择输入口,单击两次选择输出口,单击三次选择出入口,单击四次删除端口!'
+  },
+  transport: { words: '单击选择传输机,再次单击取消选择!' },
+  standCol: { words: '单击选择立柱区域,再次单击取消选择!' },
+  carriageway: { words: '单击选择行车道区域,再次点击取消选择!' },
+  park: { words: '单击选择停车位,再次点击取消选择!' },
+  charge: { words: '单击选择停车位,再次点击取消选择!' }
+}
+const mesShowTime = 5000
+const mesType = 'warning'
+const converMap = {
+  length: true,
+  width: true,
+  height: true,
+  goodsHeight: true,
+  // front: true,
+  // right: true,
+  // left: true,
+  // back: true,
+  palletWidth: true,
+  palletLength: true,
+  space: true
+}
+const wareToRackSpaceMap = {
+  op: {
+    back: 'front',
+    front: 'back',
+    left: 'right',
+    right: 'left'
+  },
+  orientation: {
+    back: 'length',
+    front: 'length',
+    left: 'width',
+    right: 'width'
+  }
+}
+export default {
+  name: 'Cfg',
+  components: {
+    Grid,
+    Floor,
+    Tip
+  },
+  mixins: [routerCache],
+  data() {
+    return {
+      isNotShowWare: false,
+      businessType: 'cfg',
+      stores: null,
+      carriers: null,
+      floor: 1,
+      formItemSts: {
+        front: false,
+        right: false,
+        left: false,
+        back: false
+      },
+      gridTop: 0,
+      gridLeft: 0,
+      houseLoading: false,
+      isShowBack: false,
+      wareWidth: '',
+      wareHeight: '',
+      btnSysInfo: {
+        CFG_LIST: ItemOperStatus.btnArr,
+        SUBMIT: 'submit',
+        loading_build: false,
+        loading_submit: false,
+        btnSize: 'mini',
+        infoWord_confirm: '确认配置',
+        infoWord_unUse: '配置不可用',
+        infoWord_xTrack: '配置主轨道',
+        infoWord_lift: '配置提升机',
+        infoWord_port: '配置出入口',
+        infoWord_transport: '配置输送机',
+        infoWord_standCol: '配置立柱',
+        infoWord_carriageway: '配置行车道',
+        infoWord_park: '配置停车位',
+        infoWord_charge: '配置充电位',
+        status_unUse: 'disConfig', // disConfig  configing toBeConfig
+        status_xTrack: 'disConfig',
+        status_lift: 'disConfig',
+        status_port: 'disConfig',
+        status_transport: 'disConfig',
+        status_standCol: 'disConfig',
+        status_carriageway: 'disConfig',
+        status_park: 'disConfig',
+        status_charge: 'disConfig',
+        status_submit: 'disConfig',
+        STATUS_FLAG: 'status_',
+        STATUS_DIS: 'disConfig',
+        STATUS_ING: 'configing',
+        STATUS_TOBE: 'toBeConfig',
+        STATUS_OPER_MAP: { configing: 'toBeConfig', toBeConfig: 'configing' }
+      },
+      forward: OrientationRacking.DEFAULT,
+      row: 0,
+      column: 0,
+      palletWidth: ItemMeasure.pallet.width,
+      palletLength: ItemMeasure.pallet.length,
+      space: ItemMeasure.space.length,
+      cfgForm: {
+        floorGoodsHeights: [],
+        notShowDet: false,
+        id: 0,
+        warehouseId: null,
+        length: 0,
+        width: 0,
+        height: 0,
+        forward: 0,
+        floor: 1,
+        goodsHeight: 0,
+        topGoodsHeight: undefined,
+        row: 0,
+        column: 0,
+        front: WareHouseSpace.front,
+        right: WareHouseSpace.right,
+        left: WareHouseSpace.left,
+        back: WareHouseSpace.back,
+        palletWidth: ItemMeasure.pallet.width,
+        palletLength: ItemMeasure.pallet.length,
+        space: ItemMeasure.space.length,
+        lateralNet: []
+      },
+      whList: [],
+      whDis: false,
+      rules: {
+        warehouseId: [
+          { required: true, message: '请选择仓库', trigger: 'blur' }
+        ],
+        length: [
+          {
+            type: 'number',
+            min: 6,
+            max: 1000,
+            message: '仓库长在3到1000米之间',
+            trigger: 'blur'
+          }
+        ],
+        width: [
+          {
+            type: 'number',
+            min: 6,
+            max: 1000,
+            message: '仓库宽在6到1000米之间',
+            trigger: 'blur'
+          }
+        ],
+        height: [
+          {
+            type: 'number',
+            min: 1,
+            max: 200,
+            message: '仓库高在1到200米之间',
+            trigger: 'blur'
+          }
+        ],
+        floor: [
+          {
+            type: 'number',
+            min: 1,
+            max: 100,
+            message: '层数在1到100层之间',
+            trigger: 'blur'
+          }
+        ],
+        goodsHeight: [
+          {
+            type: 'number',
+            trigger: 'blur'
+          }
+        ],
+        row: [
+          {
+            type: 'number',
+            min: 1,
+            max: 200,
+            message: '行在1到200之间',
+            trigger: 'blur'
+          }
+        ],
+        column: [
+          {
+            type: 'number',
+            min: 1,
+            max: 200,
+            message: '列在1到200之间',
+            trigger: 'blur'
+          }
+        ]
+      },
+      dataBase: null
+    }
+  },
+  watch: {
+    $route: {
+      handler: function(route) {
+        this.isShowBack = false
+        this.whDis = false
+        const isShowBack = route.query && route.query.isShowBack
+        if (isShowBack) {
+          this.isShowBack = isShowBack
+        }
+        const id = route.query && route.query.id
+        if (id) {
+          this.cfgForm.warehouseId = Number(id)
+          this.whDis = true
+        }
+        const title = route.query && route.query.title
+        if (title) {
+          route.meta.title = title
+        }
+      },
+      immediate: true
+    },
+    // 'cfgForm.width': {
+    //   handler: function(whWidth, whWidthOld) {
+    //     this.wareWidth =
+    //       ItemMeasure.numFormat(whWidth, false) +
+    //       4 + // grid外框样式每边多加了2px
+    //       'px'
+    //   },
+    //   immediate: true
+    // },
+    // 'cfgForm.length': {
+    //   handler: function(whLen, whLenOld) {
+    //     this.wareHeight =
+    //       ItemMeasure.numFormat(whLen, false) +
+    //       4 + // grid外框样式每边多加了2px
+    //       'px'
+    //   },
+    //   immediate: true
+    // },
+    'cfgForm.warehouseId': {
+      handler: function(warehouseId, beforeWareHouseId) {
+        this.$refs.cfgForm && this.$refs.cfgForm.clearValidate()
+        if (beforeWareHouseId) {
+          this.formParamInit()
+        }
+        this.initWareHouse(warehouseId, 'init')
+      },
+      immediate: true
+    }
+  },
+  computed: {
+    ...mapGetters(['isFullScreen']),
+    wareSty() {
+      return { width: this.wareWidth, height: this.wareHeight }
+    },
+    gridSty() {
+      // console.log({ top: this.gridTop, left: this.gridLeft })
+      return { top: this.gridTop, left: this.gridLeft }
+    }
+  },
+  mounted() {
+    if (this.businessType !== 'animation') {
+      this.getAllWareHouse()
+    }
+    // 先关闭全屏化功能
+    // listenfullscreen(this.setScreen)
+  },
+  methods: {
+    addFloorGoodsHeightCum() {
+      this.cfgForm.floorGoodsHeights.push({ floor: undefined, goodsHeight: undefined })
+    },
+    delFloorGoodsHeightCum(index) {
+      this.cfgForm.floorGoodsHeights.splice(index, 1)
+    },
+    refreshData() {
+      if (this.businessType !== 'animation') {
+        this.getAllWareHouse()
+      }
+    },
+    flrChg(val) {
+      this.floor = val || 1
+    },
+    flrChgFromFloor(val) {
+      this.$refs['grid'].flrChg(val || 1)
+    },
+    setScreen() {
+      this.$store.commit('SET_FULLSCREN')
+    },
+    async initWareHouse(warehouseId, buildType) {
+      this.wareHeight = ''
+      this.wareWidth = ''
+      if (!warehouseId) {
+        this.setOperStaus(this.btnSysInfo.STATUS_DIS)
+        return
+      }
+      this.houseLoading = true
+      this.btnSysInfo.loading_build = true
+      this.getWareHouseData()
+        .then((res) => {
+          this.dataBase = res.data
+          if (buildType === 'btn') {
+            this.$nextTick(() => {
+              this.houseLoading = false
+              this.btnSysInfo.loading_build = false
+            })
+            return
+            // return new Promise((resolve, reject) => {
+            //   resolve(this.dataBase)
+            // })
+          }
+          if (!this.dataBase) {
+            this.setOperStaus(this.btnSysInfo.STATUS_DIS)
+            this.houseLoading = false
+            this.btnSysInfo.loading_build = false
+            this.$refs['grid'].initData(this.cfgForm, null)
+            return
+          }
+          this.dataConverSet(this.dataBase)
+          this.build(buildType)
+          this.afterGetData()
+          this.houseLoading = false
+          this.btnSysInfo.loading_build = false
+        })
+        .catch((error) => {
+          this.houseLoading = false
+          this.btnSysInfo.loading_build = false
+          console.error('Failed to init ware house data:', error)
+        })
+    },
+    getWareHouseData() {
+      return this.$req({
+        url: '/pps/api',
+        method: 'post',
+        data: {
+          method: 'GetMap',
+          param: {
+            id: this.cfgForm.warehouseId.toString()
+          }
+        }
+      })
+    },
+    afterGetData() {},
+    getAllWareHouse() {
+      this.$req({
+        url: '/pps/api',
+        method: 'post',
+        data: {
+          method: 'FetchWarehouse'
+        }
+      }).then((res) => {
+        this.whList = res.data
+      })
+    },
+    handleScreen() {
+      fullscreenToggel()
+    },
+    btnBuild() {
+      this.$refs.cfgForm.validate(async(valid) => {
+        if (valid) {
+          await this.initWareHouse(this.cfgForm.warehouseId, 'btn')
+          this.build('btn')
+          this.$message({
+            showClose: true,
+            message: mes.doRealTime.words,
+            duration: mesShowTime,
+            type: mesType
+          })
+        } else {
+          // console.log('build valid fail!!')
+          return false
+        }
+      })
+    },
+    build(buildType) {
+      this.formParamInit(this.cfgForm)
+      this.view(buildType)
+      const itemOperData = this.getItemOperData(buildType)
+      this.$refs['grid'].initData(this.cfgForm, itemOperData)
+      this.setOperStaus(this.btnSysInfo.STATUS_TOBE)
+    },
+    getItemOperData(buildType) {
+      if (
+        buildType === 'btn' &&
+        this.dataBase &&
+        this.cfgForm.forward !== this.dataBase.forward
+      ) {
+        return null
+      }
+      const data =
+        this.dataBase &&
+        this.dataBase.floors &&
+        this.dataBase.floors.length > 0 &&
+        this.dataBase.floors[0]
+      return data
+    },
+    wareHouseToRackSpace(flag) {
+      this.formItemSts[flag] = false
+      this.formItemSts[wareToRackSpaceMap.op[flag]] = true
+    },
+    /**
+     *
+     * 1-格子大于20px等比例显示细节
+     * 2-格子小于20px大于15px,不按比例,占满空间。
+     * 3-小于15不显示细节
+     * @param {*} buildType
+     */
+    view(buildType) {
+      const wspHeight =
+        this.$refs.workSpace && this.$refs.workSpace.clientHeight
+      const wspWidth = this.$refs.workSpace && this.$refs.workSpace.clientWidth
+      const widthPer =
+        wspWidth /
+        ((this.isNotShowWare ? 0 : this.cfgForm.left) +
+          this.cfgForm.column +
+          (this.isNotShowWare ? 0 : this.cfgForm.right) +
+          4) // 左右两侧各留2个格子,需要放序号、port
+      const heightPer =
+        wspHeight /
+        ((this.isNotShowWare ? 0 : this.cfgForm.front) +
+          this.cfgForm.row +
+          (this.isNotShowWare ? 0 : this.cfgForm.back) +
+          4) // 上下两侧各留2个格子,需要放序号、port
+      // 不展示细节
+      if (heightPer < 15 || widthPer < 15) {
+        this.cfgForm.notShowDet = true
+      } else {
+        this.cfgForm.notShowDet = false
+      }
+      let finalNum = Math.min(widthPer, heightPer)
+      if (finalNum > 60) {
+        finalNum = 60// 限制格子最大为60
+      }
+      this.cfgForm.finalWidtPer = finalNum
+      this.cfgForm.finalHeightPer = finalNum
+    },
+    viewScale(buildType) {
+      const wspHeight =
+        this.$refs.workSpace && this.$refs.workSpace.clientHeight
+      const wspWidth = this.$refs.workSpace && this.$refs.workSpace.clientWidth
+      // console.log('宽:' + wspWidth)
+      // console.log('长:' + wspHeight)
+      const scaleHeight = (wspHeight - 4) / this.cfgForm.length
+      const scaleWidth = (wspWidth - 4) / this.cfgForm.width
+      const cumScale = scaleWidth - scaleHeight > 0 ? scaleHeight : scaleWidth
+      const finalScale = cumScale - Scale.m > 0 ? cumScale : cumScale
+      this.$refs['grid'].setScaleM(finalScale)
+      // console.log('scale:' + finalScale)
+      this.wareWidth =
+        ItemMeasure.numFormat(this.cfgForm.width, false, finalScale) +
+        4 + // grid外框样式每边多加了2px
+        'px'
+      this.wareHeight =
+        ItemMeasure.numFormat(this.cfgForm.length, false, finalScale) +
+        4 + // grid外框样式每边多加了2px
+        'px'
+      this.cumViewScale(buildType)
+      this.gridAbsPosScale(finalScale)
+    },
+    gridAbsPosScale(finalScale) {
+      this.gridTop = 0
+      this.gridLeft = 0
+      if (this.cfgForm.front) {
+        this.gridTop = ItemMeasure.numFormat(
+          this.cfgForm.front,
+          true,
+          finalScale
+        )
+      }
+      if (this.cfgForm.left) {
+        this.gridLeft = ItemMeasure.numFormat(
+          this.cfgForm.left,
+          true,
+          finalScale
+        )
+      }
+    },
+    cumViewScale(buildType) {
+      if (buildType === 'btn' && this.businessType === 'cfg') {
+        const rowUp = this.row
+        const columnUp = this.column
+        const palletLengthUp = this.$utils.precisionConversion(
+          this.palletLength,
+          this.$utils.TOTOPPER
+        )
+        const palletWidthUp = this.$utils.precisionConversion(
+          this.palletWidth,
+          this.$utils.TOTOPPER
+        )
+        const spaceUp = this.$utils.precisionConversion(
+          this.space,
+          this.$utils.TOTOPPER
+        )
+        const rackTotal = rowUp * palletLengthUp
+        const roadTotal = columnUp * palletWidthUp + spaceUp * (columnUp + 1)
+        const gridWidth =
+          this.forward === OrientationRacking.HORIZONTAL
+            ? roadTotal
+            : rackTotal
+        const gridLen =
+          this.forward === OrientationRacking.HORIZONTAL
+            ? rackTotal
+            : roadTotal
+        const spaceW =
+          this.$utils.precisionConversion(
+            this.cfgForm.width,
+            this.$utils.TOTOPPER
+          ) - gridWidth
+        const spaceL =
+          this.$utils.precisionConversion(
+            this.cfgForm.length,
+            this.$utils.TOTOPPER
+          ) - gridLen
+        let isHasCum
+        Object.keys(this.formItemSts).forEach((key) => {
+          if (this.formItemSts[key]) {
+            isHasCum = true
+            const formFlag = key
+            const opFormFlag = wareToRackSpaceMap.op[key]
+            const value = this.$utils.precisionConversion(
+              this.cfgForm[opFormFlag],
+              this.$utils.TOTOPPER
+            )
+            const setVal =
+              wareToRackSpaceMap.orientation[formFlag] === 'width'
+                ? spaceW - value
+                : spaceL - value
+
+            this.cfgForm[formFlag] = this.$utils.precisionConversion(
+              setVal,
+              this.$utils.TOLOWPER
+            )
+          }
+        })
+        if (!isHasCum) {
+          const setValInitBack =
+            wareToRackSpaceMap.orientation['back'] === 'width'
+              ? spaceW
+              : spaceL
+          const setValInitRight =
+            wareToRackSpaceMap.orientation['right'] === 'width'
+              ? spaceW
+              : spaceL
+          this.cfgForm.back = this.$utils.precisionConversion(
+            setValInitBack,
+            this.$utils.TOLOWPER
+          )
+          this.cfgForm.right = this.$utils.precisionConversion(
+            setValInitRight,
+            this.$utils.TOLOWPER
+          )
+        }
+      }
+    },
+    formParamInit(cfgForm) {
+      if (cfgForm) {
+        // 值初始化
+        this.forward = cfgForm.forward
+        this.row = cfgForm.row
+        this.column = cfgForm.column
+        this.palletWidth = cfgForm.palletWidth
+        this.palletLength = cfgForm.palletLength
+        this.space = cfgForm.space
+        return
+      }
+      // 值初始化
+      this.forward = OrientationRacking.DEFAULT
+      this.row = 0
+      this.column = 0
+      this.palletWidth = ItemMeasure.pallet.width
+      this.palletLength = ItemMeasure.pallet.length
+      this.space = ItemMeasure.space.length
+      Object.keys(this.cfgForm).forEach((key) => {
+        if (key === 'palletWidth') {
+          this.cfgForm[key] = ItemMeasure.pallet.width
+        } else if (key === 'palletLength') {
+          this.cfgForm[key] = ItemMeasure.pallet.length
+        } else if (key === 'space') {
+          this.cfgForm[key] = ItemMeasure.space.length
+        } else if (key === 'front') {
+          this.cfgForm[key] = WareHouseSpace.front
+        } else if (key === 'back') {
+          this.cfgForm[key] = WareHouseSpace.back
+        } else if (key === 'left') {
+          this.cfgForm[key] = WareHouseSpace.left
+        } else if (key === 'right') {
+          this.cfgForm[key] = WareHouseSpace.right
+        } else if (key === 'floorGoodsHeights') {
+          this.cfgForm[key] = []
+        } else if (key === 'lateralNet') {
+          this.cfgForm[key] = []
+        } else if (key === 'notShowDet') {
+          this.cfgForm[key] = false
+        } else if (key !== 'warehouseId') {
+          this.cfgForm[key] = 0
+        }
+      })
+    },
+    setOperStaus(status, obj) {
+      if (!obj) {
+        for (const item of ItemOperStatus.arr) {
+          this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + item] = status
+        }
+        this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + this.btnSysInfo.SUBMIT] =
+          status
+        return
+      }
+      for (const item of ItemOperStatus.arr) {
+        if (item === obj) {
+          this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + obj] = status
+        } else {
+          if (status === this.btnSysInfo.STATUS_ING) {
+            this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + item] =
+              this.btnSysInfo.toBeConfig
+          }
+        }
+      }
+    },
+    btnSub(itemBtn) {
+      // console.log(itemBtn)
+      if (!itemBtn) {
+        return
+      }
+      if (
+        this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + itemBtn] ===
+        this.btnSysInfo.STATUS_ING
+      ) {
+        this.setOperStaus(this.btnSysInfo.STATUS_TOBE, itemBtn)
+        this.$refs['grid'].setItemOperStatus(ItemOperStatus.default)
+        return
+      }
+      this.$message({
+        showClose: true,
+        message: mes[itemBtn].words,
+        duration: mesShowTime,
+        type: mesType
+      })
+      this.setOperStaus(this.btnSysInfo.STATUS_ING, itemBtn)
+      this.$refs['grid'].setItemOperStatus(itemBtn)
+    },
+    submitForm(formName) {
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          const itemBtn = this.$refs['grid'].itemOperStatus
+          if (
+            itemBtn &&
+            this.btnSysInfo[this.btnSysInfo.STATUS_FLAG + itemBtn] ===
+              this.btnSysInfo.STATUS_ING
+          ) {
+            this.setOperStaus(this.btnSysInfo.STATUS_TOBE, itemBtn)
+            this.$refs['grid'].setItemOperStatus(ItemOperStatus.default)
+          }
+          const data = this.$refs['grid'].grtSubmitData(this.dataConver())
+          this.$req({
+            url: '/pps/api',
+            method: 'post',
+            data: {
+              method: 'SaveMap',
+              param: data
+            }
+          }).then((res) => {
+            this.$message({
+              message: '配置成功',
+              type: 'success'
+            })
+            if (res.data) {
+              this.cfgForm.id = res.data.id
+            }
+          })
+        } else {
+          console.log('error submit!!')
+          return false
+        }
+      })
+    },
+    dataConver() {
+      const obj = {}
+      Object.keys(this.cfgForm).forEach((key) => {
+        if (converMap[key]) {
+          obj[key] = this.$utils.precisionConversion(
+            this.cfgForm[key],
+            'toTopPer'
+          )
+        } else {
+          obj[key] = this.cfgForm[key]
+        }
+      })
+      return obj
+    },
+    dataConverSet(data) {
+      Object.keys(this.cfgForm).forEach((key) => {
+        if (converMap[key]) {
+          this.cfgForm[key] = this.$utils.precisionConversion(
+            data[key],
+            'toLowPer'
+          )
+        } else {
+          this.cfgForm[key] = (key === 'floorGoodsHeights' || key === 'lateralNet') ? data[key] || [] : data[key]
+        }
+      })
+      // console.log(this.cfgForm)
+      return this.cfgForm
+    },
+    resetForm(formName) {
+      // this.$refs[formName].resetFields()
+      this.$refs[formName].clearValidate()
+      if (this.formItemSts) {
+        this.formItemSts.front = false
+        this.formItemSts.right = false
+        this.formItemSts.left = false
+        this.formItemSts.back = false
+      }
+      if (this.cfgForm.warehouseId) {
+        this.initWareHouse(this.cfgForm.warehouseId, 'init')
+      } else {
+        this.formParamInit()
+      }
+      this.$refs['grid'].resetItemOperStatus()
+      this.setOperStaus(this.btnSysInfo.STATUS_DIS)
+    }
+  }
+}

+ 6 - 11
src/global-cfg/global.js

@@ -63,7 +63,6 @@ export const ItemOperStatus = {
   gridUnit: 'gridUnit',
   gridUnit: 'gridUnit',
   itemInter: 'itemInter',
   itemInter: 'itemInter',
   wareHouseUnit: 'wareHouseUnit',
   wareHouseUnit: 'wareHouseUnit',
-  path: 'path',
   rack: 'rack',
   rack: 'rack',
   portType_Default: 0,
   portType_Default: 0,
   portType_IN: 1,
   portType_IN: 1,
@@ -71,12 +70,10 @@ export const ItemOperStatus = {
   portType_pos_BOT: 'bottom',
   portType_pos_BOT: 'bottom',
   portTyp_pos_TOP: 'top',
   portTyp_pos_TOP: 'top',
   portType_pos_LEFT: 'left',
   portType_pos_LEFT: 'left',
-  portType_pos_RIGHT: 'right',
-  entrance: 'entrance'
+  portType_pos_RIGHT: 'right'
 }
 }
 // 不同状态格子对应的颜色参数
 // 不同状态格子对应的颜色参数
 export const ColorMap = {
 export const ColorMap = {
-  carrier: 'carrierItemColor',
   xTrack: 'xTrackBgColor',
   xTrack: 'xTrackBgColor',
   transport: 'transportRailBgc',
   transport: 'transportRailBgc',
   unUse: 'unUseColor',
   unUse: 'unUseColor',
@@ -89,9 +86,7 @@ export const ColorMap = {
   wareHouseUnit: 'wareBgCo',
   wareHouseUnit: 'wareBgCo',
   rack: 'rackingColor',
   rack: 'rackingColor',
   charge: 'chargeColor',
   charge: 'chargeColor',
-  park: 'parkColor',
-  path: 'pathColor',
-  entrance: 'entranceColor'
+  park: 'parkColor'
 }
 }
 export const Scale = {
 export const Scale = {
   styUnit: 'px',
   styUnit: 'px',
@@ -158,12 +153,12 @@ export const ItemMeasure = {
     width: 10
     width: 10
   },
   },
   pallet: {
   pallet: {
-    width: 120, // 垂直车道上
-    length: 100 // 平行
+    width: 1200, // 垂直车道上
+    length: 1200 // 平行
   },
   },
   space: {
   space: {
-    width: 10, // 垂直车道上
-    length: 10 // 平行
+    width: 75, // 垂直车道上
+    length: 75 // 平行
   },
   },
   rail: {
   rail: {
     width: 10
     width: 10

+ 7 - 6
src/layout-content/ContentLayout.vue

@@ -8,8 +8,11 @@
             :key="index"
             :key="index"
             :icon="item.icon"
             :icon="item.icon"
             :disabled="item.disabledControl && multipleSelection.length != 1"
             :disabled="item.disabledControl && multipleSelection.length != 1"
+            :class="item.class ? item.class : ''"
             :type="item.btnType ? item.btnType : 'primary'"
             :type="item.btnType ? item.btnType : 'primary'"
+            class="filter-item"
             plain
             plain
+            size="mini"
             @click="operFun(item)"
             @click="operFun(item)"
           >
           >
             {{ item.label }}
             {{ item.label }}
@@ -178,13 +181,13 @@ export default {
   computed: {
   computed: {
     ...mapGetters(['permissions', 'userInfo'])
     ...mapGetters(['permissions', 'userInfo'])
   },
   },
-  async created() {
+  created() {
     console.log(this.dataId)
     console.log(this.dataId)
     this.initCfg()
     this.initCfg()
     this.searchCfg = this.getCfg('isSearch')
     this.searchCfg = this.getCfg('isSearch')
     this.formCfg = this.getCfg('isForm')
     this.formCfg = this.getCfg('isForm')
     this.tableCfgCol = this.getShowCfg()
     this.tableCfgCol = this.getShowCfg()
-    await this.initPropDict()
+    this.initPropDict()
     this.refreshData('isCreatedInit')
     this.refreshData('isCreatedInit')
   },
   },
   mounted() {},
   mounted() {},
@@ -202,14 +205,12 @@ export default {
     tableBtnOper(data) {
     tableBtnOper(data) {
       this.operFun(data.item, data.data)
       this.operFun(data.item, data.data)
     },
     },
-    async initPropDict() { // 添加 async
-      const promises = []
+    initPropDict() {
       this.columnConfig.forEach((q) => {
       this.columnConfig.forEach((q) => {
         if (q.type === this.$GCFG.typeSel) {
         if (q.type === this.$GCFG.typeSel) {
-          promises.push(this.initDicts(q)) // 收集所有 promise
+          this.initDicts(q)
         }
         }
       })
       })
-      await Promise.all(promises) // 等待所有字典加载完成
     },
     },
     initCfg() {
     initCfg() {
       this.columnConfig.forEach((item) => {
       this.columnConfig.forEach((item) => {

+ 6 - 0
src/layout-content/CustomSearch.vue

@@ -8,6 +8,7 @@
           v-model="searchForm[item.prop]"
           v-model="searchForm[item.prop]"
           style="width: 100%"
           style="width: 100%"
           :placeholder="getPropPH(item, businessKey, 'search')"
           :placeholder="getPropPH(item, businessKey, 'search')"
+          :size="$GCFG.size"
           clearable
           clearable
           @change="selectChg($event, item)"
           @change="selectChg($event, item)"
         >
         >
@@ -23,6 +24,7 @@
           :key="index"
           :key="index"
           v-model="searchForm[item.prop]"
           v-model="searchForm[item.prop]"
           :placeholder="getPropPH(item, businessKey, 'search')"
           :placeholder="getPropPH(item, businessKey, 'search')"
+          :size="$GCFG.size"
           type="datetime"
           type="datetime"
           format="yyyy-MM-dd HH:mm:ss"
           format="yyyy-MM-dd HH:mm:ss"
           value-format="yyyy-MM-dd HH:mm:ss"
           value-format="yyyy-MM-dd HH:mm:ss"
@@ -33,6 +35,7 @@
           :key="index"
           :key="index"
           v-model="searchForm[$GCFG.getOrgObjKeyFlag(item.prop)].name"
           v-model="searchForm[$GCFG.getOrgObjKeyFlag(item.prop)].name"
           :placeholder="getPropPH(item, businessKey, 'search')"
           :placeholder="getPropPH(item, businessKey, 'search')"
+          :size="$GCFG.size"
           suffix-icon="el-icon-search"
           suffix-icon="el-icon-search"
           @click.native="showOfficeDialog(searchForm, item)"
           @click.native="showOfficeDialog(searchForm, item)"
         />
         />
@@ -41,16 +44,19 @@
           :key="index"
           :key="index"
           v-model="searchForm[item.prop]"
           v-model="searchForm[item.prop]"
           :placeholder="getPropPH(item, businessKey, 'search')"
           :placeholder="getPropPH(item, businessKey, 'search')"
+          :size="$GCFG.size"
         />
         />
       </el-col>
       </el-col>
     </el-row>
     </el-row>
     <div class="btn-container">
     <div class="btn-container">
       <el-button
       <el-button
+        :size="$GCFG.size"
         type="primary"
         type="primary"
         icon="el-icon-search"
         icon="el-icon-search"
         @click="search()"
         @click="search()"
       >{{ $GPROP.searchBtn }}</el-button>
       >{{ $GPROP.searchBtn }}</el-button>
       <el-button
       <el-button
+        :size="$GCFG.size"
         icon="el-icon-refresh"
         icon="el-icon-refresh"
         @click="search('reset')"
         @click="search('reset')"
       >{{ $GPROP.resetBtn }}</el-button>
       >{{ $GPROP.resetBtn }}</el-button>

+ 2 - 2
src/layout-content/core/dictService.js

@@ -13,7 +13,7 @@ export function initDicts(item, relyOnVal, isIniting, successDoFun) {
   const dictPropCfg = JSON.parse(JSON.stringify(item.dict))
   const dictPropCfg = JSON.parse(JSON.stringify(item.dict))
   const newReqObj = reqestParamsProc(dictPropCfg.urlObj, relyOnVal)
   const newReqObj = reqestParamsProc(dictPropCfg.urlObj, relyOnVal)
 
 
- return procDictRes(newReqObj, item, successDoFun)
+  procDictRes(newReqObj, item, successDoFun)
 }
 }
 function procDict(item, data, successDoFun) {
 function procDict(item, data, successDoFun) {
   const dictMapObj = {}
   const dictMapObj = {}
@@ -29,7 +29,7 @@ function procDict(item, data, successDoFun) {
   }
   }
 }
 }
 function procDictRes(url, item, successDoFun) {
 function procDictRes(url, item, successDoFun) {
-  return request(url).then((response) => {
+  request(url).then((response) => {
     if (!response) {
     if (!response) {
       return
       return
     }
     }

+ 2 - 3
src/layout-content/mixins/dict.js

@@ -8,16 +8,15 @@ export default {
     }
     }
   },
   },
   methods: {
   methods: {
-    async initDicts(item, relyOnVal) {
+    initDicts(item, relyOnVal) {
       const that = this
       const that = this
-      const res = await initDicts(item, relyOnVal, true, (data, dictMapObj) => {
+      initDicts(item, relyOnVal, true, (data, dictMapObj) => {
         that.$set(that.dictMap, item.prop, data)
         that.$set(that.dictMap, item.prop, data)
         that.$set(that.dictMapMap, item.prop, dictMapObj)
         that.$set(that.dictMapMap, item.prop, dictMapObj)
         if (item.dictInitEmit) {
         if (item.dictInitEmit) {
           that.$emit('dictInitEmit', that.dictMap, that.dictMapMap)
           that.$emit('dictInitEmit', that.dictMap, that.dictMapMap)
         }
         }
       })
       })
-      return res
     }
     }
   }
   }
 }
 }

+ 1 - 4
src/layout-content/scss/layout-content.scss

@@ -6,7 +6,7 @@
     // height: calc(100% - 10px);
     // height: calc(100% - 10px);
     width:100%;
     width:100%;
     height: 100%;
     height: 100%;
-    padding: 12px;
+    padding: 20px 12px 12px 16px;
     background-color: #fff;
     background-color: #fff;
     // margin: 10px;
     // margin: 10px;
     // background-color: red;
     // background-color: red;
@@ -20,9 +20,6 @@
             // position: absolute;
             // position: absolute;
             // top: 0;
             // top: 0;
             // left: 0;
             // left: 0;
-            // .filter-item {
-            //     padding: 8px;
-            // }
         }
         }
 
 
         .search-c {
         .search-c {

+ 1 - 1
src/layout/components/AppMain.vue

@@ -27,7 +27,7 @@ export default {
   width: 100%;
   width: 100%;
   position: relative;
   position: relative;
   overflow: hidden;
   overflow: hidden;
-  /* padding: 10px 10px 0 10px; */
+  padding: 10px 10px 0 10px;
   /* background-color: blue; */
   /* background-color: blue; */
 }
 }
 .fixed-header + .app-main {
 .fixed-header + .app-main {

+ 0 - 1
src/layout/components/Sidebar/Logo.vue

@@ -59,7 +59,6 @@ export default {
       height: 32px;
       height: 32px;
       vertical-align: middle;
       vertical-align: middle;
       margin-right: 12px;
       margin-right: 12px;
-      filter: brightness(1.3);
     }
     }
 
 
     & .sidebar-title {
     & .sidebar-title {

+ 66 - 247
src/layout/index.vue

@@ -1,274 +1,93 @@
 <template>
 <template>
-  <div class="layout-container">
-    <header class="header-c">
-        <el-button
-          v-if="showBackButton"
-          type="text"
-          icon="el-icon-arrow-left"
-          @click="goBack"
-          class="back-button"
-        >
-          返回
-        </el-button>
-      <div class="container">
-        <div class="left-section">
-          <!-- Logo -->
-          <div class="logo">
-            <router-link to="/">
-              <img src="@/assets/logo.png" alt="Logo" />
-            </router-link>
-          </div>
-
-          <!-- Navigation -->
-          <nav class="nav-menu">
-            <router-link
-              v-for="item in menuItems"
-              :key="item.path"
-              :to="item.path"
-              :class="{ 'router-link-active': isActive(item.path) }"
-            >
-              {{ item.title }}
-            </router-link>
-          </nav>
-        </div>
-
-        <!-- Auth buttons -->
-        <div class="right-menu">
-          <el-dropdown class="avatar-container" trigger="click">
-            <div class="avatar-wrapper">
-              <i class="el-icon-s-custom user-avatar" />
-            </div>
-            <el-dropdown-menu slot="dropdown" class="user-dropdown">
-              <el-dropdown-item divided @click.native="logout">
-                <span style="display: block">退出</span>
-              </el-dropdown-item>
-            </el-dropdown-menu>
-          </el-dropdown>
-        </div>
+  <div :class="classObj" class="app-wrapper">
+    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
+    <sidebar class="sidebar-container" />
+    <div class="main-container">
+      <div :class="{'fixed-header':fixedHeader}">
+        <navbar />
       </div>
       </div>
-    </header>
-
-    <!-- 添加 AppMain 部分 -->
-    <section class="app-main">
-      <transition name="fade-transform" mode="out-in">
-        <keep-alive>
-          <router-view :key="key" />
-        </keep-alive>
-      </transition>
-    </section>
+      <app-main />
+    </div>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import { mapGetters } from "vuex";
+import { Navbar, Sidebar, AppMain } from './components'
+import ResizeMixin from './mixin/ResizeHandler'
 
 
 export default {
 export default {
-  name: "Layout",
-  data() {
-    return {
-      menuItems: [
-        { path: "/warehouse", title: "首页" },
-        { path: "/materialconfig/materialconfig", title: "部件配置" },
-        { path: "/totalPriceCfg/totalPriceCfg", title: "总价配置" },
-      ],
-    };
+  name: 'Layout',
+  components: {
+    Navbar,
+    Sidebar,
+    AppMain
   },
   },
+  mixins: [ResizeMixin],
   computed: {
   computed: {
-    ...mapGetters(["avatar"]),
-    // 添加 AppMain 的 computed 属性
-    key() {
-      return this.$route.path;
+    sidebar() {
+      return this.$store.state.app.sidebar
     },
     },
-    // 添加显示返回按钮的计算属性
-    showBackButton() {
-      const currentPath = this.$route.path;
-      return !this.menuItems.some((item) => currentPath.startsWith(item.path));
+    device() {
+      return this.$store.state.app.device
     },
     },
-  },
-  methods: {
-    async logout() {
-      try {
-        await this.$store.dispatch("user/logout");
-        this.$router.push(`/login?redirect=${this.$route.fullPath}`);
-      } catch (error) {
-        console.error("登出失败:", error);
-      }
+    fixedHeader() {
+      return this.$store.state.settings.fixedHeader
     },
     },
-    isActive(path) {
-      if (path === "/warehouse") {
-        const homeActivePaths = [
-          "/warehouse",
-          "/cfg/cfg",
-          "/show/2dshow",
-          "/show/3dshow",
-          "/show/2-5dshow-v0",
-          "/show/2-5dshow-v1",
-          "/materialdetail/materialdetail",
-          "/materialcost/materialcost",
-          "/totalPrice/totalPrice",
-        ];
-        return homeActivePaths.some((activePath) =>
-          this.$route.path.startsWith(activePath)
-        );
-      }
-      if (path === "/materialconfig/materialconfig") {
-        const homeActivePaths = [
-          "//materialconfig/materialconfig",
-          "/specConfig/specConfig",
-        ];
-        return homeActivePaths.some((activePath) =>
-          this.$route.path.startsWith(activePath)
-        );
+    classObj() {
+      return {
+        hideSidebar: !this.sidebar.opened,
+        openSidebar: this.sidebar.opened,
+        withoutAnimation: this.sidebar.withoutAnimation,
+        mobile: this.device === 'mobile'
       }
       }
-      return this.$route.path === path;
-    },
-    // 添加返回方法
-    goBack() {
-      this.$router.go(-1);
-    },
+    }
   },
   },
-};
+  methods: {
+    handleClickOutside() {
+      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
+    }
+  }
+}
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
-$header-height: 64px;
-.header-c {
-  height: $header-height;
-  line-height: $header-height;
-  background-color: #2d2d2d;
-  /* padding: 1rem 0; */
-}
-
-.container {
-  max-width: 1320px;
-  margin: 0 auto;
-  padding: 0 0.75rem;
-  display: flex;
-  justify-content: space-between;
-  align-items: center;
-  position: relative;
-}
-
-.logo {
-  display: flex;
-  align-items: center;
-  margin-left:2rem;
-}
-
-.logo img {
-  height: 36px;
-  display: block;
-}
-
-.nav-menu {
-  font-size: 16px;
-  display: flex;
-  gap: 2rem;
-  align-items: center;
-}
-
-.nav-item {
-  color: #fff;
-  text-decoration: none;
-  font-size: 1rem;
-}
-
-.nav-item:hover {
-  color: #409eff;
-}
-
-.right-menu {
-  float: right;
-  height: 100%;
-}
-
-.avatar-wrapper {
-  margin-top: 5px;
-  position: relative;
-}
-
-.user-avatar {
-  cursor: pointer;
-  font-size: 20px;
-  color: #fff;
-}
-
-.user-avatar:hover {
-  color: #409eff;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-  /*   .nav-menu {
-    display: none;
-  } */
-
-  .auth-buttons {
-    gap: 0.5rem;
+  @import "~@/styles/mixin.scss";
+  @import "~@/styles/variables.scss";
+
+  .app-wrapper {
+    @include clearfix;
+    position: relative;
+    height: 100%;
+    width: 100%;
+    &.mobile.openSidebar{
+      position: fixed;
+      top: 0;
+    }
   }
   }
-
-  .login-btn,
-  .signup-btn {
-    padding: 0.4rem 0.8rem;
-    font-size: 0.9rem;
+  .drawer-bg {
+    background: #000;
+    opacity: 0.3;
+    width: 100%;
+    top: 0;
+    height: 100%;
+    position: absolute;
+    z-index: 999;
   }
   }
-}
-
-/* 添加 AppMain 样式 */
-.app-main {
-  position: relative;
-  // flex: 1;
-  overflow: hidden;
-  height: calc(100vh - #{$header-height});
-}
-
-.left-section {
-  display: flex;
-  align-items: center;
-  gap: 2rem;
-  margin-left: 68px;
-}
-
-/* 添加新的布局样式 */
-.layout-container {
-  height: 100vh;
-}
-
-.router-link-active {
-  color: #409eff !important;
-  font-weight: bold;
-}
-
-.nav-menu a {
-  color: #fff;
-  text-decoration: none;
-}
 
 
-// 添加返回按钮样式
-.back-button {
-  position: absolute;
-  line-height: $header-height;
-  left: 0.75rem;
-  color: #fff;
-  font-size: 14px;
-  padding: 0 10px;
-  z-index: 1;
-
-  &:hover {
-    color: #409eff;
+  .fixed-header {
+    position: fixed;
+    top: 0;
+    right: 0;
+    z-index: 9;
+    width: calc(100% - #{$sideBarWidth});
+    transition: width 0.28s;
   }
   }
 
 
-  i {
-    margin-right: 5px;
+  .hideSidebar .fixed-header {
+    width: calc(100% - 54px)
   }
   }
-}
-</style>
 
 
-<style lang="scss">
-/* 添加 AppMain 的全局样式 */
-.el-popup-parent--hidden {
-  .fixed-header {
-    padding-right: 15px;
+  .mobile .fixed-header {
+    width: 100%;
   }
   }
-}
 </style>
 </style>

+ 0 - 93
src/layout/index_yuanlai.vue

@@ -1,93 +0,0 @@
-<template>
-  <div :class="classObj" class="app-wrapper">
-    <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
-    <sidebar class="sidebar-container" />
-    <div class="main-container">
-      <div :class="{'fixed-header':fixedHeader}">
-        <navbar />
-      </div>
-      <app-main />
-    </div>
-  </div>
-</template>
-
-<script>
-import { Navbar, Sidebar, AppMain } from './components'
-import ResizeMixin from './mixin/ResizeHandler'
-
-export default {
-  name: 'Layout',
-  components: {
-    Navbar,
-    Sidebar,
-    AppMain
-  },
-  mixins: [ResizeMixin],
-  computed: {
-    sidebar() {
-      return this.$store.state.app.sidebar
-    },
-    device() {
-      return this.$store.state.app.device
-    },
-    fixedHeader() {
-      return this.$store.state.settings.fixedHeader
-    },
-    classObj() {
-      return {
-        hideSidebar: !this.sidebar.opened,
-        openSidebar: this.sidebar.opened,
-        withoutAnimation: this.sidebar.withoutAnimation,
-        mobile: this.device === 'mobile'
-      }
-    }
-  },
-  methods: {
-    handleClickOutside() {
-      this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
-    }
-  }
-}
-</script>
-
-<style lang="scss" scoped>
-  @import "~@/styles/mixin.scss";
-  @import "~@/styles/variables.scss";
-
-  .app-wrapper {
-    @include clearfix;
-    position: relative;
-    height: 100%;
-    width: 100%;
-    &.mobile.openSidebar{
-      position: fixed;
-      top: 0;
-    }
-  }
-  .drawer-bg {
-    background: #000;
-    opacity: 0.3;
-    width: 100%;
-    top: 0;
-    height: 100%;
-    position: absolute;
-    z-index: 999;
-  }
-
-  .fixed-header {
-    position: fixed;
-    top: 0;
-    right: 0;
-    z-index: 9;
-    width: calc(100% - #{$sideBarWidth});
-    transition: width 0.28s;
-  }
-
-  .hideSidebar .fixed-header {
-    width: calc(100% - 54px)
-  }
-
-  .mobile .fixed-header {
-    width: 100%;
-  }
-</style>

+ 0 - 1
src/main.js

@@ -20,7 +20,6 @@ import '@/icons' // icon
 import '@/permission' // permission control
 import '@/permission' // permission control
 import request from '@/utils/request'
 import request from '@/utils/request'
 import utils from '@/utils/index'
 import utils from '@/utils/index'
-import '@/components/map/GLB-GRID-CONST.js'
 /**
 /**
  * If you don't want to use mock-server
  * If you don't want to use mock-server
  * you want to use MockJs for mock api
  * you want to use MockJs for mock api

+ 0 - 149
src/map-test/config.js

@@ -1,149 +0,0 @@
-window.VERSION_JQUERY = "3D-jquery";
-window.VERSION_VUE = "3D-vue";
-window.versionMsg = window.VERSION_VUE;
-window.isSmulatingData = true;
-window.isGetDataFromOut = false;
-window.isLogingMm = false;
-window.openWcsTestMode = false;
-/**
-const cBef = 0
-const rBef = 0
-//driverLane
-const combinedArrayDriverLane = combineArraysCum(11, [12, 17, 24], [16, 33], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const combinedArrayDriverLane1 = combineArraysCum(11, [29], [16, 27], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const combinedArrayDriverLaneFinal = [...combinedArrayDriverLane, ...combinedArrayDriverLane1]
-console.log('driverLane config DATA', JSON.stringify(combinedArrayDriverLaneFinal));
-
-//disable 数据
-const combinedArrayDisable1 = combineArraysCum(11, [11, 13, 16, 18, 23, 25], [34, 36], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const combinedArrayDisable2 = combineArraysCum(11, [21], [32, 36], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const combinedArrayDisable3 = combineArraysCum(11, [26, 31], [36], cBef, rBef, { fProxy: 'num', cProxy: 'idxStartEnd', rProxy: 'arr' });
-const combinedArrayDisable4 = combineArraysCum(11, [12, 17, 24], [35, 36], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'arr' });//电梯占用两个位置,先配置成占用一个位置
-const finalCombinedArrayDisable = [...combinedArrayDisable1, ...combinedArrayDisable2, ...combinedArrayDisable3, ...combinedArrayDisable4]
-console.log('Disable config DATA', JSON.stringify(finalCombinedArrayDisable));
-
-// // disable_JNotForGood 后台数据的不可用  20240702渲染占无差异
-const disNotForGood2 = combineArraysCum(11, [11, 31], [1], cBef, rBef, { fProxy: 'num', cProxy: 'idxStartEnd', rProxy: 'arr' });
-const disNotForGood3 = combineArraysCum(11, [26, 31], [35], cBef, rBef, { fProxy: 'num', cProxy: 'idxStartEnd', rProxy: 'arr' });
-const disNotForGood1 = combineArraysCum(11, [21], [17, 25], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const disNotForGood4 = combineArraysCum([7], [21], [11, 16], cBef, rBef, { fProxy: 'arr', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const disNotForGood5 = combineArraysCum([7], [21], [26, 31], cBef, rBef, { fProxy: 'arr', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const disNotForGood6 = combineArraysCum([6], [21], [11, 16], cBef, rBef, { fProxy: 'arr', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const disNotForGood7 = combineArraysCum([6], [21], [26, 31], cBef, rBef, { fProxy: 'arr', cProxy: 'arr', rProxy: 'idxStartEnd' });
-const disNotForGood8 = combineArraysCum([1], [11, 31], [11], cBef, rBef, { fProxy: 'arr', cProxy: 'idxStartEnd', rProxy: 'arr' });
-const disNotForGood = [...disNotForGood1, ...disNotForGood2, ...disNotForGood3, ...disNotForGood4, ...disNotForGood5, ...disNotForGood6, ...disNotForGood7, ...disNotForGood8]
-console.log('Disable NOT FOR GOOD config DATA', JSON.stringify(disNotForGood));
-//货架内输送线,当将输送线在around中配置时,2D使用
-const conveyorInRacking = combineArraysCum([1], [12, 17, 24], [33, 36], cBef, rBef, { fProxy: 'arr', cProxy: 'arr', rProxy: 'idxStartEnd' });
-console.log('conveyorInRacking config DATA', JSON.stringify(conveyorInRacking));
-// // around外围数据
-const fArrChainConveyor = 1;
-//跟电梯关联的输送线
-const combinedArraychainConveyor = combineArraysCum(fArrChainConveyor, [12, 17, 24], [33, 37], cBef, rBef);
-//入货口到货架方向
-const combinedArraychainConveyor1 = combineArraysCum(fArrChainConveyor, [25], [37, 48], cBef, rBef);
-
-//货架处多余上面未配的
-const combinedArraychainConveyor2 = combineArraysCum(fArrChainConveyor, [17], [38, 38], cBef, rBef);
-
-//紧挨第一个提升机处输送线
-const combinedArraychainConveyor3 = combineArraysCum(fArrChainConveyor, [11], [37, 38], cBef, rBef);
-
-//出货方向
-const combinedArraychainConveyor4 = combineArraysCum(fArrChainConveyor, [7], [30, 37], cBef, rBef);
-
-const finalCombinedArraychainConveyor = [...combinedArraychainConveyor, ...combinedArraychainConveyor1, ...combinedArraychainConveyor2, ...combinedArraychainConveyor3, ...combinedArraychainConveyor4]
-console.log('around- chainConveyor config DATA', JSON.stringify(finalCombinedArraychainConveyor));
-
-// //around- rollerConveyor
-//平行主巷道
-const rollerConveyor = combineArraysCum(fArrChainConveyor, [7, 25], [37], cBef, rBef, { fProxy: 'num', cProxy: 'idxStartEnd', rProxy: 'arr' }, { rotation: { x: 0, y: -Math.PI / 2, z: 0 } });
-
-//入货方向
-const rollerConveyor1 = combineArraysCum(fArrChainConveyor, [25], [49, 55], cBef, rBef);
-
-//平行主巷道方向的质检、托盘
-const rollerConveyor3 = combineArraysCum(fArrChainConveyor, [22, 25], [42, 53], cBef, rBef, { fProxy: 'num', cProxy: 'idxStartEnd', rProxy: 'arr' }, { rotation: { x: 0, y: -Math.PI / 2, z: 0 } });
-const finalRollerConveyor = [...rollerConveyor, ...rollerConveyor1, ...rollerConveyor3]
-console.log('around- RollerConveyor config DATA', JSON.stringify(finalRollerConveyor));
- */
-/**
-const cBef = 0
-const rBef = 0
-//driverLane
-const charge = combineArraysCum(11, [11], [33], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'arr' });
-const charge2 = combineArraysCum(11, [31], [36], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'arr' });
-const charge3 = combineArraysCum(11, [20], [36], cBef, rBef, { fProxy: 'num', cProxy: 'arr', rProxy: 'arr' });
-const finalCharge = [...charge, ...charge2, ...charge3]
-console.log('charge config DATA', JSON.stringify(finalCharge));
- */
-
-/**
- * 外部获取WS上发数据
- * 部分模拟数据备份,请查看D:\0job\00代码之外\000交付\3-山东潍坊滨海石化202406\联调测试[模拟数据等]
- * const simulateDataFromOutInit = ''
- * const simulateDataFromOutUpArr = ['']
- */
-//充电桩数据 true 黄色 false 绿色
-// const simulateDataFromOutInit = ''
-// const simulateDataFromOutUpArr = ['{"action":"update","data":{"plc_lift": [{"c": 42,"r": 12,"did": "1_1","cur_floor": 2,"items": "00","has_shuttle": false}]}}']
-// 提升机
-// const simulateDataFromOutUpArr = ['{"action":"update","data":{"plc_lift": [{"c": 13,"r": 18,"did": "1_1","cur_floor": 2,"items": "00","has_shuttle": false}]}}']
-//充电桩更新数据
-// const simulateDataFromOutUpArr = ['{"action":"update","data":{"plc_charger": [{"f": 1,"c": 13,"r": 33,"did": "1","power_on": true},{"f": 1,"c": 12,"r": 15,"did": "1","power_on": true}]}}']
-//线路
-// const simulateDataFromOutInit = ''
-// const simulateDataFromOutUpArr = ['{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":33,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":32,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":31,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":30,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":29,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":28,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":27,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":26,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":25,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":24,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":23,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":22,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":21,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":20,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":19,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":18,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":17,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":16,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":15,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":14,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":13,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":12,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":11,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":12,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":13,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":14,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":15,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":16,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":17,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":18,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":19,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":20,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":21,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":22,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":23,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":24,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":25,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":26,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":27,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":28,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":29,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":30,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":31,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":32,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":33,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":34,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}',
-//     '{"action":"update","data":{"cells":[],"shuttle":[{"f":1,"c":17,"r":35,"sid":"s8","items":"01","steps":[{"r":12,"f":1,"c":13},{"f":1,"c":13,"r":13},{"f":1,"c":13,"r":14},{"f":1,"c":13,"r":15},{"f":1,"c":13,"r":16},{"f":1,"c":14,"r":16},{"r":16,"f":1,"c":15},{"f":1,"c":16,"r":16},{"r":16,"f":1,"c":17},{"f":1,"c":18,"r":16},{"f":1,"c":19,"r":16},{"f":1,"c":20,"r":16},{"f":1,"c":21,"r":16},{"c":22,"r":16,"f":1},{"f":1,"c":23,"r":16},{"c":24,"r":16,"f":1},{"f":1,"c":25,"r":16},{"r":16,"f":1,"c":26},{"f":1,"c":27,"r":16},{"f":1,"c":28,"r":16},{"c":29,"r":16,"f":1},{"f":1,"c":30,"r":16},{"f":1,"c":31,"r":16},{"f":1,"c":31,"r":17},{"f":1,"c":31,"r":18},{"f":1,"c":31,"r":19},{"r":20,"f":1,"c":31},{"f":1,"c":31,"r":21},{"f":1,"c":31,"r":22},{"f":1,"c":31,"r":23},{"f":1,"c":31,"r":24},{"f":1,"c":31,"r":25}],"step_index":8,"status":"procing"}]}}'
-
-// ]
-/* 初始化车辆位置 2024 车上带托盘
-const simulateDataFromOutInit =
-  '{"action":"update","data":{"shuttle":[{"f":1,"c":17,"r":12,"sid":"s8","items":"01"}]}}';
-const simulateDataFromOutUpArr = [];
- */

File diff suppressed because it is too large
+ 0 - 385
src/map-test/dataSimulate.js


+ 0 - 26
src/mixins/map/canvas/gridCanvasMixin.js

@@ -1,26 +0,0 @@
-export default {
-  data() {
-    return {
-      containerWidth: 0,
-      containerHeight: 0,
-    };
-  },
-  
-  mounted() {
-    this.updateContainerSize();
-    window.addEventListener("resize", this.updateContainerSize);
-  },
-  
-  beforeDestroy() {
-    window.removeEventListener("resize", this.updateContainerSize);
-  },
-  
-  methods: {
-    updateContainerSize() {
-      if (this.$refs.container) {
-        this.containerWidth = this.$refs.container.offsetWidth;
-        this.containerHeight = this.$refs.container.offsetHeight;
-      }
-    },
-  },
-}; 

+ 0 - 3482
src/mixins/map/gridBaseMixin.js

@@ -1,3482 +0,0 @@
-import shuttleLogImg from "@/assets/map/shuttle_v0_canvas.png";
-import {
-  COMMON_CONST,
-  ITEMSTATUS,
-  LOCTYPE,
-  ITEM_ATTRIBUTE_TYPE,
-  getCFG,
-  getScss,
-} from "@/components/map//GRID-CONST";
-import CellSelPanel from "@/components/map/grid-canvas/cell-sel-panel.vue";
-import RenderStrategyFactory from "./renderStrategies/RenderStrategyFactory";
-
-export default {
-  props: {
-    mapOperModel: {
-      type: String,
-      default: "",
-    },
-    isShowNumInCell: {
-      type: Boolean,
-      default: true,
-    },
-    isShowHoverInfo: {
-      type: Boolean,
-      default: true,
-    },
-    includedAngle: {
-      type: Number,
-      default: 90,
-    },
-    isShowAllFlr: {
-      type: Boolean,
-      default: true,
-    },
-    isShowRackIndxNum: {
-      type: Boolean,
-      default: false,
-    },
-    containerWidth: {
-      type: Number,
-      default: 0,
-    },
-    containerHeight: {
-      type: Number,
-      default: 0,
-    },
-    operFloor: {
-      type: Number,
-      default: 1,
-    },
-    renderType: {
-      type: String,
-      default: "svg",
-      validator: (value) => ["svg", "canvas", "webgl"].includes(value),
-    },
-  },
-  components: {
-    CellSelPanel,
-  },
-  data() {
-    return {
-      renderer: null,
-      showChgPalletCodeDia: false,
-      chgPalletCodeDiaData: {
-        warehouse_id: null,
-        f: null,
-        c: null,
-        r: null,
-
-        pallet_code: null,
-      },
-      showContextMenu: false,
-      contextMenuPosition: {
-        x: 0,
-        y: 0,
-      },
-      selectedItemArr: null,
-      canvasWidth: 0,
-      canvasHeight: 0,
-      canvasLoading: false,
-      hoveredInfo: {
-        hoveredRowIndex: null,
-        hoveredColIndex: null,
-        hoveredFloorIndex: null,
-        hoveredItemStsName: null,
-      },
-      hoveredPalletCode: "",
-      hoveredSid: "",
-      imageBtnSrc: require("@/assets/map/rorate.jpg"),
-      isPanelOnRight: true, // 控制面板位置的状态
-      rotationAngleType: 0,
-    };
-  },
-  computed: {
-    cellSelPanelVisible() {
-      return this.selectedItemArr && this.selectedItemArr.length > 0;
-    },
-    isCfgSty() {
-      return this.mapOperModel === "cfg";
-    },
-    imageBtnStyle() {
-      return {
-        transform: `rotate(${this.rotationAngleType * 90}deg)`,
-        width: "28px", // 控制图片宽度为18px,高度会自动调整以保持图片比例
-        height: "auto",
-        transition: "transform 0.5s", // 使旋转有动画效果
-      };
-    },
-    rCFStrToArr() {
-      return (key) => {
-        const arr = key.split(COMMON_CONST.idSep);
-        if (!arr || arr.length !== 3) {
-          return;
-        }
-        const newArr = [];
-        arr.forEach((numStr) => {
-          newArr.push(Number(numStr));
-        });
-        return newArr;
-      };
-    },
-    panelPositionClass() {
-      return this.isPanelOnRight ? "panel-right" : "panel-left";
-    },
-  },
-  watch: {
-    operFloor: {
-      handler(newVal, oldVal) {
-        if (newVal !== oldVal) {
-          this.flrChg();
-        }
-      },
-      immediate: false,
-    },
-    isShowNumInCell: {
-      handler(newVal, oldVal) {
-        if (newVal !== oldVal) {
-          this.clearSelItemArr();
-          this.initData(this.storeData, true);
-        }
-      },
-      immediate: false,
-      deep: true,
-    },
-    mapOperModel(newVal) {
-      this.canBeSelected = newVal === "cfg";
-    },
-    selectedItemArr(newVal) {
-      if (
-        newVal &&
-        newVal.length > 0 &&
-        (newVal[0].backC === undefined || newVal[0].backR === undefined)
-      ) {
-        this.pageIdxToBusiIndx(newVal[0], this.rotationAngleType);
-      }
-    },
-    "renderer.selectedCell": {
-      handler(newVal) {
-        if (!newVal) {
-          // 当没有选中单元格时,清空hoveredInfo
-          this.hoveredInfo = {
-            hoveredRowIndex: null,
-            hoveredColIndex: null,
-            hoveredFloorIndex: null,
-            hoveredItemStsName: null,
-          };
-          this.hoveredPalletCode = "";
-          this.hoveredSid = "";
-          return;
-        }
-
-        // 获取选中的单元格数据
-        // 从renderer中获取当前选中的单元格数据
-        const cell = this.renderer.getCurrentSelectedCellData();
-        if (!cell) return;
-        // 获取业务索引
-        const itemBui = this.pageIdxToBusiIndx(
-          { r: cell.rowIndex, c: cell.colIndex },
-          this.rotationAngleType
-        );
-
-        // 更新hoveredInfo
-        const itemStatus = cell.status;
-        const itemStatusName = itemStatus
-          ? this.itemStsMap[itemStatus].name
-          : null;
-
-        this.hoveredInfo = {
-          hoveredItemStsName: itemStatusName,
-          hoveredFloorIndex: cell.flrNum,
-          hoveredRowIndex: itemBui ? itemBui.r : null,
-          hoveredColIndex: itemBui ? itemBui.c : null,
-        };
-
-        // 更新hoveredSid
-        if (itemBui) {
-          this.hoveredSid = this.checkShuttleExist(
-            cell.flrNum,
-            itemBui.c,
-            itemBui.r
-          );
-        }
-      },
-      immediate: true,
-    },
-  },
-  created() {
-    // 初始化渲染器
-    this.renderer = RenderStrategyFactory.createStrategy(this.renderType, this);
-    // 如果渲染器提供了自己的样式变量,则使用渲染器的
-    if (this.renderer.getStyleVariables) {
-      this.scssVariables = this.renderer.getStyleVariables();
-    }
-
-    this.initComponentParam();
-    this.initShuttleImg();
-    this.initSysBaseData();
-  },
-
-  mounted() {
-    this.$nextTick(() => {
-      if (this.renderer) {
-        this.renderer.initRenderer();
-      }
-    });
-    // 点击其他区域关闭菜单
-    document.addEventListener("click", this.closeContextMenu);
-  },
-
-  beforeDestroy() {
-    if (this.renderer) {
-      this.renderer.dispose();
-    }
-    document.removeEventListener("click", this.closeContextMenu);
-  },
-  methods: {
-    calculateCenterPoint(item) {
-      const offsetX = this.warehousPageCfg.rowOffsetX;
-      const offsetY = this.warehousPageCfg.colOffsetY;
-      return {
-        x: (item.x1 + item.x2 + item.x3 + item.x4) / 4 + offsetX,
-        y: (item.y1 + item.y2 + item.y3 + item.y4) / 4 + offsetY,
-      };
-    },
-    saveViewState() {
-      if (this.renderer) {
-        const saved = this.renderer.saveViewState(this.wareHouseId);
-        if (saved) {
-          this.$message.success("视图状态已保存");
-        } else {
-          this.$message.error("保存视图状态失败");
-        }
-      } else {
-        this.$message.warning("渲染器未就绪");
-      }
-    },
-    resetView() {
-      if (this.renderer) {
-        this.renderer.resetTransform();
-        this.$message.success("视图已重置");
-      }
-    },
-    submitChgPalletCode() {
-      this.$req({
-        url: "/wcs/api/map/cell/set/pallet",
-        method: "post",
-        data: this.chgPalletCodeDiaData,
-      })
-        .then((res) => {
-          this.$message.success("修改托盘码成功");
-          this.showChgPalletCodeDia = false;
-        })
-        .catch((err) => {
-          console.error("修改托盘码失败:", err);
-        });
-    },
-    handleContextMenu(e) {
-      e.preventDefault();
-      const ele = this.getCurrentMouseCellEle(e);
-      if (!ele) {
-        return;
-      }
-      // 记录右键点击位置
-      this.contextMenuPosition = {
-        x: e.clientX,
-        y: e.clientY,
-      };
-      this.showContextMenu = true;
-    },
-
-    closeContextMenu() {
-      this.showContextMenu = false;
-    },
-
-    handleMenuClick(option) {
-      // 处理菜单选项点击
-      switch (option) {
-        case "chgPalletCode":
-          this.procPalletCode("chgPalletCode");
-          break;
-        case "copyPalletCode":
-          this.procPalletCode("copyPalletCode");
-          break;
-      }
-      this.closeContextMenu();
-    },
-    procPalletCode(option) {
-      if (!this.curCell) return;
-
-      // 获取业务索引
-      const backEle = this.pageIdxToBusiIndx(
-        {
-          f: this.curCell.flrNum,
-          c: this.curCell.colIndex,
-          r: this.curCell.rowIndex,
-        },
-        this.rotationAngleType
-      );
-      let afterGetPalletCodeDo = null;
-      if (option === "chgPalletCode") {
-        afterGetPalletCodeDo = () => {
-          this.showChgPalletCodeDia = true;
-          this.chgPalletCodeDiaData = {
-            warehouse_id: this.wareHouseId,
-            f: backEle.f,
-            c: backEle.c,
-            r: backEle.r,
-            pallet_code: this.hoveredPalletCode,
-          };
-        };
-      } else if (option === "copyPalletCode") {
-        afterGetPalletCodeDo = (palletCode) => {
-          if (!palletCode) {
-            this.$message.warning(
-              "此处" + `(${backEle.f}-${backEle.c}-${backEle.r})` + "无托盘"
-            );
-            return;
-          }
-          navigator.clipboard
-            .writeText(palletCode)
-            .then(() => {
-              this.$message.success("托盘码已复制到剪贴板");
-            })
-            .catch((err) => {
-              console.error("复制失败:", err);
-            });
-        };
-      }
-
-      this.getPalletCode(backEle, afterGetPalletCodeDo);
-    },
-    togglePanelPosition() {
-      this.isPanelOnRight = !this.isPanelOnRight;
-    },
-    onCellSelItemClick(itemCfgInfo, cfgTableSts) {
-      let operItems = this.selectedItemArr;
-      if (
-        itemCfgInfo.cellSelPanel &&
-        itemCfgInfo.cellSelPanel.procItemDataFun
-      ) {
-        operItems = itemCfgInfo.cellSelPanel.procItemDataFun(this);
-      }
-      this.itemStsInitBatch(operItems, cfgTableSts, itemCfgInfo.key);
-      this.drawCanvas();
-      this.$emit("grid-canvas-save", this.getCfgData());
-    },
-    getUniqueRowsOrCols() {
-      const key = this.isHorizontal() ? "rowIndex" : "colIndex";
-      const uniqueIndices = [
-        ...new Set(this.selectedItemArr.map((item) => item[key])),
-      ];
-      // 返回符合条件的一个元素
-      return uniqueIndices.map((index) => {
-        return this.selectedItemArr.find((item) => item[key] === index);
-      });
-    },
-    initComponentParam() {
-      this.scssVariables = getScss("svg");
-      this.canBeSelected = false;
-      this.isCfgByFloor = false;
-      this.mouseSts = "";
-      this.cfgOperingItem = "";
-      this.rowStart = 0;
-      this.colStart = 0;
-      this.rowStartOri = 0;
-      this.colStartOri = 0;
-      this.showSty = process.env.VUE_APP_SHOW_STYLE; // show[展示模式] cfg[配置模式]//TESTMM1113
-      // this.showSty = 'show'; // show[展示模式] cfg[配置模式]
-      this.expandRowNum = 0;
-      this.expandColNum = 0;
-      this.expandRowStart = 0;
-      this.expandColStart = 0;
-      this.converyAround = [];
-      this.conveyorAroundMap = {};
-      this.wareHouseId = null;
-      this.wareHouseName = null;
-      this.flrFromSty = "bTOt"; // 楼层显示-从下到上 bTOt 从上到下 tTOb
-      // this.operFloor = 1;
-      this.totalFlr = 1;
-      this.shuttleImg = null;
-      this.totalPageFlr = 0; // 页面共有几层楼层
-      this.thetaInRadians = (90 * Math.PI) / 180;
-      this.flrHorizontalTotalHangLen = 0; // 单层横向悬空长度
-      this.flrHorizontalShowType = "many"; // 横向空间层显示类型,'one' 'many'
-      this.flrHorizontalTotalLen = 0; // 每层横向总长度
-      this.flrVehTotalLen = 0; // 每层纵向总长度
-      this.flrHorizontalLen = 0; // 每层横向向总长度
-      this.flrHorizontalSpace = 10; // 层横向间距
-      this.flrVehSpace = 3; // 层纵向间距
-      this.totalHorizontalFlrPer = 0; // 横向放置层的数量
-      this.rotationAngleType = 0; // 原始0,1-顺时针旋转90度,2-顺时针旋转180度,3-顺时针旋转270度,4-顺时针旋转360度(状态同原始)
-      this.front = 0; // 屏幕的上面,在行数的方向不同时需要关注
-      this.right = 0;
-      this.left = 0;
-      this.back = 0; // 屏幕的下面,在行数的方向不同时需要关注
-      this.isShowing = false;
-      this.clickCount = 0;
-      this.clickTimeout = null;
-      this.rotationAngle = 0;
-      this.ctx = null;
-      this.canvas = null;
-      this.animationFrameId = null;
-      this.scale = 1;
-      this.startDrag = { x: 0, y: 0 };
-      this.offset = { x: 0, y: 0 };
-      this.pageFloorGridDataObj = {}; // 存储页面数据,与页面显示对象一一对应。旋转时,改变数据位置内容 不放在data中,不适用双向绑定
-      this.storePageFloorGridDataObj = null;
-      this.storeData = null;
-      this.shuttleVisObj = {}; // 车辆数据(基础数据、线路、页面位置信息)
-      this.goodsVisObj = {}; // 货物数据
-      this.pageRow = 0; // 维护的所有格子的行数
-      this.pageCol = 0; // 维护的所有格子的列数
-      this.rackRow = 0;
-      this.rackCol = 0;
-      this.wareRow = 0;
-      this.wareCol = 0;
-      this.cellWidth = 0; // 四边形横向边长度
-      this.cellLen = 0; // 四边形纵向边长度
-      this.verticalCellHeight = 0; // 四边形横向边间距离
-      this.horizontalPointOffset = 0; // 四边形左下角水平方向的偏移
-      this.warehousPageCfg = {
-        rowOffsetX: 0, // 在第一列左侧预留的宽度,需计算使得整个仓库位于视口中间位置
-        colOffsetY: 0, // 在第一行上方预留的高度,需计算使得整个仓库位于视口中间位置
-      };
-      this.aroundInfo = {}; // 配置时,外围扩展信息
-    },
-    setIsAni(isAni) {
-      this.isAni = isAni;
-    },
-    initSysBaseData() {
-      this.initItemStsMap();
-    },
-    initItemStsMap() {
-      this.itemStsMap = {};
-      for (const itemType of getCFG("svg").baseItemStsArr) {
-        /*         if (itemType.isNotCellData) {
-                  continue
-                } */
-        this.itemStsMap[itemType.key] = itemType;
-      }
-    },
-    saveCanvasAsImage() {
-      if (!this.isCfgSty) {
-        return;
-      }
-      const canvas = this.$refs.canvas;
-      const image = canvas
-        .toDataURL("image/png")
-        .replace("image/png", "image/octet-stream");
-      const link = document.createElement("a");
-      link.href = image;
-      const fileName = this.wareHouseName
-        ? `${this.wareHouseName}_楼层${this.operFloor}.png`
-        : `仓库_楼层${this.operFloor}.png`;
-      link.download = fileName;
-      link.click();
-    },
-    /*     flrChg(flr) {
-      this.operFloor = flr;
-      this.initData(this.storeData);
-    }, */
-    flrChg(flr) {
-      // this.operFloor = flr;
-      this.clearSelItemArr();
-      this.drawCanvas();
-    },
-    setFlr(flr) {
-      this.operFloor = flr;
-    },
-    initShuttleImg() {
-      if (this.shuttleImg) return; // 避免重复加载
-
-      const img = new Image();
-      img.onload = () => {
-        this.shuttleImg = img;
-        // 图片加载完成后重新渲染
-        this.drawCanvas();
-      };
-      img.onerror = (err) => {
-        console.error("Failed to load shuttle image:", err);
-      };
-      img.src = shuttleLogImg;
-    },
-    rotateBtn() {
-      const storeRotationType = localStorage.getItem("rotationAngleType") || 0;
-      const storeNum = parseInt(storeRotationType);
-      let rotationFinal = storeNum + 1;
-      if (rotationFinal > 3) {
-        // 当达到360度时重置
-        rotationFinal = 0;
-      }
-      localStorage.setItem("rotationAngleType", rotationFinal);
-      this.initData(this.storeData);
-    },
-    getWareHouseData() {
-      return this.$req({
-        url: "/wcs/api/map/get/" + this.wareHouseId || window.glbMapId,
-        method: "post",
-      });
-    },
-    rotateGridData(pageFloorGridDataObj, rotationAngleType = 0) {
-      let result = [];
-      const rows = pageFloorGridDataObj.length;
-      const cols = pageFloorGridDataObj[0].length;
-
-      switch (rotationAngleType) {
-        case 0: // 不旋转
-          result = pageFloorGridDataObj;
-          break;
-        case 1: // 90度顺时针旋转
-          for (let col = 0; col < cols; col++) {
-            const newRow = [];
-            for (let row = rows - 1; row >= 0; row--) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        case 2: // 180度顺时针旋转
-          for (let row = rows - 1; row >= 0; row--) {
-            const newRow = [];
-            for (let col = cols - 1; col >= 0; col--) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        case 3: // 270度顺时针旋转或90度逆时针旋转
-          for (let col = cols - 1; col >= 0; col--) {
-            const newRow = [];
-            for (let row = 0; row < rows; row++) {
-              newRow.push(pageFloorGridDataObj[row][col]);
-            }
-            result.push(newRow);
-          }
-          break;
-        default:
-          result = pageFloorGridDataObj;
-      }
-
-      return result;
-    },
-    resetData() {
-      this.rackRow = 0;
-      this.rackCol = 0;
-      this.pageRow = 0;
-      this.pageCol = 0;
-      this.pageFloorGridDataObj = {};
-      this.storePageFloorGridDataObj = null;
-      this.storeData = null;
-      this.renderer && this.renderer.resetTransform();
-    },
-    /*
-    this.pageFloorGridDataObj对应页面整个数据。
-    每个最底层元素,持有从后台数据转换而来的数据信息。
-    关键动作:后台数据转前台页面数据。
-    */
-    initData(res, isInitAllFlrData) {
-      this.resetData();
-      if (!res) {
-        return;
-      }
-      const data = res.row;
-      if (!data) {
-        // this.resetData();
-        return;
-      }
-      this.storeData = res;
-      try {
-        this.canvasLoading = true;
-        this.assignment(data); // 后台基础数据赋值
-        this.initCfg(data);
-        if (this.isNotDo()) {
-          this.canvasLoading = false;
-          return;
-        }
-        this.pageFloorGridDataObj = this.initFloorGridData(
-          this.pageFloorGridDataObj,
-          isInitAllFlrData
-        );
-        this.parseOperItemData(data, isInitAllFlrData); // 依赖this.pageFloorGridDataObj
-        this.initCfgBefRender();
-        this.storePageFloorGridDataObj = JSON.parse(
-          JSON.stringify(this.pageFloorGridDataObj)
-        );
-        // Vue更新视图后再执行drawCanvas(),从而确保在更改画布大小后正确渲染内容
-        this.$nextTick(() => {
-          this.drawCanvas();
-          this.canvasLoading = false;
-        });
-      } catch (error) {
-        console.error(error);
-        this.canvasLoading = false;
-      }
-    },
-    parseOperItemData(data, isInitAllFlrData) {
-      const dataIn = JSON.parse(JSON.stringify(data));
-      const keys = Object.keys(this.pageFloorGridDataObj);
-      for (const flrNumStr of keys) {
-        const flrNum = Number(flrNumStr);
-        if (
-          !this.isShowAllFlr &&
-          flrNum !== this.operFloor &&
-          !isInitAllFlrData
-        ) {
-          continue;
-        }
-        for (let itemType of getCFG("svg").baseItemStsArr) {
-          const dataKey = itemType.backKey || itemType.key;
-          const itemStatusKey = itemType.key;
-          const itemsDataArr = dataIn[dataKey] ? dataIn[dataKey] : []; // 配置项数组【"mainRoad":[1,2],"lift":[{"f":1,"c":1,"r":1}],】
-          if (!Array.isArray(itemsDataArr)) {
-            continue;
-          }
-          if (!itemsDataArr || itemsDataArr.length === 0) {
-            continue;
-          }
-          const newItemsDataArr = JSON.parse(JSON.stringify(itemsDataArr));
-          newItemsDataArr.forEach((elementIn) => {
-            if (itemStatusKey === ITEMSTATUS.xTrack) {
-              const mainRoadDirNum = this.isHorizontal()
-                ? this.pageCol
-                : this.pageRow; // 主巷道方向行数
-              for (let j = 0; j < mainRoadDirNum; j++) {
-                let element = {};
-                if (this.isHorizontal()) {
-                  element.r = elementIn;
-                  element.c = j + this.colStartOri;
-                } else {
-                  element.r = j + this.rowStartOri;
-                  element.c = elementIn;
-                }
-                this.busiIndxToPageIdx(element, this.rotationAngleType);
-                const item = this.getTheItem(element.r, element.c, flrNum);
-                // const item = this.getTheItem(this.isHorizontal() ? idx : j, this.isHorizontal() ? j : idx, flrNum);
-                if (item?.type !== LOCTYPE.around) {
-                  this.itemStsInit(item, itemStatusKey);
-                }
-              }
-            } else if (
-              itemStatusKey === ITEMSTATUS.lift ||
-              flrNum === elementIn.f
-            ) {
-              //适配了非1楼无梯子数据也需要渲染
-
-              if (
-                elementIn.rE !== undefined ||
-                elementIn.rS !== undefined ||
-                elementIn.cE !== undefined ||
-                elementIn.cS !== undefined
-              ) {
-                this.procManyRowOrCol(elementIn, itemStatusKey, flrNum);
-              } else {
-                this.busiIndxToPageIdx(elementIn, this.rotationAngleType);
-                const item = this.getTheItem(elementIn.r, elementIn.c, flrNum);
-                this.itemStsInit(item, itemStatusKey);
-              }
-            }
-          });
-        }
-      }
-    },
-    getCfgData() {
-      const result = {};
-      const xTrackMap = new Set();
-      const isHorizontal = this.isHorizontal();
-
-      // 初始化结果对象
-      Object.keys(this.itemStsMap).forEach((key) => {
-        const itemType = this.itemStsMap[key];
-        if (!itemType.noToBackData) {
-          const backKey = itemType.backKey || key;
-          result[backKey] = [];
-        }
-      });
-
-      // 处理单个状态对象
-      const processStatus = (ele, status, flrNum) => {
-        const itemTypeEle = this.itemStsMap[status];
-        if (
-          !itemTypeEle ||
-          (itemTypeEle.displayControl &&
-            itemTypeEle.displayControl.isNotShowInCfg)
-        )
-          return;
-
-        const backKey = itemTypeEle.backKey || status;
-        if (!backKey) return;
-
-        if (!result[backKey]) {
-          result[backKey] = [];
-        }
-
-        const eleBack = this.buildElementBack(ele, flrNum);
-
-        if (itemTypeEle.key === ITEMSTATUS.xTrack) {
-          const trackValue = isHorizontal ? eleBack.r : eleBack.c;
-          xTrackMap.add(trackValue);
-        } else {
-          result[backKey].push(eleBack);
-        }
-      };
-
-      // 遍历楼层数据
-      for (let flrNum = 1; flrNum <= this.totalFlr; flrNum++) {
-        const flrData =
-          this.pageFloorGridDataObj[flrNum] || this.pageFloorGridDataObj[1];
-        if (!flrData) continue;
-
-        // 处理每层的网格数据
-        Object.values(flrData).forEach((pageCArr) => {
-          pageCArr.forEach((ele) => {
-            const itemType = this.itemStsMap[ele.status];
-            if (itemType && !itemType.noToBackData) {
-              if (ele.status) {
-                processStatus(ele, ele.status, flrNum);
-              }
-            }
-
-            // 处理状态列表
-            if (ele.statusList?.length) {
-              ele.statusList.forEach((statusObj) => {
-                const itemType = this.itemStsMap[statusObj.status];
-                if (itemType && !itemType.noToBackData) {
-                  if (statusObj.status) {
-                    processStatus(ele, statusObj.status, flrNum);
-                  }
-                }
-              });
-            }
-          });
-        });
-      }
-
-      // 处理xTrack数据
-      if (xTrackMap.size > 0) {
-        result[this.itemStsMap["xTrack"].key] = Array.from(xTrackMap)
-          .map(Number)
-          .sort((a, b) => a - b);
-      }
-
-      return result;
-    },
-    buildElementBack(ele, flrNum) {
-      const eleBack = { ...ele };
-      if (ele.backR !== undefined && ele.backC !== undefined) {
-        return {
-          ...eleBack,
-          f: flrNum,
-          c: ele.backC,
-          r: ele.backR,
-        };
-      }
-
-      const backEle = this.pageIdxToBusiIndx(
-        ele,
-        this.rotationAngleType,
-        true,
-        false
-      );
-      return {
-        ...eleBack,
-        f: flrNum,
-        c: backEle.backC,
-        r: backEle.backR,
-      };
-    },
-    procManyRowOrCol(elementIn, itemStatusKey, flrNum) {
-      const rStart = elementIn.rS ?? elementIn.r;
-      const rEnd = elementIn.rE ?? elementIn.r;
-      const cStart = elementIn.cS ?? elementIn.c;
-      const cEnd = elementIn.cE ?? elementIn.c;
-
-      // 遍历行
-      if (rStart <= rEnd) {
-        for (let i = rStart; i <= rEnd; i++) {
-          // 遍历列
-          if (cStart <= cEnd) {
-            for (let j = cStart; j <= cEnd; j++) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          } else {
-            for (let j = cStart; j >= cEnd; j--) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          }
-        }
-      } else {
-        for (let i = rStart; i >= rEnd; i--) {
-          // 遍历列
-          if (cStart <= cEnd) {
-            for (let j = cStart; j <= cEnd; j++) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          } else {
-            for (let j = cStart; j >= cEnd; j--) {
-              const newElementIn = { ...elementIn, r: i, c: j };
-              this.procLiftBackData(itemStatusKey, flrNum, i, newElementIn);
-            }
-          }
-        }
-      }
-    },
-    procLiftBackData(itemStatusKey, flrNum, i, elementIn) {
-      let liftEle = { r: i, c: elementIn.c };
-      const canNotBeClick = i === elementIn.r ? false : true;
-      this.busiIndxToPageIdx(liftEle, this.rotationAngleType);
-      const item = this.getTheItem(liftEle.r, liftEle.c, flrNum);
-      this.itemStsInit(item, itemStatusKey);
-      if (canNotBeClick) {
-        item.canNotBeClick = canNotBeClick;
-      }
-    },
-    initAroundConveyor(dataIn) {
-      if (!dataIn || !dataIn.around) {
-        this.converyAround = [];
-        return;
-      }
-      const chainConveyor = dataIn.around.chainConveyor || [];
-      const rollerConveyor = dataIn.around.rollerConveyor || [];
-      // 合并 chainConveyor 和 rollerConveyor,并去重
-      const aroundConveyor = [];
-      const uniqueSet = new Set();
-      const palletizer = dataIn.around.palletizer || [];
-
-      // 获取最大和最小的 r, c 值
-      let maxR = -Infinity;
-      let maxC = -Infinity;
-      let minR = Infinity;
-      let minC = Infinity;
-
-      const processItem = (item) => {
-        maxR = Math.max(maxR, item.r);
-        maxC = Math.max(maxC, item.c);
-        minR = Math.min(minR, item.r);
-        minC = Math.min(minC, item.c);
-        const key = `${item.r}-${item.c}-${item.f}`;
-        if (!uniqueSet.has(key)) {
-          uniqueSet.add(key);
-          aroundConveyor.push(item);
-        }
-      };
-
-      [...chainConveyor, ...rollerConveyor].forEach(processItem);
-      palletizer.forEach((item) => {
-        if (Array.isArray(item.for2D)) {
-          item.for2D.forEach(processItem);
-        }
-      });
-      // 计算行列范围
-      const rowRange = {
-        start: this.rowStart,
-        end: this.rackRow + this.rowStart - 1,
-      };
-      const colRange = {
-        start: this.colStart,
-        end: this.rackCol + this.colStart - 1,
-      };
-
-      // 计算行列差异
-      const calculateDiff = (min, max, range) => ({
-        min: min - range.start,
-        max: max - range.end,
-      });
-
-      const rowDiff = calculateDiff(minR, maxR, rowRange);
-      const colDiff = calculateDiff(minC, maxC, colRange);
-
-      // 计算需要扩展的行数和列数
-      const calculateExpansion = (diff) =>
-        Math.max(0, -diff.min) + Math.max(0, diff.max);
-
-      this.expandRowNum = calculateExpansion(rowDiff);
-      this.expandColNum = calculateExpansion(colDiff);
-      if (rowDiff.min < 0) {
-        this.expandRowStart = Math.abs(rowDiff.min);
-        this.rowStart = this.rowStart + rowDiff.min;
-      }
-      if (colDiff.min < 0) {
-        // 当小于0时,行列序号集体加
-        this.expandColStart = Math.abs(colDiff.min);
-        this.colStart = this.colStart + colDiff.min;
-      }
-      this.converyAround = aroundConveyor;
-    },
-    itemIsStackable(itemStsCfgInfo) {
-      return (
-        itemStsCfgInfo.itemAttributeType === ITEM_ATTRIBUTE_TYPE.dev ||
-        itemStsCfgInfo.itemAttributeType === ITEM_ATTRIBUTE_TYPE.sysSet
-      );
-    },
-    /**
-     * 将数据值同步到现有页面数据中
-     */
-    itemStsInit(element, itemStatus, theOperingKey) {
-      if (!element) {
-        return;
-      }
-      const stackableItemKey = itemStatus || theOperingKey;
-      const itemStsCfgInfo = this.itemStsMap[stackableItemKey];
-      if (itemStsCfgInfo && this.itemIsStackable(itemStsCfgInfo)) {
-        if (!element.statusList) {
-          element.statusList = [];
-        }
-        if (!itemStatus) {
-          const index = element.statusList.findIndex(
-            (item) => item.status === theOperingKey
-          );
-          if (index > -1) {
-            element.statusList.splice(index, 1);
-          }
-        } else {
-          if (!element.statusList.find((item) => item.status === itemStatus)) {
-            element.statusList.push({ status: itemStatus });
-          }
-        }
-      } else {
-        const stsInfo = this.getItemStsInfo(itemStatus, element.type);
-        element["status"] = stsInfo.status;
-        element["fillColor"] =
-          stsInfo.fillColor || this.scssVariables.gridFillColor;
-        element["borderColor"] =
-          stsInfo.borderColor || this.scssVariables.gridBorderColor;
-        element["lineWidth"] =
-          stsInfo.lineWidth || this.scssVariables.gridLineWidth;
-      }
-    },
-    /**
-     * 页面下标转业务下标【页面坐标原点在左上角,实际二维码坐标[坐标原点据旋转]】
-     *
-     * 1-页面坐标考转为二维码坐标[坐标原点据旋转]。
-     * 2-将不带预留位坐标[即现场的物理视觉坐标]转为业务坐标[二维码(从0开始)]
-     *rotationAngleType=0【未旋转】时实际二维码坐标原点在左下
-     *rotationAngleType=1【旋转90】时实际二维码坐标原点在左上
-     * rotationAngleType=2【旋转180】时实际二维码坐标原点在右上
-     * rotationAngleType=3【旋转270】时实际二维码坐标原点在右下
-     *  @param {*} item
-     * @returns
-     */
-    pageIdxToBusiIndx(
-      item,
-      rotationAngleType = 0,
-      isNotChgEle = false,
-      isLog = false
-    ) {
-      const rIsNum = typeof item.r === "number";
-      const cIsNum = typeof item.c === "number";
-      if (!rIsNum && !cIsNum) {
-        return;
-      }
-      const pageR = item.r;
-      const pageC = item.c;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "正在处理-页面坐标 c:",
-          pageC,
-          "r:",
-          pageR
-        );
-      }
-      const { rotatedY_R, rotatedX_C } = this.rotateCoordinates(
-        pageR,
-        pageC,
-        rotationAngleType,
-        "toBack"
-      );
-      const isNumRoR = typeof rotatedY_R === "number";
-      const isNumRoC = typeof rotatedX_C === "number";
-      const backR = isNumRoR && this.transformIndex(rotatedY_R, "r", "toBack");
-      const backC = isNumRoC && this.transformIndex(rotatedX_C, "c", "toBack");
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "加上预留位的坐标 c:",
-          backC,
-          "r:",
-          backR
-        );
-      }
-      item.backR = backR;
-      item.backC = backC;
-      if (isNotChgEle) {
-        return { backR, backC };
-      }
-      item.r = backR;
-      item.c = backC;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "处理完成-业务坐标 c:",
-          item.c,
-          "r:",
-          item.r
-        );
-      }
-      return item;
-    },
-    /**
-     * 业务下标转页面下标【页面坐标原点在左上角,实际二维码坐标原点在左下,旋转后实际二维码坐标原点发生改变】
-     * 后台上传数据时
-     * 1-将业务坐标转为不带预留位坐标[即现场的物理视觉坐标]
-     * 2-根据二维码坐标原点为页面坐标。
-     * rotationAngleType=0【未旋转】时实际二维码坐标原点在左下
-     *rotationAngleType=1【旋转90】时实际二维码坐标原点在左上
-     * rotationAngleType=2【旋转180】时实际二维码坐标原点在右上
-     * rotationAngleType=3【旋转270】时实际二维码坐标原点在右下
-     * @param {*} itemBusi 后台数据
-     * @returns
-     */
-    busiIndxToPageIdx(itemBusi, rotationAngleType = 0, isLog = false) {
-      const rIsNum = typeof itemBusi.r === "number";
-      const cIsNum = typeof itemBusi.c === "number";
-      if (!rIsNum && !cIsNum) {
-        return;
-      }
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "正在处理-业务坐标 c:",
-          itemBusi.c,
-          "r:",
-          itemBusi.r
-        );
-      }
-      const pageR = rIsNum && this.transformIndex(itemBusi.r, "r", "toPage");
-      const pageC = cIsNum && this.transformIndex(itemBusi.c, "c", "toPage");
-      if (isLog) {
-        console.log("去除预留的坐标c:", pageC, "r:", pageR);
-      }
-      const { rotatedY_R, rotatedX_C } = this.rotateCoordinates(
-        pageR,
-        pageC,
-        rotationAngleType,
-        "toPage",
-        isLog
-      );
-      const finalR = rotatedY_R;
-      const finalC = rotatedX_C;
-      itemBusi.r = finalR;
-      itemBusi.c = finalC;
-      itemBusi.pageR = finalR;
-      itemBusi.pageC = finalC;
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          "处理完成-页面坐标 c:",
-          itemBusi.c,
-          "r:",
-          itemBusi.r
-        );
-      }
-      return itemBusi;
-    },
-    /**
-     * 在计算反转的坐标时,需要区分是后台数据,还是前台数据在反转
-     * @param oriR
-     * @param oriC
-     * @param rotationAngleType
-     * @param rotateC_Road
-     * @param rotateR_good
-     */
-    rotateCoordinates(r, c, rotationAngleType, dir = "toPage", isLog) {
-      const rowNum = dir === "toPage" ? this.busiRowOri : this.pageRow;
-      const colNum = dir === "toPage" ? this.busiColOri : this.pageCol;
-      const reverseR = this.calcRevNum(rowNum - 1, r);
-      const reverseC = this.calcRevNum(colNum - 1, c);
-      if (isLog) {
-        console.log(
-          "坐标c:",
-          c,
-          "r:",
-          r,
-          "反转后对应的坐标c:",
-          reverseC,
-          "r:",
-          reverseR
-        );
-      }
-      let rotatedY_R, rotatedX_C;
-      switch (rotationAngleType) {
-        case 0: // 现实坐标不动(左下角坐标原点)。页面X轴(c)取c,页面Y轴(r)取reverseR
-          rotatedY_R = reverseR;
-          rotatedX_C = c;
-          break;
-        case 1: // 现实坐标原点在左上。页面X轴(c)取r,页面Y轴(r)取c
-          rotatedY_R = c;
-          rotatedX_C = r;
-          break;
-        case 2: // 现实坐标原点在右上。页面X轴(c)取reverseC,页面Y轴(r)取r
-          rotatedY_R = r;
-          rotatedX_C = reverseC;
-          break;
-        case 3: // 现实坐标在右下。页面X轴(c)取reverseC,页面Y轴(r)取reverseR
-          rotatedY_R = reverseC;
-          rotatedX_C = reverseR;
-          break;
-        default: // 同 case 0
-          rotatedY_R = reverseR;
-          rotatedX_C = c;
-      }
-      if (isLog) {
-        console.log(
-          "rotationAngleType:",
-          rotationAngleType,
-          dir === "toPage" ? "业务c:" : "页面c:",
-          c,
-          "r:",
-          r,
-          dir === "toPage" ? "页面c:" : "业务c:",
-          reverseC,
-          "r:",
-          reverseR
-        );
-      }
-      return { rotatedY_R, rotatedX_C };
-    },
-    transformIndex(idx, type = "r", direction = "toPage") {
-      const startValue = type === "r" ? this.rowStart : this.colStart;
-      const numericIdx = Number(idx);
-      if (isNaN(numericIdx)) {
-        throw new Error("idx must be a number or convertible to a number");
-      }
-      return direction === "toPage"
-        ? numericIdx - startValue
-        : numericIdx + startValue;
-    },
-    /**
-     *
-     * 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17反转位置17,16,15,14...
-     * 根据起始位置和总数计算反转后的位置
-     */
-    calcRevNum(row, idx) {
-      const reverseNumber = row - idx;
-      return reverseNumber;
-    },
-    /**
-     *
-     * 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17反转位置17,16,15,14...
-     * 根据起始位置和总数计算反转后的位置
-     */
-    consiPIdxSt(num, startNum, offset) {
-      if (!startNum || startNum === 0) {
-        return num;
-      }
-      return num + offset;
-    },
-    isNotDo() {
-      if (!this.rackRow || !this.rackCol || !this.pageRow || !this.pageCol) {
-        return true;
-      }
-      return false;
-    },
-    isHorizontal() {
-      return this.orientationRacking === COMMON_CONST.MAIN_TRACK_DIR.HORIZONTAL;
-    },
-    assignment(data) {
-      if (!data) {
-        this.resetData();
-        return;
-      }
-      this.wareHouseId = data.id;
-      this.orientationRacking =
-        data.forward || COMMON_CONST.MAIN_TRACK_DIR.DEFAULT;
-      // this.rackRow = this.isHorizontal() ? data.row : data.col
-      // this.rackCol = this.isHorizontal() ? data.col : data.row
-      this.rackRow = data.row;
-      this.rackCol = data.col;
-      if (!this.rackRow || !this.rackCol) {
-        this.resetData();
-        return;
-      }
-      this.front = data.front;
-      this.right = data.right;
-      this.left = data.left;
-      this.back = data.back;
-      /* 页面总楼层 */
-      this.totalFlr = data.floor;
-      this.rowStart = data.rowStart || 0;
-      this.colStart = data.colStart || 0;
-      this.rowStartOri = data.rowStart || 0;
-      this.colStartOri = data.colStart || 0;
-      if (this.isCfgSty) {
-        this.rotationAngleType = data.rotation || 0;
-        this.aroundInfo = data.around || {};
-        this.procRowColStartWhenCfg(data);
-      } else {
-        const storeRotationType = localStorage.getItem("rotationAngleType");
-        const storeNum =
-          (storeRotationType !== undefined && storeRotationType !== null
-            ? storeRotationType
-            : data.rotation || 0) || 0;
-        this.rotationAngleType = parseInt(storeNum);
-      }
-    },
-    procRowColStartWhenCfg(data) {
-      const { down = 0, left = 0, up = 0, right = 0 } = this.aroundInfo || {};
-      switch (this.rotationAngleType) {
-        case 0: // 原始方向,左下角为原点
-          this.rowStart = data.rowStart - down;
-          this.colStart = data.colStart - left;
-          this.rowStartOri = data.rowStart - down;
-          this.colStartOri = data.colStart - left;
-          break;
-        case 1: // 顺时针90度,左上角为原点
-          this.rowStart = data.rowStart - left;
-          this.colStart = data.colStart - up;
-          this.rowStartOri = data.rowStart - left;
-          this.colStartOri = data.colStart - up;
-          break;
-        case 2: // 顺时针180度,右上角为原点
-          this.rowStart = data.rowStart - up;
-          this.colStart = data.colStart - right;
-          this.rowStartOri = data.rowStart - up;
-          this.colStartOri = data.colStart - right;
-          break;
-        case 3: // 顺时针270度,右下角为原点
-          this.rowStart = data.rowStart - right;
-          this.colStart = data.colStart - down;
-          this.rowStartOri = data.rowStart - right;
-          this.colStartOri = data.colStart - down;
-          break;
-      }
-    },
-    mesDo(wsData) {
-      if (!wsData) {
-        return;
-      }
-      if (!this.pageFloorGridDataObj) {
-        return "isNotReady";
-      }
-      this.setIsAni(true);
-      let dataIn;
-      if (typeof wsData === "string") {
-        dataIn = JSON.parse(wsData);
-      } else {
-        dataIn = JSON.parse(JSON.stringify(wsData));
-      }
-      const { data, action } = dataIn;
-      this.animationProc(action, data);
-      this.drawCanvas();
-    },
-    animationProc(action, data) {
-      if (action === "init") {
-        if (data && data.cells) {
-          this.cellsStsInit(data.cells);
-        }
-      } else if (action === "update") {
-        if (data && data.cells) {
-          this.cellsStsUpdate(data.cells);
-        }
-      }
-
-      // 设置车辆的基础数据到视图数据中
-      if (data && data.shuttle) {
-        this.shuttleInfoRefresh(data.shuttle);
-      }
-      if (data && data.plc_conveyor) {
-        this.conveyorInfoUp(data.plc_conveyor);
-      }
-    },
-    conveyorInfoUp(conveyorData) {
-      // 将this.conveyorAroundMap中所有值设置为0
-      Object.keys(this.conveyorAroundMap).forEach((key) => {
-        this.conveyorAroundMap[key] = 0;
-      });
-      for (let i = 0; i < conveyorData.length; i++) {
-        const conveyor = conveyorData[i];
-        const idKey = this.idKey(conveyor);
-        let item = (conveyor.items && conveyor.items[0]) || 0;
-        item = parseInt(item);
-        if (!item) {
-          item = (conveyor.items && conveyor.items[1]) || 0;
-        }
-        this.conveyorAroundMap[idKey] = parseInt(item);
-      }
-    },
-    idKey(ele) {
-      return `${ele.f}${COMMON_CONST.idSep}${ele.c}${COMMON_CONST.idSep}${ele.r}`;
-    },
-    /**
-     * 存储每次上发得车辆数据
-     * @param {*} shuttleData 结构{sn1:{},sn2:{},sn3:{},}
-     */
-    shuttleInfoRefresh(shuttleData) {
-      if (!shuttleData || shuttleData.length === 0) {
-        return;
-      }
-      for (let i = 0; i < shuttleData.length; i++) {
-        const data = shuttleData[i];
-        const shuttleKey = data.sid;
-        if (!this.shuttleVisObj[shuttleKey]) {
-          this.shuttleVisObj[shuttleKey] = {};
-        }
-        this.shuttleVisObj[shuttleKey]["baseInfo"] = data;
-      }
-    },
-    // 初始化货位所有状态为指定状态,直接修改floorGridDoubleArr数据
-    /**
-     *{
-  "data": {
-    "1"-层: {
-      "4"-列: [0-行, 1, 9, 0, 1, 9, 0, 1],
-      "5": [0, 1, 9, 0, 1, 9, 0, 1]
-    },
-    "2": {
-      "6": [0, 1, 9, 0, 1, 9, 0, 1],
-      "7": [0, 1, 9, 0, 1, 9, 0, 1]
-    }
-  }
-  }
-     *
-     */
-    cellsStsInit(cells) {
-      this.goodsVisObj = {};
-      if (!cells || !this.pageFloorGridDataObj) {
-        return;
-      }
-
-      for (const flr in cells) {
-        // if (!this.pageFloorGridDataObj[flr]) {
-        //   continue
-        // }
-        const cellsFloorSts = cells[flr];
-        const cols = Object.keys(cellsFloorSts);
-        if (!cols || cols.length < 1) {
-          return;
-        }
-
-        cols.forEach((colKey) => {
-          const dataArr = cellsFloorSts[colKey];
-          const colNum = Number(colKey);
-
-          for (let rowNum = 0; rowNum < dataArr.length; rowNum++) {
-            if (dataArr[rowNum]) {
-              // 计算key值,格式为"1-1-1"
-              const addrKey = `${flr}${COMMON_CONST.idSep}${colNum}${COMMON_CONST.idSep}${rowNum}`;
-              this.goodsVisObj[addrKey] = dataArr[rowNum];
-            }
-          }
-        });
-      }
-    },
-    cellsStsUpdate(cells) {
-      if (!cells || !this.pageFloorGridDataObj) {
-        return;
-      }
-      cells.forEach((cell) => {
-        const idKey = `${cell.f}${COMMON_CONST.idSep}${cell.c}${COMMON_CONST.idSep}${cell.r}`;
-        this.goodsVisObj[idKey] = cell.items;
-      });
-    },
-    initFloorGridData(pageFloorGridDataObj, isInitAllFlrData) {
-      if (!this.totalFlr) {
-        return;
-      }
-      pageFloorGridDataObj = {};
-      for (let i = 1; i <= this.totalFlr; i++) {
-        if (!this.isShowAllFlr && this.operFloor !== i && !isInitAllFlrData) {
-          continue;
-        }
-        pageFloorGridDataObj[i] = this.initGridDoubleArr([], i);
-      }
-      return pageFloorGridDataObj;
-    },
-    getTheItem(r, c, f) {
-      return (
-        this.pageFloorGridDataObj[f] &&
-        this.pageFloorGridDataObj[f][r] &&
-        this.pageFloorGridDataObj[f][r][c]
-      );
-    },
-    getTheItemStore(r, c, f) {
-      return (
-        this.storePageFloorGridDataObj[f] &&
-        this.storePageFloorGridDataObj[f][r] &&
-        this.storePageFloorGridDataObj[f][r][c]
-      );
-    },
-    resetPageRowCol() {
-      const rowNum = this.isCfgSty
-        ? (this.aroundInfo.up || 0) + (this.aroundInfo.down || 0)
-        : this.expandRowNum;
-      const colNum = this.isCfgSty
-        ? (this.aroundInfo.left || 0) + (this.aroundInfo.right || 0)
-        : this.expandColNum;
-      this.busiRowOri = this.rackRow + rowNum;
-      this.busiColOri = this.rackCol + colNum;
-      if (this.rotationAngleType === 0 || this.rotationAngleType === 2) {
-        this.pageRow = this.rackRow + rowNum;
-        this.pageCol = this.rackCol + colNum;
-      }
-      if (this.rotationAngleType === 1 || this.rotationAngleType === 3) {
-        this.pageRow = this.rackCol + colNum;
-        this.pageCol = this.rackRow + rowNum;
-      }
-    },
-    initCfg(data) {
-      this.initAroundConveyor(JSON.parse(JSON.stringify(data)));
-      this.resetPageRowCol();
-      if (this.isNotDo()) {
-        return;
-      }
-      this.calculateBoundInfo(this.rotationAngleType, this.isCfgSty);
-      this.refreshCanvasSize();
-    },
-    refreshCanvasSize() {
-      const containerWidth =
-        this.containerWidth - getCFG("svg").cellSty.rackIdxNumOffsetLen;
-      const containerHeight =
-        this.containerHeight - getCFG("svg").cellSty.rackIdxNumOffsetLen;
-      this.thetaInRadians = (this.includedAngle * Math.PI) / 180;
-      const mathSin = Math.sin(this.thetaInRadians);
-      const mathCos = Math.cos(this.thetaInRadians);
-      const mathTan = Math.tan(this.thetaInRadians);
-      const horizontalCellWidth = containerWidth / this.pageCol; // horizontalCellWidth为横向四边形占用的总空间
-      // const pageFlr = !this.isShowAllFlr ? 1 : this.totalFlr;
-      const pageFlr = 1;
-      const verticalCellHeight =
-        (containerHeight - (pageFlr - 1) * this.flrVehSpace) /
-        (this.pageRow * pageFlr); //verticalCellHeight为竖向四边形占用的总空间
-      const verticalEdgeLen = verticalCellHeight / mathSin;
-      let cellLen = Math.min(verticalEdgeLen, horizontalCellWidth);
-      if (cellLen < 8) {
-        cellLen = 8;
-      }
-      if (cellLen > 40) {
-        cellLen = 40;
-      }
-      // 使用余弦函数偏移量
-      let offset = !this.isShowAllFlr ? 0 : cellLen * mathCos;
-      let isComNum = false;
-      while (offset * this.pageRow + cellLen * this.pageCol > containerWidth) {
-        cellLen -= 0.3;
-        isComNum = true;
-        // 使用正弦函数计算偏移量
-        offset = cellLen * mathCos;
-        if (cellLen < 10) {
-          break;
-        }
-      }
-      if (isComNum) {
-        cellLen += 0.3;
-      }
-      this.cellLen = cellLen;
-      this.cellWidth = cellLen;
-      // 根据 cellWidth  cellLen 重新计算参数
-      this.verticalCellHeight = this.cellLen * mathSin;
-      // 判断倾斜角度是否为90的倍数
-      const isRightAngle = this.includedAngle % 90 === 0;
-      // 向右倾斜
-      this.horizontalPointOffset = isRightAngle ? 0 : -this.cellLen * mathCos;
-
-      // 2.1 计算this.flrVehTotalLen值
-      this.flrVehTotalLen = this.verticalCellHeight * this.pageRow;
-
-      // 2.2 计算this.flrHorizontalTotalHangLen
-
-      this.flrHorizontalTotalHangLen = !this.isShowAllFlr
-        ? 0
-        : this.flrVehTotalLen / mathTan;
-      // 2.3 计算this.flrHorizontalLen
-      this.flrHorizontalLen = this.cellWidth * this.pageCol;
-
-      // 2.4 计算this.flrHorizontalTotalLen
-      this.flrHorizontalTotalLen =
-        this.flrHorizontalLen + this.flrHorizontalTotalHangLen;
-
-      // 2.5 计算this.totalHorizontalFlrPer
-      // let flrPer = Math.floor(
-      //   (containerWidth + this.flrHorizontalSpace) / this.flrHorizontalTotalLen
-      // );
-      // flrPer = flrPer || 1;
-      // this.totalHorizontalFlrPer = !this.isShowAllFlr ? 1 : flrPer;
-      this.totalHorizontalFlrPer = 1;
-      const { currentPageFloorNum } = this.calcCurPageFloor(
-        this.totalFlr,
-        this.totalHorizontalFlrPer,
-        "tTOb"
-      );
-      this.totalPageFlr = !this.isShowAllFlr ? 1 : currentPageFloorNum;
-      // 3-根据最终的 cellWidth 和 cellLen 计算画布大小
-      this.canvasWidth =
-        containerWidth + getCFG("svg").cellSty.rackIdxNumOffsetLen;
-      this.canvasHeight =
-        containerHeight + getCFG("svg").cellSty.rackIdxNumOffsetLen;
-    },
-    /**
-     *  初始化 rowOffsetX 和 colOffsetY
-     *
-     */
-    initCfgBefRender() {
-      const lenInfo = this.getCavasAreaLen(this.pageFloorGridDataObj);
-
-      // 根据是否显示货架索引号来决定是否添加偏移量
-      const indexOffset = this.isShowRackIndxNum
-        ? getCFG("svg").cellSty.rackIdxNumOffsetLen
-        : 0;
-      const renderTotalWidth = lenInfo.widthX + indexOffset;
-
-      // 计算渲染总高度
-      const renderTotalHeight =
-        this.pageRow * this.verticalCellHeight * this.totalPageFlr +
-        (this.totalPageFlr - 1) * this.flrVehSpace;
-
-      // 计算倾斜导致的左侧偏移
-      const inclineLeftX = lenInfo.minX < 0 ? Math.abs(lenInfo.minX) : 0;
-
-      // 计算X轴偏移量
-      let XOffset = 0;
-      if (this.canvasWidth > renderTotalWidth) {
-        XOffset = (this.canvasWidth - renderTotalWidth) / 2;
-      } else {
-        this.canvasWidth = renderTotalWidth;
-      }
-
-      // 计算Y轴偏移量
-      let YOffset = 0;
-      if (this.canvasHeight > renderTotalHeight) {
-        YOffset = (this.canvasHeight - renderTotalHeight) / 2;
-      } else {
-        this.canvasHeight = renderTotalHeight;
-      }
-
-      // 设置最终的偏移量,根据是否显示索引号来决定是否添加indexOffset
-      this.warehousPageCfg.rowOffsetX =
-        inclineLeftX + XOffset + (this.isShowRackIndxNum ? indexOffset : 0);
-      this.warehousPageCfg.colOffsetY =
-        YOffset + (this.isShowRackIndxNum ? indexOffset : 0);
-      this.renderTotalWidth = this.canvasWidth;
-      this.renderTotalHeight = this.canvasHeight;
-      if (this.renderer) {
-        this.renderer.updateSize();
-        // 尝试恢复保存的视觉状态
-        if (!this.renderer.loadViewState(this.wareHouseId)) {
-          // 如果没有保存的状态或状态已过期,使用默认视图
-          this.renderer.resetTransform();
-        }
-      }
-    },
-    /**
-     * pageFloorGridDataObj的数据结构为{层:[[ele,ele2],[],[]]}
-     * ele的结构为{type: 'gridUnit', status: 'default', fillColor: '#fff', borderColor: '#000', lineWidth: 1, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0, x4: 0, y4: 0}
-     * 循环每一层数据,取出第一行第一个元素、最后一个元素;最后一行第一个元素、最后一个元素,计算出最大x和最小x,最大y和最小y
-     * 根据最大x和最小x,最大y和最小y计算出画布的宽和高
-     */
-    getCavasAreaLen(pageFloorGridDataObj) {
-      // 初始化最大和最小 x、y 值
-      let minX = Infinity;
-      let maxX = -Infinity;
-      let minY = Infinity;
-      let maxY = -Infinity;
-
-      // 遍历每一层的数据
-      for (const floorData of Object.values(pageFloorGridDataObj)) {
-        // 获取第一行和最后一行的元素
-        const firstRowFirstEle = floorData[0][0];
-        const firstRowLastEle = floorData[0][floorData[0].length - 1];
-        const lastRowFirstEle = floorData[floorData.length - 1][0];
-        const lastRowLastEle =
-          floorData[floorData.length - 1][
-            floorData[floorData.length - 1].length - 1
-          ];
-
-        // 更新最大和最小 x、y 值
-        minX = Math.min(
-          minX,
-          firstRowFirstEle.x1,
-          firstRowLastEle.x2,
-          lastRowFirstEle.x1,
-          lastRowLastEle.x2
-        );
-        maxX = Math.max(
-          maxX,
-          firstRowFirstEle.x1,
-          firstRowLastEle.x2,
-          lastRowFirstEle.x1,
-          lastRowLastEle.x2
-        );
-        minY = Math.min(
-          minY,
-          firstRowFirstEle.y1,
-          firstRowLastEle.y2,
-          lastRowFirstEle.y1,
-          lastRowLastEle.y2
-        );
-        maxY = Math.max(
-          maxY,
-          firstRowFirstEle.y1,
-          firstRowLastEle.y2,
-          lastRowFirstEle.y1,
-          lastRowLastEle.y2
-        );
-      }
-
-      // 计算画布的宽度和高度
-      const canvasWidth = maxX - minX;
-      const canvasHeight = maxY - minY;
-
-      return { widthX: canvasWidth, heightY: canvasHeight, minX, minY };
-    },
-    initGridDoubleArr(gridDoubleArr, curFlrNum) {
-      const { currentPageFloorNum, positionInPageFloorNum } =
-        this.calcCurPageFloor(curFlrNum, this.totalHorizontalFlrPer);
-      for (let rowIndex = 0; rowIndex < this.pageRow; rowIndex++) {
-        const row = [];
-        for (let colIndex = 0; colIndex < this.pageCol; colIndex++) {
-          const itemType = this.getItemType(rowIndex, colIndex);
-          const ele = {
-            rowIndex, //页面行
-            colIndex, //页面列
-            flrNum: curFlrNum, //货架层
-            r: rowIndex, //页面行
-            c: colIndex, //页面列
-            pageR: rowIndex, //页面行
-            pageC: colIndex, //页面列
-            type: itemType, //LOCTYPE元素的基础位置类型
-            status: "", //元素基础状态
-            statusList: [], //元素可叠加状态列表
-            fillColor: "",
-            borderColor: "",
-            lineWidth: 0,
-          };
-          const pos = this.getCellPos(
-            rowIndex,
-            colIndex,
-            currentPageFloorNum,
-            positionInPageFloorNum
-          );
-          Object.assign(ele, pos);
-          this.itemStsInit(ele, "");
-
-          row.push(ele);
-        }
-        gridDoubleArr.push(row);
-      }
-      return gridDoubleArr;
-    },
-    /**
-     * currentPageFloorNum 处于页面的哪一层
-     * positionInPageFloorNum处于具体层的具体行号
-     * 根据rcf计算位置信息
-     */
-    getCellPos(
-      rowIndex,
-      colIndex,
-      currentPageFloorNum,
-      positionInPageFloorNum
-    ) {
-      const { x1, y1 } = this.calcPoint1(
-        rowIndex,
-        colIndex,
-        currentPageFloorNum,
-        positionInPageFloorNum
-      );
-      const x2 = x1 + this.cellWidth;
-      const x3 = x2 + this.horizontalPointOffset;
-      const x4 = x3 - this.cellWidth;
-      const y2 = y1;
-      const y3 = y2 + this.verticalCellHeight;
-      const y4 = y3;
-      return { x1, y1, x2, y2, x3, y3, x4, y4 };
-    },
-    calcCurPageFloor(curFlrNum, totalHorizontalFlrPer, flrFromSty) {
-      const finalFlrFromSty = flrFromSty || this.flrFromSty;
-      // 确保curFlrNum和totalHorizontalFlrPer都是有效的数字
-      if (
-        typeof curFlrNum !== "number" ||
-        typeof totalHorizontalFlrPer !== "number" ||
-        totalHorizontalFlrPer <= 0
-      ) {
-        console.error("Invalid input");
-        return;
-      }
-      if (!this.isShowAllFlr) {
-        return {
-          currentPageFloorNum: 1,
-          positionInPageFloorNum: 1,
-        };
-      }
-      // 计算当前编号货架层属于第几层
-      let currentPageFloorNum = Math.ceil(curFlrNum / totalHorizontalFlrPer);
-      // if (this.flrFromSty === 'bTOt') {
-      //   currentPageFloorNum =
-      //     this.totalPageFlr - Math.ceil(curFlrNum / totalHorizontalFlrPer) + 1 // 从下往上计算层数
-      // } else {
-      //   currentPageFloorNum = Math.ceil(curFlrNum / totalHorizontalFlrPer) // 从上往下计算层数
-      // }
-
-      // 计算当前货架层是所在层中的第几块
-      const positionInPageFloorNum =
-        curFlrNum % totalHorizontalFlrPer === 0
-          ? totalHorizontalFlrPer
-          : curFlrNum % totalHorizontalFlrPer;
-      if (finalFlrFromSty !== "bTOt") {
-        // 返回当前层及该层中的位置
-        return {
-          currentPageFloorNum,
-          positionInPageFloorNum,
-        };
-      }
-      currentPageFloorNum = this.totalPageFlr - currentPageFloorNum + 1;
-      return {
-        currentPageFloorNum,
-        positionInPageFloorNum,
-      };
-    },
-    /**
-     * rowIndex,行序号
-      colIndex,列序号
-      currentPageFloorNum,页面上属于第几行
-      positionInPageFloorNum 在页面行中属于第几个
-     */
-    calcPoint1(
-      rowIndex,
-      colIndex,
-      currentPageFloorNum,
-      positionInPageFloorNum
-    ) {
-      const flrVehTotalLen =
-        this.verticalCellHeight * (this.pageRow - rowIndex);
-      const flrHorizontalTotalHangLen =
-        flrVehTotalLen / Math.tan(this.thetaInRadians);
-      const x1 =
-        (positionInPageFloorNum - 1) *
-          (this.flrHorizontalTotalLen + this.flrHorizontalSpace) +
-        flrHorizontalTotalHangLen +
-        colIndex * this.cellWidth;
-      const y1 =
-        (currentPageFloorNum - 1) * (this.flrVehTotalLen + this.flrVehSpace) +
-        rowIndex * this.verticalCellHeight;
-      return { x1, y1 };
-    },
-    /**
-     * 1-[0,0][this.rackCol+this.expandColStart,0][this.rackCol+this.expandColStart,this.rackRow+this.expandRowStart][0,this.rackRow+this.expandRowStart]转换到页面后货架边界的四个顶点。
-     * 2-确认rowIndexIn colIndexIn是否在四个顶点范围内
-     * @param rowIndexIn 页面序号
-     * @param colIndexIn 页面序号
-     * @param rotationAngleType
-     */
-    getItemType(rowIndexIn, colIndexIn) {
-      const minR = this.rackBoundInfo.minR;
-      const maxR = this.rackBoundInfo.maxR;
-      const minC = this.rackBoundInfo.minC;
-      const maxC = this.rackBoundInfo.maxC;
-      if (!this.isCfgSty) {
-        if (
-          rowIndexIn >= minR &&
-          rowIndexIn <= maxR &&
-          colIndexIn >= minC &&
-          colIndexIn <= maxC
-        ) {
-          return LOCTYPE.rack;
-        } else {
-          return LOCTYPE.default;
-        }
-      }
-      // 判断是否在货架区域内
-      if (
-        rowIndexIn >= minR &&
-        rowIndexIn <= maxR &&
-        colIndexIn >= minC &&
-        colIndexIn <= maxC
-      ) {
-        return LOCTYPE.rack;
-      }
-      const {
-        minR: aroundMinR,
-        maxR: aroundMaxR,
-        minC: aroundMinC,
-        maxC: aroundMaxC,
-      } = this.aroundBoundInfo;
-      // 判断是否在外围区域内
-      if (
-        rowIndexIn >= aroundMinR &&
-        rowIndexIn <= aroundMaxR &&
-        colIndexIn >= aroundMinC &&
-        colIndexIn <= aroundMaxC
-      ) {
-        return LOCTYPE.around;
-      }
-      return LOCTYPE.default;
-    },
-    calculateBoundInfo(rotationAngleType, includeAround) {
-      const around = this.aroundInfo || {};
-      const { up = 0, down = 0, left = 0, right = 0 } = around;
-
-      const innerOffset = includeAround ? { r: down, c: left } : { r: 0, c: 0 };
-      const outerOffset = includeAround
-        ? { r: down + up, c: left + right }
-        : { r: 0, c: 0 };
-
-      const vertices = this.getVertices(innerOffset, outerOffset);
-
-      vertices.forEach((vertex) => {
-        this.busiIndxToPageIdx(vertex, rotationAngleType);
-      });
-
-      const rackBoundInfo = this.getBoundInfo(vertices.slice(0, 4));
-      const aroundBoundInfo = includeAround
-        ? this.getBoundInfo(vertices.slice(4))
-        : null;
-
-      this.rackBoundInfo = rackBoundInfo;
-      if (includeAround) {
-        this.aroundBoundInfo = aroundBoundInfo;
-      }
-
-      return includeAround ? aroundBoundInfo : rackBoundInfo;
-    },
-
-    getVertices(innerOffset, outerOffset) {
-      const innerVertex1 = {
-        r: this.rowStartOri + innerOffset.r,
-        c: this.colStartOri + innerOffset.c,
-      };
-      const innerVertex2 = {
-        r: this.rackRow + this.rowStartOri + innerOffset.r - 1,
-        c: this.colStartOri + innerOffset.c,
-      };
-      const innerVertex3 = {
-        r: this.rackRow + this.rowStartOri + innerOffset.r - 1,
-        c: this.rackCol + this.colStartOri + innerOffset.c - 1,
-      };
-      const innerVertex4 = {
-        r: this.rowStartOri + innerOffset.r,
-        c: this.rackCol + this.colStartOri + innerOffset.c - 1,
-      };
-
-      const outerVertex1 = { r: this.rowStartOri, c: this.colStartOri };
-      const outerVertex2 = {
-        r: this.rackRow + this.rowStartOri + outerOffset.r - 1,
-        c: this.colStartOri,
-      };
-      const outerVertex3 = {
-        r: this.rackRow + this.rowStartOri + outerOffset.r - 1,
-        c: this.rackCol + this.colStartOri + outerOffset.c - 1,
-      };
-      const outerVertex4 = {
-        r: this.rowStartOri,
-        c: this.rackCol + this.colStartOri + outerOffset.c - 1,
-      };
-
-      return [
-        innerVertex1,
-        innerVertex2,
-        innerVertex3,
-        innerVertex4,
-        outerVertex1,
-        outerVertex2,
-        outerVertex3,
-        outerVertex4,
-      ];
-    },
-
-    getBoundInfo(vertices) {
-      const minR = Math.min(...vertices.map((v) => v.r));
-      const maxR = Math.max(...vertices.map((v) => v.r));
-      const minC = Math.min(...vertices.map((v) => v.c));
-      const maxC = Math.max(...vertices.map((v) => v.c));
-
-      return { minR, maxR, minC, maxC };
-    },
-    /**
-     * 如果itemStatus为空,则根据LOCTYPE(type)获取itemStatus
-     * @param {*} itemStatus
-     * @param {*} type
-     * @returns
-     */
-    getItemStsInfo(itemStatus, type) {
-      if (!itemStatus) {
-        if (type === LOCTYPE.rack) {
-          itemStatus = ITEMSTATUS.storageLoc;
-        } else {
-          itemStatus = type;
-        }
-      }
-      const defaultStyle = this.itemStsMap[ITEMSTATUS.default].sty;
-      const itemStyle = this.itemStsMap[itemStatus]?.sty || {};
-
-      return {
-        status: itemStatus,
-        fillColor: itemStyle.fillColor || defaultStyle.fillColor,
-        borderColor: itemStyle.borderColor || defaultStyle.borderColor,
-        lineWidth: itemStyle.lineWidth || defaultStyle.lineWidth,
-      };
-    },
-    updateMapTransform() {
-      this.ctx.setTransform(
-        this.scale,
-        0,
-        0,
-        this.scale,
-        this.offset.x,
-        this.offset.y
-      );
-    },
-    /**
-     * 设置是否展示,匹配跟3D一起展示的情景
-     */
-    setIsShowing(isShow) {
-      this.isShowing = isShow;
-      if (this.isShowing) {
-        this.aniDraw();
-      } else {
-        this.stopAniDraw();
-      }
-    },
-    drawCanvas() {
-      if (!this.renderer) {
-        console.error("Renderer not initialized");
-        return;
-      }
-      this.renderer.drawAct();
-    },
-    getRackIndxNum(e) {
-      const canvas = this.$refs.canvas;
-      const rect = canvas.getBoundingClientRect();
-
-      // 获取鼠标点击的坐标
-      let x = (e.clientX - rect.left - this.offset.x) / this.scale;
-      let y = (e.clientY - rect.top - this.offset.y) / this.scale;
-
-      const SIDE_PADDING = getCFG("svg").cellSty.idxNumSidePadding || 4;
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-
-      if (!firstFloorData || firstFloorData.length === 0) {
-        return null;
-      }
-
-      // 检查是否点击了行号区域
-      if (firstFloorData[0] && firstFloorData[0][0]) {
-        for (let rowIndex = 0; rowIndex < firstFloorData.length; rowIndex++) {
-          if (firstFloorData[rowIndex] && firstFloorData[rowIndex][0]) {
-            const firstCell = firstFloorData[rowIndex][0];
-            const { x1, y1, y4 } = this.calculateCoordinates(firstCell);
-            const centerY = y1 + (y4 - y1) / 2;
-
-            // 检查点击是否在行号区域内
-            if (
-              x >= x1 - getCFG("svg").cellSty.rackIdxNumOffsetLen &&
-              x <=
-                x1 -
-                  getCFG("svg").cellSty.rackIdxNumOffsetLen +
-                  SIDE_PADDING * 4 &&
-              y >= centerY - 10 &&
-              y <= centerY + 10
-            ) {
-              // 转换回业务索引
-              // const backEle = this.pageIdxToBusiIndx(
-              //   { r: rowIndex, c: 0 },
-              //   this.rotationAngleType,
-              //   true,
-              //   false
-              // )
-              return {
-                type: "row",
-                index: rowIndex,
-              };
-            }
-          }
-        }
-      }
-
-      // 检查是否点击了列号区域
-      if (firstFloorData[0]) {
-        for (
-          let colIndex = 0;
-          colIndex < firstFloorData[0].length;
-          colIndex++
-        ) {
-          if (firstFloorData[0][colIndex]) {
-            const firstCell = firstFloorData[0][colIndex];
-            const { x1, x2, y1 } = this.calculateCoordinates(firstCell);
-            const centerX = x1 + (x2 - x1) / 2;
-
-            // 检查点击是否在列号区域内
-            if (
-              y >=
-                y1 -
-                  getCFG("svg").cellSty.rackIdxNumOffsetLen -
-                  SIDE_PADDING * 2 &&
-              y <= y1 - SIDE_PADDING &&
-              x >= centerX - 15 &&
-              x <= centerX + 15
-            ) {
-              // 转换回业务索引
-              // const backEle = this.pageIdxToBusiIndx(
-              //   { r: 0, c: colIndex },
-              //   this.rotationAngleType,
-              //   true,
-              //   false
-              // )
-              return {
-                type: "col",
-                index: colIndex,
-              };
-            }
-          }
-        }
-      }
-      return null;
-    },
-    drawRackIndxNum(ctx) {
-      if (!this.isShowRackIndxNum) {
-        return;
-      }
-      const SIDE_PADDING_X = getCFG("svg").cellSty.rackIdxNumSideXPadding;
-      const SIDE_PADDING_Y = getCFG("svg").cellSty.rackIdxNumSideYPadding;
-      const FONT = getCFG("svg").cellSty.rackIdxNumFont || "12px Arial";
-      const DEFAULT_COLOR =
-        getCFG("svg").cellSty.rackIdxNumFontColor || "#666666";
-      const HIGHLIGHT_BG = "#CCE6FF"; // 中等蓝色背景
-      const HIGHLIGHT_TEXT = "#000000"; // 纯黑色文字
-      const HIGHLIGHT_FONT = "bold 12px Arial";
-
-      // 基础文本样式设置
-      ctx.font = FONT;
-      ctx.fillStyle = DEFAULT_COLOR;
-      ctx.textBaseline = "middle";
-
-      // 获取选中项
-      const firstSelectedItem = this.selectedItemArr?.[0] || null;
-      const highlightRow = firstSelectedItem?.rowIndex;
-      const highlightCol = firstSelectedItem?.colIndex;
-
-      // 获取当前楼层数据
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-      if (!firstFloorData?.length) return;
-
-      // 绘制行号
-      this.drawRowNumbers(ctx, firstFloorData, highlightRow, {
-        SIDE_PADDING_X,
-        DEFAULT_COLOR,
-        FONT,
-        HIGHLIGHT_BG,
-        HIGHLIGHT_TEXT,
-        HIGHLIGHT_FONT,
-      });
-
-      // 绘制列号
-      this.drawColumnNumbers(ctx, firstFloorData, highlightCol, {
-        SIDE_PADDING_Y,
-        DEFAULT_COLOR,
-        FONT,
-        HIGHLIGHT_BG,
-        HIGHLIGHT_TEXT,
-        HIGHLIGHT_FONT,
-      });
-    },
-
-    // 抽取行号绘制逻辑
-    drawRowNumbers(ctx, firstFloorData, highlightRow, styles) {
-      for (let rowIndex = 0; rowIndex < firstFloorData.length; rowIndex++) {
-        const firstCell = firstFloorData[rowIndex]?.[0];
-        if (!firstCell) continue;
-
-        const { x1, y1, y4 } = this.calculateCoordinates(firstCell);
-        const backEle = this.pageIdxToBusiIndx(
-          { r: rowIndex, c: 0 },
-          this.rotationAngleType,
-          false,
-          false
-        );
-        const formattedRowNum = backEle.backR.toString();
-
-        // 计算行高度和垂直中心位置
-        const rowHeight = y4 - y1;
-        const centerY = y1 + rowHeight / 2;
-
-        // 计算文本框的位置和尺寸
-        const textX =
-          x1 -
-          getCFG("svg").cellSty.rackIdxNumOffsetLen +
-          styles.SIDE_PADDING_X;
-        const textWidth =
-          getCFG("svg").cellSty.rackIdxNumOffsetLen - styles.SIDE_PADDING_X * 2;
-
-        // 高亮处理
-        if (rowIndex === highlightRow) {
-          // 绘制高亮背景,确保背景框与文本区域对齐
-          this.drawHighlightBackground(
-            ctx,
-            textX - styles.SIDE_PADDING_X,
-            y1,
-            textWidth + styles.SIDE_PADDING_X * 2,
-            rowHeight,
-            styles.HIGHLIGHT_BG
-          );
-          ctx.fillStyle = styles.HIGHLIGHT_TEXT;
-          ctx.font = styles.HIGHLIGHT_FONT;
-        } else {
-          ctx.fillStyle = styles.DEFAULT_COLOR;
-          ctx.font = styles.FONT;
-        }
-
-        // 设置文本对齐方式
-        ctx.textAlign = "center";
-        ctx.textBaseline = "middle";
-
-        // 在计算出的中心位置绘制文本
-        ctx.fillText(
-          formattedRowNum,
-          textX + textWidth / 2, // 文本框的水平中心
-          centerY // 单元格的垂直中心
-        );
-      }
-    },
-
-    // 抽取列号绘制逻辑
-    drawColumnNumbers(ctx, firstFloorData, highlightCol, styles) {
-      const firstRow = firstFloorData[0];
-      if (!firstRow) return;
-
-      for (let colIndex = 0; colIndex < firstRow.length; colIndex++) {
-        const firstCell = firstRow[colIndex];
-        if (!firstCell) continue;
-
-        const { x1, x2, y1 } = this.calculateCoordinates(firstCell);
-        const backEle = this.pageIdxToBusiIndx(
-          { r: 0, c: colIndex },
-          this.rotationAngleType,
-          false,
-          false
-        );
-        const formattedColNum = backEle.backC.toString();
-
-        // 计算列宽度和水平中心位置
-        const colWidth = x2 - x1;
-        const centerX = x1 + colWidth / 2;
-
-        // 计算文本框的位置和尺寸
-        const textY =
-          y1 -
-          getCFG("svg").cellSty.rackIdxNumOffsetLen +
-          styles.SIDE_PADDING_Y;
-        const textHeight =
-          getCFG("svg").cellSty.rackIdxNumOffsetLen - styles.SIDE_PADDING_Y * 2;
-
-        // 高亮处理
-        if (colIndex === highlightCol) {
-          // 绘制高亮背景,确保背景框与文本区域对齐
-          this.drawHighlightBackground(
-            ctx,
-            x1, // 起始x坐标
-            y1 - getCFG("svg").cellSty.rackIdxNumOffsetLen, // 起始y坐标
-            colWidth, // 宽度
-            getCFG("svg").cellSty.rackIdxNumOffsetLen, // 高度
-            styles.HIGHLIGHT_BG,
-            false
-          );
-          ctx.fillStyle = styles.HIGHLIGHT_TEXT;
-          ctx.font = styles.HIGHLIGHT_FONT;
-        } else {
-          ctx.fillStyle = styles.DEFAULT_COLOR;
-          ctx.font = styles.FONT;
-        }
-
-        // 设置文本对齐方式
-        ctx.textAlign = "center";
-        ctx.textBaseline = "middle";
-
-        // 在计算出的中心位置绘制文本
-        ctx.fillText(
-          formattedColNum,
-          centerX,
-          textY + textHeight / 2 // 文本框的垂直中心
-        );
-      }
-    },
-
-    // 抽取高亮背景绘制逻辑
-    // 修改高亮背景绘制逻辑
-    drawHighlightBackground(ctx, x, y, width, height, color) {
-      const padding = 2; // 背景内边距
-      ctx.fillStyle = color;
-      ctx.fillRect(
-        x + padding, // 左边加padding
-        y + padding, // 上边加padding
-        width - padding * 2, // 减去左右padding
-        height - padding * 2 // 减去上下padding
-      );
-    },
-    drawSelItemArr(ctx) {
-      if (!this.selectedItemArr || this.selectedItemArr.length < 1) {
-        return;
-      }
-
-      // 按照行列排序selectedItemArr
-      const sortedItems = [...this.selectedItemArr].sort((a, b) => {
-        if (a.flrNum !== b.flrNum) return a.flrNum - b.flrNum;
-        if (a.rowIndex !== b.rowIndex) return a.rowIndex - b.rowIndex;
-        return a.colIndex - b.colIndex;
-      });
-
-      // 绘制边框
-      sortedItems.forEach((item) => {
-        const { x1, y1, x2, y2, x3, y3, x4, y4 } =
-          this.calculateCoordinates(item);
-
-        // 检查四个方向是否有相邻元素
-        const hasLeft = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex &&
-            other.colIndex === item.colIndex - 1
-        );
-        const hasRight = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex &&
-            other.colIndex === item.colIndex + 1
-        );
-        const hasTop = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex - 1 &&
-            other.colIndex === item.colIndex
-        );
-        const hasBottom = sortedItems.find(
-          (other) =>
-            other.flrNum === item.flrNum &&
-            other.rowIndex === item.rowIndex + 1 &&
-            other.colIndex === item.colIndex
-        );
-
-        // 绘制主边框
-        ctx.beginPath();
-        ctx.strokeStyle = "#409EFF"; // 主边框颜色
-        ctx.lineWidth = 2;
-
-        // 只绘制没有相邻元素的边
-        if (!hasTop) {
-          ctx.moveTo(x1, y1);
-          ctx.lineTo(x2, y2);
-        }
-        if (!hasRight) {
-          ctx.moveTo(x2, y2);
-          ctx.lineTo(x3, y3);
-        }
-        if (!hasBottom) {
-          ctx.moveTo(x3, y3);
-          ctx.lineTo(x4, y4);
-        }
-        if (!hasLeft) {
-          ctx.moveTo(x4, y4);
-          ctx.lineTo(x1, y1);
-        }
-        ctx.stroke();
-
-        // 绘制外发光效果
-        ctx.beginPath();
-        ctx.strokeStyle = "rgba(64, 158, 255, 0.3)"; // 半透明的边框颜色
-        ctx.lineWidth = 4;
-
-        if (!hasTop) {
-          ctx.moveTo(x1, y1 - 1);
-          ctx.lineTo(x2, y2 - 1);
-        }
-        if (!hasRight) {
-          ctx.moveTo(x2 + 1, y2);
-          ctx.lineTo(x3 + 1, y3);
-        }
-        if (!hasBottom) {
-          ctx.moveTo(x3, y3 + 1);
-          ctx.lineTo(x4, y4 + 1);
-        }
-        if (!hasLeft) {
-          ctx.moveTo(x4 - 1, y4);
-          ctx.lineTo(x1 - 1, y1);
-        }
-        ctx.stroke();
-      });
-    },
-    drawGoods(ctx, drawObj) {
-      const goodsAddrArr = Object.keys(drawObj);
-      if (!goodsAddrArr || goodsAddrArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < goodsAddrArr.length; i++) {
-        const addr = goodsAddrArr[i];
-        const [f, c, r] = this.rCFStrToArr(addr);
-        if (!this.pageFloorGridDataObj[f] || !drawObj[addr]) {
-          continue;
-        }
-        const compuItem = this.busiIndxToPageIdx(
-          { r: r, c: c },
-          this.rotationAngleType
-        );
-        const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-        if (ele) {
-          const newItem = JSON.parse(JSON.stringify(ele));
-          this.itemStsInit(newItem, ITEMSTATUS.goods);
-          // 绘制车辆,部分参数不使用
-          this.parallelogramDraw(ctx, newItem);
-        }
-      }
-    },
-    drawRackIndx(ctx) {
-      if (!this.isShowAllFlr) {
-        ctx.font = "12px Arial";
-        ctx.fillStyle = "white";
-        for (let colIndex = 0; colIndex < this.rackCol; colIndex++) {
-          const x = this.calculateCoordinate(colIndex * this.cellWidth, "x");
-          ctx.fillText(colIndex + 1, x + 5, 15);
-        }
-
-        for (let rowIndex = 0; rowIndex < this.rackRow; rowIndex++) {
-          const y = this.calculateCoordinate(rowIndex * this.cellLen, "y");
-          ctx.fillText(rowIndex + 1, 5, y + 15);
-        }
-      }
-    },
-    aniDraw() {
-      if (!this.isAni) {
-        this.stopAniDraw();
-        return;
-      }
-      this.animationFrameId = requestAnimationFrame(this.drawCanvas);
-    },
-    stopAniDraw() {
-      if (this.animationFrameId) {
-        cancelAnimationFrame(this.animationFrameId);
-        this.animationFrameId = null;
-      }
-    },
-    drawGrid(ctx) {
-      this.drawFloorGirdDoubleArr(this.pageFloorGridDataObj, ctx);
-    },
-    drawPath() {
-      /* test
-      this.shuttleVisObj = {
-        1: {
-          baseInfo: {
-            sid: "1",
-            f: 2,
-            r: 17,
-            c: 15,
-            items: "00", // 表示载货状态,第一位是货物,第二位是托盘
-            steps: [
-              { f: 2, r: 17, c: 13 },
-              { f: 2, r: 17, c: 14 },
-              { f: 2, r: 17, c: 15 },
-              { f: 2, r: 17, c: 16 },
-              { f: 2, r: 17, c: 17 },
-            ],
-            step_index: 2,
-          },
-        },
-        2: {
-          baseInfo: {
-            sid: "2",
-            f: 1,
-            r: 18,
-            c: 39,
-            items: "00", // 只载托盘无货物
-            steps: [
-              { f: 1, r: 18, c: 37 },
-              { f: 1, r: 18, c: 38 },
-              { f: 1, r: 18, c: 39 },
-              { f: 1, r: 18, c: 40 },
-              { f: 1, r: 18, c: 41 },
-            ],
-            step_index: 3,
-          },
-        },
-      }; */
-      const shuttleArr = Object.keys(this.shuttleVisObj);
-      if (!shuttleArr || shuttleArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < shuttleArr.length; i++) {
-        const shuttleKey = shuttleArr[i];
-        const shuttle = this.shuttleVisObj[shuttleKey];
-        if (
-          !shuttle ||
-          !shuttle.baseInfo ||
-          !shuttle.baseInfo.steps ||
-          shuttle.baseInfo.steps.length < 1
-        ) {
-          continue;
-        }
-        const step_index = shuttle.baseInfo.step_index;
-        const steps = shuttle.baseInfo.steps;
-        const pathArr = [];
-        const pathArrBef = [];
-        for (let j = 0; j < steps.length; j++) {
-          const stepItem = steps[j];
-          const f = stepItem.f;
-          const r = stepItem.r;
-          const c = stepItem.c;
-          const compuItem = this.busiIndxToPageIdx(
-            { r: r, c: c },
-            this.rotationAngleType
-          );
-          const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-          if (!ele) {
-            continue;
-          }
-
-          if (j < step_index) {
-            pathArrBef.push(this.getCellCenterPos(ele));
-          } else if (j === step_index) {
-            pathArrBef.push(this.getCellCenterPos(ele));
-            pathArr.push(this.getCellCenterPos(ele));
-          } else {
-            pathArr.push(this.getCellCenterPos(ele));
-          }
-        }
-        // const pathColors = this.itemTypeProxy?.shuttle?.pathColors?.[shuttleKey];
-        // const passedColor = pathColors?.passed || 'rgb(200, 200, 200)'; // 已经过路径的颜色,默认灰色
-        // const toPassColor = pathColors?.toPass || PAGECFG_CONST.ITEMSTATUS.path.fillColor;
-
-        // 获取当前仓库的穿梭车颜色配置
-        const warehouseColors =
-          window.warehouseShuttleColors?.[this.wareHouseId];
-        const shuttleColors = warehouseColors?.[shuttleKey];
-
-        // 使用全局存储的颜色,如果没有则使用默认值
-        const passedColor =
-          shuttleColors?.path_passed_color || this.scssVariables.pathHasDrived;
-        const toPassColor =
-          shuttleColors?.path_color || this.scssVariables.path;
-        if (pathArr.length > 1) {
-          this.drawLineByArr(pathArr, toPassColor);
-        }
-        if (pathArrBef.length > 1) {
-          // this.startBlinkInter();
-          this.drawLineByArr(pathArrBef, passedColor);
-        }
-      }
-    },
-    startBlinkInter() {
-      if (this.blinkInter) {
-        return;
-      }
-      this.blinkInter = setInterval(() => {
-        this.isBlink = !this.isBlink;
-      }, 1000);
-    },
-    stopBlinkInter() {
-      if (this.blinkInter) {
-        clearInterval(this.blinkInter);
-        this.blinkInter = null;
-      }
-    },
-    /**
-     * 根据pathArr绘制线条
-     */
-    drawLineByArr(pathArr, fillColor) {
-      const ctx = this.ctx;
-      ctx.strokeStyle =
-        fillColor || this.itemStsMap[ITEMSTATUS.path].sty.fillColor;
-      ctx.lineWidth = this.itemStsMap[ITEMSTATUS.path].sty.lineWidth;
-      ctx.beginPath();
-      ctx.moveTo(
-        this.calculateCoordinate(pathArr[0].x, "x"),
-        this.calculateCoordinate(pathArr[0].y, "y")
-      );
-      for (let i = 1; i < pathArr.length; i++) {
-        ctx.lineTo(
-          this.calculateCoordinate(pathArr[i].x, "x"),
-          this.calculateCoordinate(pathArr[i].y, "y")
-        );
-      }
-      ctx.stroke();
-    },
-    /**
-     * ele结构为{r: 1, c: 1, x1: 0, y1: 0, x2: 0, y2: 0, x3: 0, y3: 0, x4: 0, y4: 0, type: "warehouse", status: "default", fillColor: "white", borderColor: "black", lineWidth: 1}
-     * 根据ele上四个点的坐标获取四边形的中心点坐标
-     */
-    getCellCenterPos(ele) {
-      const x = (ele.x1 + ele.x2 + ele.x3 + ele.x4) / 4;
-      const y = (ele.y1 + ele.y2 + ele.y3 + ele.y4) / 4;
-      return { x, y };
-    },
-    // shuttle渲染数据this.shuttleVisObj
-    drawShuttle(ctx) {
-      // console.log(JSON.stringify(this.shuttleVisObj))
-      /* TESTMM1113OVER
-      this.shuttleVisObj = {
-        test: {
-          baseInfo: {
-            "f": 1,
-            "c": 11,
-            "r": 11,
-            "sid": "1",
-            "items": "00",
-            "steps": [{ "f": 1, "c": 1, "r": 1 }, { "f": 1, "c": 2, "r": 1 }],
-            "step_index": 1
-          }
-        }
-      } */
-      const shuttleArr = Object.keys(this.shuttleVisObj);
-      if (!shuttleArr || shuttleArr.length < 1) {
-        return;
-      }
-      for (let i = 0; i < shuttleArr.length; i++) {
-        const key = shuttleArr[i];
-        const shuttle = this.shuttleVisObj[key];
-        const baseInfo = shuttle.baseInfo;
-        // const [f, c, r] = this.rCFStrToArr(baseInfo.addr)
-        const f = baseInfo.f;
-        const c = baseInfo.c;
-        const r = baseInfo.r;
-        if (!this.isShowAllFlr && f !== this.operFloor) {
-          continue;
-        }
-        const compuItem = this.busiIndxToPageIdx(
-          { r: r, c: c },
-          this.rotationAngleType
-        );
-        const ele = this.getTheItem(compuItem.r, compuItem.c, f);
-        if (ele) {
-          const locShuttle = JSON.parse(JSON.stringify(ele));
-          this.itemStsInit(locShuttle, ITEMSTATUS.shuttle.name);
-          locShuttle["type"] = ITEMSTATUS.shuttle;
-          if (
-            ele.status === ITEMSTATUS.goods ||
-            (ele.status === ITEMSTATUS.default && ele.type === LOCTYPE.rack)
-          ) {
-            const backEle = this.pageIdxToBusiIndx(
-              { f: ele.flrNum, c: ele.colIndex, r: ele.rowIndex },
-              this.rotationAngleType
-            );
-            const id = this.idKey(backEle);
-            if (this.goodsVisObj[id] || this.conveyorAroundMap[id]) {
-              locShuttle.isUnderGood = true;
-            }
-          }
-          // 绘制车辆,部分参数不使用
-          this.parallelogramDrawShuttle(ctx, locShuttle);
-          const goodTypeStr = baseInfo.items && baseInfo.items[0];
-          const goodType = goodTypeStr && parseInt(goodTypeStr);
-          const palletTypeStr = baseInfo.items && baseInfo.items[1];
-          const palletType = goodTypeStr && parseInt(palletTypeStr);
-          if (goodType || palletType) {
-            const goodsPageEle = this.getParallelogramByPageEle(ele);
-            this.itemStsInit(goodsPageEle, ITEMSTATUS.goods);
-            goodsPageEle.borderColor =
-              this.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-            this.parallelogramDraw(ctx, goodsPageEle);
-          }
-        }
-      }
-    },
-    getParallelogramByPageEle(pageEle) {
-      // 如果没有传入pageEle或缺少必要的坐标信息,返回null
-      if (!pageEle || !pageEle.x1 || !pageEle.y1) {
-        return null;
-      }
-      // 将角度转换为弧度
-      const angleInRadians = (this.includedAngle * Math.PI) / 180;
-      const offset = this.cellLen * 0.1;
-      const xOffsetLen = this.includedAngle === 90 ? 0 : this.cellWidth * 0.05;
-      // 计算offset在y轴方向的投影
-      const offsetY = offset * Math.sin(angleInRadians);
-
-      // 计算offset在x轴方向的投影
-      const offsetX = offset * Math.cos(angleInRadians);
-
-      // 构造新的平行四边形坐标
-      const parallelogram = {
-        // 左上角点(加上offset的投影)
-        x1: pageEle.x1 - offsetX - xOffsetLen,
-        y1: pageEle.y1 + offsetY,
-
-        // 右上角点(加上offset的投影)
-        x2: pageEle.x2 + offsetX,
-        y2: pageEle.y2 + offsetY,
-
-        // 右下角点(减去offset的投影)
-        x3: pageEle.x3 + offsetX + xOffsetLen,
-        y3: pageEle.y3 - offsetY,
-
-        // 左下角点(减去offset的投影)
-        x4: pageEle.x4 - offsetX,
-        y4: pageEle.y4 - offsetY,
-      };
-
-      return parallelogram;
-    },
-    drawFloorGirdDoubleArr(pageFloorGridDataObj, ctx) {
-      const flrNums = Object.keys(pageFloorGridDataObj);
-      for (let i = 0; i < flrNums.length; i++) {
-        if (this.drawFlrConditon(flrNums[i])) {
-          continue;
-        }
-        const flrNum = flrNums[i];
-        const gridDoubleArr = pageFloorGridDataObj[flrNum];
-        this.drawGirdDoubleArr(gridDoubleArr, ctx, flrNum);
-      }
-      // for (let i = 1; i <= this.totalFlr; i++) {
-      //   const gridDoubleArr = pageFloorGridDataObj[i]
-      //   this.drawGirdDoubleArr(gridDoubleArr, ctx)
-      // }
-    },
-    drawFlrConditon(flrNum) {
-      if (this.isCfgSty && flrNum != this.operFloor) {
-        return true;
-      }
-    },
-    drawGirdDoubleArr(gridDoubleArr, ctx, flrNum) {
-      gridDoubleArr.forEach((row, rowIndex) => {
-        row.forEach((col, colIndex) => {
-          this.parallelogramDraw(ctx, col);
-          // 按状态列表顺序依次绘制
-          if (col.statusList && col.statusList.length > 0) {
-            col.statusList.forEach((statusObj) => {
-              const drawConfig = {
-                ...col,
-                ...statusObj, // 传入当前要绘制的状态
-              };
-              this.parallelogramDraw(ctx, drawConfig);
-            });
-          }
-        });
-      });
-    },
-    parallelogramDraw(ctx, col, fillColor) {
-      const cumDraw = this.itemCumFunDo(col, "drawFun");
-      if (cumDraw) {
-        return;
-      }
-      this.parallelogramDrawCommon(ctx, col, fillColor);
-      this.parallelogramDrawNum(ctx, col);
-    },
-    itemCumFunDo(ele, funName) {
-      const operItemSts = ele.status;
-      if (
-        this.itemStsMap[operItemSts] &&
-        this.itemStsMap[operItemSts][funName]
-      ) {
-        return this.itemStsMap[operItemSts][funName](this, ele);
-      }
-    },
-    parallelogramDrawCommon(ctx, col, fillColor) {
-      ctx.fillStyle = fillColor || col.fillColor;
-      ctx.strokeStyle = col.borderColor;
-      ctx.lineWidth = col.lineWidth;
-      ctx.beginPath();
-      const { x1, y1, x2, y2, x3, y3, x4, y4 } = this.calculateCoordinates(col);
-      ctx.moveTo(x1, y1);
-      ctx.lineTo(x2, y2);
-      ctx.lineTo(x3, y3);
-      ctx.lineTo(x4, y4);
-      ctx.closePath();
-      ctx.fill();
-      ctx.stroke();
-    },
-    parallelogramDrawNum(ctx, col) {
-      if (!this.isShowNumInCell) {
-        return;
-      }
-      if (col.type === LOCTYPE.around) {
-        return;
-      }
-      const { flrNum, rowIndex, colIndex } = col;
-      if (
-        !(
-          flrNum === undefined ||
-          rowIndex === undefined ||
-          colIndex === undefined
-        )
-      ) {
-        let backR = col.backR;
-        let backC = col.backC;
-        if (backR === undefined || backC === undefined) {
-          const backEle = this.pageIdxToBusiIndx(
-            col,
-            this.rotationAngleType,
-            true,
-            false
-          );
-          backR = backEle.backR;
-          backC = backEle.backC;
-        }
-        const formattedFlrNum = flrNum.toString().padStart(2, "0");
-        const formattedRowIndex = backR.toString().padStart(3, "0");
-        const formattedColIndex = backC.toString().padStart(3, "0");
-        const itemNumSty =
-          this.itemStsMap[col.status] &&
-          this.itemStsMap[col.status].sty &&
-          this.itemStsMap[col.status].sty.numSty;
-        ctx.font =
-          (itemNumSty && itemNumSty.cellNumFont) ||
-          getCFG("svg").cellSty.cellNumFont;
-        ctx.fillStyle =
-          (itemNumSty && itemNumSty.cellNumFontColor) ||
-          getCFG("svg").cellSty.cellNumFontColor;
-        let offsetX1Fixed =
-          (itemNumSty && itemNumSty.cellXOffset) ||
-          getCFG("svg").cellSty.cellXOffset;
-        let loc1FlrNum = 0;
-        /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-          loc1FlrNum += getCFG('svg').cellSty.widthForFlrNum1;
-        } */
-        const offsetX2 = offsetX1Fixed + loc1FlrNum;
-        const loc2ColInd = getCFG("svg").cellSty.widthColInd2;
-        const offsetX3 = offsetX2 + loc2ColInd;
-        const { x1, y1 } = this.calculateCoordinates(col);
-        if (this.isTheRotationAngleType()) {
-          /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-            ctx.fillText(
-              formattedFlrNum,
-              x1 + offsetX1Fixed,
-              y1 + getCFG('svg').cellSty.cellYOffset
-            );
-          } */
-          ctx.fillText(
-            formattedColIndex,
-            x1 + offsetX2,
-            y1 + getCFG("svg").cellSty.cellYOffset
-          );
-          ctx.fillText(
-            formattedRowIndex,
-            x1 + offsetX3,
-            y1 + getCFG("svg").cellSty.cellYOffset
-          );
-        } else {
-          ctx.save();
-          ctx.translate(x1, y1);
-          ctx.rotate(Math.PI / 2);
-          /* if (PAGECFG_CONST.isShowFlrNumInCell) {
-            ctx.fillText(formattedFlrNum, offsetX1Fixed, -4);
-          } */
-          ctx.fillText(formattedColIndex, offsetX2, -4);
-          ctx.fillText(formattedRowIndex, offsetX3, -4);
-          ctx.restore();
-        }
-      }
-    },
-    parallelogramDrawShuttle(ctx, col) {
-      this.parallelogramDraw(ctx, col);
-      const { x1, y1, x2, y2, x3, y3, x4, y4 } = col;
-      // 计算四边形的宽度和高度
-      const width = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
-      const height = Math.sqrt((x3 - x2) ** 2 + (y3 - y2) ** 2);
-      ctx.save();
-      ctx.setTransform(
-        (x2 - x1) / width,
-        (y2 - y1) / width,
-        (x3 - x2) / height,
-        (y3 - y2) / height,
-        this.calculateCoordinate(x1, "x"),
-        this.calculateCoordinate(y1, "y")
-      );
-      ctx.drawImage(this.shuttleImg, 0, 0, width, height);
-      ctx.restore();
-      if (col.isUnderGood) {
-        // 获取cell状态的填充色
-        const cellFillColor = this.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-        // 将颜色转换为带50%透明度的颜色
-        const cellFillColorHalf = cellFillColor + "80";
-        /* // 将颜色转换为带70%透明度的颜色
-        const cellFillColorWithOpacity = cellFillColor + 'B3'
-        // 将颜色转换为带30%透明度的颜色
-        const cellFillColorWithOpacity30 = cellFillColor + '4D' */
-        this.parallelogramDraw(ctx, col, cellFillColorHalf);
-      }
-    },
-    isTheRotationAngleType() {
-      if (this.rotationAngleType === 0 || this.rotationAngleType === 2) {
-        return true;
-      }
-    },
-    // 绘制每条边
-    drawEdge(ctx, fromX, fromY, toX, toY, edgeProps) {
-      ctx.beginPath();
-      ctx.moveTo(fromX, fromY);
-      ctx.lineTo(toX, toY);
-      ctx.strokeStyle = edgeProps.color;
-      ctx.lineWidth = edgeProps.width;
-      ctx.stroke();
-    },
-    handleWheel(e) {
-      // 清除画布
-      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
-
-      const delta = e.deltaY > 0 ? -0.1 : 0.1; // 根据滚动方向调整缩放因子
-      this.scale += delta;
-      this.scale = Math.max(0.1, Math.min(3, this.scale)); // 限制缩放范围 0.1-3
-
-      this.updateMapTransform();
-      // this.$nextTick(() => {
-      this.drawCanvas();
-      // })
-    },
-    handleMouseDown(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      e.preventDefault();
-      this.mouseStartDragLoc = { x: e.clientX, y: e.clientY };
-      this.mouseSts = "down";
-      this.currentHoverEle = null;
-      this.clearSelItemArr();
-    },
-    handleMouseUp(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      e.preventDefault();
-      this.mouseEndDragLoc = { x: e.clientX, y: e.clientY };
-      this.refreshMouseDownInfo("up");
-    },
-    refreshMouseDownInfo(mouseSts) {
-      this.mouseSts = mouseSts;
-      if (
-        Math.abs(this.mouseEndDragLoc.x - this.mouseStartDragLoc.x) > 5 ||
-        Math.abs(this.mouseEndDragLoc.y - this.mouseStartDragLoc.y) > 5
-      ) {
-        this.isDragMove = true;
-      } else {
-        this.isDragMove = false;
-      }
-    },
-    mouseHoveredNothing(isClearSelItemArr) {
-      isClearSelItemArr && this.clearSelItemArr();
-      this.handleMouseHoverInfo(null);
-      this.drawCanvas();
-    },
-    clearSelItemArr() {
-      this.selectedItemArr = [];
-    },
-    handleMouseMove(e) {
-      e.preventDefault();
-      const ele = this.getCurrentMouseCellEle(e, this.operFloor);
-      if (!ele) {
-        this.mouseHoveredNothing();
-        return;
-      }
-      const theCellIsChg =
-        !this.currentHoverEle ||
-        ele.rowIndex !== this.currentHoverEle.rowIndex ||
-        ele.colIndex !== this.currentHoverEle.colIndex ||
-        ele.flrNum !== this.currentHoverEle.flrNum;
-      if (theCellIsChg) {
-        if (this.mouseSts === "down") {
-          this.procSelItemArr(e, ele, "mouseMove");
-        }
-        this.hoveredPalletCode = "";
-        this.hoveredSid = "";
-        const showHoverInfo =
-          this.isShowHoverInfo && this.isTheGoodLocCell(ele);
-        if (showHoverInfo) {
-          this.handleMouseHoverInfo(ele);
-        } else {
-          this.handleMouseHoverInfo(null);
-        }
-      }
-      this.currentHoverEle = ele;
-    },
-    isMouseActionDo(e, mouseActionFun) {
-      if (
-        this.itemStsMap[this.cfgOperingItem] &&
-        this.itemStsMap[this.cfgOperingItem][mouseActionFun]
-      ) {
-        const isDo = this.itemStsMap[this.cfgOperingItem][mouseActionFun](e);
-        if (isDo === false) {
-          return false;
-        }
-      }
-      return true;
-    },
-    isTheGoodLocCell(ele) {
-      if (ele.status) {
-        return true;
-      }
-      return false;
-    },
-    handleClick(e) {
-      if (!this.mapOperModel) {
-        return;
-      }
-      if (this.isDragMove) {
-        return;
-      }
-      this.clearSelItemArr();
-      this.procSelItemArr(e, null, "click");
-    },
-    procSelItemArr(e, currentEleIn, mouseActionType) {
-      // 1. 初始化选中数组
-      if (!this.selectedItemArr) {
-        this.selectedItemArr = [];
-      }
-      // 2. 获取当前选中元素
-      const currentEle =
-        currentEleIn || this.getCurrentMouseCellEle(e, this.operFloor);
-
-      // 3. 处理无选中元素的情况
-      if (!currentEle) {
-        return this.handleNoCurrentElement(e, mouseActionType);
-      }
-
-      // 4. 处理单个元素的选中/取消选中
-      this.selElement(currentEle);
-
-      // 5. 重绘画布
-      this.drawCanvas();
-    },
-
-    // 处理无选中元素的情况
-    handleNoCurrentElement(e, mouseActionType) {
-      const rackIndxNumEle = this.getRackIndxNum(e);
-      if (rackIndxNumEle && mouseActionType === "click") {
-        this.handleRackIndexClick(rackIndxNumEle);
-        return;
-      }
-      this.mouseHoveredNothing(true);
-    },
-
-    // 处理货架索引点击
-    handleRackIndexClick(rackIndxNumEle) {
-      const firstFloorData = this.pageFloorGridDataObj[this.operFloor];
-      if (!firstFloorData) return;
-
-      // 根据类型处理行或列
-      if (rackIndxNumEle.type === "row") {
-        this.handleRowSelection(rackIndxNumEle, firstFloorData);
-      } else if (rackIndxNumEle.type === "col") {
-        this.handleColumnSelection(rackIndxNumEle, firstFloorData);
-      }
-
-      this.drawCanvas();
-    },
-
-    // 处理行选择
-    handleRowSelection(rackIndxNumEle, firstFloorData) {
-      const rowCells = this.getCells(firstFloorData[0].length, (colIndex) =>
-        this.getTheItem(rackIndxNumEle.index, colIndex, this.operFloor)
-      );
-
-      this.toggleCellsSelection(rowCells, "rowIndex", rackIndxNumEle.index);
-    },
-
-    // 处理列选择
-    handleColumnSelection(rackIndxNumEle, firstFloorData) {
-      const colCells = this.getCells(firstFloorData.length, (rowIndex) =>
-        this.getTheItem(rowIndex, rackIndxNumEle.index, this.operFloor)
-      );
-
-      this.toggleCellsSelection(colCells, "colIndex", rackIndxNumEle.index);
-    },
-
-    // 获取单元格数组
-    getCells(length, getCellFn) {
-      const cells = [];
-      for (let i = 0; i < length; i++) {
-        const cell = getCellFn(i);
-        if (cell) cells.push(cell);
-      }
-      return cells;
-    },
-
-    // 切换单元格选择状态
-    toggleCellsSelection(cells, indexType, indexValue) {
-      const allSelected = this.areAllCellsSelected(cells);
-
-      if (allSelected) {
-        // 取消选中
-        this.selectedItemArr = this.selectedItemArr.filter(
-          (item) =>
-            item[indexType] !== indexValue || item.flrNum !== this.operFloor
-        );
-      } else {
-        // 选中新单元格
-        cells.forEach((cell) => {
-          if (!this.isCellSelected(cell)) {
-            this.selectedItemArr.push(cell);
-          }
-        });
-      }
-    },
-
-    // 检查所有单元格是否已选中
-    areAllCellsSelected(cells) {
-      return cells.every((cell) => this.isCellSelected(cell));
-    },
-
-    // 检查单个单元格是否已选中
-    isCellSelected(cell) {
-      return this.selectedItemArr.some(
-        (item) =>
-          item.rowIndex === cell.rowIndex &&
-          item.colIndex === cell.colIndex &&
-          item.flrNum === cell.flrNum
-      );
-    },
-
-    // 切换单个元素的选中状态
-    selElement(currentEle) {
-      const existingIndex = this.selectedItemArr.findIndex(
-        (item) =>
-          item.rowIndex === currentEle.rowIndex &&
-          item.colIndex === currentEle.colIndex &&
-          item.flrNum === currentEle.flrNum
-      );
-      if (existingIndex === -1) {
-        this.selectedItemArr.push(currentEle);
-      }
-    },
-    itemStsInitBatch(operItems, theTargetSts, theOperingKey) {
-      if (!this.isCfgByFloor) {
-        const flrNumArr = Object.keys(this.pageFloorGridDataObj);
-        flrNumArr.forEach((flrNum) => {
-          operItems.forEach((operItem) => {
-            if (operItem.flrNum == flrNum) {
-              this.procItemStsWhenCfg(operItem, theTargetSts, theOperingKey);
-            } else {
-              const newOperItem = this.getTheItem(
-                operItem.rowIndex,
-                operItem.colIndex,
-                flrNum
-              );
-              this.procItemStsWhenCfg(newOperItem, theTargetSts, theOperingKey);
-            }
-          });
-        });
-      } else {
-        operItems.forEach((operItem) => {
-          this.procItemStsWhenCfg(operItem, theTargetSts, theOperingKey);
-        });
-      }
-    },
-    procItemStsWhenCfg(operItem, theTargetSts, theOperingKey) {
-      const theFinalSts = theTargetSts;
-      this.itemStsInit(operItem, theFinalSts, theOperingKey);
-    },
-    getOperItemsForLine(arr) {
-      const isHorizontal = this.isHorizontal();
-      const totalNum = isHorizontal ? this.pageCol : this.pageRow;
-      const operItems = [];
-      for (const ele of arr) {
-        const fixIndx = isHorizontal ? ele.rowIndex : ele.colIndex;
-        for (let i = 0; i < totalNum; i++) {
-          const rowIndex = isHorizontal ? fixIndx : i;
-          const colIndex = isHorizontal ? i : fixIndx;
-          const operItem = this.getTheItem(rowIndex, colIndex, ele.flrNum);
-          if (operItem && operItem.type !== LOCTYPE.around) {
-            operItems.push(operItem);
-          }
-        }
-      }
-      return operItems;
-    },
-    getTheTargetStsWhenCfg(ele) {
-      if (!this.cfgOperingItem) {
-        return;
-      }
-      if (
-        this.itemStsMap[this.cfgOperingItem] &&
-        this.itemStsMap[this.cfgOperingItem].getTheTargetStsWhenCfg
-      ) {
-        return this.itemStsMap[this.cfgOperingItem].getTheTargetStsWhenCfg(
-          this,
-          ele
-        );
-      }
-      const theSts = ele.status;
-      let theStoreSts = this.getTheStoreSts(ele);
-      if (theStoreSts === this.cfgOperingItem) {
-        theStoreSts = ITEMSTATUS.default;
-      }
-      const theTargetSts =
-        theSts === this.cfgOperingItem ? theStoreSts : this.cfgOperingItem;
-      return theTargetSts;
-    },
-    getTheStoreSts(ele) {
-      const theStoreEle = this.getTheItemStore(
-        ele.rowIndex,
-        ele.colIndex,
-        ele.flrNum
-      );
-      return theStoreEle.status;
-    },
-    handleDoubleClick(e, curCellDbClick) {
-      if (this.mapOperModel !== "selPointForOrderDoing") {
-        return;
-      }
-      e.preventDefault();
-      e.stopPropagation();
-      if (!curCellDbClick) {
-        return;
-      }
-      if (
-        curCellDbClick.status === ITEMSTATUS.unUse ||
-        curCellDbClick.canNotBeClick
-      ) {
-        this.canBeSelected &&
-          this.$message({
-            message: "当前位置不可用,不可作为选点被选中!",
-            type: "warning",
-          });
-        return;
-      }
-      if (!this.isTheGoodLocCell(curCellDbClick)) {
-        return;
-      }
-      const backEle = this.pageIdxToBusiIndx(
-        {
-          f: curCellDbClick.flrNum,
-          c: curCellDbClick.colIndex,
-          r: curCellDbClick.rowIndex,
-        },
-        this.rotationAngleType
-      );
-      this.getPalletCode(backEle);
-      this.$emit("selPointForOrder", backEle);
-    },
-    getPalletCode(ele, afterFunDo) {
-      this.$req({
-        url: "/wcs/api/map/cell/get/pallet",
-        method: "post",
-        data: {
-          warehouse_id: this.wareHouseId || window.glbMapId,
-          f: parseInt(ele.f),
-          c: parseInt(ele.c),
-          r: parseInt(ele.r),
-        },
-      })
-        .then((res) => {
-          console.log(res);
-          this.hoveredPalletCode = (res.row && res.row.pallet_code) || "";
-          afterFunDo && afterFunDo(this.hoveredPalletCode);
-        })
-        .catch((err) => {
-          console.error("获取托盘码失败:", err);
-        });
-    },
-    handleThreeClick(event) {
-      clearTimeout(this.clickTimeout);
-      this.clickCount++;
-
-      this.clickTimeout = setTimeout(() => {
-        this.clickCount = 0;
-      }, 1000);
-
-      if (this.clickCount === 3) {
-        this.rotationAngle = this.rotationAngle + 90;
-        if (this.rotationAngle === 360) {
-          this.rotationAngle = 0;
-        }
-        this.drawCanvas();
-        this.clickCount = 0;
-      }
-    },
-    rotateCanvas() {
-      this.ctx.save();
-      // 如果需要旋转角度,则进行旋转
-      if (this.rotationAngle !== 0) {
-        const centerX = this.canvas.width / 2;
-        const centerY = this.canvas.height / 2;
-        this.ctx.translate(centerX, centerY);
-        this.ctx.rotate((Math.PI / 180) * this.rotationAngle);
-        this.ctx.translate(-centerX, -centerY);
-      }
-      this.ctx.restore();
-    },
-    /**
-     * rowIndex 货架渲染后页面行号 从0 开的
-     * colIndex 货架渲染后页面列号 从 0 开始
-     * floor  从0 开始
-     * 根据点击点获取,所在行列(整体序号)。this.horizontalPointOffset大于0小于0分情况考虑。y向根据夹角和x位置,确认y所在的位置范围
-     * 关注scale
-     */
-    getMousePosition(event, operFlrNum) {
-      const canvas = this.$refs.canvas;
-      const rect = canvas.getBoundingClientRect();
-      const scaleX = this.scale;
-      const scaleY = this.scale;
-
-      // 获取鼠标点击的坐标
-      let x = event.clientX - rect.left;
-      let y = event.clientY - rect.top;
-
-      // 考虑 rowOffsetX 和 colOffsetY
-      x -= this.warehousPageCfg.rowOffsetX / scaleX;
-      y -= this.warehousPageCfg.colOffsetY / scaleY;
-
-      // 考虑缩放和平移
-      x = (x - this.offset.x) / this.scale;
-      y = (y - this.offset.y) / this.scale;
-
-      const keys = Object.keys(this.pageFloorGridDataObj);
-      for (const i of keys) {
-        const indxEle = this.getRowColIndx(x, y, this.pageFloorGridDataObj[i]);
-        if (indxEle.rowIndex !== undefined && indxEle.colIndex !== undefined) {
-          const rowIndex = indxEle.rowIndex;
-          const colIndex = indxEle.colIndex;
-          // const floor = i - 1
-          // const ele = this.getTheItem(rowIndex, colIndex, i)
-          // ele.flrNum = i
-          return { rowIndex, colIndex, flrNum: operFlrNum || i };
-        }
-      }
-    },
-    getRowColIndx(x, y, gridDoubleArr) {
-      // 考虑缩放和平移
-      x = (x - this.offset.x) / this.scale;
-      y = (y - this.offset.y) / this.scale;
-      let rowIndex, colIndex;
-      const horizontalPointOffset = Math.abs(this.horizontalPointOffset);
-      for (let i = 0; i < gridDoubleArr.length; i++) {
-        for (let j = 0; j < gridDoubleArr[i].length; j++) {
-          const cell = gridDoubleArr[i][j];
-          const offsetPointX = cell.x1 + this.cellWidth - horizontalPointOffset;
-          // 最小的cell.x1 + this.horizontalPointOffset 最大点cell.x1 + this.cellWidth
-          const isWithinParallelogramLessOffset =
-            x >= cell.x1 + this.horizontalPointOffset &&
-            x <= cell.x1 + this.cellWidth &&
-            y >= cell.y1 &&
-            y <= cell.y4;
-          if (!this.horizontalPointOffset && isWithinParallelogramLessOffset) {
-            rowIndex = i;
-            colIndex = j;
-            return { rowIndex, colIndex };
-          }
-
-          const isWithinParallelogramMoreOffset =
-            x >= cell.x1 &&
-            x <= cell.x1 + this.cellWidth + this.horizontalPointOffset &&
-            y >= cell.y1 &&
-            y <= cell.y4;
-          if (
-            this.horizontalPointOffset < 0 &&
-            isWithinParallelogramLessOffset
-          ) {
-            if (
-              x >= cell.x1 &&
-              x <= offsetPointX &&
-              y >= cell.y1 &&
-              y <= cell.y4
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-
-            let len;
-            if (x < cell.x1) {
-              len = Math.abs(cell.x1 - x);
-            }
-            if (x > offsetPointX) {
-              len = cell.x1 + this.cellWidth - x;
-            }
-            const angle = this.includedAngle;
-            const theYLen = len * Math.tan(angle * (Math.PI / 180));
-            const yLen = y - cell.y1;
-            if (
-              (x < cell.x1 && yLen > theYLen) ||
-              (x > offsetPointX && yLen < theYLen)
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-          }
-          if (
-            this.horizontalPointOffset > 0 &&
-            isWithinParallelogramMoreOffset
-          ) {
-            if (
-              x >= offsetPointX &&
-              x <= cell.x1 + this.cellWidth &&
-              y >= cell.y1 &&
-              y <= cell.y4
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-
-            let len;
-            if (x > cell.x1 && x < offsetPointX) {
-              len = Math.abs(cell.x1 - x);
-            }
-            if (x > cell.x1 + this.cellWidth) {
-              len = x - cell.x1 - this.cellWidth;
-            }
-            const angle = 180 - this.includedAngle;
-            const theYLen = len * Math.tan(angle * (Math.PI / 180));
-            const yLen = y - cell.y1;
-            if (
-              (x > cell.x1 && x < offsetPointX && yLen < theYLen) ||
-              (x > cell.x1 + this.cellWidth && yLen > theYLen)
-            ) {
-              rowIndex = i;
-              colIndex = j;
-              break;
-            }
-          }
-        }
-        if (rowIndex !== undefined) {
-          break; // Exit the outer loop if we found a match
-        }
-      }
-      return { rowIndex, colIndex };
-    },
-    handleMouseHoverInfo(ele) {
-      if (!ele) {
-        this.hoveredInfo = {
-          hoveredRowIndex: null,
-          hoveredColIndex: null,
-          hoveredFloorIndex: null,
-          hoveredItemStsName: null,
-        };
-        this.hoveredPalletCode = "";
-        this.hoveredSid = "";
-        return;
-      }
-      const itemStatus = ele.status;
-      const itemStatusName = itemStatus
-        ? this.itemStsMap[itemStatus].name
-        : null;
-      const itemBui = this.pageIdxToBusiIndx(
-        { r: ele.rowIndex, c: ele.colIndex },
-        this.rotationAngleType
-      );
-      const hoveredRowIndex = itemBui ? itemBui.r : null;
-      const hoveredColIndex = itemBui ? itemBui.c : null;
-
-      this.hoveredInfo.hoveredItemStsName = itemStatusName;
-      this.hoveredInfo.hoveredFloorIndex = ele.flrNum;
-      this.hoveredInfo.hoveredRowIndex = hoveredRowIndex;
-      this.hoveredInfo.hoveredColIndex = hoveredColIndex;
-      this.hoveredSid = this.checkShuttleExist(
-        ele.flrNum,
-        hoveredColIndex,
-        hoveredRowIndex
-      );
-    },
-    checkShuttleExist(f, c, r) {
-      // 参数校验
-      if (
-        typeof f !== "number" ||
-        typeof c !== "number" ||
-        typeof r !== "number"
-      ) {
-        return "";
-      }
-
-      // 遍历所有穿梭车
-      for (const shuttleId in this.shuttleVisObj) {
-        const shuttle = this.shuttleVisObj[shuttleId];
-
-        // 检查baseInfo是否存在
-        if (!shuttle.baseInfo) {
-          continue;
-        }
-
-        // 比较坐标
-        if (
-          shuttle.baseInfo.f === f &&
-          shuttle.baseInfo.c === c &&
-          shuttle.baseInfo.r === r
-        ) {
-          return shuttle.baseInfo.sid;
-        }
-      }
-
-      return "";
-    },
-    getCurrentMouseCellEle(event, operFlrNum) {
-      const theMousePosition = this.getMousePosition(event, operFlrNum);
-      if (!theMousePosition) {
-        return;
-      }
-      const ele = this.getTheItem(
-        theMousePosition.rowIndex,
-        theMousePosition.colIndex,
-        theMousePosition.flrNum
-      );
-      return ele;
-    },
-    setOperingCfgItem(setOperingCfgItem) {
-      this.cfgOperingItem = setOperingCfgItem.key;
-      this.isCfgByFloor = setOperingCfgItem.isByFloor;
-      this.paramToMergeObj = setOperingCfgItem.paramToMergeObj;
-      this.storePageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.pageFloorGridDataObj)
-      );
-    },
-    cancelCfg() {
-      this.operCfgInit();
-      this.pageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.storePageFloorGridDataObj)
-      );
-      this.drawCanvas();
-    },
-    resetCfg() {
-      this.resetTheItemAllCfg(
-        this.storePageFloorGridDataObj,
-        this.cfgOperingItem
-      );
-      this.operCfgInit();
-      this.pageFloorGridDataObj = JSON.parse(
-        JSON.stringify(this.storePageFloorGridDataObj)
-      );
-      this.drawCanvas();
-    },
-    operCfgInit() {
-      this.cfgOperingItem = "";
-      this.paramToMergeObj = null;
-      this.isCfgByFloor = undefined;
-    },
-    resetTheItemAllCfg(pageFloorGridDataObj, itemType) {
-      if (!itemType) {
-        return;
-      }
-      Object.keys(pageFloorGridDataObj).forEach((flrNum) => {
-        pageFloorGridDataObj[flrNum].forEach((row) => {
-          row.forEach((cellData) => {
-            if (cellData.status === itemType) {
-              this.itemStsInit(cellData, ITEMSTATUS.default);
-            }
-            if (cellData.statusList) {
-              cellData.statusList.forEach((statusObj) => {
-                if (statusObj.status === itemType) {
-                  this.itemStsInit(cellData, "", itemType);
-                }
-              });
-            }
-          });
-        });
-      });
-    },
-    setCfgIsByFloor(isCfgByFloor) {
-      this.isCfgByFloor = isCfgByFloor;
-    },
-    calculateCoordinates(col) {
-      const coordinates = {
-        x1: this.calculateCoordinate(col.x1, "x"),
-        y1: this.calculateCoordinate(col.y1, "y"),
-        x2: this.calculateCoordinate(col.x2, "x"),
-        y2: this.calculateCoordinate(col.y2, "y"),
-        x3: this.calculateCoordinate(col.x3, "x"),
-        y3: this.calculateCoordinate(col.y3, "y"),
-        x4: this.calculateCoordinate(col.x4, "x"),
-        y4: this.calculateCoordinate(col.y4, "y"),
-      };
-
-      return coordinates;
-    },
-    calculateCoordinate(value, type) {
-      const offset =
-        type === "x"
-          ? this.warehousPageCfg.rowOffsetX
-          : this.warehousPageCfg.colOffsetY;
-
-      return value * this.scale + offset;
-    },
-  },
-};

+ 0 - 33
src/mixins/map/gridViewMixin.js

@@ -1,33 +0,0 @@
-export default {
-  data() {
-    return {
-      // 容器配置
-      containerWidth: 0,
-      containerHeight: 0,
-      includedAngle: 45,
-    };
-  },
-
-  methods: {
-    initSize() {
-      if (!this.$el) return;
-
-      const { clientWidth, clientHeight } = this.$el;
-      if (clientWidth && clientHeight) {
-        this.containerWidth = clientWidth;
-        this.containerHeight = clientHeight;
-      }
-    },
-  },
-
-  mounted() {
-    this.$nextTick(() => {
-      this.initSize();
-      window.addEventListener("resize", this.initSize);
-    });
-  },
-
-  beforeDestroy() {
-    window.removeEventListener("resize", this.initSize);
-  },
-};

+ 0 - 56
src/mixins/map/mapDataMixin.js

@@ -1,56 +0,0 @@
-export default {
-  data() {
-    return {
-      routeName: "2dshow",
-      currentFloor: 1,
-      totalFlrNum: 1,
-      isShowFlr: true,
-    };
-  },
-  watch: {
-    "$route.query.warehouse": {
-      handler(newVal) {
-        if (this.$route.name === this.routeName) {
-          this.fetchMapData(newVal);
-        }
-      },
-      immediate: true,
-    },
-  },
-  methods: {
-    fetchMapData() {
-      if (!this.$route.query.warehouse) {
-        this.commonAction(null);
-        return;
-      }
-      const warehouse = JSON.parse(this.$route.query.warehouse);
-      if (!warehouse || !warehouse.id) {
-        this.commonAction(null);
-        return;
-      }
-      this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "GetMapConfig",
-          param: { id: warehouse.id },
-        },
-      })
-        .then((response) => {
-          this.commonAction(response);
-        })
-        .catch((error) => {
-          console.error("获取地图数据失败:", error);
-          this.$message.error("获取地图数据失败");
-        });
-    },
-    commonAction(response) {
-      this.totalFlrNum = (response && response.data.floor) || 1;
-      this.isShowFlr = this.totalFlrNum >= 1;
-      this.$refs.gridCanvasRef?.initData(
-        { row: response && response.data },
-        true
-      );
-    },
-  },
-};

+ 0 - 27
src/mixins/map/renderStrategies/BaseRenderStrategy.js

@@ -1,27 +0,0 @@
-export default class BaseRenderStrategy {
-  constructor() {
-    if (this.constructor === BaseRenderStrategy) {
-      throw new Error('BaseRenderStrategy is an abstract class');
-    }
-  }
-
-  initRenderer() {
-    throw new Error('Must implement initRenderer');
-  }
-
-  drawAct() {
-    throw new Error('Must implement drawAct');
-  }
-
-  renderCells() {
-    throw new Error('Must implement renderCells');
-  }
-
-  updateSize() {
-    throw new Error('Must implement updateSize');
-  }
-
-  dispose() {
-    throw new Error('Must implement dispose');
-  }
-} 

+ 0 - 20
src/mixins/map/renderStrategies/RenderStrategyFactory.js

@@ -1,20 +0,0 @@
-import SvgRenderStrategy from './SvgRenderStrategy';
-// import CanvasRenderStrategy from './CanvasRenderStrategy';
-// import WebGLRenderStrategy from './WebGLRenderStrategy';
-
-export default class RenderStrategyFactory {
-  static createStrategy(type, component) {
-    switch (type) {
-      case 'svg':
-        return new SvgRenderStrategy(component);
-      case 'canvas':
-        // return new CanvasRenderStrategy(component);
-        throw new Error('Canvas renderer not implemented');
-      case 'webgl':
-        // return new WebGLRenderStrategy(component);
-        throw new Error('WebGL renderer not implemented');
-      default:
-        throw new Error(`Unknown render type: ${type}`);
-    }
-  }
-} 

+ 0 - 1106
src/mixins/map/renderStrategies/SvgRenderStrategy.js

@@ -1,1106 +0,0 @@
-import BaseRenderStrategy from "./BaseRenderStrategy";
-import * as d3 from "d3";
-import { ITEMSTATUS } from "@/components/map//GRID-CONST";
-export default class SvgRenderStrategy extends BaseRenderStrategy {
-  constructor(component) {
-    super();
-    this.component = component;
-    this.svg = null;
-    this.zoom = null;
-    this.mainGroup = null;
-    this.selectedCell = null;
-    this.originalStyles = null; // 保存原始样式
-    // 添加一个Map来存储polygon和cell的映射关系
-    this.cellDataMap = new WeakMap();
-  }
-
-  calculateViewBox(containerWidth, containerHeight, canvasWidth, canvasHeight) {
-    // 计算宽高比
-    const viewBoxRatio = canvasWidth / canvasHeight;
-    const containerRatio = containerWidth / containerHeight;
-
-    // 计算viewBox尺寸
-    let viewBoxWidth, viewBoxHeight;
-    if (viewBoxRatio > containerRatio) {
-      // 如果画布更宽,以宽度为基准
-      viewBoxWidth = canvasWidth;
-      viewBoxHeight = canvasWidth / containerRatio;
-    } else {
-      // 如果画布更高,以高度为基准
-      viewBoxHeight = canvasHeight;
-      viewBoxWidth = canvasHeight * containerRatio;
-    }
-
-    // 计算viewBox的起始位置,使内容居中
-    const viewBoxX = (viewBoxWidth - canvasWidth) / -2;
-    const viewBoxY = (viewBoxHeight - canvasHeight) / -2;
-
-    // 计算内边距
-    const padding = Math.min(viewBoxWidth, viewBoxHeight) * 0.1; // 10%的内边距
-
-    return {
-      x: viewBoxX - padding,
-      y: viewBoxY - padding,
-      width: viewBoxWidth + padding * 2,
-      height: viewBoxHeight + padding * 2,
-    };
-  }
-
-  setViewBox(container) {
-    if (!this.svg || !container) return;
-
-    // 获取容器尺寸
-    const containerWidth = container.clientWidth || 800;
-    const containerHeight = container.clientHeight || 600;
-
-    // 获取实际渲染内容的尺寸,如果未定义则使用容器尺寸
-    const renderWidth = this.component.renderTotalWidth || containerWidth;
-    const renderHeight = this.component.renderTotalHeight || containerHeight;
-
-    // 验证尺寸是否有效
-    if (
-      isNaN(renderWidth) ||
-      isNaN(renderHeight) ||
-      renderWidth <= 0 ||
-      renderHeight <= 0
-    ) {
-      console.warn("无效的渲染尺寸,使用容器尺寸");
-      // 使用容器尺寸作为后备方案
-      this.svg.setAttribute("width", containerWidth);
-      this.svg.setAttribute("height", containerHeight);
-      this.svg.setAttribute(
-        "viewBox",
-        `0 0 ${containerWidth} ${containerHeight}`
-      );
-      return;
-    }
-
-    // 设置 SVG 元素尺寸为容器尺寸
-    this.svg.setAttribute("width", containerWidth);
-    this.svg.setAttribute("height", containerHeight);
-
-    // 计算缩放比例
-    const scaleX = containerWidth / renderWidth;
-    const scaleY = containerHeight / renderHeight;
-    const scale = Math.min(scaleX, scaleY);
-
-    // 计算居中所需的偏移量
-    const offsetX = (containerWidth - renderWidth * scale) / 2;
-    const offsetY = (containerHeight - renderHeight * scale) / 2;
-
-    // 设置viewBox,使内容居中显示
-    this.svg.setAttribute(
-      "viewBox",
-      `${-offsetX / scale} ${-offsetY / scale} ${containerWidth / scale} ${
-        containerHeight / scale
-      }`
-    );
-
-    // 设置mainGroup的初始变换,使其居中
-    if (this.mainGroup) {
-      this.mainGroup.setAttribute(
-        "transform",
-        `translate(${offsetX}, ${offsetY}) scale(${scale})`
-      );
-    }
-  }
-
-  initRenderer() {
-    const container = this.component.$refs.wareHouseArea;
-    if (!container) {
-      console.warn("Container not found");
-      return;
-    }
-
-    // 清除已存在的 SVG
-    const existingSvg = container.querySelector("svg");
-    if (existingSvg) {
-      container.removeChild(existingSvg);
-    }
-
-    // 创建 SVG 元素
-    this.svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
-
-    // 设置SVG尺寸和视口
-    this.setViewBox(container);
-
-    // 创建主要的 group 元素
-    this.mainGroup = document.createElementNS(
-      "http://www.w3.org/2000/svg",
-      "g"
-    );
-    this.svg.appendChild(this.mainGroup);
-
-    // 添加到容器中
-    container.appendChild(this.svg);
-
-    // this.testData();
-
-    // 初始化缩放行为
-    this.component.$nextTick(() => {
-      this.initZoom();
-    });
-
-    // 添加事件监听 - 点击空白区域取消选中
-    this.svg.addEventListener("click", (event) => {
-      if (event.target === this.svg || event.target === this.mainGroup) {
-        this.clearSelection();
-      }
-    });
-
-    // 添加SVG的右键点击事件监听
-    this.svg.addEventListener("contextmenu", (event) => {
-      if (event.target === this.svg || event.target === this.mainGroup) {
-        event.preventDefault();
-        this.clearSelection();
-      }
-    });
-  }
-  testData() {
-    // 添加测试数据
-    this.component.goodsVisObj = {
-      // 格式: "楼层-列-行": 状态值
-      "1-12-13": 1, // 1层2列3行有货物
-      "1-13-13": 1, // 1层3列3行有货物
-      "1-14-13": 1, // 1层4列3行有货物
-      "2-12-14": 1, // 2层2列4行有货物
-      "2-13-14": 1, // 2层3列4行有货物
-    };
-
-    // 添加传送带测试数据
-    this.component.conveyorAroundMap = {
-      "1-15-11": 1, // 1层5列1行有传送带
-      "1-15-12": 1, // 1层5列2行有传送带
-      "1-15-13": 1, // 1层5列3行有传送带
-      "2-15-11": 1, // 2层5列1行有传送带
-    };
-    this.component.shuttleVisObj = {
-      1: {
-        baseInfo: {
-          sid: "1",
-          f: 2,
-          r: 14,
-          c: 15,
-          items: "00", // 表示载货状态,第一位是货物,第二位是托盘
-          steps: [
-            { f: 2, r: 14, c: 13 },
-            { f: 2, r: 14, c: 14 },
-            { f: 2, r: 14, c: 15 },
-            { f: 2, r: 14, c: 16 },
-            { f: 2, r: 14, c: 17 },
-          ],
-          step_index: 2,
-        },
-      },
-      2: {
-        baseInfo: {
-          sid: "2",
-          f: 1,
-          r: 12,
-          c: 19,
-          items: "00", // 只载托盘无货物
-          steps: [
-            { f: 1, r: 12, c: 17 },
-            { f: 1, r: 12, c: 18 },
-            { f: 1, r: 12, c: 19 },
-            { f: 1, r: 12, c: 20 },
-            { f: 1, r: 12, c: 21 },
-          ],
-          step_index: 3,
-        },
-      },
-    };
-  }
-
-  initZoom() {
-    if (!this.svg) return;
-    try {
-      this.zoom = d3
-        .zoom()
-        .scaleExtent([0.01, 50])
-        .on("zoom", () => {
-          const transform = d3.event.transform;
-          // 验证transform值是否有效
-          if (isNaN(transform.x) || isNaN(transform.y) || isNaN(transform.k)) {
-            console.warn("无效的transform值");
-            return;
-          }
-          this.mainGroup.setAttribute(
-            "transform",
-            `translate(${transform.x}, ${transform.y}) scale(${transform.k})`
-          );
-        });
-
-      // 将缩放行为应用到 SVG 上
-      d3.select(this.svg).call(this.zoom);
-
-      // 设置初始变换
-      const initialTransform = d3.zoomIdentity.translate(0, 0).scale(1);
-      d3.select(this.svg).call(this.zoom.transform, initialTransform);
-    } catch (error) {
-      console.warn("初始化缩放失败:", error);
-    }
-  }
-  resetTransform() {
-    if (!this.svg || !this.zoom) return;
-
-    try {
-      // 重置为初始变换状态
-      const initialTransform = d3.zoomIdentity.translate(0, 0).scale(1);
-
-      // 使用过渡动画平滑重置
-      d3.select(this.svg)
-        .transition()
-        .duration(750) // 动画持续时间,单位为毫秒
-        .call(this.zoom.transform, initialTransform);
-
-      // 更新主组的变换属性
-      this.mainGroup.setAttribute("transform", `translate(0, 0) scale(1)`);
-    } catch (error) {
-      console.warn("重置变换失败:", error);
-    }
-  }
-
-  drawAct() {
-    if (!this.svg) return;
-
-    // 清空cellDataMap
-    this.cellDataMap = new WeakMap();
-
-    // 修改清空逻辑,只清空 mainGroup
-    while (this.mainGroup.firstChild) {
-      this.mainGroup.removeChild(this.mainGroup.firstChild);
-    }
-
-    this.fillOffsetBackGroundColor();
-    // 渲染单元格
-    this.renderCells();
-    this.renderStructElements();
-    // 渲染动态元素
-    this.renderDynamicElements();
-  }
-
-  renderCells() {
-    const pageFloorGridDataObj = this.component.pageFloorGridDataObj;
-    if (!pageFloorGridDataObj) return;
-
-    Object.keys(pageFloorGridDataObj).forEach((floorNum) => {
-      const floorData = pageFloorGridDataObj[floorNum];
-      floorData.forEach((row) => {
-        row.forEach((cell) => {
-          this.renderCell(cell);
-          this.renderStackableCell(cell);
-        });
-      });
-    });
-  }
-  renderStackableCell(cell) {
-    if (!cell.statusList || cell.statusList.length < 1) return;
-    const statusList = cell.statusList;
-    for (let i = 0; i < statusList.length; i++) {
-      const status = statusList[i];
-      const itemStsCfgInfo = this.component.itemStsMap[status.status];
-      if (itemStsCfgInfo && itemStsCfgInfo.drawFunSvg) {
-        itemStsCfgInfo.drawFunSvg(this, cell);
-      }
-    }
-  }
-
-  renderCell(cell, noNum = false) {
-    const group = this.createSvgElement("g");
-    const polygon = this.createPolygon(cell);
-    // 保存polygon和cell的映射关系
-    this.cellDataMap.set(polygon, cell);
-    group.appendChild(polygon);
-
-    if (!noNum && this.component.isShowNumInCell && cell.type !== "around") {
-      const { flrNum, rowIndex, colIndex } = cell;
-      if (
-        !(
-          flrNum === undefined ||
-          rowIndex === undefined ||
-          colIndex === undefined
-        )
-      ) {
-        let { backR, backC } = cell;
-        if (backR === undefined || backC === undefined) {
-          const backEle = this.component.pageIdxToBusiIndx(
-            cell,
-            this.component.rotationAngleType,
-            true,
-            false
-          );
-          backR = backEle.backR;
-          backC = backEle.backC;
-        }
-
-        const text = this.createCellText(cell, backR, backC);
-        group.appendChild(text);
-      }
-    }
-
-    // 添加左键点击事件
-    group.addEventListener("click", (event) => {
-      event.preventDefault();
-      event.stopPropagation();
-      this.component.showContextMenu = false;
-      this.handleCellClick(group, cell);
-    });
-
-    // 添加右键点击事件
-    group.addEventListener("contextmenu", (event) => {
-      event.preventDefault();
-      event.stopPropagation();
-      this.handleCellRightClick(event, cell);
-    });
-
-    // 添加双击事件
-    group.addEventListener("dblclick", (event) => {
-      event.preventDefault();
-      event.stopPropagation();
-      this.handleCellDoubleClick(event, cell);
-    });
-
-    this.mainGroup.appendChild(group);
-    return group;
-  }
-
-  handleCellClick(element, cell) {
-    // 如果点击的是已选中的单元格,取消选中
-    if (this.selectedCell === element) {
-      this.clearSelection();
-      return;
-    }
-
-    // 清除之前的选中状态
-    this.clearSelection();
-
-    // 保存原始样式
-    const polygon = element.querySelector("polygon");
-    if (polygon) {
-      this.originalStyles = {
-        stroke: polygon.getAttribute("stroke"),
-        strokeWidth: polygon.getAttribute("stroke-width"),
-      };
-
-      // 设置新选中单元格的样式
-      polygon.setAttribute(
-        "stroke",
-        this.component.scssVariables.selGridBorderColor
-      );
-      polygon.setAttribute("stroke-width", "2");
-    }
-
-    // 创建新的选中效果层
-    const selectedEffect = this.createSelectedEffect(element);
-    this.mainGroup.appendChild(selectedEffect);
-
-    // 更新选中的单元格引用
-    this.selectedCell = element;
-
-    // 触发选中事件
-    this.component.$emit("cell-selected", cell);
-  }
-
-  // 新增方法:创建选中效果
-  createSelectedEffect(element) {
-    const polygon = element.querySelector("polygon");
-    const points = polygon.getAttribute("points");
-
-    const selectedPolygon = this.createSvgElement("polygon", {
-      points: points,
-      fill: "none",
-      stroke: this.component.scssVariables.selGridBorderColor,
-      "stroke-width": "2",
-      "pointer-events": "none",
-    });
-
-    return selectedPolygon;
-  }
-
-  handleCellRightClick(event, cell) {
-    // 设置右键菜单位置,使用页面坐标
-    this.component.contextMenuPosition = {
-      x: event.pageX, // 使用pageX替代clientX
-      y: event.pageY, // 使用pageY替代clientY
-    };
-
-    // 保存当前右键点击的单元格数据
-    this.component.curCell = cell;
-
-    this.component.showContextMenu = true;
-    event.preventDefault();
-    event.stopPropagation();
-  }
-
-  handleCellDoubleClick(event, cell) {
-    this.component.handleDoubleClick(event, cell);
-  }
-
-  clearSelection() {
-    if (this.selectedCell && this.originalStyles) {
-      // 恢复原始样式
-      const polygon = this.selectedCell.querySelector("polygon");
-      if (polygon) {
-        polygon.setAttribute("stroke", this.originalStyles.stroke);
-        polygon.setAttribute("stroke-width", this.originalStyles.strokeWidth);
-      }
-
-      // 移除所有选中效果层
-      const selectedEffects = this.mainGroup.querySelectorAll(
-        'polygon[stroke="' +
-          this.component.scssVariables.selGridBorderColor +
-          '"]'
-      );
-      selectedEffects.forEach((effect) => {
-        if (effect.getAttribute("pointer-events") === "none") {
-          effect.parentNode.removeChild(effect);
-        }
-      });
-
-      this.selectedCell = null;
-      this.originalStyles = null;
-
-      // 清理右键菜单相关数据
-      this.component.curCell = null;
-      this.component.curEvent = null;
-      this.component.showContextMenu = false;
-
-      // 触发取消选中事件
-      this.component.$emit("cell-unselected");
-    }
-  }
-
-  renderDynamicElements() {
-    this.renderGoods(this.component.goodsVisObj);
-    this.renderGoods(this.component.conveyorAroundMap);
-    this.renderPaths();
-    this.renderShuttles();
-  }
-  renderStructElements() {
-    this.renderFlrNum();
-    this.renderFlrBottomLine();
-  }
-  fillOffsetBackGroundColor() {
-    // 获取第一层数据来确定三角形的顶点
-    const flrData =
-      this.component.pageFloorGridDataObj[this.component.totalFlr];
-    if (!flrData || flrData.length < 1) return;
-
-    // 获取第一行和最后一行的数据
-    const oneFlrFirstRow = flrData[0];
-    const oneFlrLastRow = flrData[flrData.length - 1];
-    const lastFlrData = this.component.pageFloorGridDataObj[1];
-    const lastFlrFirstRow = lastFlrData[0];
-    const lastFlrLastRow = lastFlrData[lastFlrData.length - 1];
-    if (
-      !oneFlrFirstRow ||
-      !oneFlrLastRow ||
-      !lastFlrFirstRow ||
-      !lastFlrLastRow
-    )
-      return;
-    // 获取关键点的坐标
-    const offsetX = this.component.warehousPageCfg.rowOffsetX;
-    const offsetY = this.component.warehousPageCfg.colOffsetY;
-
-    // 上方三角形 (A-B-C) 的坐标点
-    const bgPoints = [
-      [oneFlrLastRow[0].x4 + offsetX, 0], //左上
-      [oneFlrFirstRow[oneFlrFirstRow.length - 1].x2 + offsetX, 0], //右上
-      [
-        oneFlrFirstRow[oneFlrFirstRow.length - 1].x2 + offsetX,
-        lastFlrLastRow[0].y4 + offsetY * 2,
-      ],
-      [oneFlrLastRow[0].x4 + offsetX, lastFlrLastRow[0].y4 + offsetY * 2], //左下
-      //右下
-    ];
-
-    const bgTriangle = this.createSvgElement("polygon", {
-      points: bgPoints.map((point) => point.join(",")).join(" "),
-      fill: this.component.scssVariables.offsetBackGroundColor,
-      stroke: "none",
-    });
-
-    this.mainGroup.appendChild(bgTriangle);
-  }
-  renderFlrBottomLine() {
-    for (let i = 1; i <= this.component.totalFlr; i++) {
-      const flrData = this.component.pageFloorGridDataObj[i];
-      if (!flrData || flrData.length < 1) continue;
-      const firstRow = flrData[0];
-      const firstRowLastCol = firstRow[firstRow.length - 1];
-      const lastRow = flrData[flrData.length - 1];
-      const lastRowFirstCol = lastRow[0];
-      const offset = this.component.flrVehSpace / 2;
-      const firstCell = {
-        x: lastRowFirstCol.x4,
-        y: lastRowFirstCol.y4 + offset,
-      };
-      const lastCell = {
-        x: firstRowLastCol.x2,
-        y: lastRowFirstCol.y4 + offset,
-      };
-      const line = document.createElementNS(
-        "http://www.w3.org/2000/svg",
-        "line"
-      );
-      line.setAttribute(
-        "x1",
-        firstCell.x + this.component.warehousPageCfg.rowOffsetX
-      );
-      line.setAttribute(
-        "y1",
-        firstCell.y + this.component.warehousPageCfg.colOffsetY
-      );
-      line.setAttribute(
-        "x2",
-        lastCell.x + this.component.warehousPageCfg.rowOffsetX
-      );
-      line.setAttribute(
-        "y2",
-        lastCell.y + this.component.warehousPageCfg.colOffsetY
-      );
-      line.setAttribute(
-        "stroke",
-        this.component.scssVariables.flrBottomLineColor
-      );
-      line.setAttribute("stroke-width", this.component.flrVehSpace);
-      this.mainGroup.appendChild(line);
-    }
-  }
-  renderFlrNum() {
-    Object.keys(this.component.pageFloorGridDataObj).forEach((flrNum) => {
-      const { currentPageFloorNum, positionInPageFloorNum } =
-        this.component.calcCurPageFloor(
-          Number(flrNum),
-          this.component.totalHorizontalFlrPer
-        );
-
-      const pos = this.component.getCellPos(
-        0,
-        0,
-        currentPageFloorNum,
-        positionInPageFloorNum
-      );
-      const text = this.createFloorText(pos, flrNum);
-      this.mainGroup.appendChild(text);
-    });
-  }
-  renderShuttles() {
-    const shuttleArr = Object.keys(this.component.shuttleVisObj);
-    if (!shuttleArr || shuttleArr.length < 1) {
-      return;
-    }
-    for (let i = 0; i < shuttleArr.length; i++) {
-      const key = shuttleArr[i];
-      const shuttle = this.component.shuttleVisObj[key];
-      const baseInfo = shuttle.baseInfo;
-      const f = baseInfo.f;
-      const c = baseInfo.c;
-      const r = baseInfo.r;
-      const compuItem = this.component.busiIndxToPageIdx(
-        { r: r, c: c },
-        this.component.rotationAngleType
-      );
-      const ele = this.component.getTheItem(compuItem.r, compuItem.c, f);
-      if (ele) {
-        const locShuttle = JSON.parse(JSON.stringify(ele));
-        this.component.itemStsInit(locShuttle, ITEMSTATUS.shuttle);
-        locShuttle["type"] = ITEMSTATUS.shuttle;
-        if (
-          ele.status === ITEMSTATUS.goods ||
-          (ele.status === ITEMSTATUS.default && ele.type === LOCTYPE.rack)
-        ) {
-          const backEle = this.component.pageIdxToBusiIndx(
-            { f: ele.flrNum, c: ele.colIndex, r: ele.rowIndex },
-            this.component.rotationAngleType
-          );
-          const id = this.component.idKey(backEle);
-          if (
-            this.component.goodsVisObj[id] ||
-            this.component.conveyorAroundMap[id]
-          ) {
-            locShuttle.isUnderGood = true;
-          }
-        }
-        this.parallelogramDrawShuttle(locShuttle);
-        const goodTypeStr = baseInfo.items && baseInfo.items[0];
-        const goodType = goodTypeStr && parseInt(goodTypeStr);
-        const palletTypeStr = baseInfo.items && baseInfo.items[1];
-        const palletType = goodTypeStr && parseInt(palletTypeStr);
-        if (goodType || palletType) {
-          const goodsPageEle = this.component.getParallelogramByPageEle(ele);
-          this.component.itemStsInit(goodsPageEle, ITEMSTATUS.goods);
-          goodsPageEle.borderColor =
-            this.component.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-          this.renderCell(goodsPageEle, true);
-        }
-      }
-    }
-  }
-  parallelogramDrawShuttle(shuttleData) {
-    if (!this.component.shuttleImg || !this.component.shuttleImg.src) {
-      console.warn("Shuttle image not loaded");
-      return;
-    }
-    const group = this.createSvgElement("g");
-
-    // 绘制基础平行四边形
-    const polygon = this.createPolygon(shuttleData);
-    group.appendChild(polygon);
-
-    // 获取带偏移量的坐标点
-    const offsetX = this.component.warehousPageCfg.rowOffsetX;
-    const offsetY = this.component.warehousPageCfg.colOffsetY;
-
-    // 计算变换参数
-    const x1 = shuttleData.x1 + offsetX;
-    const y1 = shuttleData.y1 + offsetY;
-    const x2 = shuttleData.x2 + offsetX;
-    const y2 = shuttleData.y2 + offsetY;
-    const x3 = shuttleData.x3 + offsetX;
-    const y3 = shuttleData.y3 + offsetY;
-    // 计算宽度和高度
-    const width = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
-    const height = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2));
-
-    // 根据倾斜角度计算所需padding
-    const angle = this.component.includedAngle || 90; // 默认90度
-    const angleInRadians = (angle * Math.PI) / 180;
-    const padding = Math.max(
-      width * Math.abs(Math.cos(angleInRadians)),
-      height * Math.abs(Math.sin(angleInRadians))
-    );
-
-    const extendedWidth = width + padding * 2;
-    const extendedHeight = height + padding * 2;
-
-    // 创建唯一的pattern ID
-    const patternId = `shuttlePattern-${Date.now()}-${Math.random()
-      .toString(36)
-      .substr(2, 9)}`;
-
-    // 创建图案定义
-    const pattern = this.createSvgElement("pattern", {
-      id: patternId,
-      patternUnits: "userSpaceOnUse",
-      width: extendedWidth,
-      height: extendedHeight,
-      patternTransform: `translate(${x1 - padding},${y1 - padding})`, // 调整起始位置
-    });
-
-    // 创建一个包含图片的SVG元素
-    const svgInPattern = this.createSvgElement("svg", {
-      width: extendedWidth,
-      height: extendedHeight,
-      overflow: "visible",
-    });
-
-    // 计算变换矩阵,考虑padding
-    const a = (x2 - x1) / width;
-    const b = (y2 - y1) / width;
-    const c = (x3 - x2) / height;
-    const d = (y3 - y2) / height;
-    const e = padding; // x方向的偏移
-    const f = padding; // y方向的偏移
-
-    // 创建图片元素
-    const image = this.createSvgElement("image", {
-      href: this.component.shuttleImg.src,
-      width: width,
-      height: height,
-      preserveAspectRatio: "none",
-      transform: `matrix(${a},${b},${c},${d},${e},${f})`, // 添加偏移量
-    });
-
-    svgInPattern.appendChild(image);
-    pattern.appendChild(svgInPattern);
-
-    let defs = this.svg.querySelector("defs");
-    if (!defs) {
-      defs = this.createSvgElement("defs");
-      this.svg.appendChild(defs);
-    }
-    defs.appendChild(pattern);
-
-    // 创建使用图案的多边形
-    const filledPolygon = this.createPolygon(shuttleData, {
-      fill: `url(#${patternId})`,
-      stroke: shuttleData.borderColor,
-      "stroke-width": shuttleData.lineWidth,
-    });
-
-    group.appendChild(filledPolygon);
-
-    if (shuttleData.isUnderGood) {
-      // 从颜色中提取RGB部分
-      const baseColor =
-        this.component.itemStsMap[ITEMSTATUS.goods].sty.fillColor;
-      const rgbColor = baseColor.substring(0, 7); // 只取 #RRGGBB 部分
-      const overlay = this.createPolygon(shuttleData, {
-        fill: `${rgbColor}40`, // 只使用RGB颜色值,添加40的透明度
-        stroke: "none",
-        "pointer-events": "none",
-      });
-      group.appendChild(overlay);
-    }
-
-    this.mainGroup.appendChild(group);
-    return group;
-  }
-
-  renderGoods(visObj) {
-    const goodsAddrArr = Object.keys(visObj);
-    if (!goodsAddrArr || goodsAddrArr.length < 1) return;
-
-    goodsAddrArr.forEach((addr) => {
-      const [f, c, r] = this.component.rCFStrToArr(addr);
-      if (!this.component.pageFloorGridDataObj[f] || !visObj[addr]) return;
-
-      const compuItem = this.component.busiIndxToPageIdx(
-        { r, c },
-        this.component.rotationAngleType
-      );
-
-      const ele = this.component.getTheItem(compuItem.r, compuItem.c, f);
-      if (!ele) return;
-
-      const newItem = JSON.parse(JSON.stringify(ele));
-      this.component.itemStsInit(newItem, ITEMSTATUS.goods);
-      this.renderCell(newItem);
-    });
-  }
-
-  renderPaths() {
-    const shuttleArr = Object.keys(this.component.shuttleVisObj);
-    if (!shuttleArr || shuttleArr.length < 1) return;
-
-    shuttleArr.forEach((shuttleKey) => {
-      const shuttle = this.component.shuttleVisObj[shuttleKey];
-      if (!shuttle?.baseInfo?.steps || shuttle.baseInfo.steps.length < 1) {
-        return;
-      }
-
-      const step_index = shuttle.baseInfo.step_index;
-      const steps = shuttle.baseInfo.steps;
-      const pathArr = [];
-      const pathArrBef = [];
-
-      // 收集路径点
-      steps.forEach((stepItem, j) => {
-        const { f, r, c } = stepItem;
-        const compuItem = this.component.busiIndxToPageIdx(
-          { r, c },
-          this.component.rotationAngleType
-        );
-        const ele = this.component.getTheItem(compuItem.r, compuItem.c, f);
-        if (!ele) {
-          return;
-        }
-
-        const centerPos = this.component.getCellCenterPos(ele);
-
-        if (j < step_index) {
-          pathArrBef.push(centerPos);
-        } else if (j === step_index) {
-          pathArrBef.push(centerPos);
-          pathArr.push(centerPos);
-        } else {
-          pathArr.push(centerPos);
-        }
-      });
-
-      // 获取仓库的穿梭车颜色配置
-      const warehouseColors =
-        window.warehouseShuttleColors?.[this.component.wareHouseId];
-      const shuttleColors = warehouseColors?.[shuttleKey];
-
-      // 使用全局存储的颜色或默认值
-      const passedColor =
-        shuttleColors?.path_passed_color ||
-        this.component.scssVariables.pathHasDrived;
-      const toPassColor =
-        shuttleColors?.path_color || this.component.scssVariables.path;
-      // 绘制未经过的路径
-      if (pathArr.length > 1) {
-        this.drawPathLine(pathArr, toPassColor);
-      }
-
-      // 绘制已经过的路径
-      if (pathArrBef.length > 1) {
-        this.drawPathLine(pathArrBef, passedColor);
-      }
-    });
-  }
-
-  drawPathLine(points, color) {
-    if (!points || points.length < 2) {
-      console.warn("路径点数不足,无法绘制");
-      return;
-    }
-    // 创建路径数据
-    const pathData = points.reduce((acc, point, index) => {
-      const x = this.component.calculateCoordinate(point.x, "x");
-      const y = this.component.calculateCoordinate(point.y, "y");
-      return acc + (index === 0 ? `M ${x},${y}` : ` L ${x},${y}`);
-    }, "");
-
-    // 创建路径元素
-    const path = this.createSvgElement("path", {
-      d: pathData,
-      stroke: color,
-      "stroke-width": this.component.itemStsMap[ITEMSTATUS.path].sty.lineWidth,
-      fill: "none",
-      "stroke-linecap": "round",
-      "stroke-linejoin": "round",
-    });
-    this.mainGroup.appendChild(path);
-  }
-
-  updateSize() {
-    if (!this.svg || !this.component.$refs.wareHouseArea) return;
-
-    // 更新SVG尺寸和视口
-    this.setViewBox(this.component.$refs.wareHouseArea);
-  }
-
-  dispose() {
-    // 清理缩放行为
-    if (this.zoom) {
-      d3.select(this.svg).on(".zoom", null);
-      this.zoom = null;
-    }
-
-    // 清理资源
-    if (this.svg && this.svg.parentNode) {
-      this.svg.parentNode.removeChild(this.svg);
-    }
-    this.svg = null;
-
-    if (this.svg) {
-      this.svg.removeEventListener("click", this.clearSelection);
-    }
-    this.selectedCell = null;
-    this.mainGroup = null;
-    this.originalStyles = null;
-    this.cellDataMap = new WeakMap();
-  }
-
-  // SVG元素创建和属性设置的通用方法
-  createSvgElement(type, attributes = {}) {
-    const element = document.createElementNS(
-      "http://www.w3.org/2000/svg",
-      type
-    );
-    Object.entries(attributes).forEach(([key, value]) => {
-      element.setAttribute(key, value);
-    });
-    return element;
-  }
-
-  // 计算带偏移量的坐标点
-  calculateOffsetPoints(item) {
-    const offsetX = this.component.warehousPageCfg.rowOffsetX;
-    const offsetY = this.component.warehousPageCfg.colOffsetY;
-
-    return [
-      `${item.x1 + offsetX},${item.y1 + offsetY}`,
-      `${item.x2 + offsetX},${item.y2 + offsetY}`,
-      `${item.x3 + offsetX},${item.y3 + offsetY}`,
-      `${item.x4 + offsetX},${item.y4 + offsetY}`,
-    ].join(" ");
-  }
-
-  // 创建多边形的通用方法
-  createPolygon(item, attributes = {}) {
-    return this.createSvgElement("polygon", {
-      points: this.calculateOffsetPoints(item),
-      fill: item.fillColor || this.component.scssVariables.gridFillColor,
-      stroke: item.borderColor || this.component.scssVariables.gridBorderColor,
-      "stroke-width":
-        item.lineWidth || this.component.scssVariables.gridLineWidth,
-      ...attributes,
-    });
-  }
-  // 创建文本元素的通用方法
-  createText(content, attributes = {}) {
-    const text = this.createSvgElement("text", {
-      "font-family": "Arial",
-      "text-anchor": "middle",
-      "dominant-baseline": "central",
-      "pointer-events": "none",
-      ...attributes,
-    });
-    text.textContent = content;
-    return text;
-  }
-
-  // 计算文本大小和调整
-  calculateTextSize(text, baseFontSize, maxWidth) {
-    const textWidth = text.length * (baseFontSize * 0.6);
-    if (textWidth > maxWidth) {
-      return Math.max(
-        Math.floor((maxWidth / textWidth) * baseFontSize),
-        Math.min(baseFontSize * 0.5, 9)
-      );
-    }
-    return baseFontSize;
-  }
-
-  // 获取基础字体大小
-  getBaseFontSize() {
-    return Math.min(this.component.cellWidth, this.component.cellLen) * 0.3;
-  }
-
-  // 创建单元格文本
-  createCellText(cell, backR, backC) {
-    const formattedText = `${cell.flrNum}-${backC}-${backR}`;
-    const centerPoint = this.component.calculateCenterPoint(cell);
-    const baseFontSize = this.getBaseFontSize();
-
-    const text = this.createText(formattedText, {
-      x: centerPoint.x,
-      y: centerPoint.y,
-      "font-size": `${baseFontSize}px`,
-      fill: "#666",
-      "pointer-events": "none",
-      "user-select": "none",
-    });
-
-    // 调整文本大小以适应单元格
-    const diagonalWidth = Math.abs(cell.x2 - cell.x1);
-    const usableWidth = diagonalWidth * 0.45;
-    const fontSize = this.calculateTextSize(
-      formattedText,
-      baseFontSize,
-      usableWidth
-    );
-    text.setAttribute("font-size", `${fontSize}px`);
-
-    return text;
-  }
-
-  // 创建楼层文本
-  createFloorText(pos, flrNum) {
-    const x =
-      pos.x1 -
-      this.component.flrHorizontalTotalHangLen +
-      this.component.warehousPageCfg.rowOffsetX +
-      24;
-    const y =
-      pos.y1 +
-      this.component.flrVehTotalLen / 2 +
-      this.component.warehousPageCfg.colOffsetY;
-
-    return this.createText(`${flrNum}层`, {
-      x,
-      y,
-      "font-size": "12px",
-      fill: "gray",
-    });
-  }
-
-  // 获取当前视觉状态
-  getSvgViewState() {
-    if (!this.svg || !this.zoom) return null;
-
-    try {
-      // 获取当前transform状态
-      const transform = d3.zoomTransform(this.svg);
-
-      return {
-        scale: transform.k,
-        translateX: transform.x,
-        translateY: transform.y,
-        timestamp: Date.now(),
-      };
-    } catch (error) {
-      console.warn("获取SVG视觉状态失败:", error);
-      return null;
-    }
-  }
-
-  // 恢复视觉状态
-  restoreSvgViewState(viewState) {
-    if (!this.svg || !this.zoom || !viewState) return;
-
-    try {
-      // 创建transform对象
-      const transform = d3.zoomIdentity
-        .translate(viewState.translateX, viewState.translateY)
-        .scale(viewState.scale);
-
-      // 使用过渡动画平滑恢复状态
-      d3.select(this.svg)
-        .transition()
-        .duration(750)
-        .call(this.zoom.transform, transform);
-
-      // 更新主组的变换属性
-      this.mainGroup.setAttribute(
-        "transform",
-        `translate(${viewState.translateX}, ${viewState.translateY}) scale(${viewState.scale})`
-      );
-
-      return true;
-    } catch (error) {
-      console.warn("恢复SVG视觉状态失败:", error);
-      return false;
-    }
-  }
-  // 保存视觉状态到localStorage
-  saveViewState(wareHouseId) {
-    const viewState = this.getSvgViewState();
-    if (viewState) {
-      try {
-        localStorage.setItem(
-          `svgViewState-${wareHouseId}`,
-          JSON.stringify(viewState)
-        );
-        return true;
-      } catch (error) {
-        console.warn("保存视觉状态到localStorage失败:", error);
-        return false;
-      }
-    }
-    return false;
-  }
-
-  // 从localStorage加载视觉状态
-  loadViewState(wareHouseId) {
-    // 确保必要的属性已经初始化
-    if (!this.component.renderTotalWidth || !this.component.renderTotalHeight) {
-      console.warn("渲染尺寸未初始化,跳过加载视觉状态");
-      return false;
-    }
-
-    try {
-      const savedState = localStorage.getItem(`svgViewState-${wareHouseId}`);
-      if (savedState) {
-        const viewState = JSON.parse(savedState);
-        if (viewState) {
-          return this.restoreSvgViewState(viewState);
-        } else {
-          localStorage.removeItem(`svgViewState-${wareHouseId}`);
-          console.warn("存储的视觉状态无效,已删除");
-        }
-      }
-    } catch (error) {
-      console.warn("从localStorage加载视觉状态失败:", error);
-      localStorage.removeItem(`svgViewState-${wareHouseId}`);
-    }
-    return false;
-  }
-
-  getCurrentSelectedCellData() {
-    if (!this.selectedCell) return null;
-
-    // 从选中的group元素中获取polygon元素
-    const polygon = this.selectedCell.querySelector("polygon");
-    if (!polygon) return null;
-
-    // 直接从WeakMap中获取cell数据
-    return this.cellDataMap.get(polygon) || null;
-  }
-}

+ 0 - 202
src/mixins/map/threeDOri.js

@@ -1,202 +0,0 @@
-const cssUrls = [
-  "./3d-orgin/assets/dist/admin/adminlte.min.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/font-awesome/css/font-awesome.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/magnific-popup/magnific-popup.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-datepicker/css/bootstrap-datepicker3.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.theme.min.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-timepicker/css/bootstrap-timepicker.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/pnotify/pnotify.custom.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/introjs/introjs.min.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/css/theme.css",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/css/skins/default.css",
-  "./3d-orgin/assets/3dconfigurator/css/index.css",
-];
-const scripts = [
-  "./3d-orgin/custom/pre.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/modernizr/modernizr.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery/jquery.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-browser-mobile/jquery.browser.mobile.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/popper/umd/popper.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap/js/bootstrap.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/nanoscroller/nanoscroller.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/pnotify/pnotify.custom.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-validation/jquery.validate.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/vendor/introjs/introjs.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/js/theme.js",
-  "./3d-orgin/assets/3dconfigurator/lib/ui/js/theme.init.js",
-  "./3d-orgin/assets/3dconfigurator/lib/pep.js",
-  "./3d-orgin/assets/3dconfigurator/lib/jspdf/svg64.js",
-  "./3d-orgin/assets/3dconfigurator/lib/jspdf/jspdf.umd.js",
-  "./3d-orgin/assets/3dconfigurator/lib/jspdf/jspdf.autotable.js",
-  "./3d-orgin/assets/3dconfigurator/lib/browser.maker.js",
-  "./3d-orgin/assets/3dconfigurator/lib/bezier.js",
-  "./3d-orgin/assets/3dconfigurator/lib/opentype.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/earcut.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/babylon.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/inspector.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/gui.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/serializers.js",
-  "./3d-orgin/assets/3dconfigurator/lib/babylon/babylon.glTF2FileLoader.js",
-  "./3d-orgin/assets/res/frontend/global.js",
-  "./3d-orgin/assets/res/frontend/globalByRowCol.js",
-  "./3d-orgin/assets/res/frontend/items.js",
-  "./3d-orgin/assets/res/frontend/templates.js",
-  "./3d-orgin/assets/res/frontend/behavior.js",
-  "./3d-orgin/assets/res/frontend/utils.js",
-  "./3d-orgin/assets/res/frontend/export.js",
-  "./3d-orgin/assets/res/frontend/simulation2.js",
-  "./3d-orgin/assets/res/frontend/itViewer.js",
-  "./3d-orgin/assets/3dconfigurator/js/index.js",
-  "./3d-orgin/assets/res/frontend/material.js",
-  "./3d-orgin/assets/res/frontend/loader.js",
-  "./3d-orgin/assets/res/frontend/rulers.js",
-  "./3d-orgin/assets/res/frontend/baseline.js",
-  "./3d-orgin/assets/res/frontend/warehouse.js",
-  "./3d-orgin/assets/res/frontend/tools.js",
-  "./3d-orgin/assets/3dconfigurator/js/icube2.js",
-  "./3d-orgin/custom/meshCommon.js",
-  "./3d-orgin/assets/3dconfigurator/js/icubeByRowCol.js",
-  "./3d-orgin/assets/res/frontend/tutorial.js",
-
-  "./3d-orgin/custom/fetch-data.js",
-  "./3d-orgin/custom/module/mouseTracking.js",
-  "./3d-orgin/custom/module/fileInputHandler.js",
-  "./3d-orgin/custom/module/modelLoader.js",
-  "./3d-orgin/custom/module/moveGoodsHandler.js",
-  "./3d-orgin/custom/module/pageVisiblity.js",
-  "./3d-orgin/custom/aroundMesh.js",
-  "./3d-orgin/custom/aroundProc.js",
-  "./3d-orgin/custom/objects.js",
-
-  "./3d-orgin/assets/res/frontend/main.js",
-  "./3d-orgin/custom/event.js",
-];
-export default {
-  created() {
-    // 确保在created钩子中初始化
-    this.initNonReactiveData();
-  },
-  mounted() {},
-  methods: {
-    initNonReactiveData() {
-      // 使用this.$options来存储非响应式数据
-      // 注意:这不是响应式的,Vue不会追踪这些数据的变化
-      this.$options.nonReactiveData = {
-        styleSheets: [],
-        scriptDoms: [],
-        selectedIcube: null,
-      };
-    },
-    load3DOri(warehouseId) {
-      console.log("load3DOri");
-      // 添加检查确保nonReactiveData已初始化
-      if (!this.$options.nonReactiveData) {
-        this.initNonReactiveData();
-      }
-
-      if (!this.$3dDe.loaded && !this.$3dDe.isLoading) {
-        const loading = this.$loading({
-          lock: true,
-          background: "rgba(0, 0, 0, 0.3)",
-        });
-        console.log("loading 1");
-        try {
-          this.$3dDe.isLoading = true;
-          this.downloadCss();
-          this.loadScripts()
-            .then(() => {
-              this.$3dDe.loaded = true;
-              console.log("loading over2");
-
-              // this.main() // Call actionDo after all scripts are loaded
-            })
-            .finally(() => {
-              this.loadScene(warehouseId);
-              console.log("loading over3");
-              this.$3dDe.isLoading = false;
-              loading.close();
-            });
-        } catch (error) {
-          console.error(error);
-        }
-      } else {
-        this.$nextTick(() => {
-          this.loadScene(warehouseId);
-        });
-      }
-    },
-    async loadScene(warehouseId) {
-      if (this.$3dDe.loaded && !this.$3dDe.isLoading) {
-        console.log("3d do again");
-        const sceneInfo = await window.mainThreeDFun(warehouseId);
-        this.$options.nonReactiveData.selectedIcube = sceneInfo.selectedIcube;
-      } else {
-        setTimeout(() => {
-          this.loadScene(warehouseId);
-        }, 1000);
-      }
-    },
-    main() {
-      if (typeof actionDo === "function") {
-        // eslint-disable-next-line no-undef
-        actionDo(); // Call actionDo after all scripts are loaded
-      } else {
-        console.log("actionDo is not defined or is not a function.");
-      }
-    },
-    downloadCss() {
-      cssUrls.forEach((url) => {
-        const link = document.createElement("link");
-        link.setAttribute("rel", "stylesheet");
-        link.setAttribute("type", "text/css");
-        link.setAttribute("href", url);
-        document.head.appendChild(link);
-        this.$options.nonReactiveData.styleSheets.push(link);
-      });
-    },
-    async loadScripts() {
-      for (const src of scripts) {
-        await this.loadScript(src);
-        // console.log(`Loaded script: ${src}`)
-      }
-      console.log("All scripts have been loaded and executed.");
-      // 在所有脚本加载完成后执行其他操作
-    },
-    async loadAllScripts() {
-      // Use Promise.all to wait for all scripts to load
-      await Promise.all(scripts.map((src) => this.loadScript(src)));
-      console.log("All scripts have been loaded and executed...");
-    },
-    loadScript(src) {
-      return new Promise((resolve, reject) => {
-        const script = document.createElement("script");
-        script.src = src;
-        script.defer = true;
-
-        script.onload = resolve;
-        script.onerror = reject;
-        document.head.appendChild(script);
-        this.$options.nonReactiveData.scriptDoms.push(script);
-      });
-    },
-    removeAllScripts() {
-      for (const src of this.$options.nonReactiveData.scriptDoms) {
-        src && src.parentNode.removeChild(src);
-        // const script = document.querySelector(`script[src="${src}"]`)
-        // if (script) {
-        //   script.parentNode.removeChild(script)
-        // }
-      }
-      console.log("All scripts have been removed.");
-    },
-    removeCss() {
-      this.$options.nonReactiveData.styleSheets.forEach((sheet) => {
-        sheet && document.head.removeChild(sheet);
-      });
-      console.log("All css have been removed.");
-    },
-  },
-};

+ 0 - 90
src/mixins/map/warehouseDataMixin.js

@@ -1,90 +0,0 @@
-/* eslint-disable */
-export default {
-  data() {
-    return {
-      warehouseId: null,
-    };
-  },
-
-  watch: {
-    "$route.query.warehouse": {
-      handler(newVal) {
-        if (this.$route.name === this.routeName) {
-          this.fetchWarehouseData();
-        }
-      },
-      immediate: true,
-    },
-  },
-
-  methods: {
-    async fetchWarehouseData() {
-      try {
-        const res = await this.getWarehouseData();
-        await this.handleWarehouseData(res.data);
-      } catch (error) {
-        console.error("获取仓库数据失败:", error);
-        this.handleError(error);
-      }
-    },
-
-    async handleWarehouseData(data, gridElement) {
-      const gridComponent = gridElement || this.getGridComponent();
-      if (!gridComponent) {
-        console.error("Grid component not found");
-        return;
-      }
-
-      if (!gridComponent.initData) {
-        console.error("initData method not found on grid component");
-        return;
-      }
-
-      try {
-        await gridComponent.initData({ row: data });
-      } catch (error) {
-        console.error("处理仓库数据失败:", error);
-        this.$message?.error?.("处理仓库数据失败");
-      }
-    },
-
-    getGridComponent() {
-      return this.$refs.gridSvg;
-    },
-
-    refreshWarehouseData() {
-      return this.fetchWarehouseData();
-    },
-
-    handleError(error) {
-      this.$message?.error?.("获取数据失败");
-    },
-
-    async getWarehouseData() {
-      const warehouseId = this.getWarehouseId();
-      if (!warehouseId) {
-        throw new Error("未找到仓库ID");
-      }
-
-      return await this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "GetMapConfig",
-          param: { id: warehouseId },
-        },
-      });
-    },
-
-    getWarehouseId() {
-      try {
-        const warehouse = this.$route.query.warehouse;
-        return warehouse ? JSON.parse(warehouse).id : null;
-      } catch (error) {
-        console.error("解析仓库ID失败:", error);
-        return null;
-      }
-    },
-  },
-};
-/* eslint-enable */

+ 0 - 21
src/mixins/map/warehouseRouteMixin.js

@@ -1,21 +0,0 @@
-export default {
-  beforeRouteEnter(to, from, next) {
-    next(vm => {
-      vm.handleWarehouseFromRoute(to.query.warehouse);
-    });
-  },
-
-  beforeRouteUpdate(to, from, next) {
-    this.handleWarehouseFromRoute(to.query.warehouse);
-    next();
-  },
-
-  methods: {
-    handleWarehouseFromRoute(warehouse) {
-      if (warehouse) {
-        this.warehouseData = typeof warehouse === 'string' ? 
-          JSON.parse(warehouse) : warehouse;
-      }
-    }
-  }
-};

+ 0 - 14
src/mixins/socket/componentLevel/sockeHeart.js

@@ -1,14 +0,0 @@
-window.maxRetryAttempts = 360
-window.currentRetryAttempts = 0
-setInterval(() => {
-  if (
-    !window.isSmulatingData &&
-    window.mesDoFunFun &&
-    (!window.wcsWebsocket ||
-      window.wcsWebsocket.readyState === WebSocket.CLOSED)
-  ) {
-    window.currentRetryAttempts++
-    console.error('第' + window.currentRetryAttempts + '次重连中...')
-    window.socketCreJs(window.mesDoFunFun)
-  }
-}, 10000)

+ 0 - 33
src/mixins/socket/componentLevel/socket.js

@@ -1,33 +0,0 @@
-/**
- * 场景:仓库状态实时展示
- * 处理socket相关业务
- */
-import "./socketJs.js";
-/**
- * 组件级别管理socket。点击组件,重连socket
- */
-export default {
-  beforeDestroy() {
-    this.socketDes();
-  },
-  // 缓存模式下页面离开
-  deactivated() {
-    this.socketDes();
-  },
-  methods: {
-    socketCre(fun) {
-      window.socketCreJs(fun, this.storeData);
-    },
-    socketDes() {
-      // 是否需要socket的全局标志位
-      window.mesDoFunFun = null;
-      if (
-        window.wcsWebsocket &&
-        window.wcsWebsocket.readyState === WebSocket.OPEN
-      ) {
-        window.wcsWebsocket.close(4000, "by clinet");
-        window.wcsWebsocket = null;
-      }
-    },
-  },
-};

+ 0 - 83
src/mixins/socket/componentLevel/socketJs.js

@@ -1,83 +0,0 @@
-import { startSimulate } from "@/map-test/dataSimulate";
-
-window.socketLog = false;
-let socketTimes = 0;
-window.socketCreJs = function (mesDoFun, data) {
-  const storeWareHouseId = localStorage.getItem("wareHouseId");
-  if (!storeWareHouseId) {
-    return;
-  }
-  window.mesDoFunFun = mesDoFun;
-  if (window.isSmulatingData) {
-    startSimulate(mesDoFun, data);
-    return;
-  }
-  if (
-    !window.wcsWebsocket ||
-    window.wcsWebsocket.readyState === WebSocket.CLOSED ||
-    window.wcsWebsocket.readyState === WebSocket.CLOSING
-  ) {
-    const hostName = window.location.hostname;
-    let port = window.location.port || "443";
-    if (window.currentEnvType === "development") {
-      port = "443";
-    }
-    // 创建WebSocket对象
-    window.wcsWebsocket = new WebSocket(
-      "wss://" + hostName + ":" + port + "/wcs/status/" + storeWareHouseId
-    );
-    // // 实际生成环境
-    // if (window.currentEnvType === 'production') {
-    //   window.wcsWebsocket = new WebSocket(
-    //     'wss://' + hostName + ':443/wcs/status/' + storeWareHouseId
-    //   )
-    // }
-    // // 测试使用
-    // if (window.currentEnvType === 'development') {
-    //   window.wcsWebsocket = new WebSocket(
-    //     'wss://' + hostName + ':443/wcs/test/status/' + storeWareHouseId
-    //   )
-    // }
-  }
-  if (window.wcsWebsocket) {
-    // 监听WebSocket事件
-    window.wcsWebsocket.onopen = () => {
-      window.currentRetryAttempts = 0;
-      if (window.socketLog) {
-        socketTimes = 0;
-      }
-      console.log("WCSWebSocket已连接");
-      console.log("WebSocket URL:", window.wcsWebsocket.url);
-    };
-
-    window.wcsWebsocket.onmessage = (event) => {
-      // console.log('WCSWebSocket收到消息:', event.data)
-      // console.log('时间:', new Date())
-      if (window.socketLog) {
-        socketTimes++;
-        console.log("WCSWebSocket第" + socketTimes + "次收到消息:", event.data);
-      }
-      const data = JSON.parse(event.data);
-      mesDoFun && mesDoFun(data);
-    };
-
-    window.wcsWebsocket.onclose = (event) => {
-      console.log("关闭socket");
-    };
-
-    window.wcsWebsocket.onerror = (error) => {
-      console.error("WCSWebSocket发生错误:", error);
-    };
-  }
-};
-window.socketDesJs = function () {
-  // 是否需要socket的全局标志位
-  window.mesDoFunFun = null;
-  if (
-    window.wcsWebsocket &&
-    window.wcsWebsocket.readyState === WebSocket.OPEN
-  ) {
-    window.wcsWebsocket.close(4000, "by clinet");
-    window.wcsWebsocket = null;
-  }
-};

+ 1 - 13
src/router/index.js

@@ -118,21 +118,9 @@ export const constantRoutes = [
       {
       {
         path: '2dshow',
         path: '2dshow',
         name: '2dshow',
         name: '2dshow',
-        component: () => import('@/views/show/2D/index'),
+        component: () => import('@/views/show/index'),
         meta: { title: '2D模拟', routerOpened: false, roleRequ: 'Admin' }
         meta: { title: '2D模拟', routerOpened: false, roleRequ: 'Admin' }
       },
       },
-      {
-        path: '2-5dshow-v0',
-        name: '2-5dshow-v0',
-        component: () => import('@/views/show/2-5D/V0/index'),
-        meta: { title: '2-5D模拟', routerOpened: false, roleRequ: 'Admin' }
-      },
-      {
-        path: '2-5dshow-v1',
-        name: '2-5dshow-v1',
-        component: () => import('@/views/show/2-5D/V1/index'),
-        meta: { title: '2-5D模拟', routerOpened: false, roleRequ: 'Admin' }
-      },
       {
       {
         path: '3dshow',
         path: '3dshow',
         name: '3dshow',
         name: '3dshow',

+ 10 - 139
src/styles/element-ui.scss

@@ -57,14 +57,14 @@
 // 本项目自定义弹框样式
 // 本项目自定义弹框样式
 .custom-dialog {
 .custom-dialog {
   &.el-dialog {
   &.el-dialog {
-    width: fit-content !important;
-    min-width: 600px; // 设置最小宽度
-    max-width: 80vw; // 设置最大宽度为视窗宽度的80%
     border-radius: 2px;
     border-radius: 2px;
   }
   }
 
 
   .el-dialog__header {
   .el-dialog__header {
-    padding: 13px 16px;
+    // font-family: PingFangSC-Medium, PingFang SC;
+    // font-weight: 500;
+    // height: 48px;
+    // padding: 13px 16px;
     border-bottom: 1px solid #ddd;
     border-bottom: 1px solid #ddd;
 
 
     @include flexCenter(space-between);
     @include flexCenter(space-between);
@@ -82,7 +82,6 @@
   }
   }
 
 
   .el-dialog__body {
   .el-dialog__body {
-    padding: 10px 20px;
     .el-form {
     .el-form {
       .el-form-item {
       .el-form-item {
         .el-form-item__content {
         .el-form-item__content {
@@ -100,24 +99,22 @@
   }
   }
 }
 }
 
 
+
+
 .el-input-number {
 .el-input-number {
   width: 100%;
   width: 100%;
 }
 }
-
 .el-input__inner {
 .el-input__inner {
   padding: 0 3px;
   padding: 0 3px;
 }
 }
-
 .el-input-number.is-without-controls .el-input__inner {
 .el-input-number.is-without-controls .el-input__inner {
   padding-left: 3px;
   padding-left: 3px;
   padding-right: 3px;
   padding-right: 3px;
 }
 }
-
 .el-input-number.is-controls-right .el-input__inner {
 .el-input-number.is-controls-right .el-input__inner {
   padding-left: 3px;
   padding-left: 3px;
   padding-right: 33px;
   padding-right: 33px;
 }
 }
-
 .el-input--suffix .el-input__inner {
 .el-input--suffix .el-input__inner {
   padding-right: 35px;
   padding-right: 35px;
   text-align: center;
   text-align: center;
@@ -128,139 +125,13 @@
     padding: 0;
     padding: 0;
   }
   }
 }
 }
-
 .el-table .cell {
 .el-table .cell {
   padding-left: 0px;
   padding-left: 0px;
   padding-right: 0px;
   padding-right: 0px;
 }
 }
-
-.el-button + .el-button {
-  margin-left: 6px;
+.el-button+.el-button{
+margin-left: 6px;
 }
 }
-
-.el-button [class*="el-icon-"] + span {
+.el-button [class*=el-icon-]+span {
   margin-left: 2px;
   margin-left: 2px;
-}
-
-.el-radio-group-cum {
-  .el-radio {
-    margin-right: 2px;
-
-    .el-radio__inner {
-      width: 12px;
-      height: 12px;
-
-      &::after {
-        width: 4px;
-        height: 4px;
-      }
-    }
-
-    .el-radio__label {
-      padding-left: 2px;
-      font-size: 12px;
-    }
-  }
-}
-
-.el-switch-mini {
-  .el-switch__core {
-    height: 16px;
-    width: 28px !important;
-  }
-
-  .el-switch__core:after {
-    width: 12px;
-    height: 12px;
-  }
-}
-
-.form-sec-cum {
-  .el-input__inner,
-  .el-select .el-input__inner {
-    border-radius: 0;
-    height: 28px;
-    line-height: 28px;
-  }
-}
-.el-button {
-  height: 32px; 
-  padding: 8px 10px;  // 调整按钮内边距
-  line-height: 1;
-/*   &--mini {
-    padding: 5px 10px;
-  }
-  
-  &--small {
-    padding: 6px 12px;
-  }
-  
-  &--medium {
-    padding: 8px 15px;
-  } */
-}
-//------start 统一表单控件高度和内边距---------------------
-.el-input__inner,
-.el-textarea__inner,
-.el-select .el-input__inner,
-.el-date-editor.el-input,
-.el-date-editor.el-input__inner,
-.el-cascader .el-input__inner {
-  height: 32px;
-  line-height: 32px;
-  padding: 0 8px;
-}
-
-// Select 下拉框
-// .el-select-dropdown__item {
-//   height: 32px;
-//   line-height: 32px;
-//   padding: 0 8px;
-// }
-
-// // DatePicker
-// .el-date-editor .el-range__icon,
-// .el-date-editor .el-range-separator,
-// .el-date-editor .el-range__close-icon {
-//   line-height: 32px;
-// }
-
-// // 数字输入框
-// .el-input-number {
-//   line-height: 32px;
-  
-//   .el-input-number__decrease,
-//   .el-input-number__increase {
-//     height: 15px;
-//     line-height: 15px;
-//   }
-// }
-
-// // 表单项标签
-// .el-form-item__label {
-//   height: 32px;
-//   line-height: 32px;
-// }
-
-// // 表单项内容区
-// .el-form-item__content {
-//   height: 32px;
-//   line-height: 32px;
-// }
-
-// // 级联选择器
-// .el-cascader-panel {
-//   .el-cascader-node {
-//     height: 32px;
-//     line-height: 32px;
-//     padding: 0 8px;
-//   }
-// }
-
-// // 下拉菜单
-// .el-dropdown-menu__item {
-//   height: 32px;
-//   line-height: 32px;
-//   padding: 0 8px;
-// }
-//------end 统一表单控件高度和内边距---------------------
+}

+ 1 - 6
src/styles/index.scss

@@ -11,12 +11,7 @@ body {
   -moz-osx-font-smoothing: grayscale;
   -moz-osx-font-smoothing: grayscale;
   -webkit-font-smoothing: antialiased;
   -webkit-font-smoothing: antialiased;
   text-rendering: optimizeLegibility;
   text-rendering: optimizeLegibility;
-  // font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
-  font-family: Roboto, Helvetica Neue, Helvetica, Arial, sans-serif;
-  font-size: 13px;
-  line-height: 1.846;
-  color: #666;
-  background-color: #fff;
+  font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
 }
 }
 
 
 // label {
 // label {

+ 220 - 145
src/views/3d-orgin/index.vue

@@ -1,17 +1,24 @@
 <template>
 <template>
   <div class="three-d-con">
   <div class="three-d-con">
-    <button id="saveViewButton">保存视角</button>
-    <div id="customModal" class="modal">
-      <div class="modal-content">
-        <span class="close-btn">&times;</span>
-        <h2 id="modalTitle">Custom Modal</h2>
-        <p id="modalMessage">This is a custom modal dialog box.</p>
-      </div>
-    </div>
+<!--    <div class="ware-house-sel-con">-->
+<!--      <el-select-->
+<!--        ref="warehouseSel"-->
+<!--        v-model="warehouseId"-->
+<!--        placeholder="请选择仓库"-->
+<!--      >-->
+<!--        <el-option-->
+<!--          v-for="wh in whList"-->
+<!--          :key="wh.id"-->
+<!--          :label="wh.name"-->
+<!--          :value="wh.id"-->
+<!--        />-->
+<!--      </el-select>-->
+<!--    </div>-->
+
     <div id="loading-marker">
     <div id="loading-marker">
       <div class="spinner">
       <div class="spinner">
         <span class="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
         <span class="glyphicon glyphicon-refresh glyphicon-refresh-animate" />
-        <span>正在加载系统(</span>
+        <span>正在加载AS/RS系统(</span>
         <span id="loadedItemNo">0%</span>
         <span id="loadedItemNo">0%</span>
         <span>)</span>
         <span>)</span>
       </div>
       </div>
@@ -40,16 +47,72 @@
           <div class="canvas-container">
           <div class="canvas-container">
             <div class="controls-ui" style="z-index: unset">
             <div class="controls-ui" style="z-index: unset">
               <div id="pNotifyContext" />
               <div id="pNotifyContext" />
+              <!-- <div id="icube-tab" class="icube-tab" /> -->
+              <!-- 20230620去除
+                <div class="palletNoJS">
+                <div class="tab-item">
+                  <span>系统托盘容量: </span>
+                  <span id="palletNoJS">0</span>
+                </div>
+              </div> -->
+              <!-- <div class="top-right">
+                <div id="zoomBar" class="main-toolbar">
+                  <div role="toolbar" class="btn-toolbar">
+                    <div class="btn-group-sm btn-group-vertical">
+
+                        <button
+                        id="zoomIn"
+                        type="button"
+                        class="btn btn-default btn-border-none btn-baby-control fs-1em"
+                      >
+                        <span class="fa fa-plus" />
+                      </button>
+                      <button
+                        id="zoomOut"
+                        type="button"
+                        class="btn btn-default btn-border-none btn-baby-control fs-1em"
+                      >
+                        <span class="fa fa-minus" />
+                      </button>
+                      <button
+                        id="btn-full-screen"
+                        type="button"
+                        class="btn btn-sm btn-default btn-border-none btn-baby-control fs-1em"
+                      >
+                        <span class="glyphicon glyphicon-resize-full" />
+                      </button>
+                         <button
+                        id="resetCamera"
+                        type="button"
+                        class="btn btn-default btn-border-none btn-baby-control fs-1em"
+                      >
+                        <span class="fa fa-refresh" />
+                      </button>
+                    </div>
+                  </div>
+                </div>
+              </div> -->
+              <div class="bottom-center2">
+                <div id="btn-save-view" class="btn btn-default">
+                  <i class="glyphicon glyphicon-print" />
+                  <span>下载当前视图</span>
+                </div>
+                <div id="btn-save-pdf" class="btn btn-default">
+                  <i class="glyphicon glyphicon-print" />
+                  <span>下载PDF布局</span>
+                </div>
+              </div>
+
               <div class="bottom-center">
               <div class="bottom-center">
                 <div
                 <div
                   id="view_Tut"
                   id="view_Tut"
                   class="btn-group flex"
                   class="btn-group flex"
                   style="margin: 0 auto"
                   style="margin: 0 auto"
                 >
                 >
-                  <!-- <div id="cameraView3D" class="btn btn-default">3D视图</div>
+                  <div id="cameraView3D" class="btn btn-default">3D视图</div>
                   <div id="cameraView2D" class="btn btn-default">2D视图</div>
                   <div id="cameraView2D" class="btn btn-default">2D视图</div>
                   <div id="cameraFront" class="btn btn-default">前视图</div>
                   <div id="cameraFront" class="btn btn-default">前视图</div>
-                  <div id="cameraSide" class="btn btn-default">侧视图</div> -->
+                  <div id="cameraSide" class="btn btn-default">侧视图</div>
                 </div>
                 </div>
               </div>
               </div>
               <div class="loading-control" />
               <div class="loading-control" />
@@ -88,7 +151,7 @@
               class="scene"
               class="scene"
               tabindex="1"
               tabindex="1"
             />
             />
-            <!-- <div id="loadingScene" class="loading_popup">
+            <div id="loadingScene" class="loading_popup">
               <span
               <span
                 class="glyphicon glyphicon-refresh glyphicon-refresh-animate"
                 class="glyphicon glyphicon-refresh glyphicon-refresh-animate"
               />
               />
@@ -118,7 +181,7 @@
               id="items.gif"
               id="items.gif"
               class="tutorialGif"
               class="tutorialGif"
               src="assets/3dconfigurator/images/tutorials/items.gif"
               src="assets/3dconfigurator/images/tutorials/items.gif"
-            > -->
+            >
           </div>
           </div>
         </div>
         </div>
       </div>
       </div>
@@ -126,151 +189,163 @@
   </div>
   </div>
 </template>
 </template>
 <script>
 <script>
-import three3DOri from "@/mixins/map/threeDOri";
+const cssUrls = [
+  '/3d-orgin/assets/dist/admin/adminlte.min.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/font-awesome/css/font-awesome.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/magnific-popup/magnific-popup.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-datepicker/css/bootstrap-datepicker3.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.theme.min.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-timepicker/css/bootstrap-timepicker.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/pnotify/pnotify.custom.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/introjs/introjs.min.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/css/theme.css',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/css/skins/default.css',
+  '/3d-orgin/assets/3dconfigurator/css/index.css'
+]
+const scripts = [
+  '/3d-orgin/custom/pre.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/modernizr/modernizr.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery/jquery.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-browser-mobile/jquery.browser.mobile.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/popper/umd/popper.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap/js/bootstrap.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/bootstrap-datepicker/js/bootstrap-datepicker.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/nanoscroller/nanoscroller.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-ui/jquery-ui.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/pnotify/pnotify.custom.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/jquery-validation/jquery.validate.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/vendor/introjs/introjs.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/js/theme.js',
+  '/3d-orgin/assets/3dconfigurator/lib/ui/js/theme.init.js',
+  '/3d-orgin/assets/3dconfigurator/lib/pep.js',
+  '/3d-orgin/assets/3dconfigurator/lib/jspdf/svg64.js',
+  '/3d-orgin/assets/3dconfigurator/lib/jspdf/jspdf.umd.js',
+  '/3d-orgin/assets/3dconfigurator/lib/jspdf/jspdf.autotable.js',
+  '/3d-orgin/assets/3dconfigurator/lib/browser.maker.js',
+  '/3d-orgin/assets/3dconfigurator/lib/bezier.js',
+  '/3d-orgin/assets/3dconfigurator/lib/opentype.js',
+  '/3d-orgin/assets/3dconfigurator/lib/babylon/earcut.js',
+  '/3d-orgin/assets/3dconfigurator/lib/babylon/babylon.js',
+  '/3d-orgin/assets/3dconfigurator/lib/babylon/inspector.js',
+  '/3d-orgin/assets/3dconfigurator/lib/babylon/gui.js',
+  '/3d-orgin/assets/3dconfigurator/lib/babylon/serializers.js',
+  '/3d-orgin/assets/res/frontend/global.js',
+  '/3d-orgin/assets/res/frontend/items.js',
+  '/3d-orgin/assets/res/frontend/templates.js',
+  '/3d-orgin/assets/res/frontend/behavior.js',
+  '/3d-orgin/assets/res/frontend/utils.js',
+  '/3d-orgin/assets/res/frontend/export.js',
+  '/3d-orgin/assets/res/frontend/simulation2.js',
+  '/3d-orgin/assets/res/frontend/itViewer.js',
+  '/3d-orgin/assets/3dconfigurator/js/index.js',
+  '/3d-orgin/assets/res/frontend/material.js',
+  '/3d-orgin/assets/res/frontend/loader.js',
+  '/3d-orgin/assets/res/frontend/rulers.js',
+  '/3d-orgin/assets/res/frontend/baseline.js',
+  '/3d-orgin/assets/res/frontend/warehouse.js',
+  '/3d-orgin/assets/res/frontend/tools.js',
+  '/3d-orgin/assets/3dconfigurator/js/icube2.js',
+  '/3d-orgin/assets/res/frontend/tutorial.js',
+  '/3d-orgin/assets/res/frontend/main.js',
+  '/3d-orgin/assets/res/frontend/event.js'
+]
 export default {
 export default {
-  name: "TreeDOrgin",
+  name: 'TreeDOrgin',
   components: {},
   components: {},
-  mixins: [three3DOri],
+  data() {
+    return {
+      styleSheets: [],
+      scriptDoms: [],
+      warehouseId: null
+    }
+  },
   watch: {
   watch: {
-    "$route.query.warehouse": {
-      handler(newVal, oldVal) {
-        if (this.$route.name !== "3dshow") {
-          return;
-        }
-        console.log("warehouse chg", newVal);
-        const warehouse = JSON.parse(newVal);
-        if (!window.ref3DBasicData) {
-          if (newVal) {
-            if (newVal !== oldVal) {
-              this.load3DOri(warehouse.id);
-            }
-          } else {
-            this.load3DOri();
-          }
-        } else {
-          this.$req({
-            url: "/pps/api",
-            method: "post",
-            data: {
-              method: "GetMapConfig",
-              param: { id: warehouse.id },
-            },
-          })
-            .then((response) => {
-              const selectedIcube = this.$options.nonReactiveData.selectedIcube;
-              window.ref3DBasicData &&
-                window.ref3DBasicData(response, selectedIcube);
-            })
-            .catch((error) => {
-              console.error("获取地图数据失败:", error);
-              this.$message.error("获取地图数据失败");
-            });
+    $route: {
+      handler: function(route) {
+        const id = route.query && route.query.warehouseId
+        if (id || id === 0) {
+          this.warehouseId = Number(id)
         }
         }
       },
       },
-      immediate: true,
+      immediate: true
     },
     },
+    warehouseId: {
+      handler: function(warehouseId, beforeWareHouseId) {},
+      immediate: true
+    }
+  },
+  mounted() {
+    if (!this.$3dDe.loaded) {
+      this.downloadCss()
+      this.loadScripts()
+      this.$3dDe.loaded = true
+    }
   },
   },
-};
+  beforeDestroy() {
+    // this.removeAllScripts()
+    // this.removeCss()
+  },
+  methods: {
+    downloadCss() {
+      cssUrls.forEach((url) => {
+        const link = document.createElement('link')
+        link.setAttribute('rel', 'stylesheet')
+        link.setAttribute('type', 'text/css')
+        link.setAttribute('href', url)
+        document.head.appendChild(link)
+        this.styleSheets.push(link)
+      })
+    },
+    async loadScripts() {
+      for (const src of scripts) {
+        await this.loadScript(src)
+        console.log(`Loaded script: ${src}`)
+      }
+      console.log('All scripts have been loaded and executed.')
+      // 在所有脚本加载完成后执行其他操作
+    },
+    loadScript(src) {
+      return new Promise((resolve, reject) => {
+        const script = document.createElement('script')
+        script.src = src
+        script.defer = true
+
+        script.onload = resolve
+        script.onerror = reject
+        document.head.appendChild(script)
+        this.scriptDoms.push(script)
+      })
+    },
+    removeAllScripts() {
+      for (const src of this.scriptDoms) {
+        src && src.parentNode.removeChild(src)
+        // const script = document.querySelector(`script[src="${src}"]`)
+        // if (script) {
+        //   script.parentNode.removeChild(script)
+        // }
+      }
+      console.log('All scripts have been removed.')
+    },
+    removeCss() {
+      this.styleSheets.forEach((sheet) => {
+        sheet && document.head.removeChild(sheet)
+      })
+      console.log('All css have been removed.')
+    }
+  }
+}
 </script>
 </script>
 <style lang="scss">
 <style lang="scss">
 .three-d-con {
 .three-d-con {
-  height: 100%; // 使用视窗高度
   position: relative;
   position: relative;
-  width: 100%;
-  overflow: hidden; // 防止内容溢出
-  #saveViewButton {
+  height: calc(100vh - 70px);
+  .ware-house-sel-con {
+    width: 120px;
     position: absolute;
     position: absolute;
     top: 10px;
     top: 10px;
-    right: 10px;
-    z-index: 9;
-    background-color: #4caf50;
-    border: none;
-    color: #fff;
-    padding: 5px;
-    border-radius: 3px;
-    margin: 0;
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); // 添加轻微阴影
-    transition: all 0.2s ease-in-out; // 优化过渡效果
-    &:hover {
-      background-color: #45a049; // 稍微暗一点的悬停色
-      box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
-    }
-    &:active {
-      background-color: #3d8b40; // 点击时的颜色
-      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
-    }
+    left: 10px;
+    z-index: 1;
   }
   }
 }
 }
-
-/* The Modal (background) */
-.modal {
-  display: none;
-  /* Hidden by default */
-  position: fixed;
-  /* Stay in place */
-  z-index: 10;
-  /* Sit on top */
-  left: 0;
-  top: 0;
-  width: 100%;
-  /* Full width */
-  height: 100%;
-  /* Full height */
-  overflow: auto;
-  /* Enable scroll if needed */
-  background-color: rgb(0, 0, 0);
-  /* Fallback color */
-  background-color: rgba(0, 0, 0, 0.4);
-  /* Black w/ opacity */
-  padding-top: 60px;
-}
-
-/* Modal Content */
-.modal-content {
-  background-color: #fefefe;
-  margin: 5% auto;
-  /* 15% from the top and centered */
-  padding: 20px;
-  border: 1px solid #888;
-  width: 80%;
-  /* Could be more or less, depending on screen size */
-  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
-  border-radius: 10px;
-  animation-name: modalopen;
-  animation-duration: 0.4s;
-}
-
-/* Add Animation */
-@keyframes modalopen {
-  from {
-    opacity: 0;
-  }
-
-  to {
-    opacity: 1;
-  }
-}
-
-/* The Close Button */
-.close-btn {
-  color: #aaa;
-  float: right;
-  font-size: 28px;
-  font-weight: bold;
-}
-
-.close-btn:hover,
-.close-btn:focus {
-  color: black;
-  text-decoration: none;
-  cursor: pointer;
-}
-
-/* Center p tag content */
-.modal-content p {
-  text-align: center;
-}
 </style>
 </style>

+ 20 - 0
src/views/3d/index.vue

@@ -0,0 +1,20 @@
+<template>
+  <div>
+    TODO
+  </div>
+</template>
+
+<script>
+
+export default {
+  name: 'Dashboard',
+  components: {
+  },
+  mounted() {
+
+  },
+  methods: {}
+}
+</script>
+
+<style lang="scss" scoped></style>

+ 35 - 0
src/views/3d/show/index.vue

@@ -0,0 +1,35 @@
+<template>
+  <!-- <iframe src="http:localhost:8080/3d" /> -->
+  <!-- <iframe src="https://www.baidu.com/" /> -->
+  <div class="show-con" v-html="content" />
+</template>
+
+<script>
+export default {
+  name: 'ThreeDShow',
+  components: {},
+  data() {
+    return {
+      content: ''
+    }
+  },
+  mounted() {
+    this.$req({
+      url: '/3d',
+      method: 'get',
+      params: {
+        warehouseId: 13
+      }
+    }).then((res) => {
+      this.content = res
+    })
+  },
+  methods: {}
+}
+</script>
+
+<style lang="scss" scoped>
+.show-con {
+  background: red;
+}
+</style>

+ 0 - 1162
src/views/cfg/components/cfg-panel.vue

@@ -1,1162 +0,0 @@
-<template>
-  <div class="cfg-panel-container">
-    <div class="content-area">
-      <el-form
-        class="cfg-form"
-        :model="formData"
-        :rules="rules"
-        ref="form"
-        size="small"
-        :inline="true"
-      >
-        <el-form-item label="仓库" class="custom-label-width">
-          <template #label>
-            <span class="custom-label"> 仓库 </span>
-          </template>
-          <el-input v-model="formData.name" :disabled="true" />
-          <!-- <el-select v-model="formData.id" placeholder="请选择">
-            <el-option
-              v-for="warehouse in warehouseList"
-              :key="warehouse.id"
-              :label="warehouse.name"
-              :value="warehouse.id"
-            ></el-option>
-          </el-select> -->
-        </el-form-item>
-        <el-form-item label="唯一ID" prop="cumKey" class="custom-label-width">
-          <template #label>
-            <span class="custom-label"> 唯一ID </span>
-          </template>
-          <el-input v-model="formData.cumKey" />
-        </el-form-item>
-        <div class="gradient-divider"></div>
-        <!-- <el-form-item label="配置名称" prop="name">
-                        <el-input v-model="formData.name" />
-                    </el-form-item> -->
-        <div class="flex-container">
-          <el-form-item label="仓库宽" prop="warehouseWidth">
-            <template #label>
-              <span class="custom-label"> 仓库宽 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.warehouseWidth"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-          <el-form-item prop="warehouseLen" label="仓库长">
-            <template #label>
-              <span class="custom-label"> 仓库长 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.warehouseLen"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-          <el-form-item label="仓库高" prop="warehouseHeight">
-            <template #label>
-              <span class="custom-label"> 仓库高 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.warehouseHeight"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-        </div>
-        <div class="gradient-divider"></div>
-        <div class="flex-container">
-          <el-form-item label="列数" prop="col">
-            <template #label>
-              <span class="custom-label"> 列数 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.col"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-          <el-form-item label="行数" prop="row">
-            <template #label>
-              <span class="custom-label"> 行数 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.row"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-          <el-form-item prop="floor" label="层数">
-            <template #label>
-              <span class="custom-label"> 层数 </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.floor"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-        </div>
-        <div class="gradient-divider"></div>
-        <el-form-item label="二维码始行" prop="rowStart">
-          <template #label>
-            <span class="custom-label"> 二维码始行 </span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.rowStart"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="二维码始列" prop="colStart">
-          <template #label>
-            <span class="custom-label"> 二维码始列 </span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.colStart"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="主轨道方向" prop="mainTrackDir">
-          <template #label>
-            <span class="custom-label"> 主轨道方向 </span>
-          </template>
-          <el-select
-            v-model.number="formData.mainTrackDir"
-            placeholder="请选择"
-          >
-            <el-option label="横向" :value="0"></el-option>
-            <el-option label="纵向" :value="1"></el-option>
-          </el-select>
-        </el-form-item>
-        <el-form-item label="货架初始旋转角度">
-          <template #label>
-            <span class="custom-label"> 旋转角度 </span>
-          </template>
-          <el-select v-model.number="formData.rotation" placeholder="请选择">
-            <el-option label="0°" :value="0"></el-option>
-            <el-option label="90°" :value="1"></el-option>
-            <el-option label="180°" :value="2"></el-option>
-            <el-option label="270°" :value="3"></el-option>
-          </el-select>
-        </el-form-item>
-        <div class="gradient-divider"></div>
-        <el-form-item
-          label="托盘类型"
-          prop="palletType"
-          class="pallet-type-item"
-        >
-          <template #label>
-            <span> 托盘类型 </span>
-            <el-tooltip
-              effect="light"
-              content="请选择托盘类型,类型为托盘宽(mm)*托盘长(mm)"
-              placement="right"
-            >
-              <i
-                class="el-icon-info"
-                style="margin-left: 5px; color: #909399"
-              ></i>
-            </el-tooltip>
-          </template>
-          <el-select v-model="formData.palletType" placeholder="请选择">
-            <el-option label="1200mmX1000mm" value="1200*1000"></el-option>
-            <el-option label="1100mmX1000mm" value="1100*1000"></el-option>
-          </el-select>
-        </el-form-item>
-        <div class="flex-container flex-container-col2">
-          <el-form-item label="厚度(mm)" prop="palletHeight">
-            <template #label>
-              <span class="custom-label"> 厚度(mm) </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.palletHeight"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-          <el-form-item label="承重(kg)" prop="palletLoadCapacity">
-            <template #label>
-              <span class="custom-label"> 承重(kg) </span>
-            </template>
-            <el-input
-              type="number"
-              v-model.number="formData.palletLoadCapacity"
-              :min="1"
-              step="1"
-            />
-          </el-form-item>
-        </div>
-        <div class="gradient-divider"></div>
-        <el-form-item label="货高(mm)" prop="goodsHeight">
-          <template #label>
-            <span class="custom-label"> 货高 (mm) </span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.goodsHeight"
-            :min="1"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="间距(mm)" prop="space">
-          <template #label>
-            <span class="custom-label"> 间距 (mm) </span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.space"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="层高(mm)" prop="space">
-          <template #label>
-            <span class="custom-label"> 层高 (mm) </span>
-          </template>
-          <el-input
-            v-model="formData.floorHeight"
-            :disabled="true"
-            type="number"
-          />
-        </el-form-item>
-        <el-button
-          @click="openGoodHeiCumDia"
-          type="primary"
-          plain
-          class="goods-height-cum-btn"
-          size="mini"
-          >+ 定制每层高度</el-button
-        >
-        <div class="gradient-divider" style="margin-top: 10px"></div>
-        <el-form-item
-          label="护网"
-          prop="lateralNet"
-          class="custom-label-width-40"
-        >
-          <template #label>
-            <span class="custom-label"> 护网 </span>
-          </template>
-          <el-checkbox-group
-            v-model="formData.lateralNet"
-            class="checkbox-group"
-          >
-            <el-checkbox :label="0">前</el-checkbox>
-            <el-checkbox :label="1">后</el-checkbox>
-            <el-checkbox :label="2">左</el-checkbox>
-            <el-checkbox :label="3">右</el-checkbox>
-          </el-checkbox-group>
-        </el-form-item>
-      </el-form>
-    </div>
-    <div class="bottom-buttons">
-      <!-- <el-button class="bottom-btn" type="primary" @click="build" size="mini">应用</el-button> -->
-      <div class="button-grid">
-        <div
-          v-for="(item, index) in cfgItemArr"
-          :key="index"
-          class="button-item"
-        >
-          <el-button
-            type="primary"
-            plain
-            size="mini"
-            @click="openCfgDia(item)"
-            :style="item.sty && item.sty.btnStyle && item.sty.btnStyle.style"
-          >
-            <!-- <i v-if="!(item.sty && item.sty.btnStyle && item.sty.btnStyle.noIcon)" class="el-icon-plus"></i> -->
-            {{ item.name }}
-          </el-button>
-        </div>
-      </div>
-      <div class="bottom-action-buttons">
-        <el-button class="bottom-btn" type="primary" @click="save" size="mini"
-          >保存并应用</el-button
-        >
-        <el-button
-          class="bottom-btn"
-          type="primary"
-          @click="downloadImg"
-          size="mini"
-          >下载图片</el-button
-        >
-        <el-button
-          class="bottom-btn"
-          type="primary"
-          @click="exportCfg"
-          size="mini"
-          >导出</el-button
-        >
-      </div>
-    </div>
-    <el-dialog
-      :title="dialogTitle"
-      :visible.sync="showCfgDia"
-      :close-on-click-modal="false"
-      custom-class="custom-dialog"
-    >
-      <el-form v-if="cfgingItem && cfgingItem.key === 'around'">
-        <el-form-item label="货架上方">
-          <template #label>
-            <span class="custom-label">货架上方</span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.around.up"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="下">
-          <template #label>
-            <span class="custom-label">货架下方</span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.around.down"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="左">
-          <template #label>
-            <span class="custom-label">货架左侧</span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.around.left"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-        <el-form-item label="右">
-          <template #label>
-            <span class="custom-label">货架右侧</span>
-          </template>
-          <el-input
-            type="number"
-            v-model.number="formData.around.right"
-            :min="0"
-            step="1"
-          />
-        </el-form-item>
-      </el-form>
-      <cfg-table
-        v-else
-        ref="cfgTable"
-        :cfgFormData="formData"
-        :cfgingItem="cfgingItem"
-      ></cfg-table>
-      <template #footer>
-        <span class="dialog-footer">
-          <el-button @click="cancelCfgTable" size="mini">取消</el-button>
-          <el-button type="primary" @click="confirmCfgTable" size="mini"
-            >确定</el-button
-          >
-        </span>
-      </template>
-    </el-dialog>
-    <el-dialog
-      title="定制每层高度"
-      :visible.sync="goodHeiCumDiaVis"
-      :close-on-click-modal="false"
-      custom-class="custom-dialog"
-    >
-      <cfg-table
-        ref="goodHeiCumTable"
-        :cfgFormData="formData"
-        :cfgingItem="goodHeiCumCfgingItem"
-        @update:table-data="setCfgItemFormData($event, 'floorGoodsHeights')"
-      ></cfg-table>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-const DEFAULT_FORM_DATA = {
-  id: undefined,
-  name: undefined,
-  warehouseLen: undefined,
-  warehouseWidth: undefined,
-  warehouseHeight: undefined,
-  floor: undefined,
-  cumKey: undefined,
-  forward: undefined,
-  row: undefined,
-  col: undefined,
-  mainTrackDir: 0,
-  rowStart: 11,
-  colStart: 11,
-  palletType: "1200*1000",
-  palletHeight: 100,
-  palletLoadCapacity: 1000,
-  floorGoodsHeights: [],
-  lateralNet: [],
-  goodsHeight: 1500,
-  space: 75,
-  floorHeight: undefined,
-  topGoodsHeight: undefined,
-  rotation: undefined,
-  around: {
-    up: undefined,
-    down: undefined,
-    left: undefined,
-    right: undefined,
-  },
-};
-const goodHeiCumCfgingItem = {
-  key: "floorGoodsHeights",
-  name: "定制每层高度",
-  cfgTable: {
-    needWatch: true,
-    isNotApplyToOtherFloor: true,
-    isNotApplyToTotalRow: true,
-    isNotApplyToTotalCol: true,
-    columnsCfgArr: function (formData) {
-      return [
-        {
-          prop: "floor",
-          label: "层",
-          type: "number",
-          template: true,
-          inputProps: {
-            placeholder: "",
-            type: "number",
-          },
-        },
-        {
-          prop: "goodsHeight",
-          label: "货高",
-          type: "number",
-          template: true,
-          inputProps: {
-            placeholder: "",
-            type: "number",
-          },
-        },
-        {
-          prop: "space",
-          label: "间距",
-          type: "number",
-          template: true,
-          inputProps: {
-            type: "number",
-            placeholder: "",
-          },
-        },
-        {
-          prop: "floorHeight",
-          label: "层高",
-          type: "number",
-          template: true,
-          isSum: true,
-          sumProps: ["goodsHeight", "space"],
-          inputProps: {
-            type: "number",
-            placeholder: "",
-          },
-        },
-      ];
-    },
-  },
-};
-import { getCFG } from "@/components/map//GRID-CONST";
-import cfgTable from "./cfg-table.vue";
-export default {
-  name: "ConfigPage",
-  components: {
-    cfgTable,
-  },
-  props: {
-    warehouseData: {
-      type: Object,
-      default: () => ({}),
-    },
-  },
-  data() {
-    return {
-      goodHeiCumCfgingItem,
-      goodHeiCumDiaVis: false,
-      aroundFormData: {
-        up: undefined,
-        down: undefined,
-        left: undefined,
-        right: undefined,
-      },
-      cfgingItem: undefined,
-      dialogTitle: "",
-      showCfgDia: false,
-      formData: { ...DEFAULT_FORM_DATA },
-      rules: {
-        id: [{ required: true, message: " ", trigger: "change" }],
-        warehouseLen: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "仓库长必须大于0",
-            trigger: "blur",
-          },
-        ],
-        warehouseWidth: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "仓库宽必须大于0",
-            trigger: "blur",
-          },
-        ],
-        warehouseHeight: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "仓库高必须大于0",
-            trigger: "blur",
-          },
-        ],
-        floor: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "integer",
-            min: 1,
-            max: 100,
-            message: "1到100之间的整数",
-            trigger: "blur",
-          },
-        ],
-        cumKey: [{ required: true, message: " ", trigger: "blur" }],
-        /* name: [
-                    { required: true, message: '请输入配置名称', trigger: 'blur' }
-                ], */
-        row: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "integer",
-            min: 1,
-            max: 100,
-            message: "1到100之间的整数",
-            trigger: "blur",
-          },
-        ],
-        col: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "integer",
-            min: 1,
-            max: 100,
-            message: "1到100之间的整数",
-            trigger: "blur",
-          },
-        ],
-        mainTrackDir: [
-          { required: true, message: "请选择主轨道方向", trigger: "change" },
-        ],
-        rowStart: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "integer",
-            min: 0,
-            message: "必须大于等于0的整数",
-            trigger: "blur",
-          },
-        ],
-        colStart: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "integer",
-            min: 0,
-            message: "必须大于等于0的整数",
-            trigger: "blur",
-          },
-        ],
-        palletType: [{ required: true, message: " ", trigger: "change" }],
-        palletHeight: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "托盘高度必须大于0",
-            trigger: "blur",
-          },
-        ],
-        palletLoadCapacity: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "承重必须大于0",
-            trigger: "blur",
-          },
-        ],
-        space: [
-          { type: "number", min: 0, message: "间距不小于0", trigger: "blur" },
-        ],
-        goodsHeight: [
-          { required: true, message: " ", trigger: "blur" },
-          {
-            type: "number",
-            min: 0.1,
-            message: "货高必须大于0",
-            trigger: "blur",
-          },
-        ],
-      },
-      warehouseList: [], // 用于存储从后台获取的仓库数据
-      buttons: [], // 用于存储动态添加的按钮
-      cfgItemArr: [],
-    };
-  },
-  watch: {
-    warehouseData: {
-      handler(newVal) {
-        this.initFormData(DEFAULT_FORM_DATA);
-        this.fetchWarehouseDetail(newVal);
-      },
-      immediate: true,
-    },
-    "formData.goodsHeight": function () {
-      this.updateFloorHeight();
-    },
-    "formData.space": function () {
-      this.updateFloorHeight();
-    },
-    /* "formData.palletType": function (newVal) {
-      if (newVal) {
-        const [palletWidth, palletLength] = newVal.split("*").map(Number);
-        this.formData.palletWidth = palletWidth;
-        this.formData.palletLength = palletLength;
-      }
-    }, */
-  },
-  mounted() {
-    this.initBaseItemStsArr();
-    // this.fetchWarehouseData();
-  },
-  methods: {
-    setCfgItemFormData(data, key) {
-      this.formData[key] = data || [];
-    },
-    openGoodHeiCumDia() {
-      this.goodHeiCumDiaVis = true;
-    },
-    initFormData(obj = {}) {
-      this.formData = { ...this.formData, ...obj };
-      this.formData.id = this.warehouseData?.id;
-      this.formData.name = this.warehouseData?.name;
-      this.updateFloorHeight();
-    },
-    cancelCfgTable() {
-      this.showCfgDia = false;
-    },
-    confirmCfgTable() {
-      if (this.cfgingItem.key === "around") {
-        this.$emit("saveAndBuild", this.formData);
-        this.showCfgDia = false;
-        return;
-      }
-      let finalData = this.$refs.cfgTable.tableData;
-      if (this.cfgingItem.cfgTable && this.cfgingItem.cfgTable.toBackDataFun) {
-        finalData = this.cfgingItem.cfgTable.toBackDataFun(
-          this.formData,
-          finalData
-        );
-      }
-
-      // 处理空值为undefined
-      const props = ["f", "c", "r", "rS", "rE", "cS", "cE", "max_floor"];
-      finalData = finalData.map((item) => {
-        props.forEach((prop) => {
-          if (item[prop] === "") {
-            item[prop] = undefined;
-          }
-        });
-        return item;
-      });
-
-      const key = this.cfgingItem.backKey || this.cfgingItem.key;
-      this.formData[key] = finalData;
-      this.$emit("saveAndBuild", this.formData);
-      this.showCfgDia = false;
-    },
-    openCfgDia(item) {
-      this.$refs.form.validate((valid) => {
-        if (!valid) {
-          this.$message.error("请确认仓库信息填写正确");
-          return;
-        } else {
-          if (item.cfgTable && item.cfgTable.cumDia) {
-            this[item.cfgTable.cumDia] = true;
-            return;
-          }
-          const key = item.backKey || item.key;
-          let initData = this.formData[key];
-          if (item.cfgTable && item.cfgTable.toPageDataFun) {
-            initData = item.cfgTable.toPageDataFun(this.formData);
-          }
-          this.$refs.cfgTable && this.$refs.cfgTable.initTableData(initData);
-          this.cfgingItem = item;
-          this.dialogTitle = item.name;
-          this.showCfgDia = true;
-        }
-      });
-    },
-    initBaseItemStsArr() {
-      this.cfgItemArr = [];
-      const cfg = getCFG("canvas");
-      for (let i = 0; i < cfg.baseItemStsArr.length; i++) {
-        if (
-          (cfg.baseItemStsArr[i].displayControl &&
-            cfg.baseItemStsArr[i].displayControl.isNotShowInCfg) ||
-          (cfg.baseItemStsArr[i].displayControl &&
-            cfg.baseItemStsArr[i].displayControl.isNotShowInCfgPanel)
-        ) {
-          continue;
-        }
-        const item = cfg.baseItemStsArr[i];
-        if (item.isByFloor === undefined) {
-          item.isByFloor = false;
-        }
-        this.cfgItemArr.push({
-          ...item,
-          isCfging: false,
-        });
-      }
-    },
-    build() {
-      this.$refs.form.validate((valid) => {
-        this.buildFromCfgPanel();
-      });
-    },
-    save() {
-      this.$refs["form"].validate((valid) => {
-        if (valid) {
-          this.formData.id = this.warehouseData.id;
-          this.$emit("saveAndBuild", this.formData);
-        } else {
-          this.$message.error("请确认仓库信息填写正确");
-          return false;
-        }
-      });
-    },
-    exportCfg() {
-      this.$refs["form"].validate((valid) => {
-        if (valid) {
-          if (!this.formData.id) {
-            this.formData.id = this.warehouseData.id;
-          }
-          this.$emit("saveAndBuild", this.formData, true);
-          this.$confirm(
-            "此操作将导出已保存的仓库配置,是否继续?",
-            "导出配置",
-            {
-              confirmButtonText: this.$GPROP["conBtn"],
-              cancelButtonText: this.$GPROP["cancelBtn"],
-              type: "warning",
-            }
-          ).then(() => {
-            this.$req({
-              url: "/pps/api",
-              method: "post",
-              data: {
-                method: "ExportMapConfig",
-                param: { id: this.formData.id },
-              },
-              responseType: "blob",
-            }).then((res) => {
-              const name = this.formData.cumKey || "";
-              const fileName = name ? name + ".json" : "仓库配置.json";
-              this.$utils.downloadFile(res, fileName);
-            });
-          });
-        } else {
-          this.$message.error("请确认仓库信息填写正确");
-          return false;
-        }
-      });
-    },
-    downloadImg() {
-      this.$emit("downloadImg");
-    },
-    operCumFun(operItemStsObj, funName, formData) {
-      if (operItemStsObj[funName]) {
-        return operItemStsObj[funName](formData, this);
-      }
-    },
-    validateWheConfirmCfg(item) {
-      let isNotValid = false;
-      if (item.paramInfoArr && item.paramInfoArr.length > 0) {
-        for (const paramItem of item.paramInfoArr) {
-          if (paramItem.rules) {
-            const value = item.paramToMergeObj[paramItem.paramKeyVal];
-            if (value === undefined) {
-              continue;
-            }
-            for (const rule of paramItem.rules) {
-              if (rule.type === "number") {
-                if (isNaN(value) || value < rule.min) {
-                  this.$message.error(rule.message);
-                  isNotValid = true;
-                  return;
-                }
-              }
-            }
-          }
-        }
-      }
-      isNotValid = this.operCumFun(
-        item,
-        "validateWheConfirmCfg",
-        this.formData
-      );
-      return isNotValid;
-    },
-    updateCfgItemStatus(item) {
-      this.cfgItemArr.forEach((cfgItem) => {
-        if (cfgItem.key === item.key) {
-          cfgItem.isCfging = true;
-        } else {
-          cfgItem.isCfging = false;
-        }
-      });
-    },
-    async buildFromCfgPanel(isFromCfgPanel) {
-      return new Promise((resolve) => {
-        this.$refs.form.validate((valid) => {
-          if (!valid) {
-            this.$message.error("请确认仓库信息填写正确");
-            resolve(true);
-          } else {
-            this.$emit("build", this.formData);
-            resolve(false);
-          }
-        });
-      });
-    },
-    addFloorGoodsHeightCum() {},
-    delFloorGoodsHeightCum(index) {
-      this.formData.floorGoodsHeights.splice(index, 1);
-    },
-    fetchWarehouseData() {
-      this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "FetchWarehouse",
-        },
-      })
-        .then((response) => {
-          this.warehouseList = response.data;
-        })
-        .catch((error) => {
-          console.error("Failed to fetch warehouse data:", error);
-        });
-    },
-
-    fetchWarehouseDetail(warehouseData) {
-      if (!warehouseData?.id) {
-        this.handleEmptyResponse();
-        return;
-      }
-      this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "GetMapConfig",
-          param: { id: warehouseData.id },
-        },
-      })
-        .then((response) => {
-          if (!response || !response.data) {
-            this.handleEmptyResponse();
-            return;
-          }
-          this.updateFormData(response.data);
-          this.$emit("build", this.formData);
-        })
-        .catch((error) => {
-          console.error("获取仓库详情失败:", error);
-          this.$message.error("获取仓库详情失败");
-        });
-    },
-    // 处理空响应情况
-    handleEmptyResponse() {
-      this.$emit("build", this.formData);
-    },
-    // 更新表单数据
-    updateFormData(responseData) {
-      this.formData = {
-        ...this.formData,
-        ...responseData,
-        // 确保 lateralNet 始终是数组
-        lateralNet: responseData.lateralNet || [],
-      };
-
-      this.formData.id = this.warehouseData?.id;
-      this.formData.name = this.warehouseData?.name;
-      this.updateFloorHeight();
-    },
-    updateFloorHeight() {
-      this.formData.floorHeight =
-        (this.formData.goodsHeight || 0) + (this.formData.space || 0);
-    },
-  },
-};
-</script>
-<style lang="scss">
-@import "~element-ui/packages/theme-chalk/src/common/var.scss";
-@import "@/styles/variables.scss";
-
-.cfg-form {
-  .pallet-type-item {
-    display: block !important; // 强制块级显示
-
-    .el-form-item__label {
-      display: block;
-      text-align: left;
-      width: 100% !important;
-      flex: none !important;
-      padding: 0 0 4px 0 !important;
-      line-height: 1.15;
-    }
-
-    .el-form-item__content {
-      display: block;
-      margin-left: 0 !important;
-      width: 100%;
-
-      .el-select {
-        width: 100%;
-      }
-    }
-  }
-
-  .el-form-item {
-    // 默认表单项样式
-    display: flex;
-    width: 100%;
-    padding-right: 0;
-    box-sizing: border-box;
-    margin-bottom: 4px;
-    margin-right: 0px;
-    align-items: center; // 垂直居中对齐
-
-    .el-form-item__label {
-      flex: 0 0 90px; // 固定宽度100px,不伸缩
-      padding-right: $spaceExtSmall;
-      line-height: 28px;
-    }
-
-    .el-form-item__content {
-      flex: 1; // 占据剩余空间
-      margin-left: 0 !important;
-
-      // 让内部的输入框和选择框填满容器宽度
-      .el-input,
-      .el-select {
-        width: 100%;
-      }
-    }
-
-    // 输入框样式
-    .el-input__inner,
-    .el-select .el-input__inner {
-      border-radius: 0;
-      height: 28px;
-      line-height: 28px;
-    }
-  }
-
-  // 为特定表单项添加自定义宽度
-  .custom-label-width {
-    .el-form-item__label {
-      flex: 0 0 70px !important;
-    }
-  }
-
-  .custom-label-width-40 {
-    .el-form-item__label {
-      flex: 0 0 50px !important;
-    }
-  }
-
-  // 专门处理层数、行数、列数的三列布局
-  .flex-container {
-    display: flex;
-    justify-content: space-between;
-    width: 100%;
-
-    .el-form-item {
-      width: 32%;
-      display: block; // 改为块级显示
-      margin-right: $spaceExtSmall;
-
-      &:last-child {
-        margin-right: 0;
-      }
-
-      .el-form-item__label {
-        padding: 0; // 移除padding
-        line-height: 1.15; // 设置行高为1.15
-        display: block;
-        width: 100%;
-        flex: none; // 移除flex属性
-        text-align: left;
-        padding-bottom: 4px;
-      }
-
-      .el-form-item__content {
-        display: block;
-        width: 100%;
-      }
-    }
-
-    .form-item-more-width {
-      width: 100%;
-    }
-  }
-
-  .flex-container-col2 {
-    .el-form-item {
-      width: 48%;
-    }
-  }
-}
-
-// 添加通知样式
-.el-notification {
-  $notify-width: 50vw; // 使用视窗宽度的50%
-
-  width: $notify-width !important;
-  left: calc((100vw - #{$notify-width}) / 2) !important;
-  right: auto !important;
-  margin-right: 0 !important;
-}
-
-.el-radio-group-cum {
-  .el-radio {
-    .el-radio__label {
-      padding-left: 4px;
-    }
-  }
-}
-
-.el-checkbox-group.checkbox-group {
-  display: flex;
-
-  .el-checkbox {
-    margin-right: $spaceExtSmall;
-
-    .el-checkbox__label {
-      padding-left: 2px !important;
-      font-size: $--font-size-base;
-    }
-  }
-}
-</style>
-<style lang="scss" scoped>
-@import "~element-ui/packages/theme-chalk/src/common/var.scss";
-@import "@/styles/variables.scss";
-$Wid: 216px;
-.goods-height-cum-btn {
-  width: 100%;
-}
-
-.el-form-item {
-  display: flex;
-  align-items: center;
-}
-
-.cfg-panel-container {
-  width: $Wid;
-  flex: 0 0 $Wid;
-  height: 100%;
-  overflow: hidden;
-  display: flex;
-  flex-direction: column;
-  background-color: #fff;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
-
-  * {
-    font-size: $--font-size-base;
-  }
-}
-
-.content-area {
-  flex: 1;
-  padding: 0 $spaceExtSmall;
-  overflow-y: auto;
-  border-bottom: 1px solid #ebeef5;
-  background-color: #fff;
-  box-shadow: inset 0 -5px 5px -5px rgba(0, 0, 0, 0.1);
-
-  &::-webkit-scrollbar {
-    width: 0;
-    height: 0;
-  }
-}
-
-.gradient-divider {
-  height: 1px;
-  margin-bottom: $spaceExtSmall;
-  background: linear-gradient(
-    to right,
-    rgba(220, 223, 230, 0),
-    rgba(220, 223, 230, 1) 10%,
-    rgba(220, 223, 230, 1) 90%,
-    rgba(220, 223, 230, 0)
-  );
-}
-
-.bottom-buttons {
-  flex: none;
-  padding: $spaceExtSmall;
-  display: flex;
-  flex-direction: column;
-  gap: 4px;
-  background-color: #f5f7fa;
-  border-top: 1px solid #ebeef5;
-  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.05);
-
-  .bottom-btn {
-    width: 100%;
-    margin: 0;
-  }
-
-  .button-grid {
-    display: grid;
-    grid-template-columns: repeat(3, 1fr);
-    gap: 4px;
-    background-color: #fff;
-    padding: 2px 0;
-
-    .button-item {
-      width: 100%;
-
-      .el-button {
-        width: 100%;
-        padding: $spaceExtSmall 0;
-      }
-    }
-  }
-
-  .bottom-action-buttons {
-    display: flex;
-    flex-direction: column;
-    gap: 4px;
-    border-top: 1px solid #ebeef5;
-  }
-}
-</style>

+ 0 - 304
src/views/cfg/components/cfg-table.vue

@@ -1,304 +0,0 @@
-<template>
-  <div class="cfg-table-con">
-    <el-button
-      type="primary"
-      size="mini"
-      @click="handleAdd"
-      plain
-      class="oper-btn"
-    >
-      <i class="el-icon-plus"></i> 添加
-    </el-button>
-    <el-button
-      type="primary"
-      size="mini"
-      @click="handleDeleteBatch"
-      plain
-      class="oper-btn"
-    >
-      <i class="el-icon-delete"></i> 删除
-    </el-button>
-    <el-button
-      v-if="!cfgingItem.cfgTable || !cfgingItem.cfgTable.isNotApplyToTotalCol"
-      type="primary"
-      size="mini"
-      @click="handleApplyTotalCol"
-      plain
-      class="oper-btn"
-    >
-      <i class="el-icon-bottom"></i> 应用到整列
-    </el-button>
-    <el-button
-      v-if="!cfgingItem.cfgTable || !cfgingItem.cfgTable.isNotApplyToTotalRow"
-      type="primary"
-      size="mini"
-      @click="handleApplyTotalRow"
-      plain
-      class="oper-btn"
-    >
-      <i class="el-icon-right"></i> 应用到整行
-    </el-button>
-    <el-button
-      v-if="!cfgingItem.cfgTable || !cfgingItem.cfgTable.isNotApplyToOtherFloor"
-      type="primary"
-      size="mini"
-      @click="handleApplyToOtherFloor"
-      plain
-      class="oper-btn"
-    >
-      <i class="el-icon-check"></i> 应用到其他层
-    </el-button>
-    <!-- 表格 -->
-    <el-table
-      class="cfg-table form-sec-cum"
-      :data="tableData"
-      border
-      stripe
-      fit
-      :height="'calc(100vh - 400px)'"
-      :cell-style="{ padding: '6px' }"
-      :header-cell-style="{ fontWeight: '550' }"
-      @selection-change="handleSelectionChange"
-    >
-      <el-table-column type="selection" width="55" align="center">
-      </el-table-column>
-      <el-table-column type="index" label="序号" :width="50" align="center">
-      </el-table-column>
-      <el-table-column
-        v-for="(col, index) in columns"
-        :key="index"
-        :type="col.type"
-        :prop="col.prop"
-        :label="col.label"
-        :width="col.colWidth"
-        min-width="col.minWidth"
-      >
-        <template v-if="col.template" slot-scope="scope">
-          <template v-if="col.isSum">
-            {{ getSumValue(scope.row, col) }}
-          </template>
-          <template v-else>
-            <el-input
-              v-model.number="scope.row[col.prop]"
-              v-if="col.type === 'number'"
-              v-bind="col.inputProps"
-            >
-            </el-input>
-            <el-input
-              v-model="scope.row[col.prop]"
-              v-else
-              v-bind="col.inputProps"
-            >
-            </el-input>
-          </template>
-        </template>
-      </el-table-column>
-
-      <el-table-column label="操作">
-        <template slot-scope="scope">
-          <el-button type="text" @click="handleDelete(scope.$index)"
-            >删除</el-button
-          >
-        </template>
-      </el-table-column>
-    </el-table>
-
-    <!-- 底部统计 -->
-    <div class="table-footer">
-      共 {{ tableData && tableData.length }} 项数据
-    </div>
-  </div>
-</template>
-
-<script>
-export default {
-  name: "CfgTable",
-  props: {
-    cfgFormData: {
-      type: Object,
-      default: () => ({}),
-    },
-    cfgingItem: {
-      type: Object,
-      default: () => ({}),
-    },
-  },
-  data() {
-    return {
-      tableData: [],
-      selectedRows: [],
-    };
-  },
-  computed: {
-    columns() {
-      if (this.cfgingItem.cfgTable && this.cfgingItem.cfgTable.columnsCfgArr) {
-        if (typeof this.cfgingItem.cfgTable.columnsCfgArr === "function") {
-          return this.cfgingItem.cfgTable.columnsCfgArr(this.cfgFormData);
-        }
-        return this.cfgingItem.cfgTable.columnsCfgArr;
-      }
-      return [
-        {
-          prop: "c",
-          label: "列",
-          type: "number",
-          template: true,
-          inputProps: {
-            placeholder: "",
-            type: "number",
-          },
-        },
-        {
-          prop: "r",
-          label: "行",
-          type: "number",
-          template: true,
-          inputProps: {
-            type: "number",
-            placeholder: "",
-          },
-        },
-        {
-          prop: "f",
-          label: "层",
-          type: "number",
-          template: true,
-          inputProps: {
-            type: "number",
-            placeholder: "",
-          },
-        },
-      ];
-    },
-  },
-  watch: {
-    cfgingItem: {
-      immediate: true,
-      handler(newVal) {
-        if (newVal && newVal.key) {
-          let initData = this.getCfgItemFormData();
-          if (newVal.cfgTable && newVal.cfgTable.toPageDataFun) {
-            initData = newVal.cfgTable.toPageDataFun(this.cfgFormData);
-          }
-          this.initTableData(initData);
-        }
-      },
-    },
-    tableData: {
-      deep: true,
-      handler(newVal) {
-        if (this.cfgingItem.cfgTable?.needWatch) {
-          this.$emit('update:table-data', newVal);
-        }
-      },
-    },
-  },
-  methods: {
-    handleApplyToOtherFloor() {
-      this.applyToDimension("f", 1, this.cfgFormData.floor);
-    },
-    handleApplyTotalRow() {
-      this.applyToDimension(
-        "c",
-        this.cfgFormData.colStart,
-        this.cfgFormData.colStart + this.cfgFormData.col - 1
-      );
-    },
-    handleApplyTotalCol() {
-      this.applyToDimension(
-        "r",
-        this.cfgFormData.rowStart,
-        this.cfgFormData.rowStart + this.cfgFormData.row - 1
-      );
-    },
-    applyToDimension(dimension, start, end) {
-      if (this.checkIsSelected()) {
-        const selectedDataArr = this.selectedRows;
-        let newTableData = [];
-        selectedDataArr.forEach((rowData) => {
-          for (let i = start; i <= end; i++) {
-            newTableData.push({ ...rowData, [dimension]: i });
-          }
-        });
-
-        newTableData = newTableData.filter((newRow) => {
-          return !this.tableData.some((existingRow) => {
-            return Object.keys(newRow).every(
-              (key) => newRow[key] === existingRow[key]
-            );
-          });
-        });
-
-        const lastSelectedIndex = Math.max(
-          ...selectedDataArr.map((row) => this.tableData.indexOf(row))
-        );
-        this.tableData.splice(lastSelectedIndex + 1, 0, ...newTableData);
-      }
-    },
-    handleSelectionChange(selection) {
-      this.selectedRows = selection;
-    },
-    initTableData(initData) {
-      // 如果有初始数据则使用,否则置空数组
-      this.tableData = initData ? JSON.parse(JSON.stringify(initData)) : [];
-    },
-    handleAdd() {
-      const newRow = {};
-      this.columns.forEach((col) => {
-        newRow[col.prop] = undefined;
-      });
-      this.tableData.push(newRow);
-    },
-    handleClear() {
-      this.tableData = [];
-    },
-    getCfgItemFormData() {
-      return this.cfgFormData[this.cfgingItem.backKey || this.cfgingItem.key];
-    },
-    handleDelete(index) {
-      this.tableData.splice(index, 1);
-    },
-    handleDeleteBatch() {
-      if (this.checkIsSelected()) {
-        this.tableData = this.tableData.filter(
-          (row) => !this.selectedRows.includes(row)
-        );
-      }
-    },
-    checkIsSelected() {
-      const isSelected = this.selectedRows && this.selectedRows.length > 0;
-      if (!isSelected) {
-        this.$message.warning("请先选择要删除的行");
-      }
-      return isSelected;
-    },
-    getSumValue(row, colItem) {
-      const props = colItem.sumProps || [];
-      const key = colItem.prop;
-      const sum = props.reduce((sum, prop) => sum + (Number(row[prop]) || 0), 0);
-      row[key] = sum;
-      return sum
-    },
-  },
-};
-</script>
-<style lang="scss" scoped>
-$space: 6px;
-
-.cfg-table-con {
-  .oper-btn {
-    margin-bottom: $space;
-  }
-
-  .el-table__body-wrapper {
-    padding: $space;
-  }
-}
-
-.table-footer {
-  margin-top: $space * 2;
-  text-align: right;
-  color: #606266;
-  font-size: 14px;
-}
-</style>

+ 519 - 179
src/views/cfg/index.vue

@@ -1,212 +1,552 @@
 <template>
 <template>
-  <div class="cfg-container">
-    <cfg-panel
-      ref="cfgPanel"
-      :warehouseData="warehouseData"
-      @build="handleBuild"
-      @saveAndBuild="handleSaveAndBuild"
-      @downloadImg="downloadImg"
+  <div
+    ref="total"
+    class="cfg-container"
+    :class="{ 'cfg-container-pd-left': formPanelCloseSta }"
+  >
+    <!-- <div class="oper-con z-idx-top-1">
+      <i
+        class="iconfont m-r-s"
+        :class="
+          isFullScreen ? 'icon-cancel-full-screen' : 'icon-quanpingzuidahua'
+        "
+        @click="handleScreen"
+      />
+      <i
+        v-if="isShowBack"
+        class="iconfont icon-fanhui1"
+        @click="$router.back()"
+      />
+    </div> -->
+    <tip class="tip-con" />
+    <i
+      v-if="formPanelCloseSta"
+      class="iconfont form-panel-sts-btn form-panel-sts-btn-close z-idx-top-2"
+      :class="formPanelCloseSta ? 'icon-zhedie6' : 'icon-zhedie5'"
+      @click="formPanelToggle"
     />
     />
-    <div style="position: relative">
-      <Flr
-        v-show="isShowFlr"
-        :curFlr.sync="currentFloor"
-        :floors="totalFlrNum"
+    <div
+      v-show="!formPanelCloseSta"
+      ref="form"
+      class="cfg-form-container m-r-s z-idx-top-1"
+    >
+      <i
+        class="iconfont form-panel-sts-btn"
+        :class="formPanelCloseSta ? 'icon-zhedie6' : 'icon-zhedie5'"
+        @click="formPanelToggle"
       />
       />
-      <div class="switch-cell-mode-btn" @click="handleSwitchCellMode">
-        <template v-if="isShowNumInCell">
-          <span>隐</span>
-          <span>藏</span>
-          <span>列</span>
-          <span>行</span>
-        </template>
-        <template v-else>
-          <span>显</span>
-          <span>示</span>
-          <span>列</span>
-          <span>行</span>
-        </template>
+      <el-form
+        ref="cfgForm"
+        :model="cfgForm"
+        label-width="76px"
+        size="mini"
+        :rules="rules"
+        class="cum-form cum-form-cfg"
+      >
+        <el-form-item label="仓库" prop="warehouseId">
+          <el-select
+            ref="warehouseSel"
+            v-model="cfgForm.warehouseId"
+            class="w-full"
+            placeholder="请选择仓库"
+            :disabled="whDis"
+          >
+            <el-option
+              v-for="wh in whList"
+              :key="wh.id"
+              :label="wh.name"
+              :value="wh.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="层数(层)" prop="floor">
+          <el-input-number
+            v-model="cfgForm.floor"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="100"
+          />
+        </el-form-item>
+        <el-form-item label="货高(mm)" prop="goodsHeight">
+          <el-input-number
+            v-model="cfgForm.goodsHeight"
+            placeholder="请输入"
+            controls-position="right"
+          />
+        </el-form-item>
+        <el-form-item label="顶层货高" prop="topGoodsHeight">
+          <el-select
+            v-model="cfgForm.topGoodsHeight"
+            class="w-full"
+            placeholder="请选择顶层货高"
+          >
+            <el-option label="1/2" :value="0" />
+            <el-option label="1/3" :value="1" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label-width="0">
+          <div class="height-cum-con">
+            <el-button
+              class="height-cum-btn"
+              icon="el-icon-plus"
+              @click="addFloorGoodsHeightCum"
+            >定制每层货高</el-button>
+            <div>
+              <div
+                v-for="(item, index) in cfgForm.floorGoodsHeights"
+                :key="index"
+                class="height-cum"
+              >
+                <el-input-number
+                  v-model="item.floor"
+                  :controls="false"
+                  class="floor-input"
+                  placeholder="层"
+                />
+                <el-input-number
+                  v-model="item.goodsHeight"
+                  :controls="false"
+                  class="height-input"
+                  placeholder="货高(mm)"
+                />
+                <el-button
+                  title="删除"
+                  class="height-cum-btn height-cum-btn-del"
+                  icon="el-icon-minus"
+                  @click="delFloorGoodsHeightCum(index)"
+                />
+              </div>
+            </div>
+          </div>
+        </el-form-item>
+        <el-form-item label="行" prop="row">
+          <el-input-number
+            v-model="cfgForm.row"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+        <el-form-item label="列" prop="column" class="form-item-cfg">
+          <el-input-number
+            v-model="cfgForm.column"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+        <el-form-item label="托盘长(mm)" prop="palletLength">
+          <el-input-number
+            v-model="cfgForm.palletLength"
+            placeholder="请输入"
+            controls-position="right"
+          />
+        </el-form-item>
+        <el-form-item label="托盘宽(mm)" prop="palletWidth">
+          <el-input-number
+            v-model="cfgForm.palletWidth"
+            placeholder="请输入"
+            controls-position="right"
+          />
+        </el-form-item>
+        <el-form-item label="间距(mm)" prop="space">
+          <el-input-number
+            v-model="cfgForm.space"
+            placeholder="请输入"
+            controls-position="right"
+          />
+        </el-form-item>
+        <el-form-item label="护网" prop="lateralNet">
+          <el-checkbox-group
+            v-model="cfgForm.lateralNet"
+            class="horizontal-checkbox-group"
+          >
+            <el-checkbox :label="0">前</el-checkbox>
+            <el-checkbox :label="1">后</el-checkbox>
+            <el-checkbox :label="2">左</el-checkbox>
+            <el-checkbox :label="3">右</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item label="前区(行)" prop="front">
+          <el-input-number
+            v-model="cfgForm.front"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+        <el-form-item label="后区(行)" prop="back">
+          <el-input-number
+            v-model="cfgForm.back"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+        <el-form-item label="左区(列)" prop="left">
+          <el-input-number
+            v-model="cfgForm.left"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+        <el-form-item label="右区(列)" prop="right">
+          <el-input-number
+            v-model="cfgForm.right"
+            placeholder="请输入"
+            controls-position="right"
+            step-strictly
+            :min="0"
+            :max="200"
+          />
+        </el-form-item>
+      </el-form>
+      <div class="btn-con z-idx-top-1">
+        <div>
+          <el-button
+            class="w-full m-b-ext-small m-t-small"
+            type="primary"
+            :loading="btnSysInfo.loading_build"
+            :size="btnSysInfo.btnSize"
+            @click="btnBuild"
+          >应用</el-button>
+        </div>
+        <!-- <div v-for="(itemBtn, index) in btnSysInfo.CFG_LIST" :key="index">
+          <el-button
+            type="primary"
+            plain
+            class="w-full m-b-ext-small"
+            :size="btnSysInfo.btnSize"
+            :disabled="
+              btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtn] ===
+                btnSysInfo.STATUS_DIS
+            "
+            @click="btnSub(itemBtn)"
+          >{{
+            btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtn] ===
+              btnSysInfo.STATUS_ING
+              ? btnSysInfo["infoWord_confirm"]
+              : btnSysInfo["infoWord_" + itemBtn]
+          }}</el-button>
+        </div> -->
+        <el-row
+          v-for="(itemBtnArr, index) in btnSysInfo.CFG_LIST"
+          :key="index"
+          :gutter="6"
+        >
+          <el-col :span="12">
+            <el-button
+              type="primary"
+              plain
+              class="w-full m-b-ext-small"
+              :size="btnSysInfo.btnSize"
+              :disabled="
+                btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtnArr[0]] ===
+                  btnSysInfo.STATUS_DIS
+              "
+              @click="btnSub(itemBtnArr[0])"
+            >{{
+              btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtnArr[0]] ===
+                btnSysInfo.STATUS_ING
+                ? btnSysInfo["infoWord_confirm"]
+                : btnSysInfo["infoWord_" + itemBtnArr[0]]
+            }}</el-button>
+          </el-col>
+          <el-col v-if="itemBtnArr[1]" :span="12">
+            <el-button
+              type="primary"
+              plain
+              class="w-full m-b-ext-small"
+              :size="btnSysInfo.btnSize"
+              :disabled="
+                btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtnArr[1]] ===
+                  btnSysInfo.STATUS_DIS
+              "
+              @click="btnSub(itemBtnArr[1])"
+            >{{
+              btnSysInfo[btnSysInfo.STATUS_FLAG + itemBtnArr[1]] ===
+                btnSysInfo.STATUS_ING
+                ? btnSysInfo["infoWord_confirm"]
+                : btnSysInfo["infoWord_" + itemBtnArr[1]]
+            }}</el-button>
+          </el-col>
+        </el-row>
+        <div>
+          <el-button
+            class="w-full m-b-ext-small"
+            :size="btnSysInfo.btnSize"
+            @click="resetForm('cfgForm')"
+          >重置</el-button>
+        </div>
+        <div>
+          <!-- :disabled="
+              btnSysInfo[btnSysInfo.STATUS_FLAG + 'submit'] ===
+                btnSysInfo.STATUS_DIS
+            " -->
+          <el-button
+            class="w-full m-b-small"
+            type="primary"
+            :loading="btnSysInfo.loading_submit"
+            :size="btnSysInfo.btnSize"
+            @click="submitForm('cfgForm')"
+          >保存</el-button>
+        </div>
+        <div>
+          <el-button
+            icon="el-icon-download"
+            class="w-full m-b-small"
+            type="primary"
+            :loading="btnSysInfo.loading_expCfg"
+            :size="btnSysInfo.btnSize"
+            @click="expCfg('cfgForm')"
+          >导出配置</el-button>
+        </div>
       </div>
       </div>
     </div>
     </div>
-    <div class="cfg-container-content" ref="container">
-      <grid-canvas
+    <Floor
+      v-if="cfgForm.floor"
+      ref="floor"
+      :floor-num="cfgForm.floor"
+      :active-floor="0"
+      class="floor-con z-idx-top-1"
+      :class="{ 'floor-con-left': formPanelCloseSta }"
+    />
+    <div ref="workSpace" v-loading="houseLoading" class="ware-con">
+      <grid
         ref="grid"
         ref="grid"
-        operModel="cfg"
-        @grid-canvas-save="gridCanvasSave"
-        :isShowNumInCell="isShowNumInCell"
-        :isShowRackIndxNum="true"
-        :containerWidth="containerWidth"
-        :containerHeight="containerHeight"
-        :operFloor="currentFloor"
+        :style="gridSty"
+        :orientation-racking="forward"
+        :pallet-num="row"
+        :carrier-road-num="column"
+        :pallet-width="palletLength"
+        :pallet-len="palletWidth"
+        :space="space"
       />
       />
     </div>
     </div>
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
-import cfgPanel from "./components/cfg-panel.vue";
-import GridCanvas from "@/components/map/grid-canvas/index.vue";
-import Flr from "@/components/flr/flr.vue";
-import warehouseRouteMixin from "@/mixins/map/warehouseRouteMixin";
-import gridCanvasMixin from "@/mixins/map/canvas/gridCanvasMixin";
-
+import cfg from '@/core/mixins/ware-house.js'
+import { mapGetters } from 'vuex'
+import variables from '@/styles/variables.scss'
 export default {
 export default {
-  components: {
-    cfgPanel,
-    GridCanvas,
-    Flr,
-  },
+  name: 'Cfg',
+  mixins: [cfg],
   data() {
   data() {
     return {
     return {
-      isShowNumInCell: false,
-      viewModelRadio: 0,
-      workSpLoadingObj: {
-        isLoading: true,
-      },
-      totalFlr: 0,
-      warehouseData: null,
-      socket: null,
-      socketUrl: "ws://127.0.0.1:8080",
-      socketIsConnect: false,
-      mapShowModel: "show",
-      currentFloor: 1,
-      totalFlrNum: 1,
-      isShowFlr: false,
-    };
+      formPanelCloseSta: false
+    }
   },
   },
-  mixins: [warehouseRouteMixin, gridCanvasMixin],
-  mounted() {},
-  methods: {
-    handleSwitchCellMode() {
-      this.isShowNumInCell = !this.isShowNumInCell;
+  computed: {
+    ...mapGetters(['sidebar']),
+    variables() {
+      return variables
     },
     },
-    gridCanvasSave(data) {
-      const formData =
-        this.$refs["cfgPanel"] && this.$refs["cfgPanel"].formData;
-      Object.keys(data).forEach((key) => {
-        formData[key] = data[key];
-      });
-      this.handleSave(formData);
-    },
-    downloadImg() {
-      if (!this.hasBuild) {
-        this.$message({
-          message: "请先构建工作空间",
-          type: "warning",
-        });
-        return;
-      }
-      this.$refs["grid"] && this.$refs["grid"].saveCanvasAsImage();
-    },
-    handleSaveAndBuild(data, isNotToggleMes) {
-      this.handleSave(data, isNotToggleMes);
-      this.handleBuild(data);
-    },
-    procFormDataBeforeSave(data) {
-      data["mapRow"] = data["row"] + data.rowStart - 1;
-      data["mapCol"] = data["col"] + data.colStart - 1;
-      data["none"] = [...(data.unUse || []), ...(data.unExist || [])];
+    isCollapse() {
+      return !this.sidebar.opened
+    }
+  },
+  methods: {
+    formPanelToggle() {
+      this.formPanelCloseSta = !this.formPanelCloseSta
+      // console.log(this.formPanelCloseSta)
     },
     },
-    handleSave(data, isNotToggleMes) {
-      this.procFormDataBeforeSave(data);
-      this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "SaveMapConfig",
-          param: data,
-        },
+    async expCfg(formName) {
+      this.$refs[formName].validateField('warehouseId', (valid) => {
+        if (valid === '') {
+          this.$confirm(
+            '此操作将导出已保存的仓库配置,是否继续?',
+            '导出配置',
+            {
+              confirmButtonText: this.$GPROP['conBtn'],
+              cancelButtonText: this.$GPROP['cancelBtn'],
+              type: 'warning'
+            }
+          ).then(() => {
+            this.$req({
+              url: '/pps/api',
+              method: 'post',
+              data: {
+                method: 'ExportMap',
+                param: { warehouseId: this.cfgForm.warehouseId.toString() }
+              },
+              responseType: 'blob'
+            }).then((res) => {
+              const selectInstance = this.$refs.warehouseSel
+              const fileName =
+                (selectInstance.selectedLabel || '') + '-仓库配置.json'
+              this.$utils.downloadFile(res, fileName)
+            })
+          })
+        }
       })
       })
-        .then((res) => {
-          if (!isNotToggleMes) {
-            this.$message({
-              message: "保存成功",
-              type: "success",
-            });
-          }
-        })
-        .catch((error) => {
-          this.$message({
-            message: "保存失败",
-            type: "error",
-          });
-          console.error("Failed to save form data:", error);
-        });
-    },
-    handleBuild(formData) {
-      if (!formData) {
-        this.$refs["grid"] && this.$refs["grid"].resetData();
-        return;
-      }
-      this.totalFlrNum = formData.floor;
-      this.isShowFlr = true;
-      this.$refs["grid"] && this.$refs["grid"].setIsShowing(true);
-      this.$refs["grid"] &&
-        this.$refs["grid"].initData({ row: formData }, true);
-      this.hasBuild = true;
-      // this.workSpLoadingObj.isLoading = false
-    },
-    getWareHouseData() {
-      if (!this.warehouseData?.id) {
-        return;
-      }
-      return this.$req({
-        url: "/pps/api",
-        method: "post",
-        data: {
-          method: "GetMapConfig",
-          param: {
-            id: this.warehouseData.id,
-          },
-        },
-      });
-    },
-    handleFloorChange(floor) {
-      this.currentFloor = floor;
-    },
-  },
-};
+    }
+  }
+}
 </script>
 </script>
-
+<style lang="scss">
+.cum-form-cfg.el-form {
+  .el-form-item {
+    .el-form-item__label {
+      font-size: 12px;
+    }
+    .el-form-item__content {
+      .el-form-item__error {
+        font-size: 6px;
+      }
+    }
+    margin-bottom: 14px;
+  }
+  .el-button {
+    width: 100%;
+    padding: 6px 10px;
+  }
+}
+.horizontal-checkbox-group {
+  .el-checkbox {
+    margin-right: 6px;
+    .el-checkbox__label {
+      font-size: 12px;
+      padding-left: 2px;
+    }
+  }
+}
+</style>
 <style lang="scss" scoped>
 <style lang="scss" scoped>
+@import "@/styles/variables.scss";
+$btnConHeight: 284px; // before 318px
+$tipW: 40px;
+$formConWid: 236px;
 .cfg-container {
 .cfg-container {
-  display: flex;
+  background-color: #fff;
+  position: relative;
   width: 100%;
   width: 100%;
-  height: 100%;
+  height: calc(100vh - 60px);
+  padding: 0 $tipW 0 284px; //284px为操作form + 楼层宽度
   overflow: hidden;
   overflow: hidden;
-  .cfg-container-content {
-    flex: 1;
+  &-pd-left {
+    padding-left: 76px; //加上floor
+  }
+  .form-panel-sts-btn {
+    color: $operCo;
+    position: absolute;
+    font-size: 24px;
+    bottom: 20px;
+    right: -10px;
+    &-close {
+      bottom: 20px;
+      left: 4px;
+      right: 0px;
+    }
+  }
+  .oper-con {
+    position: absolute;
+    right: 8px;
+    top: 8px;
+    font-size: 20px;
+    color: $operCo;
+    background-color: #fff;
+    .back {
+      font-size: 24px;
+    }
+  }
+  .tip-con {
+    position: absolute;
+    right: 0;
+    top: 0;
+  }
+  .cfg-form-container {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: $formConWid;
     height: 100%;
     height: 100%;
+    padding: 0 0 $btnConHeight 0;
+    background-color: $bgContentMain;
+    .form-panel-sts-btn {
+      color: $operCo;
+      position: absolute;
+      font-size: 24px;
+      bottom: 20px;
+      right: -10px;
+      &-close {
+        bottom: 20px;
+        left: 4px;
+        right: 0px;
+      }
+    }
+    .cum-form {
+      height: 100%;
+      overflow-y: auto;
+      overflow-x: hidden;
+      padding-right: 8px;
+      .height-cum-con {
+        // margin-bottom: 14px;
+        .height-cum-btn {
+          // margin-bottom: 8px;
+        }
+        .height-cum-btn-del {
+          width: auto;
+        }
+        .height-cum {
+          display: flex;
+          justify-content: space-around;
+          // margin-bottom: 8px;
+          .floor-input {
+            width: 40%;
+          }
+          .height-input {
+            width: 45%;
+          }
+        }
+      }
+    }
+    .btn-con {
+      position: absolute;
+      bottom: 0;
+      width: calc(100% - 24px);
+      padding-left: 12px;
+    }
+  }
+  .floor-con {
+    position: absolute;
+    height: 100%;
+    top: 0;
+    left: 244px;
+    &-left {
+      left: 0;
+    }
+  }
+  .ware-con {
     width: 100%;
     width: 100%;
-    overflow: auto;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    overflow: hidden;
   }
   }
 }
 }
-
-.switch-cell-mode-btn {
-  position: absolute;
-  bottom: 10px;
+.checkbox-group-container {
   display: flex;
   display: flex;
-  flex-direction: column;
-  font-size: 12px;
-  padding: 4px;
-  background: #f5f7fa;
-  border: 1px solid #dcdfe6;
-  border-radius: 3px;
-  cursor: pointer;
-  color: #606266;
-  width: 24px;
-  text-align: center;
-  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12);
-  transition: all 0.3s;
+  justify-content: space-around;
+  align-items: center;
 }
 }
 
 
-.switch-cell-mode-btn span {
-  line-height: 14px;
-}
-
-.switch-cell-mode-btn:hover {
-  background: #ecf5ff;
-  border-color: #409eff;
-  color: #409eff;
+.horizontal-checkbox-group {
+  display: flex;
 }
 }
 </style>
 </style>

+ 1 - 1
src/views/materialconfig/index.vue

@@ -12,7 +12,7 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout.js'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout.js'
 export default {
 export default {
   name: 'MaterialConfig',
   name: 'MaterialConfig',
   components: {
   components: {

+ 2 - 2
src/views/materialcost/index.vue

@@ -96,8 +96,8 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout.js'
-import baseWareHouseId from '@/mixins/baseWareHouseId'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout.js'
+import baseWareHouseId from '@/core/mixins/baseWareHouseId'
 
 
 export default {
 export default {
   name: 'MaterialDetail',
   name: 'MaterialDetail',

+ 2 - 2
src/views/materialdetail/index.vue

@@ -15,8 +15,8 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout'
-import baseWareHouseId from '@/mixins/baseWareHouseId'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout'
+import baseWareHouseId from '@/core/mixins/baseWareHouseId'
 
 
 export default {
 export default {
   name: 'MaterialDetail',
   name: 'MaterialDetail',

+ 1 - 1
src/views/register/index.vue

@@ -34,7 +34,7 @@
 </template>
 </template>
 
 
 <script>
 <script>
-import routerCache from '@/mixins/routerCache.js'
+import routerCache from '@/core/mixins/routerCache.js'
 export default {
 export default {
   mixins: [routerCache],
   mixins: [routerCache],
   data() {
   data() {

+ 0 - 40
src/views/show/2-5D/V0/index.vue

@@ -1,40 +0,0 @@
-<template>
-  <div
-    class="show-container"
-    ref="container"
-  >
-    <GridCanvas
-      ref="gridCanvasRef"
-      :isShowAllFlr="true"
-      :includedAngle="45"
-      :containerWidth="containerWidth"
-      :containerHeight="containerHeight"
-    />
-  </div>
-</template>
-
-<script>
-import GridCanvas from "@/components/map/grid-canvas/index.vue";
-import gridCanvasMixin from "@/mixins/map/canvas/gridCanvasMixin";
-import mapDataMixin from "@/mixins/map/mapDataMixin";
-
-export default {
-  name: "TwoFiveDShowV0",
-  components: {
-    GridCanvas,
-  },
-  mixins: [gridCanvasMixin, mapDataMixin],
-  data() {
-    return {
-      routeName: "2-5dshow-v0",
-    };
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.show-container {
-  width: 100%;
-  height: 100%;
-}
-</style>

+ 0 - 42
src/views/show/2-5D/V1/index.vue

@@ -1,42 +0,0 @@
-<template>
-  <div class="warehouse-container">
-    <GridSvg
-      ref="gridSvg"
-      :containerWidth="containerWidth"
-      :containerHeight="containerHeight"
-      :includedAngle="includedAngle"
-      renderType="svg"
-    />
-  </div>
-</template>
-
-<script>
-import GridSvg from "@/components/map/grid-svg/index.vue";
-import warehouseDataMixin from "@/mixins/map/warehouseDataMixin";
-import gridViewMixin from "@/mixins/map/gridViewMixin";
-
-export default {
-  name: "TwoFiveDShowV1",
-
-  components: {
-    GridSvg,
-  },
-
-  mixins: [warehouseDataMixin, gridViewMixin],
-
-  data() {
-    return {
-      routeName: "2-5dshow-v1",
-    };
-  },
-};
-</script>
-
-<style lang="scss" scoped>
-.warehouse-container {
-  position: relative;
-  width: 100%;
-  height: 100%;
-  min-height: 400px;
-}
-</style>

+ 0 - 34
src/views/show/2D/index.vue

@@ -1,34 +0,0 @@
-<template>
-  <div class="show-container" ref="container">
-    <Flr style="margin-top: 10px" v-show="isShowFlr" :curFlr.sync="currentFloor" :floors="totalFlrNum" />
-    <GridCanvas
-      ref="gridCanvasRef"
-      :containerWidth="containerWidth"
-      :containerHeight="containerHeight"
-    />
-  </div>
-</template>
-
-<script>
-import GridCanvas from "@/components/map/grid-canvas/index.vue";
-import gridCanvasMixin from "@/mixins/map/canvas/gridCanvasMixin";
-import mapDataMixin from "@/mixins/map/mapDataMixin";
-import Flr from "@/components/flr/flr.vue";
-export default {
-  name: "TwoDShow",
-  components: {
-    GridCanvas,
-    Flr,
-  },
-  mixins: [gridCanvasMixin, mapDataMixin],
-};
-</script>
-
-<style lang="scss" scoped>
-.show-container {
-  display: flex;
-  width: 100%;
-  height: 100%;
-  overflow: auto;
-}
-</style>

+ 144 - 0
src/views/show/index.vue

@@ -0,0 +1,144 @@
+<template>
+  <div class="show-container">
+    <tip class="tip-con" type="ani" :not-show-det="cfgForm.notShowDet" />
+    <Floor
+      :floor-num="cfgForm.floor"
+      :active-floor-in="floor"
+      class="floor-con z-idx-top-1"
+      :can-be-click="true"
+      @flr-chg="flrChgFromFloor"
+    />
+    <div ref="workSpace" v-loading="houseLoading" class="ware-con">
+      <grid
+        ref="grid"
+        :orientation-racking="forward"
+        :pallet-num="row"
+        :carrier-road-num="column"
+        :pallet-width="palletLength"
+        :pallet-len="palletWidth"
+        :space="space"
+        oper-type="animation"
+        @flr-chg="flrChg"
+      />
+    </div>
+  </div>
+</template>
+
+<script>
+import cfg from '@/core/mixins/ware-house.js'
+// import { ItemMeasure } from '@/global-cfg/global'
+export default {
+  name: 'Show',
+  mixins: [cfg],
+  data() {
+    return {
+      businessType: 'animation',
+      stores: null,
+      carriers: null,
+      floor: 0
+    }
+  },
+  mounted() {
+    // this.animationTest()
+  },
+  methods: {
+    flrChg(val) {
+      this.floor = val || 0
+    },
+    flrChgFromFloor(val) {
+      this.$refs['grid'].flrChg(val || 0)
+    },
+    /**
+     * 20230615
+     * afterGetData ==> afterGetData2使用后台WS真实推送数据(init当前状态,updata实时状态)。
+     * afterGetData为mixins: [cfg]获取接口数据后动作
+     */
+    afterGetData2() {
+      this.$nextTick(() => {
+        if (this.cfgForm.warehouseId === 1) { // 后台模拟动画
+          this.$refs['grid'].setWHId(this.cfgForm.warehouseId)
+          // 初始楼层
+          this.$refs['grid'].setFlr(this.floor)
+          this.$refs['grid'].storesShow(this.cfgForm.warehouseId)
+          this.$refs['grid'].carriersShow(this.cfgForm.warehouseId)
+        } else { // 前台模拟动画
+          this.animationTest()
+        }
+      })
+    },
+    animationTest() {
+      this.imitateAni()
+      this.$refs['grid'].animationTest()
+    },
+    imitateAni() {
+      const res = []
+      for (let i = 0; i < 3; i++) {
+        for (let j = 0; j < this.cfgForm.column; j++) {
+          res.push([i, j])
+        }
+      }
+      this.$refs['grid'].setGoodsDisArr(res)
+      this.$refs['grid'].setCcarrierTask([
+        [this.cfgForm.row - 1, 0],
+        [0, this.cfgForm.column - 1]
+      ])
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+@import "@/styles/variables.scss";
+.show-container {
+  background-color: #fff;
+  position: relative;
+  width: 100%;
+  height: calc(100vh - 50px);
+  padding-left: 40px;
+  padding-right: 36px;//右侧提示容器大小
+  // padding-top: 40px;
+  overflow: hidden;
+  .cum-form {
+    position: absolute;
+    top: 0;
+    left: 40px;
+    margin-top: $spaceSmall;
+  }
+  .oper-con {
+    position: absolute;
+    right: 8px;
+    top: 8px;
+    font-size: 20px;
+    color: $operCo;
+    background-color: #fff;
+    .back {
+      font-size: 24px;
+    }
+  }
+  .tip-con {
+    position: absolute;
+    right: 0;
+    top: 0;
+  }
+  .floor-con {
+    position: absolute;
+    height: 100%;
+    top: 0;
+    left: 0;
+  }
+  .ware-con {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    overflow: auto;
+  }
+  .ware {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    background: $wareBgCo;
+  }
+}
+</style>

+ 1 - 1
src/views/specconfig/index.vue

@@ -13,7 +13,7 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout.js'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout.js'
 export default {
 export default {
   name: 'SpecConfig',
   name: 'SpecConfig',
   components: {
   components: {

+ 1 - 1
src/views/totalPrice/index.vue

@@ -281,7 +281,7 @@ const rowParamArr = [
   'taxRate',
   'taxRate',
   'remark'
   'remark'
 ]
 ]
-import routerCache from '@/mixins/routerCache.js'
+import routerCache from '@/core/mixins/routerCache.js'
 export default {
 export default {
   mixins: [routerCache],
   mixins: [routerCache],
   data() {
   data() {

+ 1 - 1
src/views/totalPriceCfg/index.vue

@@ -77,7 +77,7 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout.js'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout.js'
 export default {
 export default {
   name: 'MaterialConfig',
   name: 'MaterialConfig',
   components: {
   components: {

+ 12 - 67
src/views/warehouse/config.js

@@ -3,7 +3,7 @@ export const businessKey = 'warehouse'
 const idFlag = 'id'
 const idFlag = 'id'
 export const styCfg = {
 export const styCfg = {
   isNotShowSearch: false,
   isNotShowSearch: false,
-  tabOperMinWid:600,
+  tabOperMinWid: 600,
   isNotShowPagination: true,
   isNotShowPagination: true,
   pagDefSize: 10000
   pagDefSize: 10000
 }
 }
@@ -105,11 +105,10 @@ export const btnCfg = [
     icon: 'el-icon-setting',
     icon: 'el-icon-setting',
     disabledControl: true,
     disabledControl: true,
     operFun: function(that, item, data) {
     operFun: function(that, item, data) {
-      const warehouse = JSON.parse(JSON.stringify({id: data.id, name: data.name}));
       that.$router.push({
       that.$router.push({
         path: '/cfg/cfg',
         path: '/cfg/cfg',
         query: {
         query: {
-          warehouse: JSON.stringify(warehouse),
+          id: data.id,
           isShowBack: true
           isShowBack: true
         }
         }
       })
       })
@@ -120,75 +119,22 @@ export const btnCfg = [
     btnType: 'info',
     btnType: 'info',
     wordFlag: '2dshowBtn',
     wordFlag: '2dshowBtn',
     permFlag: '2dshow',
     permFlag: '2dshow',
-    label: '2D',
+    label: '2D看板',
     isNotShowInTabOperCol: false,
     isNotShowInTabOperCol: false,
     role: 'Admin',
     role: 'Admin',
     isNotShowInTabTop: true,
     isNotShowInTabTop: true,
     icon: 'el-icon-monitor',
     icon: 'el-icon-monitor',
     disabledControl: true,
     disabledControl: true,
-    /* tableOperDisCon: function(data) {
+    tableOperDisCon: function(data) {
       return !data.isConfig
       return !data.isConfig
-    }, */
+    },
     operFun: function(that, item, data) {
     operFun: function(that, item, data) {
-      const warehouse = JSON.parse(JSON.stringify({id: data.id, name: data.name}));
       that.$router.push({
       that.$router.push({
         path: '/show/2dshow',
         path: '/show/2dshow',
         query: {
         query: {
-          warehouse: JSON.stringify(warehouse),
+          id: data.id,
           isShowBack: true,
           isShowBack: true,
-          title: '2D-' + data.name
-        }
-      })
-    }
-  },
-  {
-    operFlag: '2-5dshow-v0',
-    btnType: 'info',
-    wordFlag: '2-5dshow-v0Btn',
-    permFlag: '2-5dshow-v0',
-    label: '2-5D',
-    isNotShowInTabOperCol: false,
-    role: 'Admin',
-    isNotShowInTabTop: true,
-    icon: 'el-icon-monitor',
-    disabledControl: true,
-    /* tableOperDisCon: function(data) {
-      return !data.isConfig
-    }, */
-    operFun: function(that, item, data) {
-      const warehouse = JSON.parse(JSON.stringify({id: data.id, name: data.name}));
-      that.$router.push({
-        path: '/show/2-5dshow-v0',
-        query: {
-          warehouse: JSON.stringify(warehouse),
-          isShowBack: true,
-          title: '2-5D-' + data.name
-        }
-      })
-    }
-  },
-  {
-    operFlag: '2-5dshow-v1',
-    btnType: 'info',
-    wordFlag: '2-5dshow-v1Btn',
-    permFlag: '2-5dshow-v1',
-    label: '2-5D-V1',
-    isNotShowInTabOperCol: false,
-    role: 'Admin',
-    isNotShowInTabTop: true,
-    icon: 'el-icon-monitor',
-    disabledControl: true,
-    /* tableOperDisCon: function(data) {
-      return !data.isConfig
-    }, */
-    operFun: function(that, item, data) {
-      const warehouse = JSON.parse(JSON.stringify({id: data.id, name: data.name}));
-      that.$router.push({
-        path: '/show/2-5dshow-v1',
-        query: {
-          warehouse: JSON.stringify(warehouse),
-          isShowBack: true,
-          title: '2-5D-' + data.name
+          title: '2D看板-' + data.name
         }
         }
       })
       })
     }
     }
@@ -198,23 +144,22 @@ export const btnCfg = [
     btnType: 'info',
     btnType: 'info',
     wordFlag: '3dshowBtn',
     wordFlag: '3dshowBtn',
     permFlag: '3dshow',
     permFlag: '3dshow',
-    label: '3D',
+    label: '3D看板',
     isNotShowInTabOperCol: false,
     isNotShowInTabOperCol: false,
     role: 'Admin',
     role: 'Admin',
     isNotShowInTabTop: true,
     isNotShowInTabTop: true,
     icon: 'el-icon-monitor',
     icon: 'el-icon-monitor',
     disabledControl: true,
     disabledControl: true,
-    /* tableOperDisCon: function(data) {
+    tableOperDisCon: function(data) {
       return !data.isConfig
       return !data.isConfig
-    }, */
+    },
     operFun: function(that, item, data) {
     operFun: function(that, item, data) {
-      const warehouse = JSON.parse(JSON.stringify({id: data.id, name: data.name}));
       that.$router.push({
       that.$router.push({
         path: '/show/3dshow',
         path: '/show/3dshow',
         query: {
         query: {
-          warehouse: JSON.stringify(warehouse),
+          warehouseId: data.id,
           isShowBack: true,
           isShowBack: true,
-          title: '3D-' + data.name
+          title: '3D看板-' + data.name
         }
         }
       })
       })
     }
     }

+ 1 - 1
src/views/warehouse/index.vue

@@ -12,7 +12,7 @@
 <script>
 <script>
 import Layout from '@/layout-content/ContentLayout.vue'
 import Layout from '@/layout-content/ContentLayout.vue'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
 import { columnConfig, url, styCfg, businessKey, btnCfg } from './config.js'
-import routerCacheForContentLayout from '@/mixins/routerCacheForContentLayout.js'
+import routerCacheForContentLayout from '@/core/mixins/routerCacheForContentLayout.js'
 export default {
 export default {
   name: 'Warehouse',
   name: 'Warehouse',
   components: {
   components: {

+ 1 - 1
vue.config.js

@@ -50,7 +50,7 @@ module.exports = {
     proxy: {
     proxy: {
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       // detail: https://cli.vuejs.org/config/#devserver-proxy
       [process.env.VUE_APP_BASE_API]: {
       [process.env.VUE_APP_BASE_API]: {
-        target: `https://localhost:446`, // 本地环境
+        target: `https://localhost:444`, // 本地环境
         // target: `https://123.60.57.251:443`, // 测试环境
         // target: `https://123.60.57.251:443`, // 测试环境
         // target: `https://baidu.com`,
         // target: `https://baidu.com`,
         changeOrigin: true,
         changeOrigin: true,

Some files were not shown because too many files changed in this diff