<template>
|
<div class="bigdata-container" ref="bigdataContainer">
|
<div
|
class="bigdata"
|
v-for="item in contentData"
|
:key="item.stationCode"
|
:id="item.stationCode"
|
@click="handleClick"
|
>
|
<h1>{{ item.stationCode }}--{{ item.orderData.length > 0 ?item.orderData[0].orderCode +"-"+ item.orderData[0].cusName + "-" +item.orderData[0].orderName : '暂无订单'}}</h1>
|
<!-- <h1></h1> -->
|
<div class="bigdata-content">
|
<div class="content-item" :data-value="item.stationSortedNum">工位数</div>
|
<div class="content-item" :data-value="item.sortedNum">已分拣</div>
|
<div class="content-item" :data-value="item.unsortedNum">未分拣</div>
|
<div class="content-item" :data-value="item.orderTotalNum">订单数</div>
|
</div>
|
<div class="bigdata-table">
|
<table>
|
<thead>
|
<tr>
|
<th>订单号</th>
|
<th>客户名</th>
|
<th>订单名</th>
|
<th>批次</th>
|
<th>工件名</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="(order,index) in item.orderData" :key="index">
|
<td>{{ order.orderCode }}</td>
|
<td>{{ order.cusName }}</td>
|
<td>{{ order.orderName }}</td>
|
<td>{{ order.batch }}</td>
|
<td>{{ order.productName }}</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
<div :id="item.stationCode + '-modal'" class="modal-overlay">
|
<div class="modal-content">请放行</div>
|
</div>
|
</div>
|
</div>
|
</template>
|
<script>
|
import { useRoute } from "vue-router";
|
export default {
|
name: "bigdata",
|
data() {
|
return {
|
client: null, // WebSocket客户端对象
|
deviceCode: "",
|
contentData: [
|
// {
|
// stationCode: "C011",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// },
|
// {
|
// stationCode: "C012",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// },
|
// {
|
// stationCode: "C013",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// },
|
// {
|
// stationCode: "C014",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// },
|
// {
|
// stationCode: "C015",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// },
|
// {
|
// stationCode: "C016",
|
// orderTotalNum: 9999,
|
// sortedNum: 1111,
|
// unsortedNum: 8888,
|
// orderData: [
|
// {
|
// orderCode: "A00001",
|
// cusName: "客户A",
|
// orderName: "订单A",
|
// batch: "批次A",
|
// productName: "产品A"
|
// }
|
// ]
|
// }
|
]
|
};
|
},
|
created() {
|
const route = useRoute();
|
const deviceCode = route.query.deviceCode;
|
this.deviceCode = deviceCode;
|
this.createSocket(window.webConfig.webSocketUrl + deviceCode);
|
|
this.getStations(deviceCode);
|
},
|
methods: {
|
modalOverlay(stationCode, show) {
|
const modal = document.getElementById(stationCode + "-modal");
|
if (modal) {
|
if (show) {
|
const element = document.getElementById(stationCode); // 获取元素
|
modal.style.display = "flex"; // 显示遮罩层
|
modal.style.left = element.offsetLeft + "px"; // 设置遮罩层位置
|
modal.style.top = element.offsetTop + "px"; // 设置遮罩层位置
|
modal.style.width = element.offsetWidth + "px"; // 设置遮罩层宽度
|
modal.style.height = element.offsetHeight + "px"; // 设置遮罩层高度
|
} else {
|
modal.style.display = "none"; // 隐藏遮罩层
|
}
|
// modal.classList.add("modal-blink"); // 添加闪烁效果
|
}
|
},
|
handleClick() {
|
const parent = event.target.closest(".bigdata");
|
parent.classList.remove("flash-bg");
|
void parent.offsetWidth; // 强制DOM重绘
|
parent.classList.add("flash-bg");
|
|
const stationCode = parent.id;
|
this.modalOverlay(stationCode, true); // 显示遮罩层
|
|
setTimeout(() => {
|
this.modalOverlay(stationCode, false); // 隐藏遮罩层
|
}, 10000); // 2秒后隐藏遮罩层
|
},
|
handleBackgroundColor(stationCode) {
|
const element = document.getElementById(stationCode);
|
if (element) {
|
element.classList.remove("flash-bg");
|
void element.offsetWidth; // 强制DOM重绘
|
element.classList.add("flash-bg");
|
}
|
},
|
clearStationContent(stationCode) {
|
this.contentData.find(
|
item => item.stationCode === stationCode
|
).orderTotalNum = 0;
|
this.contentData.find(
|
item => item.stationCode === stationCode
|
).sortedNum = 0;
|
this.contentData.find(
|
item => item.stationCode === stationCode
|
).unsortedNum = 0;
|
this.contentData.find(
|
item => item.stationCode === stationCode
|
).stationSortedNum = 0;
|
his.contentData.find(
|
item => item.stationCode === stationCode
|
).orderData = [];
|
},
|
createSocket(url) {
|
// 创建WebSocket连接
|
//"ws://127.0.0.1:9295/admin"
|
this.client = new WebSocket(url);
|
var _this = this; // 保存this的引用
|
this.client.onopen = function() {
|
_this.client.onmessage = _this.handleMessage;
|
console.log("WebSocket 连接成功");
|
};
|
|
this.client.onclose = function() {
|
console.log("WebSocket 连接关闭");
|
setTimeout(_this.createSocket(url), 10000);
|
};
|
|
this.client.onerror = function() {};
|
},
|
handleMessage(event) {
|
const data = JSON.parse(event.data);
|
console.log("收到消息:", event.data);
|
if (data.release == 1) {
|
this.clearStationContent(data.stationCode);
|
this.modalOverlay(data.stationCode, true); // 显示遮罩层
|
for (let i = 0; i < this.contentData.length; i++) {
|
if (this.contentData[i].orderId === data.data.orderId) {
|
this.clearStationContent(this.contentData[i].stationCode);
|
this.modalOverlay(this.contentData[i].stationCode, true); // 显示遮罩层
|
}
|
}
|
} else if (data.release == 2) {
|
this.clearStationContent(data.stationCode);
|
this.modalOverlay(data.stationCode, false); // 隐藏遮罩层
|
for (let i = 0; i < this.contentData.length; i++) {
|
if (this.contentData[i].orderId === data.data.orderId) {
|
this.clearStationContent(this.contentData[i].stationCode);
|
this.modalOverlay(this.contentData[i].stationCode, false); // 隐藏遮罩层
|
}
|
}
|
} else {
|
this.contentData
|
.find(item => item.stationCode === data.stationCode)
|
.orderData.push(data.data.orderData);
|
this.contentData.find(
|
item => item.stationCode === data.stationCode
|
).orderTotalNum = data.data.orderTotalNum;
|
this.contentData.find(
|
item => item.stationCode === data.stationCode
|
).sortedNum = data.data.sortedNum;
|
this.contentData.find(
|
item => item.stationCode === data.stationCode
|
).unsortedNum = data.data.unsortedNum;
|
this.contentData.find(
|
item => item.stationCode === data.stationCode
|
).stationSortedNum = data.data.stationSortedNum;
|
|
for (let i = 0; i < this.contentData.length; i++) {
|
if (this.contentData[i].orderId === data.data.orderId) {
|
this.contentData[i].sortedNum = data.data.sortedNum;
|
this.contentData[i].unsortedNum = data.data.unsortedNum;
|
}
|
}
|
this.handleBackgroundColor(data.stationCode);
|
}
|
},
|
getStations(deviceCode) {
|
this.http
|
.post(
|
"/api/Container/GetPutStations?deviceCode=" + deviceCode,
|
{},
|
true
|
)
|
.then(x => {
|
if (!x.status) return this.$message.error(x.message);
|
this.contentData = x.data;
|
});
|
}
|
}
|
};
|
</script>
|
|
<style scoped>
|
.modal-overlay {
|
display: none; /* 默认不显示 */
|
position: fixed; /* 全屏定位 */
|
background-color: rgba(0, 0, 0, 0.5); /* 半透明黑色遮罩 */
|
z-index: 5; /* 确保遮罩在内容之下 */
|
opacity: 1; /* 初始完全不透明 */
|
animation: modal-overlay 1.5s infinite; /* 1秒闪烁一次,无限次重复 */
|
}
|
|
@keyframes modal-overlay {
|
0%,
|
100% {
|
opacity: 1;
|
}
|
50% {
|
opacity: 0;
|
}
|
}
|
|
.modal-content {
|
position: absolute; /* 相对定位 */
|
top: 50%; /* 垂直居中 */
|
left: 50%; /* 水平居中 */
|
transform: translate(-50%, -50%); /* 精确居中 */
|
padding: 20px; /* 内边距 */
|
border-radius: 10px; /* 圆角 */
|
font-size: 20px; /* 字体大小 */
|
animation: modal-content 1.5s infinite; /* 1秒闪烁一次,无限次重复 */
|
font-family: "Microsoft YaHei", sans-serif; /* 字体样式 */
|
color: #f0f0f0; /* 字体颜色 */
|
}
|
|
@keyframes modal-content {
|
0%,
|
100% {
|
font-size: 40px;
|
color: #f0f0f0;
|
}
|
50% {
|
font-size: 20px;
|
color: #000000;
|
}
|
}
|
|
.bigdata-container {
|
width: 100%;
|
height: 100%;
|
display: grid;
|
grid-template-columns: repeat(3, 1fr);
|
grid-template-rows: repeat(2, 1fr);
|
gap: 5px;
|
padding: 5px;
|
background: #f8f9fa;
|
}
|
|
.bigdata {
|
background: #ffffff;
|
border-radius: 12px;
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
padding: 5px;
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
border: 1px solid #e9ecef;
|
overflow: hidden; /* 外层容器隐藏溢出 */
|
position: relative;
|
}
|
|
.flash-bg {
|
animation: bg-flash 1s ease-in-out;
|
position: relative;
|
}
|
|
/* 新增动画保护层 */
|
.flash-bg::before {
|
content: "";
|
position: absolute;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
border-radius: 5px;
|
animation: bg-flash 1s ease-in-out;
|
z-index: 1;
|
}
|
|
@keyframes bg-flash {
|
0%,
|
100% {
|
background-color: rgba(102, 232, 132, 0);
|
z-index: 1;
|
}
|
50% {
|
background-color: rgba(102, 232, 132, 0.4);
|
z-index: 2;
|
}
|
}
|
|
/* 保证内容始终可见 */
|
.bigdata-content,
|
.bigdata-table {
|
position: relative;
|
z-index: 3;
|
}
|
|
/* 修复表格容器样式 */
|
.bigdata-table {
|
margin-top: 5px;
|
padding-top: 5px;
|
border-top: 1px solid #eee;
|
flex: 1;
|
overflow: hidden;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.bigdata h1 {
|
font-size: 14px;
|
color: #2d8cf0;
|
font-weight: 700;
|
margin-bottom: 5px;
|
text-shadow: 1px 1px 2px rgba(45, 140, 240, 0.15);
|
letter-spacing: 0.5px;
|
font-family: "Microsoft YaHei", sans-serif;
|
}
|
|
.bigdata-content {
|
display: grid;
|
grid-template-columns: repeat(4, 1fr);
|
gap: 5px;
|
margin: 5px 0;
|
}
|
|
.content-item {
|
position: relative;
|
background: linear-gradient(145deg, #f8f9fa 0%, #e9ecef 100%);
|
border-radius: 5px;
|
padding: 5px 5px;
|
color: #343a40;
|
font-size: 20px;
|
font-weight: 600;
|
display: flex;
|
flex-direction: column;
|
align-items: center;
|
letter-spacing: 0.8px;
|
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.9);
|
transition: all 0.25s ease;
|
}
|
|
.content-item::after {
|
content: attr(data-value);
|
color: #2d8cf0;
|
font-size: 30px;
|
font-weight: 800;
|
margin-top: 12px;
|
text-shadow: 0 2px 4px rgba(45, 140, 240, 0.15);
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
}
|
|
.content-item:hover {
|
transform: translateY(-2px);
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
|
color: #2d8cf0;
|
text-shadow: 0 2px 4px rgba(45, 140, 240, 0.2);
|
}
|
|
.content-item:hover::after {
|
transform: scale(1.08);
|
text-shadow: 0 4px 8px rgba(45, 140, 240, 0.25);
|
}
|
|
.bigdata:hover {
|
transform: translateY(-5px) scale(1.02);
|
box-shadow: 0 12px 24px rgba(45, 140, 240, 0.15);
|
background: linear-gradient(45deg, #f4f9ff 0%, #e6f3ff 100%);
|
border-color: #2d8cf0;
|
}
|
|
/* 表格整体样式 */
|
.bigdata-table table {
|
width: 100%;
|
border-collapse: separate;
|
border-spacing: 0;
|
background: linear-gradient(145deg, #f8f9fa 0%, #e9ecef 100%);
|
border-radius: 10px;
|
overflow: hidden;
|
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.1);
|
margin-top: 5px;
|
max-height: 290px; /* 根据实际需要调整 */
|
display: block;
|
overflow-y: hidden; /* 隐藏滚动条 */
|
}
|
|
/* 固定表头 */
|
.bigdata-table thead {
|
position: sticky;
|
top: 0;
|
z-index: 2;
|
background: linear-gradient(145deg, #e6f3ff 0%, #d4e7ff 100%);
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
|
opacity: 1;
|
}
|
|
/* 调整tbody显示高度 */
|
.bigdata-table tbody {
|
max-height: calc(100% - 40px); /* 减去表头高度 */
|
display: block;
|
overflow-y: hidden;
|
width: 100%;
|
}
|
|
/* 主内容区 */
|
.bigdata-table tbody:first-child {
|
position: relative;
|
}
|
|
/* 克隆数据区 */
|
.bigdata-table tbody:last-child {
|
top: 100%;
|
transform: translateY(-45px); /* 初始位置补偿 */
|
}
|
|
/* 鼠标悬停暂停 */
|
.bigdata-table:hover tbody {
|
animation-play-state: paused;
|
}
|
|
/* 修正表格布局 */
|
.bigdata-table tr {
|
display: table;
|
width: 100%;
|
table-layout: fixed;
|
}
|
|
/* 表头样式 */
|
.bigdata-table th {
|
background: linear-gradient(145deg, #e6f3ff 0%, #d4e7ff 100%);
|
color: #2d8cf0;
|
font-weight: 600;
|
padding: 5px 12px;
|
border-bottom: 2px solid #2d8cf0;
|
letter-spacing: 0.5px;
|
font-size: 12px;
|
}
|
|
/* 表格单元格 */
|
.bigdata-table td {
|
padding: 12px;
|
border-bottom: 1px solid rgba(233, 236, 239, 0.8);
|
color: #495057;
|
font-size: 12px;
|
transition: all 0.25s ease;
|
}
|
|
/* 行悬停效果 */
|
.bigdata-table tr:hover td {
|
background-color: rgba(45, 140, 240, 0.05);
|
transform: translateX(4px);
|
}
|
|
/* 首列加粗 */
|
/* .bigdata-table td:first-child {
|
font-weight: 500;
|
color: #2d8cf0;
|
} */
|
|
/* 最后一行去底线 */
|
.bigdata-table tr:last-child td {
|
border-bottom: none;
|
}
|
|
/* 滚动条美化 */
|
.bigdata-table::-webkit-scrollbar {
|
width: 6px;
|
height: 6px;
|
background-color: #f8f9fa;
|
}
|
|
.bigdata-table th,
|
.bigdata-table td {
|
text-align: center;
|
vertical-align: middle;
|
}
|
|
/* 表头样式增加过渡效果 */
|
.bigdata-table th {
|
transition: all 0.3s ease;
|
}
|
|
/* 调整首列样式 */
|
.bigdata-table td:first-child {
|
font-weight: 500;
|
color: #2d8cf0;
|
text-align: left; /* 首列保持左对齐 */
|
padding-left: 5px; /* 增加左侧间距 */
|
}
|
|
/* 最后单元格右对齐 */
|
.bigdata-table td:last-child {
|
text-align: right;
|
padding-right: 5px;
|
}
|
|
@keyframes scroll {
|
0% {
|
transform: translateY(0);
|
}
|
100% {
|
transform: translateY(calc(-100% + 45px)); /* 最后一行高度补偿 */
|
}
|
}
|
|
tbody {
|
animation: scroll 30s linear infinite;
|
}
|
</style>
|