Merge branch 'master' of ssh://192.168.202.52:2022/mes/mes_web

master
黄锦贤 2 weeks ago
commit 12208fae00

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

@ -120,3 +120,60 @@ export function getBpMonthNoOk(data) {
data: data
});
}
// 免登录接口-获取工厂下拉列表
export function getBoardFactoryPublic(data) {
return request({
url: '/mes/wcsInterface/getBoardFactoryPublic',
method: 'post',
data: data
});
}
// 免登录接口-检验统计
export function getProduceStaticInfoPublic(data) {
return request({
url: '/quality/qcInterface/getProduceStaticInfoPublic',
method: 'post',
data: data
});
}
// 免登录接口-质量异常信息
export function getProduceNoOkListPublic(data) {
return request({
url: '/quality/qcInterface/getProduceNoOkListPublic',
method: 'post',
data: data
});
}
// 免登录接口-不良类型占比
export function getCheckProjectsPiePublic(data) {
return request({
url: '/quality/qcInterface/getCheckProjectsPiePublic',
method: 'post',
data: data
});
}
// 免登录接口-本月每日线体异常趋势
export function getLineDayNoOkPublic(data) {
return request({
url: '/quality/qcInterface/getLineDayNoOkPublic',
method: 'post',
data: data
});
}
// 免登录接口-产品不合格率同期对比
export function getMonthOfYearContrastPublic(data) {
return request({
url: '/quality/qcInterface/getMonthOfYearContrastPublic',
method: 'post',
data: data
});
}
// 免登录接口-白坯每月不合格数量
export function getBpMonthNoOkPublic(data) {
return request({
url: '/quality/qcInterface/getBpMonthNoOkPublic',
method: 'get',
data: data
});
}

@ -8,7 +8,7 @@ import { isRelogin } from '@/utils/request'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register','/cs4']
const whiteList = ['/login', '/register','/cs4', '/kanban/productLinePublic', '/kanban/qualitykanban1Public']
router.beforeEach((to, from, next) => {
NProgress.start()

@ -161,6 +161,17 @@ export const constantRoutes = [
component: () => import("@/views/kanban/productLine/index"),
hidden: true,
},
{
path: "/kanban/productLinePublic",
component: () => import("@/views/kanban/productLinePublic/index"),
hidden: true,
},
// 质量看板1免登录
{
path: "/kanban/qualitykanban1Public",
component: () => import("@/views/kanban/quality/kanban1Public"),
hidden: true,
},
// {
// path: "/report/board/LeadershipViewCheart",
// component: () => import("@/views/energy/LeadershipView/LeadershipViewChearts"),

@ -0,0 +1,398 @@
<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>
<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 {getProductionLineDataPublic} from "@/api/kanban/Packagingline";
export default {
name: 'ProductionBoardPublic',
data() {
return {
productionLines: [],
currentTime: '',
planTotal:0,
completeTotal: 0,
completeRate: 0
}
},
created() {
this.initProductionData();
setInterval(() => {
this.initProductionData();
}, 5000);
setInterval(() => {
this.updateCurrentTime();
}, 1000);
},
methods: {
initProductionData() {
getProductionLineDataPublic().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
})
},
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>
.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 {
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;
}
.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);
}
.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);
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);
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>

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save