Compare commits
3 Commits
3e89c0b16c
...
20d2df9373
| Author | SHA1 | Date | |
|---|---|---|---|
| 20d2df9373 | |||
| 6313be9c52 | |||
| 75f745cdb2 |
@@ -77,12 +77,12 @@
|
|||||||
已占用 <span class="legend-val">{{ statistics.occupied }}</span>
|
已占用 <span class="legend-val">{{ statistics.occupied }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="chart-dot maintenance"></span>
|
<span class="chart-dot error"></span>
|
||||||
维护中 <span class="legend-val">{{ statistics.maintenance }}</span>
|
异常 <span class="legend-val">{{ statistics.error }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="chart-dot available"></span>
|
<span class="chart-dot available"></span>
|
||||||
可用 <span class="legend-val">{{ statistics.available }}</span>
|
空闲 <span class="legend-val">{{ statistics.available }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,15 +109,15 @@
|
|||||||
<div class="grid-legend">
|
<div class="grid-legend">
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="legend-dot available"></span>
|
<span class="legend-dot available"></span>
|
||||||
<span>可用</span>
|
<span>空闲</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="legend-dot occupied"></span>
|
<span class="legend-dot occupied"></span>
|
||||||
<span>已占用</span>
|
<span>已占用</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="legend-dot maintenance"></span>
|
<span class="legend-dot error"></span>
|
||||||
<span>维护中</span>
|
<span>异常</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="legend-item">
|
<div class="legend-item">
|
||||||
<span class="legend-dot has-coil-icon"></span>
|
<span class="legend-dot has-coil-icon"></span>
|
||||||
@@ -138,24 +138,24 @@
|
|||||||
v-for="wh in gridData[colNum].layer1"
|
v-for="wh in gridData[colNum].layer1"
|
||||||
:key="wh.actualWarehouseId"
|
:key="wh.actualWarehouseId"
|
||||||
class="grid-cell"
|
class="grid-cell"
|
||||||
:class="[getStatusClass(wh), { 'has-coil': !!wh.coilCode }]"
|
:class="[getStatusClass(wh), { 'has-coil': !!wh.currentCoilNo }]"
|
||||||
:style="cellStyle"
|
:style="cellStyle"
|
||||||
@click="showDetail(wh)"
|
@click="showDetail(wh)"
|
||||||
>
|
>
|
||||||
<span class="cell-code">{{ wh.actualWarehouseCode }}</span>
|
<span class="cell-code">{{ wh.actualWarehouseCode }}</span>
|
||||||
<span v-if="wh.coilCode" class="cell-coil-dot">●</span>
|
<span v-if="wh.currentCoilNo" class="cell-coil-dot">●</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="gridData[colNum].layer1.length && gridData[colNum].layer2.length" class="layer-divider"></div>
|
<div v-if="gridData[colNum].layer1.length && gridData[colNum].layer2.length" class="layer-divider"></div>
|
||||||
<div
|
<div
|
||||||
v-for="wh in gridData[colNum].layer2"
|
v-for="wh in gridData[colNum].layer2"
|
||||||
:key="wh.actualWarehouseId"
|
:key="wh.actualWarehouseId"
|
||||||
class="grid-cell"
|
class="grid-cell"
|
||||||
:class="[getStatusClass(wh), { 'has-coil': !!wh.coilCode }]"
|
:class="[getStatusClass(wh), { 'has-coil': !!wh.currentCoilNo }]"
|
||||||
:style="cellStyle"
|
:style="cellStyle"
|
||||||
@click="showDetail(wh)"
|
@click="showDetail(wh)"
|
||||||
>
|
>
|
||||||
<span class="cell-code">{{ wh.actualWarehouseCode }}</span>
|
<span class="cell-code">{{ wh.actualWarehouseCode }}</span>
|
||||||
<span v-if="wh.coilCode" class="cell-coil-dot">●</span>
|
<span v-if="wh.currentCoilNo" class="cell-coil-dot">●</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -187,7 +187,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
<span class="detail-label">钢卷编号</span>
|
<span class="detail-label">钢卷编号</span>
|
||||||
<span class="detail-value" v-if="detailWarehouse.coilCode">📦 {{ detailWarehouse.coilCode }}</span>
|
<span class="detail-value" v-if="detailWarehouse.currentCoilNo">📦 {{ detailWarehouse.currentCoilNo }}</span>
|
||||||
<span class="detail-value empty" v-else>无</span>
|
<span class="detail-value empty" v-else>无</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="detail-row">
|
<div class="detail-row">
|
||||||
@@ -236,8 +236,8 @@ export default {
|
|||||||
// 统计数据
|
// 统计数据
|
||||||
const statistics = reactive({
|
const statistics = reactive({
|
||||||
total: 0,
|
total: 0,
|
||||||
|
error: 0,
|
||||||
occupied: 0,
|
occupied: 0,
|
||||||
maintenance: 0,
|
|
||||||
available: 0,
|
available: 0,
|
||||||
utilization: 0
|
utilization: 0
|
||||||
})
|
})
|
||||||
@@ -245,7 +245,7 @@ export default {
|
|||||||
// 动画数字
|
// 动画数字
|
||||||
const animatedTotal = ref(0)
|
const animatedTotal = ref(0)
|
||||||
const animatedOccupied = ref(0)
|
const animatedOccupied = ref(0)
|
||||||
const animatedMaintenance = ref(0)
|
const animatedError = ref(0)
|
||||||
const animatedAvailable = ref(0)
|
const animatedAvailable = ref(0)
|
||||||
const animatedUtilization = ref(0)
|
const animatedUtilization = ref(0)
|
||||||
|
|
||||||
@@ -491,8 +491,8 @@ export default {
|
|||||||
animationDuration: 1200,
|
animationDuration: 1200,
|
||||||
data: [
|
data: [
|
||||||
{ value: statistics.occupied || 0, name: '已占用', itemStyle: { color: '#7c63ff' } },
|
{ value: statistics.occupied || 0, name: '已占用', itemStyle: { color: '#7c63ff' } },
|
||||||
{ value: statistics.maintenance || 0, name: '维护中', itemStyle: { color: '#ff6b6b' } },
|
{ value: statistics.error || 0, name: '异常', itemStyle: { color: '#ff6b6b' } },
|
||||||
{ value: statistics.available || 0, name: '可用', itemStyle: { color: '#00ff88' } }
|
{ value: statistics.available || 0, name: '空闲', itemStyle: { color: '#00ff88' } }
|
||||||
]
|
]
|
||||||
}],
|
}],
|
||||||
graphic: [
|
graphic: [
|
||||||
@@ -569,28 +569,26 @@ export default {
|
|||||||
|
|
||||||
// 统计数据 — 与 getStatusClass 逻辑一一对应
|
// 统计数据 — 与 getStatusClass 逻辑一一对应
|
||||||
const total = warehouseList.value.length
|
const total = warehouseList.value.length
|
||||||
const maintenance = warehouseList.value.filter(w =>
|
|
||||||
w.isEnabled === 0
|
|
||||||
).length
|
|
||||||
const occupied = warehouseList.value.filter(w =>
|
const occupied = warehouseList.value.filter(w =>
|
||||||
w.isEnabled !== 0 && w.coilCode
|
w.isEnabled === 0 && w.currentCoilNo
|
||||||
).length
|
).length
|
||||||
const available = warehouseList.value.filter(w =>
|
const available = warehouseList.value.filter(w =>
|
||||||
w.isEnabled !== 0 && !w.coilCode
|
w.isEnabled === 1 && !w.currentCoilNo
|
||||||
).length
|
).length
|
||||||
|
const error = total - occupied - available
|
||||||
const usable = occupied + available
|
const usable = occupied + available
|
||||||
const utilization = usable > 0 ? Math.round((occupied / usable) * 100) : 0
|
const utilization = usable > 0 ? Math.round((occupied / usable) * 100) : 0
|
||||||
|
|
||||||
// 触发动画
|
// 触发动画
|
||||||
animateValue(animatedTotal.value, total, (val) => { animatedTotal.value = val })
|
animateValue(animatedTotal.value, total, (val) => { animatedTotal.value = val })
|
||||||
animateValue(animatedOccupied.value, occupied, (val) => { animatedOccupied.value = val })
|
animateValue(animatedOccupied.value, occupied, (val) => { animatedOccupied.value = val })
|
||||||
animateValue(animatedMaintenance.value, maintenance, (val) => { animatedMaintenance.value = val })
|
animateValue(animatedError.value, error, (val) => { animatedError.value = val })
|
||||||
animateValue(animatedAvailable.value, available, (val) => { animatedAvailable.value = val })
|
animateValue(animatedAvailable.value, available, (val) => { animatedAvailable.value = val })
|
||||||
animateValue(animatedUtilization.value, utilization, (val) => { animatedUtilization.value = val })
|
animateValue(animatedUtilization.value, utilization, (val) => { animatedUtilization.value = val })
|
||||||
|
|
||||||
statistics.total = total
|
statistics.total = total
|
||||||
statistics.occupied = occupied
|
statistics.occupied = occupied
|
||||||
statistics.maintenance = maintenance
|
statistics.error = error
|
||||||
statistics.available = available
|
statistics.available = available
|
||||||
statistics.utilization = utilization
|
statistics.utilization = utilization
|
||||||
updateChart()
|
updateChart()
|
||||||
@@ -603,39 +601,52 @@ export default {
|
|||||||
|
|
||||||
// 获取状态文本
|
// 获取状态文本
|
||||||
const getStatusText = (row) => {
|
const getStatusText = (row) => {
|
||||||
// isEnabled: 0=否, 1=是
|
if (row.isEnabled === 0 && row.currentCoilNo) {
|
||||||
// coilCode: 有值表示已存放钢卷
|
|
||||||
if (row.isEnabled === 0) {
|
|
||||||
return '维护中'
|
|
||||||
} else if (row.coilCode) {
|
|
||||||
return '已占用'
|
return '已占用'
|
||||||
|
} else if (row.isEnabled === 1 && !row.currentCoilNo) {
|
||||||
|
return '空闲'
|
||||||
} else {
|
} else {
|
||||||
return '可用'
|
return '异常'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取状态样式类
|
// 获取状态样式类
|
||||||
const getStatusClass = (row) => {
|
const getStatusClass = (row) => {
|
||||||
if (row.isEnabled === 0) {
|
if (row.isEnabled === 0 && row.currentCoilNo) {
|
||||||
return 'maintenance'
|
|
||||||
} else if (row.coilCode) {
|
|
||||||
return 'occupied'
|
return 'occupied'
|
||||||
} else {
|
} else if (row.isEnabled === 1 && !row.currentCoilNo) {
|
||||||
return 'available'
|
return 'available'
|
||||||
|
} else {
|
||||||
|
return 'error'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析库位编码:如 F2A101-01-1 → { column: 101, row: 1, layer: 1 }
|
// 解析库位编码:支持三级编码 F2B101-01-1 和四级编码 F2B3-X38-2
|
||||||
const parseWarehouseCode = (code) => {
|
const parseWarehouseCode = (code) => {
|
||||||
if (!code) return null
|
if (!code) return null
|
||||||
const reg = /^([A-Za-z0-9]{3})([^-]+)-(\d{2})-(\d+)$/
|
// 先尝试四级编码 F2B3-X38-2
|
||||||
const match = code.match(reg)
|
const reg4 = /^([A-Za-z0-9]{3})([^-]+)-X(\d{2})-(\d+)$/
|
||||||
if (!match) return null
|
const match4 = code.match(reg4)
|
||||||
return {
|
if (match4) {
|
||||||
column: Number(match[2]),
|
return {
|
||||||
row: Number(match[3]),
|
level: 4,
|
||||||
layer: match[4]
|
column: Number(match4[2]),
|
||||||
|
row: Number(match4[3]),
|
||||||
|
layer: match4[4]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// 再尝试三级编码 F2B101-01-1
|
||||||
|
const reg3 = /^([A-Za-z0-9]{3})([^-]+)-(\d{2})-(\d+)$/
|
||||||
|
const match3 = code.match(reg3)
|
||||||
|
if (match3) {
|
||||||
|
return {
|
||||||
|
level: 3,
|
||||||
|
column: Number(match3[2]),
|
||||||
|
row: Number(match3[3]),
|
||||||
|
layer: match3[4]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// 构建网格数据结构:按列分组 → 按层分行
|
// 构建网格数据结构:按列分组 → 按层分行
|
||||||
@@ -701,7 +712,7 @@ export default {
|
|||||||
statistics,
|
statistics,
|
||||||
animatedTotal,
|
animatedTotal,
|
||||||
animatedOccupied,
|
animatedOccupied,
|
||||||
animatedMaintenance,
|
animatedError,
|
||||||
animatedAvailable,
|
animatedAvailable,
|
||||||
animatedUtilization,
|
animatedUtilization,
|
||||||
getParticleStyle,
|
getParticleStyle,
|
||||||
@@ -1142,7 +1153,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.chart-dot.occupied { background: #7c63ff; }
|
.chart-dot.occupied { background: #7c63ff; }
|
||||||
.chart-dot.maintenance { background: #ff6b6b; }
|
.chart-dot.error { background: #ff6b6b; }
|
||||||
.chart-dot.available { background: #00ff88; }
|
.chart-dot.available { background: #00ff88; }
|
||||||
|
|
||||||
.header-badge {
|
.header-badge {
|
||||||
@@ -1229,7 +1240,7 @@ export default {
|
|||||||
|
|
||||||
.legend-dot.available { background: #00ff88; }
|
.legend-dot.available { background: #00ff88; }
|
||||||
.legend-dot.occupied { background: #7c63ff; }
|
.legend-dot.occupied { background: #7c63ff; }
|
||||||
.legend-dot.maintenance { background: #ff6b6b; }
|
.legend-dot.error { background: #ff6b6b; }
|
||||||
.legend-dot.has-coil-icon {
|
.legend-dot.has-coil-icon {
|
||||||
background: transparent;
|
background: transparent;
|
||||||
color: #00d4ff;
|
color: #00d4ff;
|
||||||
@@ -1299,7 +1310,7 @@ export default {
|
|||||||
box-shadow: 0 0 8px rgba(124, 99, 255, 0.15);
|
box-shadow: 0 0 8px rgba(124, 99, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-cell.maintenance {
|
.grid-cell.error {
|
||||||
background: rgba(255, 107, 107, 0.15);
|
background: rgba(255, 107, 107, 0.15);
|
||||||
border-color: rgba(255, 107, 107, 0.3);
|
border-color: rgba(255, 107, 107, 0.3);
|
||||||
box-shadow: 0 0 8px rgba(255, 107, 107, 0.1);
|
box-shadow: 0 0 8px rgba(255, 107, 107, 0.1);
|
||||||
@@ -1328,7 +1339,7 @@ export default {
|
|||||||
box-shadow: 0 0 20px rgba(124, 99, 255, 0.5);
|
box-shadow: 0 0 20px rgba(124, 99, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.grid-cell:hover.maintenance {
|
.grid-cell:hover.error {
|
||||||
box-shadow: 0 0 20px rgba(255, 107, 107, 0.5);
|
box-shadow: 0 0 20px rgba(255, 107, 107, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1415,7 +1426,7 @@ export default {
|
|||||||
border: 1px solid rgba(0, 255, 136, 0.3);
|
border: 1px solid rgba(0, 255, 136, 0.3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-dialog .detail-status.maintenance {
|
.detail-dialog .detail-status.error {
|
||||||
background: rgba(255, 107, 107, 0.2);
|
background: rgba(255, 107, 107, 0.2);
|
||||||
color: #ff6b6b;
|
color: #ff6b6b;
|
||||||
border: 1px solid rgba(255, 107, 107, 0.3);
|
border: 1px solid rgba(255, 107, 107, 0.3);
|
||||||
|
|||||||
Reference in New Issue
Block a user