| | |
| | | <script lang="ts" setup> |
| | | import type { MesBagCodeHomeApi } from '#/api/mes/bag-code-home'; |
| | | import type { MesTraceCrossRegionApi } from '#/api/mes/trace-cross-region'; |
| | | |
| | | import { onMounted, ref } from 'vue'; |
| | | import { useRouter } from 'vue-router'; |
| | |
| | | import { Col, Row, message } from 'ant-design-vue'; |
| | | |
| | | import { getBagCodeHomeSummary } from '#/api/mes/bag-code-home'; |
| | | import { getTraceCrossRegionSummary } from '#/api/mes/trace-cross-region'; |
| | | import { getTraceConsumerScanSummary } from '#/api/mes/trace-consumer-scan'; |
| | | |
| | | import { defaultSummary } from './data'; |
| | | import BagCodeCards from './modules/bag-code-cards.vue'; |
| | | import AlertPanel from './modules/alert-panel.vue'; |
| | | import BagCodeStatusChart from './modules/bag-code-status-chart.vue'; |
| | | import BasicCards from './modules/basic-cards.vue'; |
| | | import BatchStatusChart from './modules/batch-status-chart.vue'; |
| | | import BusinessFlow from './modules/business-flow.vue'; |
| | | import KpiCards from './modules/kpi-cards.vue'; |
| | | import ScanRegionChart from './modules/scan-region-chart.vue'; |
| | | import Shortcuts from './modules/shortcuts.vue'; |
| | | import TrendChart from './modules/trend-chart.vue'; |
| | | |
| | |
| | | |
| | | const router = useRouter(); |
| | | const summary = ref<MesBagCodeHomeApi.Summary>(defaultSummary); // 首页汇总统计 |
| | | const crossRegion = ref<MesTraceCrossRegionApi.Summary>({}); // 窜货预警汇总 |
| | | const scanTotal = ref(0); // 累计扫码次数 |
| | | |
| | | /** 跳转到目标页面(按路由 name,未加载时提示) */ |
| | | async function handleNavigate(name: string) { |
| | |
| | | } |
| | | } |
| | | |
| | | /** 加载首页汇总统计 */ |
| | | /** 加载首页汇总统计、窜货预警汇总、消费者扫码汇总 */ |
| | | async function loadSummary() { |
| | | summary.value = await getBagCodeHomeSummary(); |
| | | crossRegion.value = await getTraceCrossRegionSummary(); |
| | | const scan = await getTraceConsumerScanSummary(); |
| | | scanTotal.value = scan.total ?? 0; |
| | | } |
| | | |
| | | onMounted(() => { |
| | |
| | | |
| | | <template> |
| | | <Page> |
| | | <!-- 第一行:基础数据卡片 --> |
| | | <BasicCards :summary="summary" class="mb-2" @navigate="handleNavigate" /> |
| | | <div class="agri-dashboard"> |
| | | <!-- 第一行:业务全链路 --> |
| | | <BusinessFlow |
| | | :cross-region-total="crossRegion.total ?? 0" |
| | | :scan-total="scanTotal" |
| | | :summary="summary" |
| | | @navigate="handleNavigate" |
| | | /> |
| | | |
| | | <!-- 第二行:一袋一码卡片 --> |
| | | <BagCodeCards :summary="summary" class="mb-4" @navigate="handleNavigate" /> |
| | | <!-- 第二行:全链路 KPI 总览 --> |
| | | <KpiCards :scan-total="scanTotal" :summary="summary" @navigate="handleNavigate" /> |
| | | |
| | | <!-- 第三行:袋码趋势 + 批次/袋码状态分布 --> |
| | | <!-- 第三行:袋码生成趋势 + 消费者扫码地区分布 --> |
| | | <Row :gutter="16" class="mb-4"> |
| | | <Col :lg="12" :md="24" :sm="24" :xl="12" :xs="24" class="mb-4"> |
| | | <TrendChart /> |
| | | </Col> |
| | | <Col :lg="12" :md="24" :sm="24" :xl="12" :xs="24" class="mb-4"> |
| | | <ScanRegionChart /> |
| | | </Col> |
| | | </Row> |
| | | |
| | | <!-- 第四行:批次/袋码状态分布 + 待办与预警 --> |
| | | <Row :gutter="16" class="mb-4"> |
| | | <Col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" class="mb-4"> |
| | | <BatchStatusChart :list="summary.batchStatusList" /> |
| | | </Col> |
| | | <Col :lg="6" :md="12" :sm="24" :xl="6" :xs="24" class="mb-4"> |
| | | <BagCodeStatusChart :list="summary.bagCodeStatusList" /> |
| | | </Col> |
| | | <Col :lg="12" :md="24" :sm="24" :xl="12" :xs="24" class="mb-4"> |
| | | <AlertPanel :cross-region="crossRegion" :summary="summary" @navigate="handleNavigate" /> |
| | | </Col> |
| | | </Row> |
| | | |
| | | <!-- 第四行:快捷入口 --> |
| | | <!-- 第五行:按业务域分组的快捷入口 --> |
| | | <Shortcuts @navigate="handleNavigate" /> |
| | | </div> |
| | | </Page> |
| | | </template> |
| | | |
| | | <style lang="scss"> |
| | | /* 农业翠绿玻璃拟态首页主题 —— 对齐登录页 `agri-auth` 色调,采用更清淡的浅色玻璃与高级渐变 */ |
| | | .agri-dashboard { |
| | | position: relative; |
| | | padding: 1rem; |
| | | border-radius: 1.25rem; |
| | | background: |
| | | radial-gradient(900px 480px at 8% 0%, rgba(110, 231, 183, 0.42), transparent 55%), |
| | | radial-gradient(800px 420px at 96% 100%, rgba(6, 95, 70, 0.12), transparent 60%), |
| | | linear-gradient(160deg, #f0fdf9 0%, #dcf7ea 50%, #c7f0d9 100%); |
| | | isolation: isolate; |
| | | color: #0f5c49; |
| | | |
| | | /* 高级白玻璃卡片:内描边 + 磨砂 + 柔和层次阴影 */ |
| | | .ant-card { |
| | | color: #135746; |
| | | background: linear-gradient(160deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.55)); |
| | | border: 1px solid rgba(16, 185, 129, 0.18); |
| | | box-shadow: |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.8), |
| | | 0 12px 30px rgba(6, 78, 59, 0.08); |
| | | backdrop-filter: blur(14px); |
| | | } |
| | | |
| | | .ant-card-head { |
| | | border-bottom-color: rgba(16, 185, 129, 0.14); |
| | | } |
| | | |
| | | .ant-card-head-title, |
| | | .ant-card-head-title .anticon { |
| | | color: #0f766e; |
| | | } |
| | | |
| | | .ant-card:hover { |
| | | box-shadow: |
| | | inset 0 1px 0 rgba(255, 255, 255, 0.9), |
| | | 0 18px 44px rgba(6, 78, 59, 0.14); |
| | | border-color: rgba(16, 185, 129, 0.34); |
| | | } |
| | | |
| | | /* 覆盖 App 浅色主题的语义色:统一为柔和墨绿 */ |
| | | .text-muted-foreground { |
| | | color: rgba(15, 78, 60, 0.62); |
| | | } |
| | | |
| | | .text-2xl.font-bold { |
| | | color: #047857; |
| | | } |
| | | } |
| | | </style> |