feat: 五项目业务实现并对接完成

- MES(B): 工单/BOM/备料/工序字典/PLC下发/拧紧/扫码报工/半成品/AGV/追溯逻辑,WMS与海康RCS客户端,看板Redis缓存API(概览/设备/进度/报警/趋势)+SSE
- WMS(C): JWT滑动续签、Excel导入、盘点、内部API、种子数据、独立Postgres配置
- WMS客户端(E): Go网关8891反向代理+内嵌Vue3十页
- 工位终端(D): SQLite本地缓存+模拟拧紧源+内嵌Vue3页面
- Dashboard(A): 看板数据改接MES内部缓存API,SSE实时刷新+vite代理
- 清理各项目球形磨遗留代码,新增部署手册.md
This commit is contained in:
SunYF
2026-08-27 19:50:57 +08:00
parent c85c3bd6f1
commit a2afd2f6dc
335 changed files with 87495 additions and 7357 deletions
@@ -0,0 +1,68 @@
<script setup>
import { onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { CircleCheck, Download, List, Monitor, Search, Upload, Box, Tickets } from '@element-plus/icons-vue'
import request from '../utils/request'
import { fmtNum } from '../utils/format'
const router = useRouter()
const overview = ref({})
const loaded = ref(false)
async function load() {
overview.value = await request.get('/display/overview')
loaded.value = true
}
onMounted(load)
const cards = [
{ key: 'totalQty', label: '在库总量' },
{ key: 'lockedQty', label: '锁定量' },
{ key: 'snInStock', label: 'SN 在库数' },
{ key: 'semiInStock', label: '半成品在库' },
{ key: 'packageCount', label: '包装箱数' },
{ key: 'batchCount', label: '批次数' },
{ key: 'inToday', label: '今日入库单' },
{ key: 'outToday', label: '今日出库单' }
]
const entries = [
{ path: '/inbound', title: '入库管理', icon: Download },
{ path: '/outbound', title: '备料出库', icon: Upload },
{ path: '/inventory', title: '库存查询', icon: Search },
{ path: '/inspection', title: '质量检验', icon: CircleCheck },
{ path: '/stocktake', title: '库存盘点', icon: List },
{ path: '/package', title: '包装绑定', icon: Box },
{ path: '/ledger', title: '物料台账', icon: Tickets },
{ path: '/display', title: '免登录大屏', icon: Monitor }
]
</script>
<template>
<div>
<el-row :gutter="12">
<el-col v-for="c in cards" :key="c.key" :xs="12" :sm="8" :md="6" style="margin-bottom:12px">
<el-card shadow="hover">
<div class="kpi-label">{{ c.label }}</div>
<div class="kpi-value">{{ loaded ? fmtNum(overview[c.key]) : '—' }}</div>
</el-card>
</el-col>
</el-row>
<el-card shadow="never" header="快捷入口">
<div class="entries">
<el-button v-for="e in entries" :key="e.path" size="large"
@click="router.push(e.path)">
<el-icon style="margin-right:6px"><component :is="e.icon" /></el-icon>{{ e.title }}
</el-button>
</div>
</el-card>
</div>
</template>
<style scoped>
.kpi-label { color: #909399; font-size: 13px; }
.kpi-value { font-size: 26px; font-weight: 700; margin-top: 4px; color: #303133; }
.entries { display: flex; flex-wrap: wrap; gap: 10px; }
</style>