From bfcd7f5b405e431a5c07fe3fa77d74c892d4e66b Mon Sep 17 00:00:00 2001
From: xiazhengtongxue <133085197+xiazhengtongxue@users.noreply.github.com>
Date: 星期四, 19 三月 2026 15:52:42 +0800
Subject: [PATCH] fix: 修复出入库冲突拦截,系统位置与实际位置的映射和修复
---
项目代码/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue | 1328 ++++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 942 insertions(+), 386 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
index fc8b569..aeba5a1 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue"
@@ -1,392 +1,948 @@
-
<template>
- <view-grid
- ref="grid"
- :columns="columns"
- :detail="detail"
- :editFormFields="editFormFields"
- :editFormOptions="editFormOptions"
- :searchFormFields="searchFormFields"
- :searchFormOptions="searchFormOptions"
- :table="table"
- :extend="extend"
- >
- </view-grid>
+ <div class="container">
+ <div class="content-wrapper">
+ <!-- 鎺у埗闈㈡澘鍖哄煙 -->
+ <div class="control-panel">
+ <div class="panel-header">
+ <h3>鎺у埗闈㈡澘</h3>
+ </div>
+
+ <div class="panel-body">
+ <div class="form-group">
+ <label class="form-label">浠撳簱锛�</label>
+ <el-select size="mini" filterable v-model="selectedWarehouse" placeholder="璇烽�夋嫨浠撳簱" class="full-width"
+ @change="handleWarehouseChange">
+ <el-option v-for="item in warehouseList" :key="item.warehouseId" :value="item.warehouseId"
+ :label="getWarehouseName(item.warehouseId)">
+ </el-option>
+ </el-select>
+ </div>
+
+ <div class="form-group">
+ <label class="form-label">宸烽亾锛�</label>
+ <el-select size="mini" clearable filterable v-model="selectedRoadwayNo" placeholder="璇烽�夋嫨宸烽亾"
+ class="full-width" @change="handleRoadwayNoChange">
+ <el-option v-for="item in roadwayNoList" :key="item" :value="item" :label="'宸烽亾 ' + item"></el-option>
+ </el-select>
+ </div>
+
+ <el-button type="success" class="refresh-btn" @click="fetchLocationStatus" :loading="loading">
+ 鍒锋柊
+ </el-button>
+
+ <div class="legend-section">
+ <div class="legend-header">
+ <h4>鍥句緥璇存槑</h4>
+ </div>
+ <div class="legend-list">
+ <div class="legend-item" v-for="(item, index) in infoMsg" :key="index">
+ <span class="color-box" :style="{ 'background-color': item.bgcolor }"></span>
+ <span class="legend-label">{{ item.msg }}</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 璐т綅灞曠ず鍖哄煙 -->
+ <div class="main-content">
+ <div v-if="loading" class="loading-container">
+ <el-skeleton :rows="6" animated />
+ </div>
+
+ <div v-else-if="locationData.length > 0" class="location-container">
+ <div class="location-header">
+ <div class="location-info">
+ <span>褰撳墠鏌ョ湅锛歿{ getWarehouseName(selectedWarehouse) }} - 宸烽亾 {{ selectedRoadwayNo }}</span>
+ <span class="total-count">鍏� {{ totalLocations }} 涓揣浣�</span>
+ </div>
+ </div>
+
+ <div class="layers-container">
+ <!-- 閬嶅巻姣忎竴灞� -->
+ <div class="layer-row" v-for="layer in sortedLayerData" :key="layer.layer">
+ <div class="layer-title-area">
+ <h3 class="layer-title">灞� {{ layer.layer }}</h3>
+ <span class="layer-count">{{ getLayerLocations(layer) }} 涓揣浣�</span>
+ </div>
+
+ <div class="layer-content-wrap">
+ <!-- 鎸夎鍒嗙粍鏄剧ず -->
+ <div class="row-group" v-for="rowGroup in getRowGroups(layer)" :key="rowGroup.row">
+ <div class="row-title">
+ <span class="row-label">{{ rowGroup.row }}鎺�</span>
+ <span class="row-count">{{ rowGroup.locations.length }} 涓揣浣�</span>
+ </div>
+
+ <div class="row-content">
+ <!-- 鍦ㄦ瘡鎺掑唴鏄剧ず鍒楋紙涓嶆樉绀哄垪鏍囩锛� -->
+ <div class="location-column" v-for="column in sortedColumns(rowGroup.columns)" :key="column.column">
+ <div class="locations-wrapper">
+ <!-- 姣忓垪鏄剧ず娣卞害锛堟祬/娣憋級 -->
+ <div class="location-item" v-for="depth in column.depths" :key="depth.depth"
+ :class="getLocationStatusClass(depth)"
+ @mouseenter="showTooltip(depth, column.column, layer.layer, $event)"
+ @mouseleave="hideTooltip"
+ @click="handleLocationClick(depth)">
+ <div class="location-code">
+ {{ getLocationPositionForDisplay(depth, column.column, layer.layer) }}
+ </div>
+ <div class="location-status" v-if="depth.enableStatus !== 0">
+ 绂佺敤
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- 鏃犳暟鎹彁绀� -->
+ <div v-else class="empty-container">
+ <el-empty description="鏆傛棤璐т綅鏁版嵁">
+ <template #description>
+ <p>璇烽�夋嫨浠撳簱鍜屽贩閬撴潵鏌ョ湅璐т綅淇℃伅</p>
+ </template>
+ </el-empty>
+ </div>
+
+ <!-- 鎮诞鎻愮ず妗� -->
+ <div v-if="showTooltipFlag" class="location-tooltip" :style="{
+ left: tooltipPosition.x + 'px',
+ top: tooltipPosition.y + 'px',
+ }">
+ <div class="tooltip-content">
+ <div class="tooltip-header">
+ <h4>璐т綅璇︽儏</h4>
+ </div>
+ <div class="tooltip-body">
+ <div class="tooltip-row">
+ <span class="tooltip-label">浠撳簱锛�</span>
+ <span class="tooltip-value">{{ getWarehouseName(selectedWarehouse) }}</span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">宸烽亾锛�</span>
+ <span class="tooltip-value">{{ selectedRoadwayNo }}</span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">璐т綅缂栧彿锛�</span>
+ <span class="tooltip-value">{{ currentLocation?.locationCode || '--' }}</span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">浣嶇疆锛�</span>
+ <span class="tooltip-value">{{ getLocationPosition(currentLocation) }}</span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">绫诲瀷锛�</span>
+ <span class="tooltip-value">{{ getLocationTypeText(currentLocation?.locationType) }}</span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">鐘舵�侊細</span>
+ <span class="tooltip-value" :class="getStatusClass(currentLocation?.locationStatus)">
+ {{ getStatusText(currentLocation?.locationStatus) }}
+ </span>
+ </div>
+ <div class="tooltip-row">
+ <span class="tooltip-label">鍚敤鐘舵�侊細</span>
+ <span class="tooltip-value" :class="{ 'status-disabled': currentLocation?.enableStatus !== 0 }">
+ {{ getEnableStatusText(currentLocation?.enableStatus) }}
+ </span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
</template>
- <script>
-import extend from "@/extension/stock/stockView.js";
-import { ref, defineComponent } from "vue";
-export default defineComponent({
- setup() {
- const table = ref({
- key: "stockId",
- footer: "Foots",
- cnName: "搴撳瓨瑙嗗浘",
- name: "stockView",
- url: "/stockView/",
- sortName: "stockId",
- });
- const editFormFields = ref({
- palletCode: "",
- locationCode: "",
- locationName: "",
- });
- const editFormOptions = ref([
-
- ]);
- const searchFormFields = ref({
- palletCode: "",
- // locationCode: "",
- materielCode:"",
- batchNo:""
- });
- const searchFormOptions = ref([
- [
- { title: "鎵樼洏缂栧彿", field: "palletCode",type: "like" },
- // { title: "璐т綅缂栧彿", field: "locationCode",type: "like" },
- { title: "璐т綅鐘舵��", field: "locationStatus" ,type: "selectList",dataKey: "locationStatusEnum",data: [],},
- { title: "搴撳瓨鐘舵��", field: "stockStatus",type: "selectList",dataKey: "stockStatusEmun",data: [],},
- ],
- [
- { title: "鐗╂枡缂栧彿", field: "materielCode",type: "like"},
- { title: "鎵规鍙�", field: "batchNo",type: "like"},
- { title: "鎵�灞炰粨搴�", field: "warehouseId",type: "selectList",dataKey: "warehouses",data: [],},
- ],
- ]);
- const columns = ref([
- {
- field: "stockId",
- title: "Id",
- type: "int",
- width: 90,
- hidden: true,
- readonly: true,
- require: true,
- align: "left",
- },
- {
- field: "palletCode",
- title: "鎵樼洏缂栧彿",
- type: "string",
- width: 150,
- link: true,
- align: "left",
- },
- {
- field: "locationCode",
- title: "璐т綅缂栧彿",
- type: "string",
- width: 200,
- align: "left",
- },
- {
- field: "locationName",
- title: "璐т綅鍚嶇О",
- type: "string",
- width: 270,
- align: "left",
- },
- {
- field: "warehouseId",
- title: "鎵�灞炰粨搴�",
- type: "string",
- width: 80,
- align: "left",
- bind: { key: "warehouses", data: [] },
- },
- {
- field: "roadwayNo",
- title: "宸烽亾缂栧彿",
- type: "decimal",
- width: 100,
- align: "left",
- hidden:true
- },
- {
- field: "materielCode",
- title: "鎵�鍚墿鏂欑紪鍙�",
- type: "string",
- width: 120,
- align: "left",
- },
- {
- field: "batchNo",
- title: "鎵�鍚墿鏂欐壒娆�",
- type: "string",
- width: 200,
- align: "left"
- },
- {
- field: "materielInfo",
- title: "鎵�鍚墿鏂欐渶鏃╀复鏈�",
- type: "string",
- width: 140,
- align: "left",
- },
- {
- field: "sumStock",
- title: "鎬诲簱瀛�",
- type: "string",
- width: 140,
- align: "left",
- },
- {
- field: "row",
- title: "璐т綅琛�",
- type: "string",
- width: 90,
- align: "left",
- hidden: true,
- },
- {
- field: "column",
- title: "璐т綅鍒�",
- type: "int",
- width: 120,
- align: "left",
- hidden: true,
- },
- {
- field: "layer",
- title: "璐т綅灞�",
- type: "string",
- width: 200,
- align: "left",
- hidden: true,
- },
- {
- field: "depth",
- title: "璐т綅娣卞害",
- type: "string",
- width: 180,
- align: "left",
- hidden: true,
- },
- {
- field: "stockStatus",
- title: "搴撳瓨鐘舵��",
- type: "string",
- width: 200,
- align: "left",
- bind: { key: "stockStatusEmun", data: [] },
- },
- {
- field: "locationType",
- title: "璐т綅绫诲瀷",
- type: "string",
- width: 100,
- align: "left",
- bind:{key: "locationTypeEnum", data: []}
- },
- {
- field: "locationStatus",
- title: "璐т綅鐘舵��",
- type: "string",
- width: 120,
- align: "left",
- bind: { key: "locationStatusEnum", data: [] },
- },
- {
- field: "enalbeStatus",
- title: "绂佺敤鐘舵��",
- type: "string",
- width: 80,
- align: "left",
- bind: { key: "enableStatusEnum", data: [] },
- },
- {
- field: "creater",
- title: "鍒涘缓浜�",
- type: "string",
- width: 90,
- align: "left",
- },
- {
- field: "createDate",
- title: "鍒涘缓鏃堕棿",
- type: "datetime",
- width: 160,
- align: "left",
- },
- {
- field: "modifier",
- title: "淇敼浜�",
- type: "string",
- width: 100,
- align: "left",
- },
- {
- field: "modifyDate",
- title: "淇敼鏃堕棿",
- type: "datetime",
- width: 160,
- align: "left",
- },
- {
- field: "remark",
- title: "澶囨敞",
- type: "string",
- width: 100,
- align: "left",
- hidden:true
- },
- ]);
- const detail = ref({
- cnName: "搴撳瓨鏄庣粏淇℃伅",
- table: "StockInfoDetail",
- columns: [
- {
- field: "id",
- title: "Id",
- type: "int",
- width: 90,
- hidden: true,
- readonly: true,
- require: true,
- align: "left",
- },
- {
- field: "stockId",
- title: "搴撳瓨淇℃伅涓婚敭",
- type: "string",
- width: 90,
- align: "left",
- hidden: true
- },
- {
- field: "materielCode",
- title: "鐗╂枡缂栧彿",
- type: "string",
- width: 110,
- align: "left",
- },
- {
- field: "materielName",
- title: "鐗╂枡鍚嶇О",
- type: "string",
- width: 130,
- align: "left",
- },
- {
- field: "orderNo",
- title: "鍗曟嵁缂栧彿",
- type: "decimal",
- width: 130,
- align: "left",
- },
- {
- field: "batchNo",
- title: "鎵规鍙�",
- type: "string",
- width: 180,
- align: "left",
- },
- {
- field: "serialNumber",
- title: "搴忓垪鍙�",
- type: "int",
- width: 120,
- align: "left",
- hidden: true,
- },
- {
- field: "stockQuantity",
- title: "搴撳瓨鏁伴噺",
- type: "string",
- width: 80,
- align: "left",
- },
- {
- field: "outboundQuantity",
- title: "鍑哄簱鏁伴噺",
- type: "string",
- width: 80,
- align: "left",
- },
- {
- field: "unit",
- title: "鍗曚綅",
- type: "string",
- width: 50,
- align: "left",
- },
- {
- field: "productionDate",
- title: "鐢熶骇鏃ユ湡",
- type: "string",
- width: 80,
- align: "left",
- },
- {
- field: "effectiveDate",
- title: "鏈夋晥鏃ユ湡",
- type: "string",
- width: 80,
- align: "left",
- },
- {
- field: "status",
- title: "搴撳瓨鏄庣粏鐘舵��",
- type: "string",
- width: 120,
- align: "left",
- bind: { key: "stockStatusEmun", data: [] }
- },
- {
- field: "creater",
- title: "鍒涘缓浜�",
- type: "string",
- width: 90,
- align: "left",
- hidden: true
- },
- {
- field: "createDate",
- title: "鍒涘缓鏃堕棿",
- type: "datetime",
- width: 160,
- align: "left",
- hidden: true
- },
- {
- field: "modifier",
- title: "淇敼浜�",
- type: "string",
- width: 100,
- align: "left",
- hidden: true
- },
- {
- field: "modifyDate",
- title: "淇敼鏃堕棿",
- type: "datetime",
- width: 160,
- align: "left",
- hidden: true
- },
- {
- field: "remark",
- title: "澶囨敞",
- type: "string",
- width: 100,
- align: "left",
- hidden: true
- },
- ],
- sortName: "id",
- key: "id",
- });
+
+<script>
+import { ElButton, ElMessage, ElSelect, ElOption, ElEmpty, ElSkeleton } from "element-plus";
+
+export default {
+ data() {
return {
- table,
- extend,
- editFormFields,
- editFormOptions,
- searchFormFields,
- searchFormOptions,
- columns,
- detail,
+ warehouseList: [],
+ roadwayNoList: [],
+ selectedWarehouse: null,
+ selectedRoadwayNo: null,
+ selectedLocationCode: null,
+ infoMsg: [
+ { bgcolor: "#2BB3D5", msg: "绌鸿揣浣�" },
+ { bgcolor: "orange", msg: "鏈夎揣" },
+ { bgcolor: "lightgreen", msg: "閿佸畾" },
+ { bgcolor: "#ccc", msg: "绂佺敤" }
+ ],
+ locationData: [],
+ showTooltipFlag: false,
+ currentLocation: null,
+ tooltipPosition: { x: 0, y: 0 },
+ currentColumn: null,
+ currentLayer: null,
+ loading: false
};
},
-});
+ computed: {
+ sortedLayerData() {
+ const layerMap = {};
+
+ this.locationData.forEach(layer => {
+ if (!layerMap[layer.layer]) {
+ layerMap[layer.layer] = {
+ layer: layer.layer,
+ columns: []
+ };
+ }
+
+ layer.columns?.forEach(column => {
+ layerMap[layer.layer].columns.push({
+ column: column.column,
+ depths: column.depths || []
+ });
+ });
+ });
+
+ return Object.values(layerMap).sort((a, b) => a.layer - b.layer);
+ },
+
+ totalLocations() {
+ let count = 0;
+ this.locationData.forEach(layer => {
+ layer.columns?.forEach(column => {
+ count += column.depths?.length || 0;
+ });
+ });
+ return count;
+ }
+ },
+ methods: {
+ // 鎸夎鍒嗙粍鏁版嵁
+ getRowGroups(layer) {
+ const rowMap = {};
+
+ // 閬嶅巻鎵�鏈夊垪鍜屾繁搴︼紝鎸夎鍒嗙粍
+ layer.columns?.forEach(column => {
+ column.depths?.forEach(depth => {
+ const row = depth.row || '?';
+
+ if (!rowMap[row]) {
+ rowMap[row] = {
+ row: row,
+ locations: [],
+ columns: {}
+ };
+ }
+
+ // 娣诲姞鍒拌琛岀殑浣嶇疆鍒楄〃
+ rowMap[row].locations.push({
+ ...depth,
+ column: column.column,
+ layer: layer.layer
+ });
+
+ // 鎸夊垪缁勭粐鏁版嵁
+ if (!rowMap[row].columns[column.column]) {
+ rowMap[row].columns[column.column] = {
+ column: column.column,
+ depths: []
+ };
+ }
+
+ rowMap[row].columns[column.column].depths.push(depth);
+ });
+ });
+
+ // 杞崲涓烘暟缁勫苟鎸夎鎺掑簭
+ return Object.values(rowMap)
+ .sort((a, b) => this.compareRows(a.row, b.row));
+ },
+
+ sortedColumns(columnsObj) {
+ // 灏嗗璞¤浆鎹负鏁扮粍骞舵寜鍒楀彿鎺掑簭
+ const columns = Object.values(columnsObj || {});
+ return columns.sort((a, b) => a.column - b.column);
+ },
+
+ // 姣旇緝琛屽彿鐨勮緟鍔╂柟娉�
+ compareRows(rowA, rowB) {
+ // 濡傛灉閮芥槸鏁板瓧锛屾寜鏁板瓧姣旇緝
+ if (!isNaN(rowA) && !isNaN(rowB)) {
+ return Number(rowA) - Number(rowB);
+ }
+ // 鍚﹀垯鎸夊瓧绗︿覆姣旇緝
+ return String(rowA).localeCompare(String(rowB));
+ },
+
+ // 鑾峰彇浣嶇疆淇℃伅鐢ㄤ簬鏄剧ず
+ getLocationPositionForDisplay(location, column, layer) {
+ if (!location) return '';
+ const row = location.row || '?';
+ const depthText = location.depth === 1 ? '娴�' : '娣�';
+ return `${row}鎺�${column}鍒�${layer}灞�${depthText}`;
+ },
+
+ // 鑾峰彇浣嶇疆淇℃伅锛堢敤浜庢偓娴彁绀烘锛�
+ getLocationPosition(location) {
+ if (!location || !this.currentColumn || !this.currentLayer) return '--';
+ const row = location.row || '?';
+ const depthText = location.depth === 1 ? '娴�' : '娣�';
+ return `${row}鎺�-${this.currentColumn}鍒�-${this.currentLayer}灞�-${depthText}`;
+ },
+
+ async fetchWarehouseData() {
+ try {
+ this.loading = true;
+ const response = await this.http.get("/api/LocationInfo/GetArea");
+ this.warehouseList = response.data || [];
+
+ if (this.warehouseList.length > 0) {
+ this.selectedWarehouse = this.warehouseList[0].warehouseId;
+ this.roadwayNoList = this.warehouseList[0].roadwayNo || [];
+
+ if (this.roadwayNoList.length > 0) {
+ this.selectedRoadwayNo = this.roadwayNoList[0];
+ await this.fetchLocationStatus();
+ }
+ }
+ } catch (error) {
+ console.error("鑾峰彇浠撳簱鏁版嵁澶辫触:", error);
+ this.warehouseList = [];
+ this.roadwayNoList = [];
+ ElMessage.error("鑾峰彇浠撳簱鏁版嵁澶辫触锛岃绋嶅悗閲嶈瘯");
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ async fetchLocationStatus() {
+ if (!this.selectedWarehouse || !this.selectedRoadwayNo) {
+ ElMessage.warning("璇烽�夋嫨浠撳簱鍜屽贩閬�");
+ return;
+ }
+
+ try {
+ this.loading = true;
+ const response = await this.http.get(
+ `/api/LocationInfo/GetLocationStatus?WarehouseId=${this.selectedWarehouse}&RoadwayNo=${this.selectedRoadwayNo}`
+ );
+
+ if (response.data && response.status) {
+ this.locationData = response.data || [];
+
+ // 楠岃瘉鏁版嵁
+ console.log("璐т綅鏁版嵁:", this.locationData);
+ if (this.locationData.length > 0 && this.locationData[0].columns) {
+ console.log("绀轰緥璐т綅:", this.locationData[0].columns[0]?.depths?.[0]);
+ }
+
+ if (this.locationData.length === 0) {
+ ElMessage.info("璇ュ贩閬撴病鏈夎揣浣嶆暟鎹�");
+ }
+ } else {
+ this.locationData = [];
+ ElMessage.error(response.data?.message || "鑾峰彇璐т綅鐘舵�佸け璐�");
+ }
+ } catch (error) {
+ console.error("鑾峰彇璐т綅鐘舵�佸け璐�:", error);
+ this.locationData = [];
+ ElMessage.error("鑾峰彇璐т綅鐘舵�佸け璐ワ紝璇风◢鍚庨噸璇�");
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ handleWarehouseChange() {
+ const selectedWarehouse = this.warehouseList.find(
+ w => w.warehouseId === this.selectedWarehouse
+ );
+ this.roadwayNoList = selectedWarehouse ? selectedWarehouse.roadwayNo : [];
+ this.selectedRoadwayNo = this.roadwayNoList.length > 0 ? this.roadwayNoList[0] : null;
+ this.fetchLocationStatus();
+ },
+
+ getWarehouseName(warehouseId) {
+ const warehouseMap = {
+ 1: '鍘熸潗鏂欎粨',
+ 2: '鎴愬搧浠�'
+ };
+ return warehouseMap[warehouseId] || `浠撳簱 ${warehouseId}`;
+ },
+
+ handleRoadwayNoChange() {
+ this.fetchLocationStatus();
+ },
+
+ getLocationStatusClass(depth) {
+ if (depth.enableStatus !== 0) {
+ return 'location-disabled';
+ }
+
+ switch (depth.locationStatus) {
+ case 0: return 'location-empty'; // 绌鸿揣浣�
+ case 1: return 'location-locked'; // 閿佸畾
+ case 100: return 'location-occupied'; // 鏈夎揣
+ default: return 'location-other';
+ }
+ },
+
+ getLayerLocations(layer) {
+ let count = 0;
+ layer.columns?.forEach(column => {
+ count += column.depths?.length || 0;
+ });
+ return count;
+ },
+
+ showTooltip(depth, column, layer, event) {
+ this.currentLocation = depth;
+ this.currentColumn = column;
+ this.currentLayer = layer;
+ this.showTooltipFlag = true;
+
+ const offsetX = 15;
+ const offsetY = 15;
+ this.tooltipPosition = {
+ x: event.clientX + offsetX,
+ y: event.clientY + offsetY,
+ };
+ },
+
+ hideTooltip() {
+ this.showTooltipFlag = false;
+ this.currentLocation = null;
+ this.currentColumn = null;
+ this.currentLayer = null;
+ },
+
+ handleLocationClick(depth) {
+ console.log('鐐瑰嚮璐т綅:', depth);
+ // 杩欓噷鍙互娣诲姞鐐瑰嚮璐т綅鐨勫鐞嗛�昏緫
+ ElMessage.info(`閫変腑璐т綅: ${depth.locationCode || '鏈煡璐т綅'}`);
+ },
+
+ getStatusText(status) {
+ const statusMap = {
+ 0: "绌鸿揣浣�",
+ 1: "閿佸畾",
+ 100: "鏈夎揣",
+ };
+ return statusMap[status] || "鏈煡鐘舵��";
+ },
+
+ getStatusClass(status) {
+ const classMap = {
+ 0: 'status-empty',
+ 1: 'status-locked',
+ 100: 'status-occupied'
+ };
+ return classMap[status] || '';
+ },
+
+ getLocationTypeText(type) {
+ const typeMap = {
+ 1: "甯冨嵎",
+ 2: "鏉惧竷鍗�",
+ 3: "鎴愬搧璐т綅"
+ };
+ return typeMap[type] || "鏈煡绫诲瀷";
+ },
+
+ getEnableStatusText(status) {
+ return status === 0 ? '鍚敤' : '绂佺敤';
+ }
+ },
+ mounted() {
+ this.fetchWarehouseData();
+ },
+ components: {
+ ElButton,
+ ElSelect,
+ ElOption,
+ ElEmpty,
+ ElSkeleton
+ },
+};
</script>
-
\ No newline at end of file
+
+<style scoped>
+/* 鏍峰紡閮ㄥ垎 */
+.container {
+ display: flex;
+ flex-direction: column;
+ height: 100vh;
+ padding: 16px;
+ box-sizing: border-box;
+ background-color: #f0f2f5;
+}
+
+.content-wrapper {
+ display: flex;
+ flex: 1;
+ min-height: 0;
+ gap: 16px;
+}
+
+.control-panel {
+ width: 260px;
+ background-color: white;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ display: flex;
+ flex-direction: column;
+ flex-shrink: 0;
+ overflow: hidden;
+}
+
+.panel-header {
+ padding: 16px;
+ border-bottom: 1px solid #e8e8e8;
+ background-color: #fafafa;
+}
+
+.panel-header h3 {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+}
+
+.panel-body {
+ padding: 16px;
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+}
+
+.form-group {
+ margin-bottom: 0;
+}
+
+.form-label {
+ display: block;
+ margin-bottom: 6px;
+ font-size: 14px;
+ color: #666;
+ font-weight: 500;
+}
+
+.full-width {
+ width: 100%;
+}
+
+.refresh-btn {
+ margin-top: 8px;
+ width: 100%;
+ height: 32px;
+}
+
+.legend-section {
+ margin-top: 8px;
+ padding-top: 16px;
+ border-top: 1px solid #e8e8e8;
+}
+
+.legend-header h4 {
+ margin: 0 0 12px 0;
+ font-size: 15px;
+ font-weight: 600;
+ color: #333;
+}
+
+.legend-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.color-box {
+ width: 20px;
+ height: 20px;
+ border-radius: 4px;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ flex-shrink: 0;
+}
+
+.legend-label {
+ font-size: 13px;
+ color: #666;
+}
+
+.main-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+}
+
+.loading-container {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: white;
+ border-radius: 8px;
+ padding: 24px;
+}
+
+.location-container {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ background: white;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
+ overflow: hidden;
+ min-height: 0;
+}
+
+.location-header {
+ padding: 16px 20px;
+ background: #fafafa;
+ border-bottom: 1px solid #e8e8e8;
+ flex-shrink: 0;
+}
+
+.location-info {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ font-size: 14px;
+}
+
+.total-count {
+ font-weight: 600;
+ color: #1890ff;
+}
+
+.layers-container {
+ width: 100%;
+ height: 100%;
+ flex: 1;
+ overflow-y: auto;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ gap: 24px;
+}
+
+.layer-row {
+ background: #f9f9f9;
+ border-radius: 8px;
+ border: 1px solid #e8e8e8;
+ display: flex;
+ flex-direction: column;
+ min-height: auto;
+}
+
+.layer-title-area {
+ padding: 12px 16px;
+ background: #f0f0f0;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ flex-shrink: 0;
+}
+
+.layer-title {
+ margin: 0;
+ font-size: 16px;
+ font-weight: 600;
+ color: #333;
+}
+
+.layer-count {
+ font-size: 12px;
+ color: #666;
+ background: white;
+ padding: 4px 10px;
+ border-radius: 12px;
+ border: 1px solid #ddd;
+}
+
+.layer-content-wrap {
+ width: 100%;
+ overflow: hidden;
+ flex: 1;
+ padding: 16px;
+}
+
+/* 琛岀粍鏍峰紡 */
+.row-group {
+ margin-bottom: 10px;
+ padding: 12px;
+ background: white;
+ border-radius: 6px;
+ border: 1px solid #e8e8e8;
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
+}
+
+.row-group:last-child {
+ margin-bottom: 0;
+}
+
+.row-title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ padding-bottom: 8px;
+ border-bottom: 1px dashed #e8e8e8;
+}
+
+.row-label {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+}
+
+.row-count {
+ font-size: 12px;
+ color: #666;
+ background: #f0f0f0;
+ padding: 2px 8px;
+ border-radius: 10px;
+}
+
+.row-content {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px; /* 鍑忓皬闂磋窛 */
+}
+
+/* 缂╁皬璐т綅妗嗗昂瀵� */
+.location-column {
+ flex: 0 0 auto;
+ width: 70px; /* 鍑忓皬瀹藉害 */
+ min-height: 30px; /* 鍑忓皬楂樺害 */
+ display: flex;
+ flex-direction: column;
+ box-sizing: border-box;
+}
+
+.locations-wrapper {
+ display: flex;
+ flex-direction: column;
+ gap: 4px; /* 鍑忓皬闂磋窛 */
+ flex: 1;
+ min-height: 0;
+}
+
+/* 缂╁皬璐т綅椤� */
+.location-item {
+ min-height: 32px; /* 鍑忓皬楂樺害 */
+ padding: 4px 2px; /* 鍑忓皬鍐呰竟璺� */
+ border-radius: 4px;
+ text-align: center;
+ cursor: pointer;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ transition: all 0.2s;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 1px;
+ flex: 1;
+}
+
+.location-item:hover {
+ transform: scale(1.05);
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.15);
+ z-index: 10;
+}
+
+/* 缂╁皬璐т綅缂栧彿瀛椾綋 */
+.location-code {
+ font-size: 9px; /* 鍑忓皬瀛椾綋 */
+ font-weight: 500;
+ line-height: 1.2;
+ word-break: break-all;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ max-width: 100%;
+}
+
+.location-status {
+ font-size: 8px; /* 鍑忓皬瀛椾綋 */
+ padding: 1px 3px;
+ border-radius: 2px;
+ background: rgba(0, 0, 0, 0.1);
+}
+
+/* 璐т綅鐘舵�侀鑹� */
+.location-empty {
+ background-color: #2BB3D5;
+ color: white;
+}
+
+.location-occupied {
+ background-color: orange;
+ color: white;
+}
+
+.location-locked {
+ background-color: lightgreen;
+ color: #333;
+}
+
+.location-disabled {
+ background-color: #ccc;
+ color: #666;
+ cursor: not-allowed;
+}
+
+.location-other {
+ background-color: #b7ba6b;
+ color: white;
+}
+
+.empty-container {
+ flex: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ background: white;
+ border-radius: 8px;
+}
+
+.location-tooltip {
+ position: fixed;
+ z-index: 9999;
+ background-color: white;
+ border: 1px solid #ddd;
+ border-radius: 6px;
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
+ pointer-events: none;
+ min-width: 220px;
+ max-width: 300px;
+}
+
+.tooltip-content {
+ overflow: hidden;
+}
+
+.tooltip-header {
+ padding: 12px 16px;
+ background-color: #1890ff;
+ color: white;
+}
+
+.tooltip-header h4 {
+ margin: 0;
+ font-size: 14px;
+ font-weight: 600;
+}
+
+.tooltip-body {
+ padding: 12px 16px;
+}
+
+.tooltip-row {
+ display: flex;
+ margin-bottom: 8px;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.tooltip-row:last-child {
+ margin-bottom: 0;
+}
+
+.tooltip-label {
+ flex: 0 0 80px;
+ color: #666;
+ font-weight: 500;
+}
+
+.tooltip-value {
+ flex: 1;
+ color: #333;
+ word-break: break-all;
+}
+
+.status-disabled {
+ color: #f5222d;
+}
+
+/* 婊氬姩鏉℃牱寮� */
+.layers-container::-webkit-scrollbar {
+ width: 8px;
+}
+
+.layers-container::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ border-radius: 4px;
+}
+
+.layers-container::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 4px;
+}
+
+.layers-container::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+ .location-column {
+ width: 95px;
+ }
+}
+
+@media (max-width: 768px) {
+ .content-wrapper {
+ flex-direction: column;
+ }
+
+ .control-panel {
+ width: 100%;
+ }
+
+ .location-column {
+ width: 90px;
+ }
+
+ .row-content {
+ gap: 6px;
+ }
+}
+
+@media (max-width: 480px) {
+ .location-column {
+ width: 80px;
+ }
+
+ .location-code {
+ font-size: 8px;
+ }
+
+ .row-content {
+ gap: 4px;
+ }
+
+ .row-group {
+ padding: 8px;
+ }
+}
+
+@media (max-width: 380px) {
+ .location-column {
+ width: 70px;
+ }
+
+ .location-code {
+ font-size: 7px;
+ }
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3