From 9aaa5a60d9dc29d8db588bc066ccf43b0231affc Mon Sep 17 00:00:00 2001
From: huangxiaoqiang <huangxiaoqiang@hnkhzn.com>
Date: 星期四, 25 十二月 2025 10:33:52 +0800
Subject: [PATCH] ·
---
项目代码/WIDESEA_WMSClient/src/views/charts/wms-dashboard.vue | 725 +++++++++++++++++++++++++++++++++++++++++++++
项目代码/WIDESEA_WMSClient/src/router/viewGird.js | 4
项目代码/WIDESEA_WMSClient/package-lock.json | 174 +++++-----
3 files changed, 815 insertions(+), 88 deletions(-)
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package-lock.json" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package-lock.json"
index 053131a..55513a8 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package-lock.json"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/package-lock.json"
@@ -3612,6 +3612,11 @@
"dev": true,
"optional": true
},
+ "@popperjs/core": {
+ "version": "npm:@sxzz/popperjs-es@2.11.7",
+ "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
+ "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
+ },
"@soda/friendly-errors-webpack-plugin": {
"version": "1.8.0",
"resolved": "https://registry.npm.taobao.org/@soda/friendly-errors-webpack-plugin/download/@soda/friendly-errors-webpack-plugin-1.8.0.tgz?cache=0&sync_timestamp=1607927406873&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40soda%2Ffriendly-errors-webpack-plugin%2Fdownload%2F%40soda%2Ffriendly-errors-webpack-plugin-1.8.0.tgz",
@@ -4386,87 +4391,6 @@
"webpack-chain": "^6.4.0",
"webpack-dev-server": "^3.11.0",
"webpack-merge": "^4.2.2"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "optional": true,
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
- "optional": true,
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "optional": true,
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true,
- "optional": true
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
- "optional": true
- },
- "loader-utils": {
- "version": "2.0.4",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/loader-utils/-/loader-utils-2.0.4.tgz",
- "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
- "dev": true,
- "optional": true,
- "requires": {
- "big.js": "^5.2.2",
- "emojis-list": "^3.0.0",
- "json5": "^2.1.2"
- }
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
- "optional": true,
- "requires": {
- "has-flag": "^4.0.0"
- }
- },
- "vue-loader-v16": {
- "version": "npm:vue-loader@16.8.3",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/vue-loader/-/vue-loader-16.8.3.tgz",
- "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
- "dev": true,
- "optional": true,
- "requires": {
- "chalk": "^4.1.0",
- "hash-sum": "^2.0.0",
- "loader-utils": "^2.0.0"
- }
- }
}
},
"@vue/cli-shared-utils": {
@@ -7637,13 +7561,6 @@
"lodash-unified": "^1.0.2",
"memoize-one": "^6.0.0",
"normalize-wheel-es": "^1.2.0"
- },
- "dependencies": {
- "@popperjs/core": {
- "version": "npm:@sxzz/popperjs-es@2.11.7",
- "resolved": "https://mirrors.huaweicloud.com/repository/npm/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
- "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
- }
}
},
"element-ui": {
@@ -15471,6 +15388,87 @@
}
}
},
+ "vue-loader-v16": {
+ "version": "npm:vue-loader@16.8.3",
+ "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
+ "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chalk": "^4.1.0",
+ "hash-sum": "^2.0.0",
+ "loader-utils": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "optional": true
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "optional": true
+ },
+ "loader-utils": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+ "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "big.js": "^5.2.2",
+ "emojis-list": "^3.0.0",
+ "json5": "^2.1.2"
+ }
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
+ }
+ }
+ },
"vue-qrcode": {
"version": "2.2.2",
"resolved": "https://registry.npmmirror.com/vue-qrcode/-/vue-qrcode-2.2.2.tgz",
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
index fc89499..727c0c8 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/router/viewGird.js"
@@ -247,6 +247,10 @@
path: '/takeStockOrderDetail',
name: 'takeStockOrderDetail',
component: () => import('@/views/inbound/takeStockOrderDetail.vue')
+ }, {
+ path: '/dashboard',
+ name: 'dashboard',
+ component: () => import('@/views/charts/wms-dashboard.vue')
}
]
diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/charts/wms-dashboard.vue" "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/charts/wms-dashboard.vue"
new file mode 100644
index 0000000..5271c53
--- /dev/null
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/WIDESEA_WMSClient/src/views/charts/wms-dashboard.vue"
@@ -0,0 +1,725 @@
+<template>
+ <div class="wms-dashboard">
+ <!-- 椤堕儴鏍囬鏍� -->
+ <div class="header">
+ <h1>WMS浠撳偍鍙鍖栧浘琛ㄧ湅鏉�</h1>
+ <div class="header-right">
+ <span>2025-12-24 16:11:44</span>
+ <el-select v-model="month" placeholder="鏈湀" style="margin-left: 10px; width: 80px;">
+ <el-option label="鏈湀" value="month"></el-option>
+ <el-option label="涓婃湀" value="lastMonth"></el-option>
+ </el-select>
+ <el-button type="primary" style="margin-left: 10px;" @click="refreshCharts">鍒锋柊</el-button>
+ </div>
+ </div>
+
+ <!-- 缁熻鍗$墖鍖哄煙 -->
+ <el-row :gutter="20" class="stats-card-row">
+ <el-col :span="6">
+ <el-card class="stats-card">
+ <div class="card-title">鎬诲簱瀛橈紙浠讹級</div>
+ <div class="card-value">269,225</div>
+ <div class="card-change"><el-tag type="success">鈫� 2.1% 杈冩槰鏃�</el-tag></div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stats-card">
+ <div class="card-title">寰呭嚭搴撹鍗�</div>
+ <div class="card-value">425</div>
+ <div class="card-change"><el-tag type="warning">鈫� 5.3% 杈�1灏忔椂鍓�</el-tag></div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stats-card">
+ <div class="card-title">浠婃棩浣滀笟瀹屾垚鐜�</div>
+ <div class="card-value">93.9%</div>
+ <div class="card-change"><el-tag type="success">鈫� 1.8% 杈冩槰鏃�</el-tag></div>
+ </el-card>
+ </el-col>
+ <el-col :span="6">
+ <el-card class="stats-card">
+ <div class="card-title">鏈鐞嗗紓甯�</div>
+ <div class="card-value">7</div>
+ <div class="card-change"><el-tag type="danger">鈫� 1 杈�30鍒嗛挓鍓�</el-tag></div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 鍥捐〃鍖哄煙锛堢涓�琛岋級 -->
+ <el-row :gutter="20" class="chart-row">
+ <el-col :span="12">
+ <el-card class="chart-card">
+ <div class="chart-title">搴撳瓨搴撲綅鍒嗗竷锛堝浘鍍忓寲鍗犳瘮锛�<el-button type="text" class="view-btn">鍒囨崲瑙嗗浘</el-button></div>
+ <div ref="inventoryPieRef" class="chart-container"></div>
+ </el-card>
+ </el-col>
+ <el-col :span="12">
+ <el-card class="chart-card">
+ <div class="chart-title">杩�7鏃ュ嚭鍏ュ簱瓒嬪娍锛堝浘鍍忓寲璧板娍锛�
+ <el-button-group class="btn-group">
+ <el-button type="primary" size="small">鍏ㄩ儴</el-button>
+ <el-button type="default" size="small">鍏ュ簱</el-button>
+ <el-button type="default" size="small">鍑哄簱</el-button>
+ </el-button-group>
+ </div>
+ <div ref="stockTrendRef" class="chart-container"></div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 鍥捐〃鍖哄煙锛堢浜岃锛� -->
+ <el-row :gutter="20" class="chart-row">
+ <el-col :span="8">
+ <el-card class="chart-card">
+ <div class="chart-title">搴撲綅鍒╃敤鐜�</div>
+ <div ref="locationRateRef" class="chart-container"></div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card class="chart-card">
+ <div class="chart-title">浣滀笟绫诲瀷鍒嗗竷<el-button type="text" class="view-btn">鏌ョ湅璇︽儏</el-button></div>
+ <div ref="operationRadarRef" class="chart-container"></div>
+ </el-card>
+ </el-col>
+ <el-col :span="8">
+ <el-card class="chart-card">
+ <div class="chart-title">寮傚父绫诲瀷缁熻瓒嬪娍<el-button type="text" class="view-btn">绛涢��</el-button></div>
+ <div ref="exceptionTrendRef" class="chart-container"></div>
+ </el-card>
+ </el-col>
+ </el-row>
+
+ <!-- 琛ㄦ牸鍖哄煙 -->
+ <el-row :gutter="20" class="table-row">
+ <el-col :span="12">
+ <el-card class="table-card">
+ <div class="table-title">璁㈠崟澶勭悊杩涘害<el-select v-model="orderType" placeholder="閫�璐у叆搴�"
+ style="width: 100px; margin-left: 10px;">
+ <el-option label="閫�璐у叆搴�" value="return"></el-option>
+ <el-option label="鏅�氬嚭搴�" value="normal"></el-option>
+ </el-select></div>
+ <el-table :data="orderList" border style="width: 100%;">
+ <el-table-column prop="orderNo" label="璁㈠崟鍙�" />
+ <el-table-column prop="type" label="绫诲瀷" />
+ <el-table-column prop="priority" label="浼樺厛绾�">
+ <template #default="scope">
+ <el-tag
+ :type="scope.row.priority === '绱ф��' ? 'danger' : scope.row.priority === '鍔犳��' ? 'warning' : 'success'">
+ {{ scope.row.priority }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="progress" label="杩涘害">
+ <template #default="scope">
+ <el-progress :percentage="scope.row.progress" :color="scope.row.progressColor" />
+ </template>
+ </el-table-column>
+ </el-table>
+ <div class="table-pagination">
+ <el-button type="text">鍔犺浇鏇村璁㈠崟</el-button>
+ <el-pagination layout="prev, pager, next, jumper" :current-page="1" :total="50" />
+ </div>
+ </el-card>
+ </el-col>
+ <el-col :span="12">
+ <el-card class="table-card">
+ <div class="table-title">瀹炴椂浣滀笟鐩戞帶
+ <el-button-group class="btn-group">
+ <el-button type="primary" size="small">鍏ㄩ儴浣滀笟</el-button>
+ <el-button type="default" size="small">鍏ュ簱</el-button>
+ <el-button type="default" size="small">鍑哄簱</el-button>
+ <el-button type="default" size="small">鐩樼偣</el-button>
+ </el-button-group>
+ </div>
+ <el-table :data="operationList" border style="width: 100%;">
+ <el-table-column prop="opNo" label="浣滀笟鍗曞彿" />
+ <el-table-column prop="opType" label="浣滀笟绫诲瀷" />
+ <el-table-column prop="operator" label="鎿嶄綔浜哄憳" />
+ <el-table-column prop="startTime" label="寮�濮嬫椂闂�" />
+ <el-table-column prop="status" label="褰撳墠鐘舵��">
+ <template #default="scope">
+ <el-tag :type="scope.row.status === '澶勭悊涓�' ? 'info' : scope.row.status === '宸插畬鎴�' ? 'success' : 'danger'">
+ {{ scope.row.status }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="鎿嶄綔"><el-button type="text">璇︽儏</el-button></el-table-column>
+ </el-table>
+ <div class="table-pagination">
+ <el-pagination layout="prev, pager, next, jumper" :current-page="1" :total="50" />
+ </div>
+ </el-card>
+ </el-col>
+ </el-row>
+ </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, nextTick } from 'vue';
+import * as echarts from 'echarts';
+
+// 鍝嶅簲寮忔暟鎹�
+const month = ref('month');
+const orderType = ref('return');
+
+// 妯℃嫙鏁版嵁
+const orderList = ref([
+ { orderNo: 'OD20251224001', type: '鏅�氬嚭搴�', priority: '绱ф��', progress: 60, progressColor: '#ff4d4f' },
+ { orderNo: 'OD20251224002', type: '閫�璐у叆搴�', priority: '鏅��', progress: 80, progressColor: '#1890ff' },
+ { orderNo: 'OD20251224003', type: '璋冩嫧璁㈠崟', priority: '鍔犳��', progress: 40, progressColor: '#faad14' },
+ { orderNo: 'OD20251224004', type: '鏅�氬嚭搴�', priority: '甯歌', progress: 100, progressColor: '#52c41a' }
+]);
+const operationList = ref([
+ { opNo: 'JW251224001', opType: '鍏ュ簱', operator: '寮犱笁', startTime: '15:30:22', status: '澶勭悊涓�' },
+ { opNo: 'CK251224002', opType: '鍑哄簱', operator: '鏉庡洓', startTime: '15:25:10', status: '宸插畬鎴�' },
+ { opNo: 'PD251224003', opType: '鐩樼偣', operator: '鐜嬩簲', startTime: '15:20:05', status: '寰呯‘璁�' },
+ { opNo: 'SC251224005', opType: '涓婃灦', operator: '瀛欎竷', startTime: '15:10:18', status: '寮傚父' }
+]);
+
+// 鍥捐〃瀹瑰櫒
+const inventoryPieRef = ref(null);
+const stockTrendRef = ref(null);
+const locationRateRef = ref(null);
+const operationRadarRef = ref(null);
+const exceptionTrendRef = ref(null);
+
+// 鍥捐〃瀹炰緥
+let inventoryPieChart = null;
+let stockTrendChart = null;
+let locationRateChart = null;
+let operationRadarChart = null;
+let exceptionTrendChart = null;
+
+// 鍒濆鍖栧簱瀛樺簱浣嶅垎甯冮ゼ鍥�
+const initInventoryPie = () => {
+ if (!inventoryPieRef.value) return;
+
+ if (inventoryPieChart) {
+ inventoryPieChart.dispose();
+ }
+
+ inventoryPieChart = echarts.init(inventoryPieRef.value);
+ const option = {
+ tooltip: {
+ trigger: 'item',
+ formatter: '{a} <br/>{b}: {c}%'
+ },
+ legend: {
+ bottom: 0,
+ left: 'center',
+ data: ['甯告俯鍖篈鍖�', '鍐疯棌鍖築鍖�', '淇濈◣鍖篊鍖�', '娈嬫鍝佸尯D鍖�']
+ },
+ series: [{
+ name: '搴撳瓨搴撲綅鍒嗗竷',
+ type: 'pie',
+ radius: ['40%', '70%'],
+ center: ['50%', '40%'],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderRadius: 10,
+ borderColor: '#fff',
+ borderWidth: 2
+ },
+ label: {
+ show: false,
+ position: 'center'
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: 20,
+ fontWeight: 'bold'
+ }
+ },
+ labelLine: {
+ show: false
+ },
+ data: [
+ { value: 48.7, name: '甯告俯鍖篈鍖�', itemStyle: { color: '#5470c6' } },
+ { value: 29.2, name: '鍐疯棌鍖築鍖�', itemStyle: { color: '#91cc75' } },
+ { value: 21.9, name: '淇濈◣鍖篊鍖�', itemStyle: { color: '#fac858' } },
+ { value: 2.2, name: '娈嬫鍝佸尯D鍖�', itemStyle: { color: '#ee6666' } }
+ ]
+ }]
+ };
+
+ inventoryPieChart.setOption(option);
+ return inventoryPieChart;
+};
+
+// 鍒濆鍖栬繎7鏃ュ嚭鍏ュ簱瓒嬪娍鍥�
+const initStockTrend = () => {
+ if (!stockTrendRef.value) return;
+
+ if (stockTrendChart) {
+ stockTrendChart.dispose();
+ }
+
+ stockTrendChart = echarts.init(stockTrendRef.value);
+ const option = {
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross'
+ }
+ },
+ legend: {
+ data: ['鍏ュ簱閲�', '鍑哄簱閲�'],
+ top: 10
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ top: '15%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: true,
+ data: ['12-18', '12-19', '12-20', '12-21', '12-22', '12-23', '12-24']
+ },
+ yAxis: {
+ type: 'value',
+ name: '鏁伴噺锛堝崈浠讹級',
+ max: 25
+ },
+ series: [
+ {
+ name: '鍏ュ簱閲�',
+ type: 'bar',
+ barWidth: '30%',
+ data: [10, 12, 10, 12, 10, 12, 12],
+ itemStyle: { color: '#52c41a' }
+ },
+ {
+ name: '鍑哄簱閲�',
+ type: 'bar',
+ barWidth: '30%',
+ data: [16, 18, 14, 18, 16, 18, 20],
+ itemStyle: { color: '#1890ff' }
+ }
+ ]
+ };
+
+ stockTrendChart.setOption(option);
+ return stockTrendChart;
+};
+
+// 鍒濆鍖栧簱浣嶅埄鐢ㄧ巼鐜舰鍥�
+const initLocationRate = () => {
+ if (!locationRateRef.value) return;
+
+ if (locationRateChart) {
+ locationRateChart.dispose();
+ }
+
+ locationRateChart = echarts.init(locationRateRef.value);
+ const option = {
+ tooltip: {
+ formatter: '{a} <br/>{b} : {c}%'
+ },
+ series: [{
+ name: '搴撲綅鍒╃敤鐜�',
+ type: 'gauge',
+ min: 0,
+ max: 100,
+ splitNumber: 10,
+ radius: '90%',
+ center: ['50%', '55%'],
+ startAngle: 180,
+ endAngle: 0,
+ progress: {
+ show: true,
+ width: 20,
+ itemStyle: {
+ color: '#1890ff'
+ }
+ },
+ axisLine: {
+ lineStyle: {
+ width: 20,
+ color: [[1, 'rgba(200,200,200,0.3)']]
+ }
+ },
+ axisTick: {
+ distance: -30,
+ splitNumber: 5,
+ lineStyle: {
+ width: 2,
+ color: '#999'
+ }
+ },
+ splitLine: {
+ distance: -30,
+ length: 14,
+ lineStyle: {
+ width: 3,
+ color: '#999'
+ }
+ },
+ axisLabel: {
+ distance: -20,
+ color: '#999',
+ fontSize: 12
+ },
+ anchor: {
+ show: false
+ },
+ title: {
+ show: true,
+ offsetCenter: [0, '30%'],
+ fontSize: 16,
+ fontWeight: 'bold'
+ },
+ detail: {
+ valueAnimation: true,
+ formatter: '{value}%',
+ fontSize: 20,
+ fontWeight: 'bold',
+ offsetCenter: [0, '70%']
+ },
+ data: [{
+ value: 86.2,
+ name: '搴撲綅鍒╃敤鐜�'
+ }]
+ }]
+ };
+
+ locationRateChart.setOption(option);
+ return locationRateChart;
+};
+
+// 鍒濆鍖栦綔涓氱被鍨嬮浄杈惧浘
+const initOperationRadar = () => {
+ if (!operationRadarRef.value) return;
+
+ if (operationRadarChart) {
+ operationRadarChart.dispose();
+ }
+
+ operationRadarChart = echarts.init(operationRadarRef.value);
+ const option = {
+ tooltip: {
+ trigger: 'item'
+ },
+ legend: {
+ show: false
+ },
+ radar: {
+ indicator: [
+ { name: '鍑哄簱浣滀笟', max: 100 },
+ { name: '鍏ュ簱浣滀笟', max: 100 },
+ { name: '璋冩嫧浣滀笟', max: 100 },
+ { name: '鐩樼偣浣滀笟', max: 100 }
+ ],
+ shape: 'circle',
+ splitNumber: 5,
+ axisName: {
+ color: '#666'
+ },
+ splitLine: {
+ lineStyle: {
+ color: 'rgba(0,0,0,0.1)'
+ }
+ },
+ splitArea: {
+ show: true,
+ areaStyle: {
+ color: ['rgba(255,255,255,0.8)', 'rgba(200,200,200,0.2)']
+ }
+ }
+ },
+ series: [{
+ name: '浣滀笟绫诲瀷鍒嗗竷',
+ type: 'radar',
+ symbolSize: 8,
+ areaStyle: {
+ color: 'rgba(24,144,255,0.3)'
+ },
+ lineStyle: {
+ width: 2
+ },
+ itemStyle: {
+ color: '#1890ff'
+ },
+ data: [{
+ value: [45, 30, 15, 10],
+ name: '浣滀笟鍗犳瘮',
+ label: {
+ show: true,
+ formatter: function (params) {
+ return params.value + '%';
+ }
+ }
+ }]
+ }]
+ };
+
+ operationRadarChart.setOption(option);
+ return operationRadarChart;
+};
+
+// 鍒濆鍖栧紓甯歌秼鍔挎姌绾垮浘
+const initExceptionTrend = () => {
+ if (!exceptionTrendRef.value) return;
+
+ if (exceptionTrendChart) {
+ exceptionTrendChart.dispose();
+ }
+
+ exceptionTrendChart = echarts.init(exceptionTrendRef.value);
+ const option = {
+ tooltip: {
+ trigger: 'axis',
+ axisPointer: {
+ type: 'cross'
+ }
+ },
+ legend: {
+ data: ['搴撳瓨涓嶈冻', '璁㈠崟瓒呮椂', '搴撲綅寮傚父', '鐩樼偣宸紓'],
+ top: 10
+ },
+ grid: {
+ left: '3%',
+ right: '4%',
+ bottom: '3%',
+ top: '15%',
+ containLabel: true
+ },
+ xAxis: {
+ type: 'category',
+ boundaryGap: false,
+ data: ['12-18', '12-19', '12-20', '12-21', '12-22', '12-23', '12-24']
+ },
+ yAxis: {
+ type: 'value',
+ name: '寮傚父鏁伴噺'
+ },
+ series: [
+ {
+ name: '搴撳瓨涓嶈冻',
+ type: 'line',
+ smooth: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ data: [10, 11, 9, 12, 10, 13, 12],
+ itemStyle: { color: '#ff4d4f' },
+ lineStyle: {
+ width: 3
+ }
+ },
+ {
+ name: '璁㈠崟瓒呮椂',
+ type: 'line',
+ smooth: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ data: [8, 9, 7, 8, 7, 9, 8],
+ itemStyle: { color: '#faad14' },
+ lineStyle: {
+ width: 3
+ }
+ },
+ {
+ name: '搴撲綅寮傚父',
+ type: 'line',
+ smooth: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ data: [4, 5, 2, 4, 3, 5, 4],
+ itemStyle: { color: '#722ed1' },
+ lineStyle: {
+ width: 3
+ }
+ },
+ {
+ name: '鐩樼偣宸紓',
+ type: 'line',
+ smooth: true,
+ symbol: 'circle',
+ symbolSize: 8,
+ data: [2, 3, 1, 2, 1, 3, 2],
+ itemStyle: { color: '#13c2c2' },
+ lineStyle: {
+ width: 3
+ }
+ }
+ ]
+ };
+
+ exceptionTrendChart.setOption(option);
+ return exceptionTrendChart;
+};
+
+// 鍒锋柊鎵�鏈夊浘琛�
+const refreshCharts = () => {
+ const charts = [
+ initInventoryPie,
+ initStockTrend,
+ initLocationRate,
+ initOperationRadar,
+ initExceptionTrend
+ ];
+
+ charts.forEach(initFunc => {
+ const chart = initFunc();
+ if (chart) {
+ chart.resize();
+ }
+ });
+};
+
+// 鐩戝惉绐楀彛澶у皬鍙樺寲
+const handleResize = () => {
+ const charts = [
+ inventoryPieChart,
+ stockTrendChart,
+ locationRateChart,
+ operationRadarChart,
+ exceptionTrendChart
+ ];
+
+ charts.forEach(chart => {
+ if (chart) {
+ chart.resize();
+ }
+ });
+};
+
+// 鎸傝浇鍚庡垵濮嬪寲鍥捐〃
+onMounted(() => {
+ nextTick(() => {
+ initInventoryPie();
+ initStockTrend();
+ initLocationRate();
+ initOperationRadar();
+ initExceptionTrend();
+
+ window.addEventListener('resize', handleResize);
+ });
+});
+
+// 缁勪欢鍗歌浇鏃舵竻鐞�
+onUnmounted(() => {
+ const charts = [
+ inventoryPieChart,
+ stockTrendChart,
+ locationRateChart,
+ operationRadarChart,
+ exceptionTrendChart
+ ];
+
+ charts.forEach(chart => {
+ if (chart) {
+ chart.dispose();
+ }
+ });
+
+ window.removeEventListener('resize', handleResize);
+});
+</script>
+
+<style scoped>
+.wms-dashboard {
+ padding: 20px;
+ background: #f5f7fa;
+ min-height: 100vh;
+ box-sizing: border-box;
+}
+
+.header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+ background: white;
+ padding: 15px 20px;
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+}
+
+.stats-card-row,
+.chart-row,
+.table-row {
+ margin-bottom: 20px;
+}
+
+.stats-card {
+ height: 120px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ padding: 0 20px;
+ transition: all 0.3s ease;
+}
+
+.stats-card:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+}
+
+.card-title {
+ font-size: 14px;
+ color: #666;
+ margin-bottom: 8px;
+}
+
+.card-value {
+ font-size: 28px;
+ font-weight: bold;
+ margin: 8px 0 4px;
+ color: #333;
+}
+
+.card-change {
+ margin-top: 8px;
+}
+
+.chart-card {
+ height: 320px;
+ padding: 15px;
+ display: flex;
+ flex-direction: column;
+}
+
+.chart-container {
+ width: 100%;
+ height: 100%;
+ min-height: 250px;
+ flex: 1;
+}
+
+.chart-title,
+.table-title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+ font-size: 16px;
+ font-weight: bold;
+ color: #333;
+}
+
+.view-btn {
+ font-size: 12px;
+}
+
+.table-pagination {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-top: 15px;
+}
+
+.btn-group {
+ margin-left: 10px;
+}
+
+/* 纭繚鍥捐〃瀹瑰櫒鏈夋槑纭昂瀵� */
+:deep(.el-card__body) {
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+}
+</style>
\ No newline at end of file
--
Gitblit v1.9.3