生产产线看板、白坯看板

master
FCD 2 days ago
parent 5cfbd2d133
commit fc27855f67

@ -47,3 +47,11 @@ export function getProductionNumberPLC(data){
data: data
});
}
export function getProductionLineData(data){
return request({
url: '/mes/mesborad/getProductionLineData',
method: 'get',
data: data
});
}

@ -111,3 +111,12 @@ export function getKBTest() {
method: 'post'
});
}
// 白坯每月不合格数量
export function getBpMonthNoOk(data) {
return request({
url: '/quality/qcInterface/getBpMonthNoOk',
method: 'get',
data: data
});
}

@ -156,6 +156,11 @@ export const constantRoutes = [
component: () => import("@/views/kanban/Dryingprocess/index"),
hidden: true,
},
{
path: "/kanban/productLine",
component: () => import("@/views/kanban/productLine/index"),
hidden: true,
},
// {
// path: "/report/board/LeadershipViewCheart",
// component: () => import("@/views/energy/LeadershipView/LeadershipViewChearts"),

@ -0,0 +1,420 @@
<template>
<!-- 屏幕适配容器基于1920*1080设计稿防溢出+完整适配 -->
<v-scale-screen width="1920" height="1080" :fullScreen="false">
<div class="app-container home">
<!-- 头部区域标题+看板时间 -->
<div class="head">
<div class="head-content">
<div class="title">产线生产看板</div>
<div class="board-time">{{ currentTime }}</div>
</div>
</div>
<!-- 产线统计概览核心数据总览 -->
<div class="overview-card">
<div class="overview-item">
<span class="overview-label">总产线数</span>
<span class="overview-value">18</span>
</div>
<div class="overview-item">
<span class="overview-label">生产产线</span>
<span class="overview-value success">{{ productionLines.length }}</span>
</div>
<div class="overview-item">
<span class="overview-label">计划总产量</span>
<span class="overview-value">{{ planTotal }}</span>
</div>
<div class="overview-item">
<span class="overview-label">实际完成产量</span>
<span class="overview-value" :class="{ 'overview-warning': completeRate < 80 }">{{ completeTotal }}</span>
</div>
<div class="overview-item">
<span class="overview-label">完成比例</span>
<span class="overview-value" :class="{ 'overview-warning': completeRate < 80 }">{{ completeRate }} %</span>
</div>
</div>
<!-- 产线网格6列3行适配18条产线优化内边距避免挤压 -->
<div class="production-grid" :class="{ 'production-grid-mini': productionLines.length < 13 }">
<div
class="production-card"
v-for="line in productionLines"
:key="line.lineNo"
:class="{ 'line-warning': line.completionRate < 80 }"
>
<div class="line-number"> {{ line.equipmentName }}</div>
<!-- 修复1Vue中title绑定语法错误改为v-bind:title -->
<div class="product-name" >{{ line.productName }}</div>
<div class="data-group">
<div class="data-item">
<span class="label">计划产量</span>
<span class="value plan-value">{{ line.planTotal }}</span>
</div>
<div class="data-item">
<span class="label">当前产量</span>
<span class="value current-value" :class="{ 'reach': line.currentOutput >= line.planOutput }">
{{ line.completTotal || 0 }}
</span>
</div>
<div class="data-item efficiency-item">
<div class="efficiency-top">
<span class="label">产量完成率</span>
<span class="value efficiency-value" :class="{ 'reach': line.completionRate >= 80 }">
{{ line.completionRate }}%
</span>
</div>
<div class="efficiency-progress">
<div
class="progress-bar"
:style="{ width: line.completionRate + '%' }"
:class="{ 'progress-reach': line.completionRate >= 80 }"
></div>
</div>
</div>
</div>
</div>
</div>
</div>
</v-scale-screen>
</template>
<script>
import {getProductionLineData} from "@/api/kanban/Packagingline";
export default {
name: 'ProductionBoard',
data() {
return {
productionLines: [],
currentTime: '',
planTotal:0,
completeTotal: 0,
completeRate: 0
}
},
created() {
this.initProductionData();
setInterval(() => {
this.initProductionData();
}, 5000);
setInterval(() => {
this.updateCurrentTime();
}, 1000);
},
methods: {
// 线1
initProductionData() {
getProductionLineData().then(res=>{
let planTotal = 0
let completeTotal = 0
for (const line of res.data){
if (line.planTotal){
planTotal = planTotal + line.planTotal
}
if (line.completTotal){
completeTotal = completeTotal + line.completTotal
line.completionRate = (line.completTotal / line.planTotal * 100).toFixed(1)
}else {
line.completionRate = 0
}
}
let completeRate = ((completeTotal/planTotal) * 100 ).toFixed(1)
this.planTotal = planTotal
this.completeTotal = completeTotal
this.completeRate = completeRate
this.productionLines = res.data
})
},
// YYYY-MM-DD HH:mm:ss
updateCurrentTime() {
const now = new Date()
this.currentTime = now.toLocaleString('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).replace(/\//g, '-')
},
}
}
</script>
<style scoped>
/* 全局容器修复高度100%继承配合v-scale-screen满屏展示无溢出 */
.app-container {
padding: 0;
width: 100%;
box-sizing: border-box;
overflow: hidden; /* 核心:防止页面整体溢出滚动 */
}
.home {
width: 100%;
background: url("../../../assets/images/bg1.jpg") no-repeat center center;
background-size: cover;
background-color: #050711;
display: flex;
flex-direction: column;
gap: 16px; /* 区域间距,避免内容挤压 */
padding: 16px 24px; /* 全局内边距,防止内容贴边 */
box-sizing: border-box;
}
/* 头部区域:固定高度,避免占用过多空间,内容垂直居中 */
.head {
width: 100%;
height: 74px; /* 降低高度,为下方内容释放空间 */
position: relative;
display: flex;
align-items: center;
flex-shrink: 0; /* 禁止头部压缩,确保高度固定 */
}
/* .head-content 保留原有样式,无需修改 */
.head-content {
width: 100%;
height: 100%;
background: url("../../../assets/images/bg-head.png") no-repeat center center;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
position: relative;
}
/* 标题字体放大28px → 36px醒目且不挤压 */
.title {
position: absolute;
font-size: 36px;
color: #ffffff;
font-weight: 500;
margin: 0;
top: 0;
text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
/* 时间字体同步放大16px → 20px与标题比例协调 */
.board-time {
position: absolute;
right: 20px;
top: 70%;
transform: translateY(-50%);
font-size: 20px;
color: #e0e0e0;
margin: 0;
}
/* 概览卡片:降低高度和内边距,紧凑布局,释放垂直空间 */
.overview-card {
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
border-radius: 8px;
padding: 20px 0; /* 减少上下内边距 */
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
flex-shrink: 0; /* 禁止概览区压缩 */
height: 120px; /* 固定高度,避免占用过多空间 */
}
.overview-item {
text-align: center;
padding: 0 16px;
}
.overview-label {
display: block;
font-size: 24px;
color: #95a5a6;
margin-bottom: 4px; /* 减少间距,紧凑布局 */
}
.overview-value {
font-size: 26px; /* 降低字体,适配紧凑布局 */
color: #ffffff;
font-weight: 600;
line-height: 1.2;
}
.overview-value.success {
color: #2ecc71;
}
.overview-warning{
color: #f39c12;
}
/* 产线网格:核心修复显示不全,优化间距/高度,确保内容完整展示 */
.production-grid {
display: grid;
grid-template-columns: repeat(6, 1fr); /* 6列3行完美适配18条产线 */
grid-template-rows: repeat(3, 1fr); /* 等分剩余高度,无多余空白 */
gap: 20px; /* 减小网格间距,避免间距占用过多垂直空间 */
flex: 1; /* 填充父容器剩余高度,核心布局属性 */
box-sizing: border-box;
padding: 0; /* 移除多余内边距,释放空间 */
overflow: hidden; /* 防止网格内部内容溢出 */
}
.production-grid-mini{
grid-template-columns: repeat(4, 1fr); /* 5列4行完美适配18条产线 */
grid-template-rows: repeat(4, 1fr); /* 等分剩余高度,无多余空白 */
}
/* 单个产线卡片:彻底修复内容挤压,优化内边距/字体/间距 */
.production-card {
background: rgba(14, 28, 56, 0.9);
border-radius: 6px;
padding: 10px 12px; /* 适中内边距,内容不贴边也不挤压 */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
border: 1px solid rgba(255, 255, 255, 0.1);
transition: all 0.3s ease;
box-sizing: border-box;
width: 100%;
height: 100%; /* 卡片满网格单元格高度,无空白 */
display: flex;
flex-direction: column;
gap: 6px; /* 减小内部元素间距,紧凑但不拥挤 */
}
/* 卡片悬浮效果:细腻交互,不影响布局 */
.production-card:hover {
box-shadow: 0 6px 16px rgba(0, 183, 255, 0.2);
transform: translateY(-2px);
border-color: rgba(0, 183, 255, 0.4);
}
/* 产量未达标标识:宽度适中,醒目不占空间 */
.line-warning {
border-left: 3px solid #f39c12;
}
/* 产线编号:字体适中,分隔线细腻 */
.line-number {
font-size: 24px;
font-weight: 600;
color: #ffffff;
padding-bottom: 4px;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
line-height: 1.2;
white-space: nowrap;
margin: 0;
}
/* 产品名称:强制换行+高度自适应,超长名称自动折行显示 */
.product-name {
font-size: 22px;
color: #a0b4c8;
word-wrap: break-word !important; /* 强制换行,兼容所有浏览器 */
word-break: break-all !important; /* 中英文/数字混合也能正常换行,无截断 */
white-space: normal !important; /* 核心:取消原有不换行限制,覆盖所有冲突样式 */
min-height: 24px; /* 最小高度,避免内容过少时挤压下方 */
overflow: hidden; /* 超出最大高度时隐藏,不影响布局 */
cursor: help;
}
/* 数据组容器:弹性填充卡片剩余高度,内容垂直居中 */
.data-group {
display: flex;
flex-direction: column;
gap: 8px; /* 数据项间距适中,阅读舒适 */
flex: 1; /* 填充卡片剩余高度,无空白 */
justify-content: center; /* 内容垂直居中,避免挤压 */
box-sizing: border-box;
margin: 0;
}
/* 单个数据项:字体缩小,行高优化,紧凑布局 */
.data-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 20px; /* 核心:降低字体大小,适配小卡片,避免内容溢出 */
width: 100%;
line-height: 1.3; /* 行高适中,不重叠 */
margin: 0;
}
/* 标签和数值:颜色适配深色主题,对比度适中 */
.label {
color: #8fa4b8;
font-weight: 400;
}
.value {
color: #e0efff;
font-weight: 600;
}
/* 计划产量颜色:浅蓝色,清晰区分 */
.plan-value {
color: #4fc3f7;
}
/* 达标状态统一绿色,未达标浅橙色,视觉区分明确 */
.current-value.reach,
.completion-rate.reach,
.efficiency-value.reach {
color: #2ecc71;
}
.current-value,
.completion-rate {
color: #ffb74d;
}
/* 效率项:布局紧凑,进度条适配 */
.efficiency-item {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 4px; /* 减小间距,紧凑布局 */
width: 100%;
margin: 0;
}
.efficiency-top {
display: flex;
justify-content: space-between;
width: 100%;
align-items: center;
}
.efficiency-value {
font-size: 20px !important;
color: #ffb74d;
}
/* 效率进度条:高度适中,不占空间,样式细腻 */
.efficiency-progress {
width: 100%;
height: 5px; /* 降低进度条高度,紧凑布局 */
background: rgba(255, 255, 255, 0.1);
border-radius: 2px;
overflow: hidden;
box-sizing: border-box;
}
.progress-bar {
height: 100%;
background: #f39c12;
border-radius: 2px;
transition: width 0.8s ease-in-out;
}
.progress-bar.progress-reach {
background: #2ecc71;
}
</style>

@ -601,7 +601,7 @@ export default {
};
myChart3.setOption(option3);
// console.log(_this.selectxt)
getProMonthNoOk({
getBpMonthNoOk({
typeCode: "produce",
factoryCode: "ds_" + _this.selectxt,
}).then((response) => {

Loading…
Cancel
Save