Files

102 lines
13 KiB
Vue
Raw Permalink Normal View History

2026-01-16 22:04:12 +08:00
<template>
2026-09-03 19:56:19 +08:00
<div class="home-page">
<main class="home-shell">
<section class="hero-card">
<div class="hero-copy">
<span class="eyebrow">MRLEE · 生产运营中心</span>
<h1>让每一道工序,都清晰可追溯</h1>
<p>从订单录入、生产执行到异常闭环,集中掌握现场进度与质量状态。</p>
<div class="hero-actions">
<NuxtLink to="/produce/data-entry"><el-button type="primary" size="large"><el-icon><Plus /></el-icon>开始生产录入</el-button></NuxtLink>
<NuxtLink to="/produce/query"><el-button size="large" plain>查看订单全流程</el-button></NuxtLink>
</div>
2026-04-07 11:01:11 +08:00
</div>
2026-09-03 19:56:19 +08:00
<div class="hero-visual" aria-hidden="true">
<div class="orb orb-one"></div><div class="orb orb-two"></div>
<div class="hero-panel">
<div class="panel-topline"><span>今日生产概览</span><span class="live-dot">实时</span></div>
<strong>92.8<span>%</span></strong>
<div class="progress-track"><i style="width: 92.8%"></i></div>
<div class="panel-footer"><span>计划达成率</span><span>较昨日 +6.4%</span></div>
</div>
</div>
</section>
2026-04-07 11:01:11 +08:00
2026-09-03 19:56:19 +08:00
<section class="metric-grid" aria-label="生产指标">
<article v-for="metric in metrics" :key="metric.label" class="metric-card">
<div class="metric-icon" :class="metric.tone"><Icon :icon="metric.icon" /></div>
<div class="metric-content"><span>{{ metric.label }}</span><strong>{{ metric.value }}</strong><small :class="metric.trendTone">{{ metric.trend }}</small></div>
</article>
</section>
<section class="section-block">
<div class="section-heading"><div><span class="section-kicker">QUICK ACCESS</span><h2>快捷工作入口</h2></div><span class="section-hint">常用功能,一键直达</span></div>
<div class="quick-grid">
<NuxtLink v-for="item in quickLinks" :key="item.title" :to="item.to" class="quick-card">
<div class="quick-icon" :class="item.tone"><Icon :icon="item.icon" /></div>
<div><strong>{{ item.title }}</strong><span>{{ item.description }}</span></div><el-icon class="arrow"><ArrowRight /></el-icon>
</NuxtLink>
</div>
</section>
<section class="dashboard-grid">
<article class="surface-card process-card">
<div class="card-heading"><div><span class="section-kicker">ORDER FLOW</span><h2>订单流程进度</h2></div><NuxtLink to="/produce/query">查看全部 <el-icon><ArrowRight /></el-icon></NuxtLink></div>
<div class="process-list"><div v-for="order in orders" :key="order.number" class="process-row"><div class="order-title"><strong>{{ order.number }}</strong><span>{{ order.product }}</span></div><div class="process-track"><i :style="{ width: `${order.progress}%` }"></i></div><div class="process-meta"><span>{{ order.stage }}</span><b>{{ order.progress }}%</b></div></div></div>
</article>
<article class="surface-card activity-card">
<div class="card-heading"><div><span class="section-kicker">RECENT ACTIVITY</span><h2>现场动态</h2></div><NuxtLink to="/produce/query">更多 <el-icon><ArrowRight /></el-icon></NuxtLink></div>
<div class="activity-list"><div v-for="activity in activities" :key="activity.time + activity.title" class="activity-row"><span class="activity-dot" :class="activity.tone"></span><div><strong>{{ activity.title }}</strong><span>{{ activity.description }}</span></div><time>{{ activity.time }}</time></div></div>
</article>
</section>
<section class="insight-banner"><div><span class="section-kicker">DATA INSIGHT</span><h2>用数据发现现场的下一步</h2><p>按日、按月查看工序与步骤统计,及时识别瓶颈并优化产能。</p></div><NuxtLink to="/produce/statistics/monthly"><el-button type="primary">进入生产统计 <el-icon><ArrowRight /></el-icon></el-button></NuxtLink></section>
</main>
<Advertisement type="float" position="bottom" :offset="0" :limit="1" :closable="true" />
</div>
2026-01-16 22:04:12 +08:00
</template>
2026-09-03 19:56:19 +08:00
<script setup lang="ts">
import { ArrowRight, Plus } from '@element-plus/icons-vue'
import { Icon } from '~/components/icon'
import Advertisement from '~/components/advertisement/index.vue'
const metrics = [
{ label: '今日完成订单', value: '128', trend: '+12.6% 较昨日', icon: 'ri:archive-stack-line', tone: 'blue', trendTone: 'up' },
{ label: '生产中订单', value: '36', trend: '进行中', icon: 'ri:loader-4-line', tone: 'violet', trendTone: 'neutral' },
{ label: '待处理异常', value: '08', trend: '需及时关注', icon: 'ri:error-warning-line', tone: 'orange', trendTone: 'warning' },
{ label: '设备运行率', value: '96.4%', trend: '+2.1% 较昨日', icon: 'ri:settings-5-line', tone: 'green', trendTone: 'up' },
]
const quickLinks = [
{ title: '生产录入', description: '录入订单与生产数据', to: '/produce/data-entry', icon: 'ri:scan-2-line', tone: 'blue' },
{ title: '异常提报', description: '快速记录现场异常', to: '/produce/exception', icon: 'ri:alarm-warning-line', tone: 'orange' },
{ title: '维修记录', description: '跟进维修与备件使用', to: '/produce/repair', icon: 'ri:tools-line', tone: 'violet' },
{ title: '订单查询', description: '追踪订单全流程', to: '/produce/query', icon: 'ri:search-eye-line', tone: 'green' },
]
const orders = [
{ number: 'MO-20260902-018', product: '精密控制模块', stage: '装配工序', progress: 86 },
{ number: 'MO-20260902-021', product: '智能传感器组件', stage: '功能测试', progress: 64 },
{ number: 'MO-20260902-024', product: '工业连接器', stage: '来料检验', progress: 32 },
]
const activities = [
{ title: '异常提报已处理', description: '订单 MO-20260902-018 · 贴合不良', time: '10:42', tone: 'green' },
{ title: '维修记录已提交', description: '设备 SMT-03 · 更换送料器', time: '10:18', tone: 'violet' },
{ title: '生产录入完成', description: '订单 MO-20260902-021 · 功能测试', time: '09:56', tone: 'blue' },
{ title: '新异常待确认', description: '订单 MO-20260902-024 · 外观瑕疵', time: '09:31', tone: 'orange' },
]
2026-01-16 22:04:12 +08:00
</script>
<style lang="scss" scoped>
2026-09-03 19:56:19 +08:00
.home-page { min-height: 100%; background: #f5f7fb; color: #18243a; }
.home-shell { max-width: 1440px; margin: 0 auto; padding: 32px 40px 72px; }
.hero-card { position: relative; display: flex; min-height: 330px; overflow: hidden; border-radius: 24px; background: linear-gradient(120deg, #132d5b 0%, #1d4c87 60%, #2875a7 100%); color: #fff; box-shadow: 0 16px 40px rgba(21, 52, 97, .16); }
.hero-copy { position: relative; z-index: 1; max-width: 650px; padding: 52px 56px; }.eyebrow, .section-kicker { font-size: 11px; letter-spacing: .18em; font-weight: 700; color: #78c8ff; }.hero-copy h1 { margin: 18px 0 14px; font-size: clamp(30px, 4vw, 48px); line-height: 1.15; letter-spacing: -.03em; }.hero-copy p { max-width: 510px; margin: 0; color: rgba(255,255,255,.72); font-size: 16px; line-height: 1.8; }.hero-actions { display: flex; gap: 12px; margin-top: 32px; }.hero-actions :deep(.el-button) { border-radius: 10px; padding: 0 20px; }.hero-actions :deep(.el-button--default) { color: #fff; border-color: rgba(255,255,255,.28); background: rgba(255,255,255,.08); }
.hero-visual { position: absolute; inset: 0 0 0 54%; }.orb { position: absolute; border-radius: 50%; }.orb-one { width: 330px; height: 330px; top: -70px; right: 70px; background: rgba(121, 213, 255, .14); }.orb-two { width: 220px; height: 220px; right: -30px; bottom: -80px; background: rgba(255, 255, 255, .1); }.hero-panel { position: absolute; top: 76px; right: 12%; width: 260px; padding: 24px; border: 1px solid rgba(255,255,255,.16); border-radius: 18px; background: rgba(8, 33, 75, .42); backdrop-filter: blur(12px); }.panel-topline, .panel-footer { display: flex; justify-content: space-between; align-items: center; color: rgba(255,255,255,.66); font-size: 12px; }.live-dot { color: #8df0bb; }.live-dot::before { content: ''; display: inline-block; width: 6px; height: 6px; margin-right: 5px; border-radius: 50%; background: #62e7a4; }.hero-panel strong { display: block; margin: 24px 0 14px; font-size: 52px; letter-spacing: -.06em; }.hero-panel strong span { margin-left: 3px; font-size: 24px; }.progress-track { height: 7px; overflow: hidden; border-radius: 5px; background: rgba(255,255,255,.14); }.progress-track i { display: block; height: 100%; border-radius: inherit; background: #75d5ff; }.panel-footer { margin-top: 12px; }.panel-footer span:last-child { color: #8df0bb; }
.metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 18px; }.metric-card, .quick-card, .surface-card, .insight-banner { border: 1px solid #e7ebf3; background: #fff; box-shadow: 0 5px 18px rgba(28, 50, 86, .04); }.metric-card { display: flex; align-items: center; gap: 14px; padding: 20px; border-radius: 16px; }.metric-icon, .quick-icon { display: grid; place-items: center; flex: 0 0 auto; border-radius: 12px; }.metric-icon { width: 44px; height: 44px; font-size: 21px; }.metric-content { display: grid; gap: 4px; }.metric-content > span { color: #8490a5; font-size: 12px; }.metric-content strong { font-size: 26px; line-height: 1; letter-spacing: -.04em; }.metric-content small { font-size: 11px; }.up { color: #20aa6a; }.warning { color: #e88b2b; }.neutral { color: #8792a8; }.blue { color: #3a86f7; background: #eaf3ff; }.violet { color: #8063e8; background: #f0edff; }.orange { color: #e99532; background: #fff2df; }.green { color: #24a873; background: #e6f8f0; }
.section-block { margin-top: 42px; }.section-heading, .card-heading { display: flex; align-items: end; justify-content: space-between; }.section-heading h2, .card-heading h2, .insight-banner h2 { margin: 7px 0 0; font-size: 22px; letter-spacing: -.02em; }.section-hint { color: #98a3b5; font-size: 13px; }.quick-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-top: 18px; }.quick-card { position: relative; display: flex; align-items: center; gap: 14px; padding: 18px; border-radius: 15px; transition: transform .2s ease, box-shadow .2s ease; }.quick-card:hover { transform: translateY(-3px); box-shadow: 0 12px 26px rgba(28, 50, 86, .1); }.quick-icon { width: 42px; height: 42px; font-size: 20px; }.quick-card strong, .quick-card span { display: block; }.quick-card strong { font-size: 15px; }.quick-card span { margin-top: 5px; color: #8a95a8; font-size: 12px; }.arrow { margin-left: auto; color: #aab4c4; }
.dashboard-grid { display: grid; grid-template-columns: 1.1fr .9fr; gap: 16px; margin-top: 18px; }.surface-card { padding: 24px; border-radius: 16px; }.card-heading a { display: inline-flex; align-items: center; gap: 3px; color: #4b8bf5; font-size: 12px; }.process-list, .activity-list { margin-top: 22px; }.process-row + .process-row { margin-top: 22px; }.order-title { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; }.order-title strong { font-size: 13px; }.order-title span { color: #8a95a8; font-size: 12px; }.process-track { height: 8px; overflow: hidden; border-radius: 6px; background: #edf1f6; }.process-track i { display: block; height: 100%; border-radius: inherit; background: linear-gradient(90deg, #4b8bf5, #71c9f5); }.process-meta { display: flex; justify-content: space-between; margin-top: 7px; color: #8a95a8; font-size: 11px; }.process-meta b { color: #4b8bf5; }.activity-row { display: flex; align-items: flex-start; gap: 11px; }.activity-row + .activity-row { margin-top: 19px; }.activity-dot { width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; box-shadow: 0 0 0 4px currentColor; opacity: .75; }.activity-row div { flex: 1; }.activity-row strong, .activity-row span { display: block; }.activity-row strong { font-size: 13px; }.activity-row span { margin-top: 4px; color: #8a95a8; font-size: 12px; }.activity-row time { color: #a5afbd; font-size: 11px; }
.insight-banner { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-top: 18px; padding: 28px 32px; border-radius: 16px; background: linear-gradient(100deg, #f2f7ff, #fbfcff); }.insight-banner p { margin: 9px 0 0; color: #8490a5; font-size: 13px; }.insight-banner :deep(.el-button) { border-radius: 9px; }
@media (max-width: 1100px) { .home-shell { padding: 24px; }.hero-card { min-height: 360px; }.hero-visual { opacity: .75; right: -80px; }.metric-grid, .quick-grid { grid-template-columns: repeat(2, 1fr); }.dashboard-grid { grid-template-columns: 1fr; } }
@media (max-width: 640px) { .home-shell { padding: 16px 12px 48px; }.hero-card { min-height: 440px; }.hero-copy { padding: 34px 26px; }.hero-copy h1 { font-size: 32px; }.hero-copy p { font-size: 14px; }.hero-actions { flex-direction: column; align-items: flex-start; }.hero-visual { inset: auto 0 20px; height: 150px; opacity: .9; }.hero-panel { top: 10px; right: 26px; width: 220px; padding: 17px; }.hero-panel strong { margin: 13px 0 9px; font-size: 38px; }.metric-grid, .quick-grid { grid-template-columns: 1fr; }.metric-card { padding: 16px; }.section-block { margin-top: 32px; }.section-heading h2, .card-heading h2 { font-size: 19px; }.section-hint { display: none; }.surface-card { padding: 18px; }.insight-banner { align-items: flex-start; flex-direction: column; padding: 22px; } }
</style>