style(frontend): 工艺线SVG浅色重绘 + 登录页改版 + 品牌名改为推拉酸洗线

- Material 物料跟踪总图 SVG 全部重新配色:深色设备图改为浅色钢灰底,
  介质色保留(酸洗琥珀/漂洗青/烘干橙),当前设备与焊缝高亮改主题红
- 段位标签色加深以适配白底图例
- 登录页大改:左侧品牌 + 右侧白卡片,背景换工业钢厂实拍图 + 红色主题渐变蒙版
- 品牌名由 SIMATIC L2 改为「推拉酸洗线」(登录页与顶栏 logo)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-29 10:52:08 +08:00
parent 8583f605bd
commit 2144f13b88
4 changed files with 257 additions and 151 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

View File

@@ -4,10 +4,10 @@
<!-- TOP BAR --> <!-- TOP BAR -->
<div class="top-bar"> <div class="top-bar">
<div class="logo"> <div class="logo">
<span class="logo-mark">S</span> <span class="logo-mark"></span>
<span class="logo-text">SIMATIC L2</span> <span class="logo-text">推拉酸洗线</span>
</div> </div>
<div class="sys-title">推拉酸洗线 · L2 过程控制系统</div> <div class="sys-title">二级过程控制系统</div>
<div class="spacer"></div> <div class="spacer"></div>
<div class="status-pills"> <div class="status-pills">
<span class="pill run"><i class="dot"></i>机组运行</span> <span class="pill run"><i class="dot"></i>机组运行</span>

View File

@@ -1,34 +1,49 @@
<template> <template>
<div class="login-page"> <div class="login-page">
<div class="login-panel"> <div class="login-overlay"></div>
<div class="login-header">
<div class="header-mark">S</div> <!-- 左侧品牌区 -->
<div class="header-right"> <div class="login-brand">
<div class="header-title">SIMATIC L2</div> <div class="brand-logo">
<div class="header-sub">推拉酸洗线 过程控制系统</div> <div class="brand-mark"></div>
<div class="brand-word">
<div class="brand-title">推拉酸洗线</div>
<div class="brand-en">PUSH-PULL PICKLING LINE</div>
</div> </div>
</div> </div>
<div class="brand-slogan">二级过程控制系统</div>
<div class="brand-desc">物料跟踪 · 计划实绩 · 工艺模型 · 质量管理</div>
</div>
<div class="login-body"> <!-- 右侧登录卡片 -->
<div class="field-group"> <div class="login-card">
<div class="field-label">用户名</div> <div class="card-title">系统登录</div>
<input v-model="form.username" class="kv-input" autocomplete="username" @keyup.enter="handleLogin" /> <div class="card-tip">请输入账号密码以继续</div>
</div>
<div class="field-group"> <div class="field-group">
<div class="field-label">密码</div> <div class="field-label">用户名</div>
<input v-model="form.password" type="password" class="kv-input" autocomplete="current-password" @keyup.enter="handleLogin" /> <input v-model="form.username" class="login-input" autocomplete="username"
</div> placeholder="请输入用户名" @keyup.enter="handleLogin" />
<div v-if="error" class="login-error">{{ error }}</div> </div>
<button class="btn btn-primary fw" style="margin-top:18px;padding:7px;" :disabled="loading" @click="handleLogin"> <div class="field-group">
{{ loading ? '验证中...' : '登录' }} <div class="field-label">密码</div>
</button> <input v-model="form.password" type="password" class="login-input" autocomplete="current-password"
placeholder="请输入密码" @keyup.enter="handleLogin" />
</div> </div>
<div class="login-footer"> <div v-if="error" class="login-error">{{ error }}</div>
<i class="dot g"></i>系统就绪
<span style="margin-left:auto;">v1.0.0</span> <button class="login-btn" :disabled="loading" @click="handleLogin">
{{ loading ? '验证中' : ' ' }}
</button>
<div class="login-foot">
<span class="dot"></span>系统就绪
<span class="ver">v1.0.0</span>
</div> </div>
</div> </div>
<div class="copyright">推拉酸洗线 L2 MES · 过程控制系统</div>
</div> </div>
</template> </template>
@@ -67,101 +82,192 @@ export default {
@import '@/assets/styles/variables'; @import '@/assets/styles/variables';
.login-page { .login-page {
position: relative;
height: 100vh; height: 100vh;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: space-between;
background: $bg-base; padding: 0 9vw;
} background: url('~@/assets/images/login-bg.jpg') center/cover no-repeat;
.login-panel {
width: 360px;
background: $bg-card;
border: 1px solid $border;
border-top: 3px solid $sms-teal;
border-radius: 2px;
overflow: hidden; overflow: hidden;
} }
.login-header { // 主题色渐变蒙版(左深红 → 右半透明,保证文字与卡片可读)
display: flex; .login-overlay {
align-items: center; position: absolute;
gap: 12px; inset: 0;
padding: 20px 24px; background:
background: $bg-panel; linear-gradient(105deg, rgba($sms-teal, .82) 0%, rgba(28, 22, 24, .72) 46%, rgba(20, 16, 18, .55) 100%);
border-bottom: 1px solid $border;
} }
.header-mark { // ─── 左侧品牌 ───
width: 36px; .login-brand {
height: 36px; position: relative;
background: $sms-teal; z-index: 1;
color: $bg-base; color: #fff;
font-size: 18px; max-width: 480px;
}
.brand-logo {
display: flex;
align-items: center;
gap: 16px;
}
.brand-mark {
width: 60px;
height: 60px;
background: #fff;
color: $sms-teal;
font-size: 32px;
font-weight: 900; font-weight: 900;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
border-radius: 2px; border-radius: 8px;
box-shadow: 0 6px 20px rgba(0, 0, 0, .3);
flex-shrink: 0; flex-shrink: 0;
} }
.header-title { .brand-title {
font-size: 14px; font-size: 38px;
font-weight: 700; font-weight: 800;
color: $text-primary; letter-spacing: 6px;
line-height: 1.1;
}
.brand-en {
font-size: 12px;
letter-spacing: 3px;
opacity: .8;
margin-top: 4px;
}
.brand-slogan {
margin-top: 26px;
font-size: 20px;
font-weight: 600;
letter-spacing: 2px; letter-spacing: 2px;
} }
.header-sub { .brand-desc {
font-size: 10px; margin-top: 12px;
color: $text-secondary; font-size: 14px;
margin-top: 3px; letter-spacing: 1px;
letter-spacing: .3px; opacity: .85;
} }
.login-body { // ─── 右侧登录卡片 ───
padding: 24px; .login-card {
position: relative;
z-index: 1;
width: 380px;
background: #fff;
border-radius: 12px;
border-top: 4px solid $sms-teal;
padding: 40px 36px 28px;
box-shadow: 0 18px 50px rgba(0, 0, 0, .35);
}
.card-title {
font-size: 22px;
font-weight: 700;
color: $text-primary;
letter-spacing: 1px;
}
.card-tip {
margin-top: 6px;
font-size: 13px;
color: $text-muted;
margin-bottom: 26px;
} }
.field-group { .field-group {
margin-bottom: 14px; margin-bottom: 18px;
.field-label { .field-label {
font-size: 10px; font-size: 13px;
font-weight: 700;
color: $text-secondary; color: $text-secondary;
text-transform: uppercase; margin-bottom: 8px;
letter-spacing: .6px;
margin-bottom: 6px;
} }
}
.kv-input { padding: 7px 9px; font-size: 13px; } .login-input {
width: 100%;
height: 42px;
padding: 0 14px;
font-size: 14px;
color: $text-primary;
background: $bg-panel;
border: 1px solid $border;
border-radius: 8px;
outline: none;
transition: all .15s;
&::placeholder { color: $text-muted; }
&:focus {
background: #fff;
border-color: $sms-teal;
box-shadow: 0 0 0 3px rgba($sms-teal, .12);
}
} }
.login-error { .login-error {
margin-top: 8px; font-size: 13px;
font-size: 11px;
color: $accent-red; color: $accent-red;
padding: 5px 8px; padding: 8px 12px;
background: rgba($accent-red, .08); background: rgba($accent-red, .08);
border-left: 2px solid $accent-red; border-radius: 6px;
margin-bottom: 14px;
} }
.login-footer { .login-btn {
padding: 8px 24px; width: 100%;
background: $bg-panel; height: 44px;
border-top: 1px solid $border; margin-top: 8px;
font-size: 10px; font-size: 16px;
color: $text-muted; font-weight: 600;
letter-spacing: 4px;
color: #fff;
background: $sms-teal;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all .15s;
&:hover { background: $sms-teal-dim; box-shadow: 0 6px 16px rgba($sms-teal, .35); }
&:active { transform: translateY(1px); }
&:disabled { opacity: .6; cursor: not-allowed; }
}
.login-foot {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 6px; gap: 7px;
letter-spacing: .3px; margin-top: 22px;
font-size: 12px;
color: $text-muted;
.dot { .dot { width: 7px; height: 7px; border-radius: 50%; background: $status-run; box-shadow: 0 0 6px rgba($status-run, .6); }
width: 5px; height: 5px; border-radius: 50%; display: inline-block; .ver { margin-left: auto; }
&.g { background: $status-run; } }
}
.copyright {
position: absolute;
bottom: 22px;
left: 0;
right: 0;
text-align: center;
z-index: 1;
font-size: 12px;
color: rgba(255, 255, 255, .65);
letter-spacing: 1px;
}
// 窄屏:隐藏品牌区,卡片居中
@media (max-width: 900px) {
.login-page { justify-content: center; padding: 0 20px; }
.login-brand { display: none; }
} }
</style> </style>

View File

@@ -72,7 +72,7 @@
<div class="card-header">推拉酸洗线 - 物料跟踪总图</div> <div class="card-header">推拉酸洗线 - 物料跟踪总图</div>
<div class="line-body"> <div class="line-body">
<svg viewBox="0 0 1900 305" preserveAspectRatio="xMidYMid meet" class="line-svg"> <svg viewBox="0 0 1900 305" preserveAspectRatio="xMidYMid meet" class="line-svg">
<rect x="0" y="0" width="1900" height="305" fill="#0a1218" /> <rect x="0" y="0" width="1900" height="305" fill="#f2f5f9" />
<!-- 段位标签带 --> <!-- 段位标签带 -->
<g v-for="s in sections" :key="'sec-'+s.name"> <g v-for="s in sections" :key="'sec-'+s.name">
@@ -84,12 +84,12 @@
<!-- 顶部标签 --> <!-- 顶部标签 -->
<g v-for="eq in equipments" :key="'lab-'+eq.k" font-family="Arial,sans-serif"> <g v-for="eq in equipments" :key="'lab-'+eq.k" font-family="Arial,sans-serif">
<text :x="eq.x" y="40" text-anchor="middle" font-size="10.5" fill="#c8d4e0">{{ eq.label }}</text> <text :x="eq.x" y="40" text-anchor="middle" font-size="10.5" fill="#303133">{{ eq.label }}</text>
</g> </g>
<!-- 主带钢线 --> <!-- 主带钢线 -->
<path d="M 40 185 L 1860 185" stroke="#5a6a75" stroke-width="3" fill="none"/> <path d="M 40 185 L 1860 185" stroke="#9aa4b0" stroke-width="3" fill="none"/>
<path d="M 40 185 L 1860 185" stroke="#aabbcc" stroke-width="1.2" fill="none" stroke-dasharray="6 10"> <path d="M 40 185 L 1860 185" stroke="#c03639" stroke-width="1.4" fill="none" stroke-dasharray="6 10">
<animate attributeName="stroke-dashoffset" from="16" to="0" dur="0.7s" repeatCount="indefinite"/> <animate attributeName="stroke-dashoffset" from="16" to="0" dur="0.7s" repeatCount="indefinite"/>
</path> </path>
@@ -97,62 +97,62 @@
<g v-for="eq in equipments" :key="eq.k" :transform="`translate(${eq.x}, 185)`"> <g v-for="eq in equipments" :key="eq.k" :transform="`translate(${eq.x}, 185)`">
<!-- 开卷机 --> <!-- 开卷机 -->
<template v-if="eq.type==='coiler'"> <template v-if="eq.type==='coiler'">
<circle r="38" fill="#1a232c" stroke="#3a4a55" stroke-width="2"/> <circle r="38" fill="#e9eef4" stroke="#aab4c2" stroke-width="2"/>
<circle r="22" fill="#0a1218" stroke="#5a6a75" stroke-width="1.5"/> <circle r="22" fill="#f2f5f9" stroke="#9aa4b0" stroke-width="1.5"/>
<circle r="8" fill="#2a3a48" stroke="#5a7090" stroke-width="1"/> <circle r="8" fill="#cdd6e0" stroke="#9aa4b0" stroke-width="1"/>
<path d="M-38 0 a38 38 0 0 1 76 0" stroke="#00c8ff" stroke-width="1" fill="none" opacity="0.5"> <path d="M-38 0 a38 38 0 0 1 76 0" stroke="#c03639" stroke-width="1" fill="none" opacity="0.5">
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite"/> <animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="3s" repeatCount="indefinite"/>
</path> </path>
<text y="58" text-anchor="middle" font-size="10" fill="#b8c4cf">DC-1</text> <text y="58" text-anchor="middle" font-size="10" fill="#5b6470">DC-1</text>
</template> </template>
<!-- 九辊矫直机5上4下 --> <!-- 九辊矫直机5上4下 -->
<template v-else-if="eq.type==='rolls9'"> <template v-else-if="eq.type==='rolls9'">
<rect x="-44" y="-26" width="88" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="1.5" rx="3"/> <rect x="-44" y="-26" width="88" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="1.5" rx="3"/>
<g v-for="i in 5" :key="'t'+i"> <g v-for="i in 5" :key="'t'+i">
<circle :cx="-36 + (i-1)*18" cy="-10" r="6" fill="#2a3540" stroke="#7090a8" stroke-width="1"/> <circle :cx="-36 + (i-1)*18" cy="-10" r="6" fill="#dde4ec" stroke="#8b97a7" stroke-width="1"/>
</g> </g>
<g v-for="i in 4" :key="'b'+i"> <g v-for="i in 4" :key="'b'+i">
<circle :cx="-27 + (i-1)*18" cy="10" r="6" fill="#2a3540" stroke="#7090a8" stroke-width="1"/> <circle :cx="-27 + (i-1)*18" cy="10" r="6" fill="#dde4ec" stroke="#8b97a7" stroke-width="1"/>
</g> </g>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">STR-9</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">STR-9</text>
</template> </template>
<!-- 切头/切尾剪 --> <!-- 切头/切尾剪 -->
<template v-else-if="eq.type==='shear'"> <template v-else-if="eq.type==='shear'">
<rect x="-30" y="-26" width="60" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="1.5" rx="2"/> <rect x="-30" y="-26" width="60" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="1.5" rx="2"/>
<line x1="-18" y1="-16" x2="18" y2="16" stroke="#da3633" stroke-width="2.2"/> <line x1="-18" y1="-16" x2="18" y2="16" stroke="#da3633" stroke-width="2.2"/>
<line x1="-18" y1="16" x2="18" y2="-16" stroke="#da3633" stroke-width="2.2"/> <line x1="-18" y1="16" x2="18" y2="-16" stroke="#da3633" stroke-width="2.2"/>
<circle cx="-18" cy="-16" r="3" fill="#da3633"/> <circle cx="-18" cy="-16" r="3" fill="#da3633"/>
<circle cx="18" cy="-16" r="3" fill="#da3633"/> <circle cx="18" cy="-16" r="3" fill="#da3633"/>
<circle cx="0" cy="0" r="3" fill="#ffdd44"/> <circle cx="0" cy="0" r="3" fill="#c03639"/>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">{{ eq.code }}</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">{{ eq.code }}</text>
</template> </template>
<!-- 酸洗槽 --> <!-- 酸洗槽 -->
<template v-else-if="eq.type==='acid'"> <template v-else-if="eq.type==='acid'">
<path d="M -32 -24 L 32 -24 L 28 26 L -28 26 Z" fill="#3a2a18" stroke="#a06030" stroke-width="2"/> <path d="M -32 -24 L 32 -24 L 28 26 L -28 26 Z" fill="#f0e3cf" stroke="#cf9a5a" stroke-width="2"/>
<path d="M -30 -10 L 30 -10 L 27 24 L -27 24 Z" fill="#ffaa44" opacity="0.55"> <path d="M -30 -10 L 30 -10 L 27 24 L -27 24 Z" fill="#ffaa44" opacity="0.55">
<animate attributeName="opacity" values="0.5;0.7;0.5" dur="2.5s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.5;0.7;0.5" dur="2.5s" repeatCount="indefinite"/>
</path> </path>
<path d="M -22 -10 q 4 -6 8 0 t 8 0 t 8 0 t 8 0" stroke="#ffd28a" stroke-width="1" fill="none" opacity="0.7"/> <path d="M -22 -10 q 4 -6 8 0 t 8 0 t 8 0 t 8 0" stroke="#ffd28a" stroke-width="1" fill="none" opacity="0.7"/>
<!-- 蒸汽 --> <!-- 蒸汽 -->
<g opacity="0.6"> <g opacity="0.6">
<circle cx="-12" cy="-30" r="3" fill="#cccccc"> <circle cx="-12" cy="-30" r="3" fill="#b8c0cc">
<animate attributeName="cy" values="-30;-46;-30" dur="2s" repeatCount="indefinite"/> <animate attributeName="cy" values="-30;-46;-30" dur="2s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.6;0;0.6" dur="2s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.6;0;0.6" dur="2s" repeatCount="indefinite"/>
</circle> </circle>
<circle cx="6" cy="-32" r="2.5" fill="#cccccc"> <circle cx="6" cy="-32" r="2.5" fill="#b8c0cc">
<animate attributeName="cy" values="-32;-50;-32" dur="2.3s" repeatCount="indefinite"/> <animate attributeName="cy" values="-32;-50;-32" dur="2.3s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.5;0;0.5" dur="2.3s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.5;0;0.5" dur="2.3s" repeatCount="indefinite"/>
</circle> </circle>
</g> </g>
<text x="0" y="44" text-anchor="middle" font-size="9" fill="#ffaa44">{{ acid[eq.idx].temp.toFixed(0) }}°C · {{ acid[eq.idx].conc.toFixed(0) }}g/L</text> <text x="0" y="44" text-anchor="middle" font-size="9" fill="#c97e2a">{{ acid[eq.idx].temp.toFixed(0) }}°C · {{ acid[eq.idx].conc.toFixed(0) }}g/L</text>
</template> </template>
<!-- 漂洗段 --> <!-- 漂洗段 -->
<template v-else-if="eq.type==='rinse'"> <template v-else-if="eq.type==='rinse'">
<path d="M -34 -24 L 34 -24 L 30 26 L -30 26 Z" fill="#142a2e" stroke="#4080a0" stroke-width="2"/> <path d="M -34 -24 L 34 -24 L 30 26 L -30 26 Z" fill="#e2eef4" stroke="#5a9ec0" stroke-width="2"/>
<path d="M -32 -8 L 32 -8 L 29 24 L -29 24 Z" fill="#3aa0c8" opacity="0.55"> <path d="M -32 -8 L 32 -8 L 29 24 L -29 24 Z" fill="#3aa0c8" opacity="0.55">
<animate attributeName="opacity" values="0.5;0.7;0.5" dur="2.5s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.5;0.7;0.5" dur="2.5s" repeatCount="indefinite"/>
</path> </path>
@@ -162,8 +162,8 @@
<!-- 热风烘干段 --> <!-- 热风烘干段 -->
<template v-else-if="eq.type==='dryer'"> <template v-else-if="eq.type==='dryer'">
<rect x="-36" y="-26" width="72" height="52" fill="#2a2010" stroke="#a08030" stroke-width="2" rx="3"/> <rect x="-36" y="-26" width="72" height="52" fill="#f4ead2" stroke="#a08030" stroke-width="2" rx="3"/>
<g stroke="#ffaa00" stroke-width="1.6" fill="none"> <g stroke="#e89426" stroke-width="1.6" fill="none">
<path d="M -26 -12 q 4 -6 8 0 t 8 0 t 8 0 t 8 0 t 8 0"> <path d="M -26 -12 q 4 -6 8 0 t 8 0 t 8 0 t 8 0 t 8 0">
<animate attributeName="opacity" values="0.4;1;0.4" dur="1.4s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.4;1;0.4" dur="1.4s" repeatCount="indefinite"/>
</path> </path>
@@ -171,52 +171,52 @@
<animate attributeName="opacity" values="0.7;0.3;0.7" dur="1.4s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.7;0.3;0.7" dur="1.4s" repeatCount="indefinite"/>
</path> </path>
</g> </g>
<text y="44" text-anchor="middle" font-size="9" fill="#ffaa00">{{ dryer.t1.toFixed(0) }}/{{ dryer.t2.toFixed(0) }}/{{ dryer.t3.toFixed(0) }}°C</text> <text y="44" text-anchor="middle" font-size="9" fill="#e89426">{{ dryer.t1.toFixed(0) }}/{{ dryer.t2.toFixed(0) }}/{{ dryer.t3.toFixed(0) }}°C</text>
</template> </template>
<!-- 夹送辊 / 挤干辊 (两辊上下) --> <!-- 夹送辊 / 挤干辊 (两辊上下) -->
<template v-else-if="eq.type==='pinch'"> <template v-else-if="eq.type==='pinch'">
<rect x="-30" y="-26" width="60" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="1.5" rx="2"/> <rect x="-30" y="-26" width="60" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="1.5" rx="2"/>
<ellipse cx="0" cy="-12" rx="22" ry="6" fill="#2a3540" stroke="#7090a8" stroke-width="1.2"/> <ellipse cx="0" cy="-12" rx="22" ry="6" fill="#dde4ec" stroke="#8b97a7" stroke-width="1.2"/>
<ellipse cx="0" cy="12" rx="22" ry="6" fill="#2a3540" stroke="#7090a8" stroke-width="1.2"/> <ellipse cx="0" cy="12" rx="22" ry="6" fill="#dde4ec" stroke="#8b97a7" stroke-width="1.2"/>
<line x1="-22" y1="-12" x2="-22" y2="12" stroke="#5a6a75" stroke-width="1"/> <line x1="-22" y1="-12" x2="-22" y2="12" stroke="#9aa4b0" stroke-width="1"/>
<line x1="22" y1="-12" x2="22" y2="12" stroke="#5a6a75" stroke-width="1"/> <line x1="22" y1="-12" x2="22" y2="12" stroke="#9aa4b0" stroke-width="1"/>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">{{ eq.code }}</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">{{ eq.code }}</text>
</template> </template>
<!-- 活套坑 --> <!-- 活套坑 -->
<template v-else-if="eq.type==='loop'"> <template v-else-if="eq.type==='loop'">
<rect x="-40" y="-26" width="80" height="58" fill="#1a232c" stroke="#3a4a55" stroke-width="2" rx="3"/> <rect x="-40" y="-26" width="80" height="58" fill="#e9eef4" stroke="#aab4c2" stroke-width="2" rx="3"/>
<path d="M -32 -16 Q -20 32 -8 -16 Q 4 32 16 -16 Q 28 32 36 -16" stroke="#00c8ff" stroke-width="1.8" fill="none"> <path d="M -32 -16 Q -20 32 -8 -16 Q 4 32 16 -16 Q 28 32 36 -16" stroke="#c03639" stroke-width="1.8" fill="none">
<animate attributeName="opacity" values="0.6;1;0.6" dur="1.6s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.6;1;0.6" dur="1.6s" repeatCount="indefinite"/>
</path> </path>
<text y="48" text-anchor="middle" font-size="9" fill="#b8c4cf">LOOP</text> <text y="48" text-anchor="middle" font-size="9" fill="#5b6470">LOOP</text>
</template> </template>
<!-- 三辊张力装置 --> <!-- 三辊张力装置 -->
<template v-else-if="eq.type==='tension3'"> <template v-else-if="eq.type==='tension3'">
<rect x="-32" y="-26" width="64" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="1.5" rx="3"/> <rect x="-32" y="-26" width="64" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="1.5" rx="3"/>
<circle cx="-16" cy="-8" r="8" fill="#2a3540" stroke="#7090a8" stroke-width="1.2"/> <circle cx="-16" cy="-8" r="8" fill="#dde4ec" stroke="#8b97a7" stroke-width="1.2"/>
<circle cx="16" cy="-8" r="8" fill="#2a3540" stroke="#7090a8" stroke-width="1.2"/> <circle cx="16" cy="-8" r="8" fill="#dde4ec" stroke="#8b97a7" stroke-width="1.2"/>
<circle cx="0" cy="12" r="9" fill="#2a3540" stroke="#7090a8" stroke-width="1.2"/> <circle cx="0" cy="12" r="9" fill="#dde4ec" stroke="#8b97a7" stroke-width="1.2"/>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">TEN-3</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">TEN-3</text>
</template> </template>
<!-- 平整机 --> <!-- 平整机 -->
<template v-else-if="eq.type==='leveler'"> <template v-else-if="eq.type==='leveler'">
<rect x="-34" y="-26" width="68" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="2" rx="2"/> <rect x="-34" y="-26" width="68" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="2" rx="2"/>
<circle cx="0" cy="-14" r="11" fill="#3a4a55" stroke="#90a0b0" stroke-width="1.4"/> <circle cx="0" cy="-14" r="11" fill="#aab4c2" stroke="#8b97a7" stroke-width="1.4"/>
<circle cx="0" cy="14" r="11" fill="#3a4a55" stroke="#90a0b0" stroke-width="1.4"/> <circle cx="0" cy="14" r="11" fill="#aab4c2" stroke="#8b97a7" stroke-width="1.4"/>
<line x1="-28" y1="0" x2="-12" y2="0" stroke="#7090a8" stroke-width="1"/> <line x1="-28" y1="0" x2="-12" y2="0" stroke="#8b97a7" stroke-width="1"/>
<line x1="12" y1="0" x2="28" y2="0" stroke="#7090a8" stroke-width="1"/> <line x1="12" y1="0" x2="28" y2="0" stroke="#8b97a7" stroke-width="1"/>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">SPM</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">SPM</text>
</template> </template>
<!-- 静电涂油机 --> <!-- 静电涂油机 -->
<template v-else-if="eq.type==='oiler'"> <template v-else-if="eq.type==='oiler'">
<rect x="-26" y="-26" width="52" height="52" fill="#1a232c" stroke="#3a4a55" stroke-width="1.5" rx="2"/> <rect x="-26" y="-26" width="52" height="52" fill="#e9eef4" stroke="#aab4c2" stroke-width="1.5" rx="2"/>
<path d="M 0 -14 L -10 4 L 10 4 Z" fill="#3a4a55" stroke="#90a0b0" stroke-width="1"/> <path d="M 0 -14 L -10 4 L 10 4 Z" fill="#aab4c2" stroke="#8b97a7" stroke-width="1"/>
<g fill="#88ccff"> <g fill="#5a9bd4">
<circle cx="-6" cy="10" r="1.6"> <circle cx="-6" cy="10" r="1.6">
<animate attributeName="cy" values="6;22;6" dur="1.2s" repeatCount="indefinite"/> <animate attributeName="cy" values="6;22;6" dur="1.2s" repeatCount="indefinite"/>
</circle> </circle>
@@ -227,49 +227,49 @@
<animate attributeName="cy" values="6;22;6" dur="1.3s" repeatCount="indefinite"/> <animate attributeName="cy" values="6;22;6" dur="1.3s" repeatCount="indefinite"/>
</circle> </circle>
</g> </g>
<text y="44" text-anchor="middle" font-size="9" fill="#b8c4cf">EOL</text> <text y="44" text-anchor="middle" font-size="9" fill="#5b6470">EOL</text>
</template> </template>
<!-- 卷取机 --> <!-- 卷取机 -->
<template v-else-if="eq.type==='recoiler'"> <template v-else-if="eq.type==='recoiler'">
<circle r="38" fill="#1a232c" stroke="#3a4a55" stroke-width="2"/> <circle r="38" fill="#e9eef4" stroke="#aab4c2" stroke-width="2"/>
<circle r="22" fill="#0a1218" stroke="#5a6a75" stroke-width="1.5"/> <circle r="22" fill="#f2f5f9" stroke="#9aa4b0" stroke-width="1.5"/>
<circle r="8" fill="#2a3a48" stroke="#5a7090" stroke-width="1"/> <circle r="8" fill="#cdd6e0" stroke="#9aa4b0" stroke-width="1"/>
<path d="M-38 0 a38 38 0 0 1 76 0" stroke="#00c8ff" stroke-width="1" fill="none" opacity="0.5"> <path d="M-38 0 a38 38 0 0 1 76 0" stroke="#c03639" stroke-width="1" fill="none" opacity="0.5">
<animateTransform attributeName="transform" type="rotate" from="360" to="0" dur="3s" repeatCount="indefinite"/> <animateTransform attributeName="transform" type="rotate" from="360" to="0" dur="3s" repeatCount="indefinite"/>
</path> </path>
<text y="58" text-anchor="middle" font-size="10" fill="#b8c4cf">REC-1</text> <text y="58" text-anchor="middle" font-size="10" fill="#5b6470">REC-1</text>
</template> </template>
<!-- 当前设备高亮光环 --> <!-- 当前设备高亮光环 -->
<circle v-if="eq.k === currentEquipment.k" r="48" fill="none" stroke="#ffdd44" stroke-width="2" stroke-dasharray="4 4" opacity="0.7"> <circle v-if="eq.k === currentEquipment.k" r="48" fill="none" stroke="#c03639" stroke-width="2" stroke-dasharray="4 4" opacity="0.7">
<animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="6s" repeatCount="indefinite"/> <animateTransform attributeName="transform" type="rotate" from="0" to="360" dur="6s" repeatCount="indefinite"/>
</circle> </circle>
</g> </g>
<!-- 焊缝标记 --> <!-- 焊缝标记 -->
<g :transform="`translate(${weldX}, 185)`"> <g :transform="`translate(${weldX}, 185)`">
<circle r="11" fill="#ffdd00" opacity="0.35"> <circle r="11" fill="#ff8c1a" opacity="0.35">
<animate attributeName="r" values="9;22;9" dur="1.0s" repeatCount="indefinite"/> <animate attributeName="r" values="9;22;9" dur="1.0s" repeatCount="indefinite"/>
<animate attributeName="opacity" values="0.7;0.05;0.7" dur="1.0s" repeatCount="indefinite"/> <animate attributeName="opacity" values="0.7;0.05;0.7" dur="1.0s" repeatCount="indefinite"/>
</circle> </circle>
<circle r="6" fill="#ffee44"> <circle r="6" fill="#ff8c1a">
<animate attributeName="fill" values="#ffee44;#ff7700;#ffee44" dur="0.6s" repeatCount="indefinite"/> <animate attributeName="fill" values="#ff8c1a;#ff7700;#ff8c1a" dur="0.6s" repeatCount="indefinite"/>
</circle> </circle>
<text y="-18" text-anchor="middle" font-size="11" fill="#ffdd44" font-weight="bold">WELD</text> <text y="-18" text-anchor="middle" font-size="11" fill="#c03639" font-weight="bold">WELD</text>
</g> </g>
<!-- 图例 --> <!-- 图例 -->
<g transform="translate(20,290)" font-size="10" fill="#8b949e"> <g transform="translate(20,290)" font-size="10" fill="#606266">
<circle cx="6" cy="-3" r="5" fill="#ffee44"/> <circle cx="6" cy="-3" r="5" fill="#ff8c1a"/>
<text x="18" y="0">焊缝位置 {{ (weld.position * 100).toFixed(1) }}%</text> <text x="18" y="0">焊缝位置 {{ (weld.position * 100).toFixed(1) }}%</text>
<rect x="160" y="-7" width="12" height="8" fill="#ffaa44" opacity="0.5"/> <rect x="160" y="-7" width="12" height="8" fill="#ffaa44" opacity="0.5"/>
<text x="178" y="0">酸洗液</text> <text x="178" y="0">酸洗液</text>
<rect x="230" y="-7" width="12" height="8" fill="#3aa0c8" opacity="0.5"/> <rect x="230" y="-7" width="12" height="8" fill="#3aa0c8" opacity="0.5"/>
<text x="248" y="0">漂洗水</text> <text x="248" y="0">漂洗水</text>
<circle cx="310" cy="-3" r="5" fill="none" stroke="#ffdd44" stroke-width="1.5" stroke-dasharray="2 2"/> <circle cx="310" cy="-3" r="5" fill="none" stroke="#c03639" stroke-width="1.5" stroke-dasharray="2 2"/>
<text x="322" y="0">当前设备</text> <text x="322" y="0">当前设备</text>
<text x="420" y="0" fill="#aabbcc"> 带钢运行方向 </text> <text x="420" y="0" fill="#909399"> 带钢运行方向 </text>
</g> </g>
</svg> </svg>
</div> </div>
@@ -360,11 +360,11 @@ const EQUIPMENTS = [
] ]
const SECTION_COLORS = { const SECTION_COLORS = {
'入口段': '#5a8fc8', '入口段': '#4a7fbe',
'酸洗段': '#ffaa44', '酸洗段': '#d98a2a',
'清洗段': '#3aa0c8', '清洗段': '#2f93b8',
'烘干段': '#e87a3a', '烘干段': '#d96a2a',
'出口段': '#88c070', '出口段': '#5ba84e',
} }
// 默认辊缝值 (mm) // 默认辊缝值 (mm)
@@ -690,7 +690,7 @@ export default {
.status-item .kv-unit { color: $text-muted; font-size: 10px; margin-left: 2px; } .status-item .kv-unit { color: $text-muted; font-size: 10px; margin-left: 2px; }
.line-wrap { padding: 0; } .line-wrap { padding: 0; }
.line-body { padding: 6px 10px 10px; background: #0a1218; } .line-body { padding: 6px 10px 10px; background: #f2f5f9; }
.line-svg { width: 100%; height: 305px; display: block; } .line-svg { width: 100%; height: 305px; display: block; }
.split-row { display: grid; grid-template-columns: 1fr 3fr; gap: 10px; align-items: stretch; } .split-row { display: grid; grid-template-columns: 1fr 3fr; gap: 10px; align-items: stretch; }