8 天以前 fdd158306bf6dc3584f5110a385323f4a8dfb463
src/views/dashboard/bagCodeHome/index.vue
@@ -1,5 +1,6 @@
<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';
@@ -9,12 +10,16 @@
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';
@@ -22,6 +27,8 @@
const router = useRouter();
const summary = ref<MesBagCodeHomeApi.Summary>(defaultSummary); // 首页汇总统计
const crossRegion = ref<MesTraceCrossRegionApi.Summary>({}); // 窜货预警汇总
const scanTotal = ref(0); // 累计扫码次数
/** 跳转到目标页面(按路由 name,未加载时提示) */
async function handleNavigate(name: string) {
@@ -32,9 +39,12 @@
  }
}
/** 加载首页汇总统计 */
/** 加载首页汇总统计、窜货预警汇总、消费者扫码汇总 */
async function loadSummary() {
  summary.value = await getBagCodeHomeSummary();
  crossRegion.value = await getTraceCrossRegionSummary();
  const scan = await getTraceConsumerScanSummary();
  scanTotal.value = scan.total ?? 0;
}
onMounted(() => {
@@ -44,26 +54,94 @@
<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>