|
|
@@ -0,0 +1,863 @@
|
|
|
+<!doctype html>
|
|
|
+<html lang="zh-CN">
|
|
|
+<head>
|
|
|
+ <meta charset="UTF-8">
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
|
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
|
+ <title>MES系统综合数据大屏</title>
|
|
|
+ <style>
|
|
|
+ * { box-sizing: border-box; }
|
|
|
+ html, body {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ margin: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #03133a;
|
|
|
+ color: #f2fbff;
|
|
|
+ font-family: "Microsoft YaHei", Arial, sans-serif;
|
|
|
+ }
|
|
|
+ body {
|
|
|
+ width: 1920px;
|
|
|
+ height: 1080px;
|
|
|
+ transform-origin: 0 0;
|
|
|
+ }
|
|
|
+ .screen {
|
|
|
+ position: relative;
|
|
|
+ width: 1920px;
|
|
|
+ height: 1080px;
|
|
|
+ overflow: hidden;
|
|
|
+ background: #03133a url("${ctxStatic}/screen/imgs/screenzong27.png") center / 100% 100% no-repeat;
|
|
|
+ }
|
|
|
+ .header {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ width: 1920px;
|
|
|
+ height: 100px;
|
|
|
+ background: url("${ctxStatic}/screen/imgs/screenzong5.png") center / 100% 100% no-repeat;
|
|
|
+ z-index: 5;
|
|
|
+ }
|
|
|
+ .logo {
|
|
|
+ position: absolute;
|
|
|
+ left: 28px;
|
|
|
+ top: 26px;
|
|
|
+ width: 176px;
|
|
|
+ height: 42px;
|
|
|
+ background: url("${ctxStatic}/screen/imgs/dyLogo.png") center / contain no-repeat;
|
|
|
+ }
|
|
|
+ .title {
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: 27px;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ font-size: 35px;
|
|
|
+ line-height: 45px;
|
|
|
+ font-weight: 900;
|
|
|
+ letter-spacing: 7px;
|
|
|
+ color: #fff;
|
|
|
+ text-shadow: 0 0 16px rgba(86, 205, 255, .9);
|
|
|
+ }
|
|
|
+ .clock {
|
|
|
+ position: absolute;
|
|
|
+ right: 32px;
|
|
|
+ top: 37px;
|
|
|
+ font-size: 23px;
|
|
|
+ line-height: 28px;
|
|
|
+ color: rgba(255, 255, 255, .95);
|
|
|
+ }
|
|
|
+ .panel {
|
|
|
+ position: absolute;
|
|
|
+ z-index: 3;
|
|
|
+ overflow: hidden;
|
|
|
+ background: linear-gradient(180deg, rgba(17, 85, 180, .76), rgba(9, 61, 150, .72));
|
|
|
+ border: 1px solid rgba(46, 156, 255, .34);
|
|
|
+ box-shadow: inset 0 0 34px rgba(31, 163, 255, .2);
|
|
|
+ }
|
|
|
+ .panel:after {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ right: 10px;
|
|
|
+ top: 10px;
|
|
|
+ width: 13px;
|
|
|
+ height: 13px;
|
|
|
+ background: linear-gradient(#1787ff 0 2px, transparent 2px 5px, #1787ff 5px 7px, transparent 7px 10px, #1787ff 10px 12px);
|
|
|
+ opacity: .8;
|
|
|
+ }
|
|
|
+ .panel-title {
|
|
|
+ position: relative;
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ padding-left: 36px;
|
|
|
+ font-size: 22px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: #fff;
|
|
|
+ background: linear-gradient(110deg, rgba(25, 143, 255, .9), rgba(23, 97, 214, .66) 48%, rgba(19, 88, 197, .1) 49%, transparent 100%);
|
|
|
+ text-shadow: 0 0 10px rgba(91, 223, 255, .95);
|
|
|
+ }
|
|
|
+ .panel-title:before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ left: 13px;
|
|
|
+ top: 15px;
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
+ background: #b4f9ff;
|
|
|
+ transform: rotate(45deg);
|
|
|
+ box-shadow: 0 0 10px #54ecff;
|
|
|
+ }
|
|
|
+ .panel-body {
|
|
|
+ position: relative;
|
|
|
+ height: calc(100% - 40px);
|
|
|
+ padding: 14px 24px 18px;
|
|
|
+ }
|
|
|
+ .left-top { left: 31px; top: 110px; width: 440px; height: 377px; }
|
|
|
+ .left-middle { left: 31px; top: 506px; width: 440px; height: 226px; }
|
|
|
+ .left-bottom { left: 31px; top: 753px; width: 440px; height: 298px; }
|
|
|
+ .right-top { right: 30px; top: 110px; width: 440px; height: 377px; }
|
|
|
+ .right-middle { right: 30px; top: 506px; width: 440px; height: 297px; }
|
|
|
+ .right-bottom { right: 30px; top: 823px; width: 440px; height: 227px; }
|
|
|
+ .bottom-left { left: 489px; top: 753px; width: 447px; height: 298px; }
|
|
|
+ .bottom-right { left: 956px; top: 753px; width: 475px; height: 298px; }
|
|
|
+ .left-top { background-image: url("${ctxStatic}/screen/imgs/screenzong19.png"); background-size: 100% 100%; }
|
|
|
+ .left-middle { background-image: url("${ctxStatic}/screen/imgs/screenzong7.png"); background-size: 100% 100%; }
|
|
|
+ .left-bottom, .right-middle, .bottom-left { background-image: url("${ctxStatic}/screen/imgs/screenzong20.png"); background-size: 100% 100%; }
|
|
|
+ .right-top { background-image: url("${ctxStatic}/screen/imgs/screenzong19.png"); background-size: 100% 100%; }
|
|
|
+ .right-bottom { background-image: url("${ctxStatic}/screen/imgs/screenzong7.png"); background-size: 100% 100%; }
|
|
|
+ .bottom-right { background-image: url("${ctxStatic}/screen/imgs/screenzong24.png"); background-size: 100% 100%; }
|
|
|
+ .kpi-row {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 26px;
|
|
|
+ margin: 16px 10px 12px;
|
|
|
+ }
|
|
|
+ .kpi {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 64px 1fr;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 0;
|
|
|
+ }
|
|
|
+ .kpi img {
|
|
|
+ width: 58px;
|
|
|
+ height: 58px;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+ .kpi-label {
|
|
|
+ font-size: 14px;
|
|
|
+ line-height: 22px;
|
|
|
+ color: #d7f7ff;
|
|
|
+ font-weight: 700;
|
|
|
+ }
|
|
|
+ .kpi-value {
|
|
|
+ margin-top: 3px;
|
|
|
+ font-size: 24px;
|
|
|
+ line-height: 30px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: #fff;
|
|
|
+ text-shadow: 0 0 10px rgba(80, 218, 255, .85);
|
|
|
+ }
|
|
|
+ .kpi-unit {
|
|
|
+ margin-left: 5px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #c5edff;
|
|
|
+ }
|
|
|
+ .progress-wrap { margin: 6px 10px 0; }
|
|
|
+ .progress-line {
|
|
|
+ height: 12px;
|
|
|
+ background: rgba(5, 51, 118, .86);
|
|
|
+ overflow: hidden;
|
|
|
+ }
|
|
|
+ .progress-line span {
|
|
|
+ display: block;
|
|
|
+ width: 0;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(90deg, #15a8ff, #e9efff);
|
|
|
+ }
|
|
|
+ .progress-meta {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ margin-top: 5px;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 15px;
|
|
|
+ color: #fff;
|
|
|
+ font-weight: 800;
|
|
|
+ }
|
|
|
+ .progress-meta strong {
|
|
|
+ justify-self: end;
|
|
|
+ font-size: 26px;
|
|
|
+ }
|
|
|
+ .chart { width: 100%; height: 100%; }
|
|
|
+ #capacityChart { height: 146px; margin-top: 23px; }
|
|
|
+ #hourChart { height: 226px; }
|
|
|
+ #repairTopChart { position: absolute; left: 20px; top: 58px; width: 210px; height: 210px; }
|
|
|
+ .tabs {
|
|
|
+ position: absolute;
|
|
|
+ right: 24px;
|
|
|
+ top: 156px;
|
|
|
+ display: flex;
|
|
|
+ gap: 12px;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 800;
|
|
|
+ }
|
|
|
+ .tabs span {
|
|
|
+ padding: 2px 8px;
|
|
|
+ color: #fff;
|
|
|
+ border-bottom: 2px solid rgba(121, 226, 255, .65);
|
|
|
+ }
|
|
|
+ .chart-legend {
|
|
|
+ position: absolute;
|
|
|
+ left: 34px;
|
|
|
+ top: 196px;
|
|
|
+ display: flex;
|
|
|
+ gap: 26px;
|
|
|
+ color: #e8f9ff;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .chart-legend i {
|
|
|
+ display: inline-block;
|
|
|
+ width: 10px;
|
|
|
+ height: 10px;
|
|
|
+ margin-right: 7px;
|
|
|
+ border-radius: 2px;
|
|
|
+ }
|
|
|
+ .blue-dot { background: #19aaff; }
|
|
|
+ .yellow-dot { background: #f7e83a; }
|
|
|
+ .pink-dot { background: #ff3aa3; }
|
|
|
+ .purple-dot { background: #756bff; }
|
|
|
+ .capacity-legend {
|
|
|
+ left: 34px;
|
|
|
+ top: 172px;
|
|
|
+ gap: 30px;
|
|
|
+ height: 22px;
|
|
|
+ align-items: center;
|
|
|
+ padding: 2px 8px;
|
|
|
+ background: rgba(5, 58, 140, .36);
|
|
|
+ border: 1px solid rgba(68, 182, 255, .14);
|
|
|
+ font-size: 13px;
|
|
|
+ font-weight: 800;
|
|
|
+ z-index: 4;
|
|
|
+ }
|
|
|
+ .capacity-legend i {
|
|
|
+ width: 9px;
|
|
|
+ height: 9px;
|
|
|
+ margin-right: 6px;
|
|
|
+ }
|
|
|
+ .quality-cards {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 32px;
|
|
|
+ height: 100%;
|
|
|
+ padding: 16px 22px 6px;
|
|
|
+ }
|
|
|
+ .quality-card {
|
|
|
+ position: relative;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ min-width: 0;
|
|
|
+ padding-top: 18px;
|
|
|
+ background: linear-gradient(180deg, transparent 0, rgba(22, 160, 245, .18) 48%, rgba(20, 127, 211, .46) 49%, rgba(11, 86, 174, .32) 100%);
|
|
|
+ clip-path: polygon(16% 0, 84% 0, 100% 34%, 100% 100%, 0 100%, 0 34%);
|
|
|
+ }
|
|
|
+ .quality-icon {
|
|
|
+ position: absolute;
|
|
|
+ top: 2px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 52px;
|
|
|
+ height: 52px;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: radial-gradient(circle, #1f87df 0, #1562ba 60%, rgba(20, 113, 197, .2) 100%);
|
|
|
+ box-shadow: 0 0 18px rgba(57, 207, 255, .7);
|
|
|
+ }
|
|
|
+ .quality-icon img {
|
|
|
+ position: absolute;
|
|
|
+ left: 10px;
|
|
|
+ top: 10px;
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+ .quality-card span {
|
|
|
+ margin-top: 34px;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 800;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ .quality-card strong {
|
|
|
+ margin-top: 10px;
|
|
|
+ font-size: 26px;
|
|
|
+ color: #fff;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ }
|
|
|
+ .device-total {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr auto;
|
|
|
+ align-items: center;
|
|
|
+ margin: 8px 4px 14px;
|
|
|
+ padding-bottom: 13px;
|
|
|
+ border-bottom: 1px solid rgba(164, 228, 255, .42);
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: 900;
|
|
|
+ }
|
|
|
+ .flip-number {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 7px;
|
|
|
+ margin-right: 5px;
|
|
|
+ }
|
|
|
+ .flip-number span {
|
|
|
+ width: 33px;
|
|
|
+ height: 42px;
|
|
|
+ line-height: 42px;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 31px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: #dfffff;
|
|
|
+ background: linear-gradient(180deg, #1d7cbe, #093c8f);
|
|
|
+ border: 1px solid rgba(110, 224, 255, .34);
|
|
|
+ box-shadow: inset 0 0 13px rgba(83, 221, 255, .38);
|
|
|
+ }
|
|
|
+ .flip-unit {
|
|
|
+ margin-left: 3px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #c8efff;
|
|
|
+ }
|
|
|
+ .device-split {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: repeat(3, 1fr);
|
|
|
+ gap: 0;
|
|
|
+ margin: 0 0 18px;
|
|
|
+ }
|
|
|
+ .device-split div {
|
|
|
+ text-align: center;
|
|
|
+ border-left: 1px solid rgba(133, 224, 255, .25);
|
|
|
+ }
|
|
|
+ .device-split div:first-child { border-left: 0; }
|
|
|
+ .device-split b {
|
|
|
+ display: block;
|
|
|
+ margin-bottom: 5px;
|
|
|
+ color: #ffe83e;
|
|
|
+ font-size: 18px;
|
|
|
+ }
|
|
|
+ .device-split small { font-size: 11px; color: #f9f9ff; }
|
|
|
+ .device-split span { display: block; margin-top: 3px; font-size: 12px; color: #e2f8ff; }
|
|
|
+ .device-subtitle {
|
|
|
+ margin: 0 0 8px;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: #fff;
|
|
|
+ }
|
|
|
+ .ring-row {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 138px 1fr;
|
|
|
+ gap: 12px;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+ .ring {
|
|
|
+ width: 130px;
|
|
|
+ height: 130px;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: conic-gradient(#3a87ff 0deg, #28d5ff 0deg, rgba(38, 112, 214, .45) 0deg);
|
|
|
+ box-shadow: 0 0 20px rgba(49, 213, 255, .48);
|
|
|
+ }
|
|
|
+ .ring span {
|
|
|
+ width: 78px;
|
|
|
+ height: 78px;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: radial-gradient(circle, #33a7ec, #1261ba);
|
|
|
+ font-size: 24px;
|
|
|
+ font-weight: 900;
|
|
|
+ }
|
|
|
+ .metric-line {
|
|
|
+ margin: 13px 0 19px;
|
|
|
+ color: #e7faff;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 900;
|
|
|
+ }
|
|
|
+ .metric-line b {
|
|
|
+ float: right;
|
|
|
+ font-size: 25px;
|
|
|
+ color: #19d6ff;
|
|
|
+ }
|
|
|
+ .metric-line .bar {
|
|
|
+ clear: both;
|
|
|
+ height: 11px;
|
|
|
+ margin-top: 7px;
|
|
|
+ background: rgba(14, 70, 157, .86);
|
|
|
+ }
|
|
|
+ .metric-line .bar span {
|
|
|
+ display: block;
|
|
|
+ width: 0;
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(90deg, #0d8cff, #23f0ff);
|
|
|
+ }
|
|
|
+ .energy-grid {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 22px 10px;
|
|
|
+ padding: 28px 0 0;
|
|
|
+ }
|
|
|
+ .energy-card {
|
|
|
+ position: relative;
|
|
|
+ min-height: 68px;
|
|
|
+ padding: 10px 10px 8px 86px;
|
|
|
+ background: linear-gradient(90deg, rgba(24, 138, 230, .45), rgba(17, 103, 196, .2));
|
|
|
+ clip-path: polygon(0 0, 90% 0, 100% 50%, 90% 100%, 0 100%);
|
|
|
+ }
|
|
|
+ .energy-card img {
|
|
|
+ position: absolute;
|
|
|
+ left: 12px;
|
|
|
+ top: -4px;
|
|
|
+ width: 72px;
|
|
|
+ height: 72px;
|
|
|
+ object-fit: contain;
|
|
|
+ }
|
|
|
+ .energy-card span {
|
|
|
+ display: block;
|
|
|
+ color: #d5f7ff;
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 900;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ .energy-card strong {
|
|
|
+ display: block;
|
|
|
+ margin-top: 2px;
|
|
|
+ font-size: 22px;
|
|
|
+ line-height: 25px;
|
|
|
+ color: #fff;
|
|
|
+ letter-spacing: 1px;
|
|
|
+ overflow-wrap: anywhere;
|
|
|
+ }
|
|
|
+ .data-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ table-layout: fixed;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+ .data-table th {
|
|
|
+ height: 32px;
|
|
|
+ color: #4ec5ff;
|
|
|
+ font-weight: 900;
|
|
|
+ text-align: center;
|
|
|
+ border-bottom: 1px solid rgba(104, 208, 255, .18);
|
|
|
+ }
|
|
|
+ .data-table td {
|
|
|
+ height: 36px;
|
|
|
+ color: #fff;
|
|
|
+ text-align: center;
|
|
|
+ font-weight: 800;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+ .top-list {
|
|
|
+ position: absolute;
|
|
|
+ left: 248px;
|
|
|
+ top: 70px;
|
|
|
+ right: 20px;
|
|
|
+ bottom: 22px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ gap: 12px;
|
|
|
+ }
|
|
|
+ .top-item {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 16px 1fr 48px;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ color: #e7fbff;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 900;
|
|
|
+ }
|
|
|
+ .top-color {
|
|
|
+ width: 8px;
|
|
|
+ height: 8px;
|
|
|
+ background: #17d9ff;
|
|
|
+ }
|
|
|
+ .top-value { color: #fff; }
|
|
|
+ .warehouse-cards {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 1fr 1fr;
|
|
|
+ gap: 20px;
|
|
|
+ height: 100%;
|
|
|
+ padding: 18px 10px 8px;
|
|
|
+ }
|
|
|
+ .warehouse-card {
|
|
|
+ display: grid;
|
|
|
+ grid-template-columns: 74px 1fr;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 0;
|
|
|
+ }
|
|
|
+ .warehouse-icon {
|
|
|
+ width: 64px;
|
|
|
+ height: 64px;
|
|
|
+ background: url("${ctxStatic}/screen/imgs/screenzong18.png") center / contain no-repeat;
|
|
|
+ }
|
|
|
+ .warehouse-name {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 900;
|
|
|
+ color: #fff;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ }
|
|
|
+ .warehouse-text {
|
|
|
+ font-size: 13px;
|
|
|
+ line-height: 25px;
|
|
|
+ font-weight: 800;
|
|
|
+ color: #1defff;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ .empty {
|
|
|
+ height: 170px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ color: rgba(210, 245, 255, .58);
|
|
|
+ font-size: 15px;
|
|
|
+ }
|
|
|
+ </style>
|
|
|
+</head>
|
|
|
+<body>
|
|
|
+<div class="screen">
|
|
|
+ <div class="header">
|
|
|
+ <div class="logo"></div>
|
|
|
+ <div class="title">MES系统综合数据大屏</div>
|
|
|
+ <div class="clock" id="clock"></div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <section class="panel left-top">
|
|
|
+ <div class="panel-title">生产订单信息</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="kpi-row">
|
|
|
+ <div class="kpi">
|
|
|
+ <img src="${ctxStatic}/screen/imgs/screenzong3.png" alt="">
|
|
|
+ <div><div class="kpi-label">当日产能</div><div class="kpi-value"><span id="todayOutput">0</span></div></div>
|
|
|
+ </div>
|
|
|
+ <div class="kpi">
|
|
|
+ <img src="${ctxStatic}/screen/imgs/screenzong4.png" alt="">
|
|
|
+ <div><div class="kpi-label">日计划产能</div><div class="kpi-value"><span id="dayPlan">0</span></div></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="progress-wrap">
|
|
|
+ <div class="progress-line"><span id="finishRateBar"></span></div>
|
|
|
+ <div class="progress-meta"><span>已完成产能</span><strong><span id="finishRate">0</span>%</strong></div>
|
|
|
+ </div>
|
|
|
+ <div class="tabs"><span>周</span><span>月</span></div>
|
|
|
+ <div class="chart-legend capacity-legend"><span><i class="blue-dot"></i>完成产量</span><span><i class="yellow-dot"></i>计划产量</span></div>
|
|
|
+ <div id="capacityChart" class="chart"></div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel left-middle">
|
|
|
+ <div class="panel-title">品质指标记录</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="quality-cards">
|
|
|
+ <div class="quality-card">
|
|
|
+ <div class="quality-icon"><img src="${ctxStatic}/screen/imgs/screenzong13.png" alt=""></div>
|
|
|
+ <span>巡检合格率</span>
|
|
|
+ <strong><span id="checkPassRate">0</span>%</strong>
|
|
|
+ </div>
|
|
|
+ <div class="quality-card">
|
|
|
+ <div class="quality-icon"><img src="${ctxStatic}/screen/imgs/screenzong14.png" alt=""></div>
|
|
|
+ <span>出货完成率</span>
|
|
|
+ <strong><span id="shipRate">0</span>%</strong>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel left-bottom">
|
|
|
+ <div class="panel-title">每小时上下线数据分析</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="chart-legend" style="top:54px;left:178px;"><span><i class="pink-dot"></i>上线</span><span><i class="purple-dot"></i>下线</span></div>
|
|
|
+ <div id="hourChart" class="chart"></div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel right-top">
|
|
|
+ <div class="panel-title">设备在线状态</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="device-total">
|
|
|
+ <span>设备总数</span>
|
|
|
+ <div class="flip-number" id="deviceDigits"><span>0</span><span>0</span><span>0</span><em class="flip-unit">台</em></div>
|
|
|
+ </div>
|
|
|
+ <div class="device-split">
|
|
|
+ <div><b id="onlineDevices">0 <small>台</small></b><span>运行设备</span></div>
|
|
|
+ <div><b id="idleDevices">0 <small>台</small></b><span>空闲设备</span></div>
|
|
|
+ <div><b id="offlineDevices">0 <small>台</small></b><span>离线设备</span></div>
|
|
|
+ </div>
|
|
|
+ <div class="device-subtitle">智能设备</div>
|
|
|
+ <div class="ring-row">
|
|
|
+ <div>
|
|
|
+ <div class="ring" id="onlineRing"><span id="onlineRate">0%</span></div>
|
|
|
+ <div style="text-align:center;margin-top:4px;font-weight:900;">OEE</div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <div class="metric-line">性能稼动率 <b id="performanceRate">0%</b><div class="bar"><span id="onlineRateBar"></span></div></div>
|
|
|
+ <div class="metric-line">时间开动率 <b id="timeRate">0%</b><div class="bar"><span id="planRateBar"></span></div></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel right-middle">
|
|
|
+ <div class="panel-title">绿色制造</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="energy-grid">
|
|
|
+ <div class="energy-card"><img src="${ctxStatic}/screen/imgs/screenzong15.png" alt=""><span>今日用电/kWh</span><strong><span id="greenEnergy">0</span></strong></div>
|
|
|
+ <div class="energy-card"><img src="${ctxStatic}/screen/imgs/screenzong16.png" alt=""><span>当前总功率/kW</span><strong><span id="greenPower">0</span></strong></div>
|
|
|
+ <div class="energy-card"><img src="${ctxStatic}/screen/imgs/screenzong1.png" alt=""><span id="meterName0">电表一</span><strong><span id="meterEnergy0">0</span></strong></div>
|
|
|
+ <div class="energy-card"><img src="${ctxStatic}/screen/imgs/screenzong2.png" alt=""><span id="meterName1">电表二</span><strong><span id="meterEnergy1">0</span></strong></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel right-bottom">
|
|
|
+ <div class="panel-title">仓库出库</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div class="warehouse-cards">
|
|
|
+ <div class="warehouse-card">
|
|
|
+ <div class="warehouse-icon"></div>
|
|
|
+ <div>
|
|
|
+ <div class="warehouse-name">今日出库</div>
|
|
|
+ <div class="warehouse-text">数量 <span id="todayOut">0</span> 件</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="warehouse-card">
|
|
|
+ <div class="warehouse-icon"></div>
|
|
|
+ <div>
|
|
|
+ <div class="warehouse-name">本月出库</div>
|
|
|
+ <div class="warehouse-text">数量 <span id="monthOut">0</span> 件</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel bottom-left">
|
|
|
+ <div class="panel-title">制程不良统计TOP5</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <div id="repairTopChart" class="chart"></div>
|
|
|
+ <div class="top-list" id="repairTopList"></div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+
|
|
|
+ <section class="panel bottom-right">
|
|
|
+ <div class="panel-title">生产订单明细记录</div>
|
|
|
+ <div class="panel-body">
|
|
|
+ <table class="data-table">
|
|
|
+ <thead><tr><th>品名</th><th>工单号</th><th>工单数量</th><th>完成量</th><th>完成比例</th><th>车间</th></tr></thead>
|
|
|
+ <tbody id="orderRows"></tbody>
|
|
|
+ </table>
|
|
|
+ <div class="empty" id="orderEmpty">暂无生产订单明细</div>
|
|
|
+ </div>
|
|
|
+ </section>
|
|
|
+</div>
|
|
|
+
|
|
|
+<script src="${ctxStatic}/jquery-1.11.3.min.js"></script>
|
|
|
+<script src="${ctxStatic}/echarts/4.2/echarts.min.js"></script>
|
|
|
+<script>
|
|
|
+ var charts = {};
|
|
|
+
|
|
|
+ $(function () {
|
|
|
+ changeZoom();
|
|
|
+ updateClock();
|
|
|
+ getData();
|
|
|
+ setInterval(updateClock, 1000);
|
|
|
+ setInterval(getData, 1000 * 60 * 2);
|
|
|
+ });
|
|
|
+
|
|
|
+ $(window).on('resize', function () {
|
|
|
+ changeZoom();
|
|
|
+ Object.keys(charts).forEach(function (key) {
|
|
|
+ charts[key].resize();
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ function changeZoom() {
|
|
|
+ var scaleX = $(window).width() / 1920;
|
|
|
+ var scaleY = $(window).height() / 1080;
|
|
|
+ $('body').css('transform', 'scale(' + scaleX + ', ' + scaleY + ')');
|
|
|
+ }
|
|
|
+
|
|
|
+ function updateClock() {
|
|
|
+ var now = new Date();
|
|
|
+ var weeks = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
|
|
+ $('#clock').text(now.getFullYear() + '年' + (now.getMonth() + 1) + '月' + now.getDate() + '日 ' + weeks[now.getDay()] + ' ' + pad(now.getHours()) + ':' + pad(now.getMinutes()));
|
|
|
+ }
|
|
|
+
|
|
|
+ function pad(value) {
|
|
|
+ return value < 10 ? '0' + value : value;
|
|
|
+ }
|
|
|
+
|
|
|
+ function getData() {
|
|
|
+ $.post('${ctx}/mes/mesProduct/integratedScreenData', function (ret) {
|
|
|
+ if (!ret || !ret.data) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ renderScreen(ret.data);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderScreen(data) {
|
|
|
+ var todayOutput = number(data.todayOutput == null ? data.actual : data.todayOutput);
|
|
|
+ var dayPlan = number(data.plan);
|
|
|
+ var finishRate = dayPlan > 0 ? Math.min(100, Math.round(todayOutput * 1000 / dayPlan) / 10) : 0;
|
|
|
+ var deviceTotal = number(data.deviceTotal || data.devices);
|
|
|
+ var onlineDevices = number(data.onlineDevices);
|
|
|
+ var offlineDevices = number(data.offlineDevices);
|
|
|
+ var idleDevices = Math.max(deviceTotal - onlineDevices - offlineDevices, 0);
|
|
|
+ var onlineRate = deviceTotal > 0 ? Math.round(onlineDevices * 1000 / deviceTotal) / 10 : 0;
|
|
|
+ var todayOut = number(data.todayOut);
|
|
|
+ var monthOut = number(data.monthOut);
|
|
|
+ var shipRate = todayOutput > 0 ? Math.min(100, Math.round(todayOut * 1000 / todayOutput) / 10) : 0;
|
|
|
+
|
|
|
+ $('#todayOutput').text(todayOutput);
|
|
|
+ $('#dayPlan').text(dayPlan);
|
|
|
+ $('#finishRate').text(finishRate);
|
|
|
+ $('#finishRateBar').css('width', finishRate + '%');
|
|
|
+ $('#checkPassRate').text(number(data.checkPassRate));
|
|
|
+ $('#shipRate').text(shipRate);
|
|
|
+ $('#todayOut').text(todayOut);
|
|
|
+ $('#monthOut').text(monthOut);
|
|
|
+
|
|
|
+ renderDigits(deviceTotal);
|
|
|
+ $('#onlineDevices').html(onlineDevices + ' <small>台</small>');
|
|
|
+ $('#idleDevices').html(idleDevices + ' <small>台</small>');
|
|
|
+ $('#offlineDevices').html(offlineDevices + ' <small>台</small>');
|
|
|
+ $('#onlineRate').text(onlineRate + '%');
|
|
|
+ $('#performanceRate').text(onlineRate + '%');
|
|
|
+ $('#timeRate').text(finishRate + '%');
|
|
|
+ $('#onlineRateBar').css('width', Math.min(100, onlineRate) + '%');
|
|
|
+ $('#planRateBar').css('width', finishRate + '%');
|
|
|
+ $('#onlineRing').css('background', 'conic-gradient(#3a87ff 0deg, #28d5ff ' + (onlineRate * 3.6) + 'deg, rgba(38, 112, 214, .45) ' + (onlineRate * 3.6) + 'deg)');
|
|
|
+
|
|
|
+ renderOrderRows(data.orderDetails || [], dayPlan);
|
|
|
+ renderEnergy(data.greenMeters || [], data);
|
|
|
+ renderCapacity(data.date || [], data.output || [], data.plan);
|
|
|
+ renderHour(data.hourTimes || [], data.onlineHourlyData || [], data.offlineHourlyData || []);
|
|
|
+ renderRepairTop(data.repairTopNames || [], data.repairTopCounts || []);
|
|
|
+ }
|
|
|
+
|
|
|
+ function number(value) {
|
|
|
+ var n = Number(value);
|
|
|
+ return isNaN(n) ? 0 : n;
|
|
|
+ }
|
|
|
+
|
|
|
+ function text(value) {
|
|
|
+ return value === undefined || value === null || value === '' ? '-' : String(value);
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderDigits(value) {
|
|
|
+ var digits = String(Math.max(0, number(value))).padStart(3, '0').slice(-3).split('');
|
|
|
+ $('#deviceDigits').html('<span>' + digits[0] + '</span><span>' + digits[1] + '</span><span>' + digits[2] + '</span><em class="flip-unit">台</em>');
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderOrderRows(rows, plan) {
|
|
|
+ if (!rows.length) {
|
|
|
+ $('#orderRows').html('');
|
|
|
+ $('#orderEmpty').show();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ $('#orderEmpty').hide();
|
|
|
+ var html = '';
|
|
|
+ rows.slice(0, 5).forEach(function (row, index) {
|
|
|
+ var done = number(row.done);
|
|
|
+ var orderNum = number(row.orderNum || plan || done);
|
|
|
+ var rate = orderNum > 0 ? Math.min(100, Math.round(done * 10000 / orderNum) / 100) : 0;
|
|
|
+ html += '<tr><td>' + text(row.name || ('品名' + (index + 1))) + '</td><td>' + text(row.orderNo) + '</td><td>' + orderNum + '</td><td>' + done + '</td><td>' + rate + '%</td><td>' + text(row.workshop || 'SEB车间') + '</td></tr>';
|
|
|
+ });
|
|
|
+ $('#orderRows').html(html);
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderEnergy(meters, data) {
|
|
|
+ for (var i = 0; i < 2; i++) {
|
|
|
+ var meter = meters[i] || {};
|
|
|
+ $('#meterName' + i).text(text(meter.deviceName || meter.deviceSn || ('电表' + (i + 1))));
|
|
|
+ $('#meterEnergy' + i).text(formatNumber(number(meter.todayEnergy)) + ' kWh');
|
|
|
+ }
|
|
|
+ $('#greenPower').text(formatNumber(number(data.greenTotalPower)));
|
|
|
+ $('#greenEnergy').text(formatNumber(number(data.greenTodayEnergy)));
|
|
|
+ }
|
|
|
+
|
|
|
+ function chart(id) {
|
|
|
+ if (!charts[id]) {
|
|
|
+ charts[id] = echarts.init(document.getElementById(id));
|
|
|
+ }
|
|
|
+ return charts[id];
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderCapacity(dates, output, plan) {
|
|
|
+ var labels = (dates || []).slice(-7);
|
|
|
+ var values = (output || []).slice(-7).map(number);
|
|
|
+ var planValue = number(plan);
|
|
|
+ chart('capacityChart').setOption({
|
|
|
+ color: ['#19aaff', '#f7e83a'],
|
|
|
+ tooltip: { trigger: 'axis' },
|
|
|
+ grid: { left: 34, right: 8, top: 18, bottom: 24 },
|
|
|
+ xAxis: { type: 'category', data: labels, axisLabel: { color: '#fff', fontSize: 11 }, axisLine: { lineStyle: { color: '#2479b5' } }, axisTick: { show: false } },
|
|
|
+ yAxis: { type: 'value', axisLabel: { color: '#fff', fontSize: 11 }, splitLine: { show: false } },
|
|
|
+ series: [
|
|
|
+ { name: '完成产量', type: 'bar', barWidth: 12, data: values, itemStyle: { barBorderRadius: [6, 6, 0, 0] } },
|
|
|
+ { name: '计划产量', type: 'bar', barWidth: 12, data: labels.map(function () { return planValue; }), itemStyle: { barBorderRadius: [6, 6, 0, 0] } }
|
|
|
+ ]
|
|
|
+ }, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderHour(hours, onlineValues, offlineValues) {
|
|
|
+ chart('hourChart').setOption({
|
|
|
+ color: ['#ff3aa3', '#756bff'],
|
|
|
+ tooltip: { trigger: 'axis' },
|
|
|
+ grid: { left: 36, right: 10, top: 48, bottom: 28 },
|
|
|
+ xAxis: { type: 'category', data: hours, axisLabel: { color: '#fff', fontSize: 11 }, axisLine: { lineStyle: { color: '#2479b5' } }, axisTick: { show: false } },
|
|
|
+ yAxis: { type: 'value', max: 60, minInterval: 1, axisLabel: { color: '#fff', fontSize: 11, formatter: function (value) { return Math.floor(value) === value ? value : ''; } }, splitLine: { lineStyle: { color: 'rgba(128, 223, 255, .12)' } } },
|
|
|
+ series: [
|
|
|
+ { name: '上线', type: 'line', smooth: true, symbol: 'none', lineStyle: { width: 3 }, areaStyle: { color: 'rgba(255, 58, 163, .18)' }, data: (onlineValues || []).map(number) },
|
|
|
+ { name: '下线', type: 'line', smooth: true, symbol: 'none', lineStyle: { width: 3 }, areaStyle: { color: 'rgba(117, 107, 255, .24)' }, data: (offlineValues || []).map(number) }
|
|
|
+ ]
|
|
|
+ }, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ function renderRepairTop(names, counts) {
|
|
|
+ var colors = ['#25e8ff', '#ff6a2a', '#ffbf2d', '#2d92ff', '#18e5d8'];
|
|
|
+ if (!names.length) {
|
|
|
+ names = ['暂无不良记录'];
|
|
|
+ counts = [0];
|
|
|
+ }
|
|
|
+ var data = names.slice(0, 5).map(function (name, index) {
|
|
|
+ return { name: name, value: number(counts[index]), itemStyle: { color: colors[index % colors.length] } };
|
|
|
+ });
|
|
|
+ chart('repairTopChart').setOption({
|
|
|
+ tooltip: { trigger: 'item' },
|
|
|
+ series: [{
|
|
|
+ type: 'pie',
|
|
|
+ radius: ['58%', '78%'],
|
|
|
+ center: ['50%', '50%'],
|
|
|
+ avoidLabelOverlap: true,
|
|
|
+ label: { show: false },
|
|
|
+ labelLine: { show: false },
|
|
|
+ data: data
|
|
|
+ }]
|
|
|
+ }, true);
|
|
|
+ var html = '';
|
|
|
+ data.forEach(function (item, index) {
|
|
|
+ html += '<div class="top-item"><i class="top-color" style="background:' + colors[index % colors.length] + '"></i><span>' + text(item.name) + '</span><span class="top-value">' + item.value + '</span></div>';
|
|
|
+ });
|
|
|
+ $('#repairTopList').html(html);
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatNumber(value) {
|
|
|
+ var n = number(value);
|
|
|
+ return Math.round(n * 100) / 100;
|
|
|
+ }
|
|
|
+</script>
|
|
|
+</body>
|
|
|
+</html>
|