From 48e2278d7ac330c7f05deda6f884acb6f01206b4 Mon Sep 17 00:00:00 2001
From: yangpeixing <yangpeixing@hnkhzn.com>
Date: 星期一, 13 四月 2026 17:13:51 +0800
Subject: [PATCH] 1
---
WMS/WIDESEA_WMSClient/src/views/Home.vue | 585 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 575 insertions(+), 10 deletions(-)
diff --git a/WMS/WIDESEA_WMSClient/src/views/Home.vue b/WMS/WIDESEA_WMSClient/src/views/Home.vue
index 820437a..c272330 100644
--- a/WMS/WIDESEA_WMSClient/src/views/Home.vue
+++ b/WMS/WIDESEA_WMSClient/src/views/Home.vue
@@ -1,24 +1,589 @@
<template>
- <div class="title"></div>
+ <div class="container" id="vol-main"> <!-- 鏂板id锛屽尮閰岼S涓殑鑾峰彇閫昏緫 -->
+ <div class="header">
+ <h2 class="title">璐т綅鎺掑浘</h2>
+ </div>
+
+ <div class="content-wrapper">
+ <!-- 鎺у埗闈㈡澘鍖哄煙 -->
+ <div class="control-panel">
+ <div class="form-group">
+ <label>鍖哄煙锛�</label>
+ <el-select size="mini" filterable v-model="Area.shelf_code" placeholder="璇烽�夋嫨" class="full-width">
+ <el-option v-for="item in slectData" :value="item.shelf_code" :label="item.house_name"
+ :key="item.shelf_code"></el-option> <!-- 淇key鍊硷紝閬垮厤閲嶅 -->
+ </el-select>
+ </div>
+
+ <div class="form-group">
+ <label>鎺掞細</label>
+ <el-select size="mini" clearable filterable @change="SCChange" v-model="Area.tunnel" placeholder="璇烽�夋嫨"
+ class="full-width">
+ <el-option v-for="item in scList" :value="item" :label="item" :key="item"></el-option>
+ </el-select>
+ </div>
+
+ <el-button type="success" class="refresh-btn" @click="GetViewData">
+ 鍒锋柊
+ </el-button>
+ <el-button plain class="notify-trigger-btn" @click="open2">
+ 璀﹀憡
+ </el-button>
+ <div class="legend-section">
+ <h4>璇存槑</h4>
+ <div class="legend-grid">
+ <div class="legend-item" v-for="item in infoMsg" :key="item.state"> <!-- 淇key鍊硷紝鐢╯tate鏇村敮涓� -->
+ <span class="color-box" :style="{ 'background-color': item.bgcolor }"></span>
+ <span class="legend-label">{{ item.msg }} {{ item.quantity }}</span>
+ </div>
+ </div>
+ </div>
+
+ <!-- 楗煎浘瀹瑰櫒锛氫慨鏀规牱寮忎娇鍏跺眳涓� -->
+ <div class="echarts-container">
+ <div ref="myChart" class="chart-inner"></div>
+ </div>
+ </div>
+
+ <!-- 璐т綅灞曠ず鍖哄煙 -->
+ <div class="location-view">
+ <!-- 澧炲姞鏃犳暟鎹彁绀� -->
+ <div v-if="locationData.length === 0" class="empty-tip">鏆傛棤璐т綅鏁版嵁锛岃閫夋嫨鍖哄煙骞剁偣鍑诲埛鏂�</div>
+ <div class="layer-container" v-for="layer in locationData" :key="layer.index">
+ <h3 class="layer-title">绗瑊{ layer.index }}灞�</h3>
+ <div class="row" v-for="row in layer.rows" :key="row.index">
+ <div class="location-cell" :style="{ 'background-color': GetBgColor(col) }" v-for="col in row.cols"
+ :key="col.index" @mouseenter="showTooltip(col, $event)" @mouseleave="hideTooltip">
+ {{ row.index }}-{{ col.index }}-{{ layer.index }}
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- 鎮诞鎻愮ず妗� -->
+ <div v-if="showTooltipFlag" class="location-tooltip" :style="{
+ left: tooltipPosition.x + 'px',
+ top: tooltipPosition.y + 'px',
+ }">
+ <div v-if="currentLocation">
+ <p><strong>璐т綅鍙�:</strong>{{ currentLocation.locationCode || '鏃�' }}</p> <!-- 澧炲姞榛樿鍊� -->
+ <p>
+ <strong>璐т綅鎺掑垪灞�:</strong> {{ currentLocation.row || 0 }}鎺抺{
+ currentLocation.index || 0
+ }}鍒梴{ currentLocation.layer || 0 }}灞�
+ </p>
+ <p><strong>鐘舵��:</strong> {{ getStatusText(currentLocation) }}</p>
+ <p>
+ <strong>绂佺敤:</strong>
+ {{ currentLocation.location_lock == 3 ? "鏄�" : "鍚�" }}
+ </p>
+ <p v-if="currentLocation.location_state === 2">
+ <strong>鐗╂枡缂栫爜:</strong>
+ {{ currentLocation.material_code || "鏃�" }}
+ </p>
+ <p v-if="currentLocation.location_state === 2">
+ <strong>鏁伴噺:</strong> {{ currentLocation.quantity || "鏃�" }}
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
</template>
<script>
-import { ref, reactive } from 'vue'
+import { ElButton, ElSelect, ElOption } from "element-plus"; // 瀹屾暣寮曞叆闇�瑕佺殑缁勪欢
+import * as echarts from 'echarts';
export default {
- setup() {
+ components: { ElButton, ElSelect, ElOption }, // 娉ㄥ唽鎵�鏈夌敤鍒扮殑缁勪欢
+ data() {
return {
-
+ slectData: [],
+ scList: [],
+ Area: { house_name: "", tunnel: "", shelf_code: "" },
+ mian_height: "",
+ infoMsg: [
+ { bgcolor: "lightgreen", msg: "绌鸿揣浣�", state: 0, quantity: 0 },
+ { bgcolor: "orange", msg: "鏈夎揣", state: 2, quantity: 0 },
+ { bgcolor: "#2BB3D5", msg: "閿佸畾", state: "InAssigned", quantity: 0 },
+ { bgcolor: "#ccc", msg: "绂佺敤", state: 3, quantity: 0 },
+ { bgcolor: "#b7ba6b", msg: "鍏跺畠", state: "else", quantity: 0 },
+ ],
+ locationData: [],
+ showTooltipFlag: false,
+ currentLocation: null,
+ tooltipPosition: { x: 0, y: 0 },
+ chart: null,
+ notifyOffset: 0, // 鏂板锛氶�氱煡鍋忕Щ閲忚鏁板櫒
+ notifyHeight: 80, // 閫氱煡缁勪欢楂樺害锛堝彲鏍规嵁瀹為檯璋冩暣锛�
+ notifyGap: 15, // 閫氱煡涔嬮棿鐨勯棿璺�
+ };
+ },
+ computed: {
+ GetBgColor() {
+ return (col) => {
+ // 绠�鍖栭�昏緫锛屾彁楂樺彲璇绘��
+ if (col.location_lock == 3) {
+ return this.infoMsg.find(item => item.state === 3).bgcolor;
+ }
+ if (col.location_state === 2) {
+ return this.infoMsg.find(item => item.state === 2).bgcolor;
+ }
+ if (col.location_state > 0 && col.location_state < 100) {
+ return this.infoMsg.find(item => item.state === "InAssigned").bgcolor;
+ }
+ if (col.location_state === 0) {
+ return this.infoMsg.find(item => item.state === 0).bgcolor;
+ }
+ return this.infoMsg.find(item => item.state === "else").bgcolor;
+ };
+ },
+ // 鏂板锛氬皢infoMsg杞崲涓洪ゼ鍥鹃渶瑕佺殑鏁版嵁鏍煎紡
+ chartData() {
+ return this.infoMsg.map(item => ({
+ name: item.msg,
+ value: item.quantity,
+ itemStyle: {
+ color: item.bgcolor // 璁╅ゼ鍥鹃鑹插拰鍥句緥淇濇寔涓�鑷�
+ }
+ })).filter(item => item.value > 0); // 杩囨护鎺夋暟閲忎负0鐨勯」
}
- }
-}
+ },
+ watch: {
+ "Area.shelf_code"(newValue, oldValue) {
+ if (!newValue) return; // 绌哄�兼椂涓嶆墽琛�
+ this.scList = [];
+ const target = this.slectData.find(e => e.shelf_code === newValue);
+ if (target) {
+ this.Area.tunnel = target.tunnel?.[0] || ""; // 鍙�夐摼閬垮厤鎶ラ敊
+ this.scList = target.tunnel || [];
+ this.GetViewData(); // 鏁版嵁鍔犺浇瀹屾垚鍚庡啀璋冪敤
+ }
+ },
+ // 鐩戝惉chartData鍙樺寲锛屾洿鏂伴ゼ鍥�
+ chartData: {
+ deep: true,
+ handler() {
+ this.updateChart();
+ }
+ },
+ },
+ methods: {
+ async GetViewData() {
+ this.warinngNotification();
+ // 澧炲姞鍙傛暟鏍¢獙
+ if (!this.Area.shelf_code || !this.Area.tunnel) {
+ this.$message?.warning("璇峰厛閫夋嫨鍖哄煙鍜屾帓锛�"); // Element Plus 鎻愮ず
+ return;
+ }
+
+ try {
+ const res = await this.http.post(
+ "/api/LocationInfoRow/GetLocationStatu",
+ this.Area,
+ "鏌ヨ涓�"
+ );
+ this.locationData = res || [];
+ console.log("鍚庣杩斿洖:", this.locationData);
+
+ // 閲嶇疆缁熻鏁伴噺
+ this.infoMsg.forEach(item => item.quantity = 0);
+
+ // 缁熻鍚勭姸鎬佹暟閲�
+ this.locationData.forEach(layer => {
+ (layer.rows || []).forEach(row => {
+ (row.cols || []).forEach(col => {
+ if (col.location_lock == 3) {
+ const item = this.infoMsg.find(el => el.state === 3);
+ if (item) item.quantity++;
+ } else if (col.location_state === 2) {
+ const item = this.infoMsg.find(el => el.state === 2);
+ if (item) item.quantity++;
+ } else if (col.location_state > 0 && col.location_state < 100) {
+ const item = this.infoMsg.find(el => el.state === "InAssigned");
+ if (item) item.quantity++;
+ } else if (col.location_state === 0) {
+ const item = this.infoMsg.find(el => el.state === 0);
+ if (item) item.quantity++;
+ } else {
+ const item = this.infoMsg.find(el => el.state === "else");
+ if (item) item.quantity++;
+ }
+ });
+ });
+ });
+ } catch (error) {
+ console.error("鑾峰彇璐т綅鏁版嵁澶辫触:", error);
+ this.$message?.error("鑾峰彇鏁版嵁澶辫触锛岃閲嶈瘯锛�");
+ this.locationData = [];
+ }
+ },
+ SCChange() {
+ this.GetViewData();
+ },
+ showTooltip(location, event) {
+ this.currentLocation = location;
+ this.showTooltipFlag = true;
+ this.tooltipPosition = {
+ x: event.clientX + 10,
+ y: event.clientY + 10,
+ };
+ },
+ hideTooltip() {
+ this.showTooltipFlag = false;
+ this.currentLocation = null;
+ },
+ getStatusText(location) {
+ const stateMap = {
+ 0: "绌鸿揣浣�",
+ 1: "閿佸畾",
+ 2: "鏈夎揣",
+ 10: "鏈夎揣閿佸畾",
+ 20: "绌洪棽閿佸畾",
+ 99: "澶ф墭鐩橀攣瀹�"
+ };
+ return stateMap[location.location_state] || "鍏朵粬";
+ },
+ // 鍒濆鍖栭ゼ鍥�
+ initChart() {
+ // 姝g‘鑾峰彇myChart鍏冪礌
+ const chartDom = this.$refs.myChart;
+ if (!chartDom) return;
+ this.chart = echarts.init(chartDom);
+ // 璁剧疆楗煎浘鍩虹閰嶇疆
+ const option = {
+ // 浼樺寲tooltip閰嶇疆锛岄槻姝㈣閬尅
+ tooltip: {
+ trigger: 'item',
+ formatter: '{a} <br/>{b}: {c} ({d}%)', // 鏄剧ず鍚嶇О銆佹暟閲忋�佺櫨鍒嗘瘮
+ // 鍏抽敭閰嶇疆锛氶槻姝ooltip琚伄鎸�
+ zIndex: 99999, // 璁剧疆鏋侀珮鐨勫眰绾э紝纭繚鍦ㄦ渶涓婂眰
+ confine: true, // 灏唗ooltip闄愬埗鍦ㄥ浘琛ㄥ鍣ㄥ唴
+ position: function (point, params, dom, rect, size) {
+ // 鑷畾涔塼ooltip浣嶇疆锛岄伩鍏嶈秴鍑哄鍣�
+ const x = point[0];
+ const y = point[1];
+ // 璁$畻tooltip鐨勬樉绀轰綅缃紝浼樺厛鏄剧ず鍦ㄥ彸渚э紝瓒呭嚭鍒欐樉绀哄湪宸︿晶
+ const ret = {
+ left: x + size.contentSize[0] > size.viewSize[0]
+ ? (x - size.contentSize[0] - 10) + 'px'
+ : (x + 10) + 'px',
+ top: y + size.contentSize[1] > size.viewSize[1]
+ ? (y - size.contentSize[1] - 10) + 'px'
+ : (y + 10) + 'px'
+ };
+ return ret;
+ },
+ // 澧炲姞tooltip鏍峰紡锛屽寮鸿瑙夋晥鏋�
+ textStyle: {
+ fontSize: 12
+ },
+ backgroundColor: 'rgba(255,255,255,0.95)',
+ borderColor: '#ddd',
+ borderWidth: 1,
+ padding: 8,
+ shadowBlur: 5,
+ shadowColor: 'rgba(0,0,0,0.1)'
+ },
+ series: [
+ {
+ name: '',
+ type: 'pie',
+ radius: '64%',
+ label: {
+ show: true,
+ position: 'outside', // 鏍囩鏄剧ず鍦ㄥ閮�
+ formatter: '{b}:{d}%' // 鏄剧ず鍚嶇О鍜屾暟閲�
+ },
+ data: this.chartData,
+ emphasis: {
+ itemStyle: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: 'rgba(0, 0, 0, 0.5)'
+ }
+ }
+ }
+ ]
+ };
+ this.chart.setOption(option);
+ // 鐩戝惉绐楀彛澶у皬鍙樺寲锛岃嚜閫傚簲鍥捐〃
+ window.addEventListener('resize', () => this.chart?.resize());
+ },
+ // 鏇存柊楗煎浘鏁版嵁
+ updateChart() {
+ if (!this.chart) return;
+ this.chart.setOption({
+ series: [
+ {
+ data: this.chartData
+ }
+ ]
+ });
+ },
+ warinngNotification() {
+ this.http.post("/api/LocationInfo/LocationWarning", {}, true).then((result) => {
+ if (!result.status) {
+ this.$Message.$error(x.message);
+ } else {
+ console.log(result.data)
+ result.data.forEach(item => {
+ this.open2(item);
+ })
+ console.log(this.messageList)
+ }
+ });
+ },
+ open2(locationName) {
+ // 1. 璁$畻褰撳墠閫氱煡鐨勫亸绉婚噺
+ const currentOffset = this.notifyOffset;
+
+ // 2. 鏄剧ず閫氱煡
+ const notifyInstance = this.$notify({
+ title: '璀﹀憡 [' + locationName + ']',
+ message: "浠撳簱鍗犳湁鐜囧凡杈惧埌80%鎴�80%浠ヤ笂",
+ type: 'warning',
+ duration: 5000,
+ offset: currentOffset, // 鎵嬪姩鎸囧畾鍋忕Щ閲�
+ // 3. 閫氱煡鍏抽棴鍚庯紝閲嶇疆鍋忕Щ閲忥紙閬垮厤鍚庣画閫氱煡浣嶇疆閿欎贡锛�
+ onClose: () => {
+ this.notifyOffset -= (this.notifyHeight + this.notifyGap);
+ // 闃叉鍋忕Щ閲忎负璐熸暟
+ if (this.notifyOffset < 0) this.notifyOffset = 0;
+ }
+ });
+
+ // 4. 鏇存柊涓嬩竴涓�氱煡鐨勫亸绉婚噺
+ this.notifyOffset += (this.notifyHeight + this.notifyGap);
+ },
+ },
+ mounted() {
+ // 纭繚DOM鍔犺浇瀹屾垚鍚庤幏鍙栧厓绱�
+ this.$nextTick(() => {
+ const mainHeight = document.getElementById("vol-main");
+ if (mainHeight) {
+ this.mian_height = mainHeight.offsetHeight - 40 + "px";
+ }
+ // this.warinngNotification();
+ // 鍒濆鍖栦笅鎷夋暟鎹�
+ this.http.get("/api/LocationInfoRow/GetArea", {}, "鏌ヨ涓�")
+ .then((x) => {
+ this.slectData = x || [];
+ if (this.slectData.length > 0) {
+ this.Area.shelf_code = this.slectData[0].shelf_code;
+ this.scList = this.slectData[0].tunnel || [];
+ this.Area.tunnel = this.scList[0] || "";
+ // 鍒濆鍖栧浘琛�
+ this.initChart();
+ }
+ })
+ .catch(error => {
+ console.error("鑾峰彇鍖哄煙鏁版嵁澶辫触:", error);
+ this.$message?.error("鍔犺浇鍖哄煙鏁版嵁澶辫触锛�");
+ });
+ });
+ },
+ beforeUnmount() {
+ // 閿�姣佸浘琛紝閬垮厤鍐呭瓨娉勬紡
+ if (this.chart) {
+ this.chart.dispose();
+ this.chart = null;
+ }
+ },
+};
</script>
<style scoped>
-.title {
- line-height: 70vh;
+/* 鍘熸湁鏍峰紡淇濇寔涓嶅彉锛屾柊澧炰互涓嬫牱寮� */
+#vol-main {
+ height: 100vh;
+ /* 纭繚瀹瑰櫒鏈夐珮搴� */
+ box-sizing: border-box;
+}
+
+.empty-tip {
text-align: center;
- font-size: 28px;
- color: orange;
+ padding: 50px 0;
+ color: #999;
+ font-size: 14px;
+}
+
+/* 鍏抽敭淇敼锛氶ゼ鍥惧鍣ㄦ牱寮忥紝瀹炵幇鍦ㄦ帶鍒堕潰鏉垮尯鍩熷眳涓� */
+.echarts-container {
+ margin-top: 20px;
+ width: 100%;
+ flex: 1;
+ /* 璁╅ゼ鍥惧鍣ㄥ崰鎹帶鍒堕潰鏉垮墿浣欑┖闂� */
+ display: flex;
+ /* Flex甯冨眬瀹炵幇姘村钩+鍨傜洿灞呬腑 */
+ justify-content: center;
+ /* 姘村钩灞呬腑 */
+ align-items: center;
+ /* 鍨傜洿灞呬腑 */
+ position: relative;
+ z-index: 1;
+}
+
+/* 楗煎浘鍐呴儴瀹瑰櫒 */
+.chart-inner {
+ width: 400px;
+ height: 400px;
+ /* 楗煎浘瀹為檯澶у皬 */
+}
+
+
+/* 鏂板锛氱粰ECharts瀹炰緥瀹瑰櫒澧炲姞鏍峰紡锛岀‘淇漷ooltip涓嶈閬尅 */
+:deep(.echarts-tooltip) {
+ z-index: 99999 !important;
+ /* 寮哄埗鏈�楂樺眰绾� */
+ pointer-events: none;
+ /* 闃叉tooltip閬尅榧犳爣浜嬩欢 */
+}
+
+/* 鍘熸湁鏍峰紡 */
+.container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+ padding: 10px;
+}
+
+.header {
+ text-align: center;
+ margin-bottom: 20px;
+}
+
+.title {
+ font-size: 20px;
+ font-weight: bold;
+ margin: 0;
+}
+
+.content-wrapper {
+ display: flex;
+ flex: 1;
+ min-height: 0;
+}
+
+.control-panel {
+ width: 320px;
+ padding: 15px;
+ background-color: #f5f7fa;
+ border-radius: 4px;
+ margin-right: 15px;
+ display: flex;
+ flex-direction: column;
+ /* 纭繚鎺у埗闈㈡澘鍐呯殑鍏冪礌灞傜骇姝g‘ */
+ position: relative;
+ z-index: 10;
+}
+
+.form-group {
+ margin-bottom: 15px;
+}
+
+.full-width {
+ width: 100%;
+}
+
+.refresh-btn {
+ margin-top: 10px;
+ width: 100%;
+}
+
+.legend-section {
+ margin-top: 30px;
+}
+
+.legend-section h4 {
+ margin-bottom: 10px;
+}
+
+.legend-grid {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: 8px;
+}
+
+.legend-item {
+ display: flex;
+ align-items: center;
+}
+
+.color-box {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+ margin-right: 8px;
+ border-radius: 3px;
+}
+
+.legend-label {
+ font-size: 13px;
+}
+
+.location-view {
+ flex: 1;
+ overflow: auto;
+ padding: 10px;
+ background-color: white;
+ border-radius: 4px;
+ /* 璁剧疆鍚堢悊鐨勫眰绾э紝浣庝簬tooltip */
+ z-index: 1;
+}
+
+.layer-container {
+ margin-bottom: 25px;
+}
+
+.layer-title {
+ margin: 0 0 10px 0;
+ font-size: 16px;
+ color: #333;
+}
+
+.row {
+ display: flex;
+ flex-wrap: wrap;
+ margin-bottom: 8px;
+ cursor: pointer;
+}
+
+.location-cell {
+ width: 66px;
+ height: 38px;
+ margin: 3px;
+ text-align: center;
+ font-size: 14px;
+ border-radius: 3px;
+ line-height: 38px;
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.location-tooltip {
+ position: fixed;
+ z-index: 9999;
+ background-color: white;
+ border: 1px solid #ddd;
+ border-radius: 4px;
+ padding: 10px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
+ pointer-events: none;
+ max-width: 250px;
+}
+
+.location-tooltip p {
+ margin: 5px 0;
+ font-size: 13px;
+ line-height: 1.4;
+}
+
+.location-tooltip strong {
+ display: inline-block;
+ width: 70px;
+ color: #666;
+}
+
+.notify-trigger-btn {
+ display: none !important;
}
</style>
\ No newline at end of file
--
Gitblit v1.9.3