From 9c8d2858d15d87ea0b47e7521061e2b6c3039a43 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 09 十月 2026 14:50:49 +0800
Subject: [PATCH] feat: 仓储/售后物料改用 MDM 选择器;首页隐藏生产模块并恢复质量/设备卡片;产品入库行去除库存记录
---
src/views/dashboard/analytics/index.vue | 148 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 115 insertions(+), 33 deletions(-)
diff --git a/src/views/dashboard/analytics/index.vue b/src/views/dashboard/analytics/index.vue
index 13794de..df4d405 100644
--- a/src/views/dashboard/analytics/index.vue
+++ b/src/views/dashboard/analytics/index.vue
@@ -1,25 +1,31 @@
<script lang="ts" setup>
+import type { PageParam, PageResult } from '@vben/request';
+
+import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order';
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
+import type { MesHomeApi } from '#/api/mes/home';
+
import { computed, onMounted, ref } from 'vue';
import { useRouter } from 'vue-router';
import { Page } from '@vben/common-ui';
-import { Card, Col, Row } from 'ant-design-vue';
+import { Col, Row } from 'ant-design-vue';
+import { getPurchaseOrderPage } from '#/api/erp/purchase/order';
+import { getSaleOrderPage } from '#/api/erp/sale/order';
import { getHomeSummary } from '#/api/mes/home';
+import SummaryCard from '#/views/erp/home/modules/summary-card.vue';
+
import { defaultSummary } from './data';
-import AiInsights from './modules/ai-insights.vue';
-import AlertPanel from './modules/alert-panel.vue';
import BizCards from './modules/biz-cards.vue';
import KpiCards from './modules/kpi-cards.vue';
-import ProductionTrend from './modules/production-trend.vue';
import QuickActions from './modules/quick-actions.vue';
defineOptions({ name: 'DashboardAnalytics' });
const router = useRouter();
-const summary = ref(defaultSummary);
const greeting = computed(() => {
const hour = new Date().getHours();
@@ -41,12 +47,104 @@
router.push({ name });
}
-async function loadSummary() {
- summary.value = await getHomeSummary();
+interface PriceSummary {
+ monthPrice: number;
+ todayPrice: number;
+ yearPrice: number;
+ yesterdayPrice: number;
+}
+
+const saleSummary = ref<PriceSummary>();
+const purchaseSummary = ref<PriceSummary>();
+const homeSummary = ref<MesHomeApi.Summary>(defaultSummary);
+
+const PAGE_SIZE = 200;
+
+/** 閫愰〉鎷夊彇鍏ㄩ儴鍒嗛〉鏁版嵁锛堝悗绔� pageSize 涓婇檺 200锛� */
+async function fetchAllPages<T>(
+ fetcher: (params: PageParam) => Promise<PageResult<T>>,
+): Promise<T[]> {
+ const first = await fetcher({ pageNo: 1, pageSize: PAGE_SIZE });
+ const list: T[] = [...(first.list ?? [])];
+ const total = first.total ?? list.length;
+ const pageCount = Math.ceil(total / PAGE_SIZE);
+ for (let pageNo = 2; pageNo <= pageCount; pageNo++) {
+ const res = await fetcher({ pageNo, pageSize: PAGE_SIZE });
+ list.push(...(res.list ?? []));
+ }
+ return list;
+}
+
+function toDayStr(time?: Date | string): string {
+ if (!time) return '';
+ if (typeof time === 'string') return time.slice(0, 10);
+ const d = new Date(time);
+ if (Number.isNaN(d.getTime())) return '';
+ const m = String(d.getMonth() + 1).padStart(2, '0');
+ const day = String(d.getDate()).padStart(2, '0');
+ return `${d.getFullYear()}-${m}-${day}`;
+}
+
+/** 鎸夎鍗曟椂闂磋仛鍚堥噾棰濓細浠婃棩 / 鏄ㄦ棩 / 鏈湀 / 浠婂勾 */
+function aggregatePrice(
+ orders: Array<{ orderTime?: Date | string; totalPrice?: number }>,
+): PriceSummary {
+ const now = new Date();
+ const today = toDayStr(now);
+ const yesterdayDate = new Date(now);
+ yesterdayDate.setDate(now.getDate() - 1);
+ const yesterday = toDayStr(yesterdayDate);
+ const month = today.slice(0, 7);
+ const year = today.slice(0, 4);
+
+ const summary: PriceSummary = {
+ monthPrice: 0,
+ todayPrice: 0,
+ yearPrice: 0,
+ yesterdayPrice: 0,
+ };
+ for (const order of orders) {
+ const day = toDayStr(order.orderTime);
+ if (!day) continue;
+ const price = order.totalPrice ?? 0;
+ if (day === today) summary.todayPrice += price;
+ if (day === yesterday) summary.yesterdayPrice += price;
+ if (day.startsWith(month)) summary.monthPrice += price;
+ if (day.startsWith(year)) summary.yearPrice += price;
+ }
+ return summary;
+}
+
+async function loadStatistics() {
+ try {
+ const saleOrders = await fetchAllPages<ErpSaleOrderApi.SaleOrder>(
+ getSaleOrderPage,
+ );
+ saleSummary.value = aggregatePrice(saleOrders);
+ } catch {
+ /* 鎺ュ彛寮傚父鎴栨棤鏉冮檺 */
+ }
+ try {
+ const purchaseOrders = await fetchAllPages<ErpPurchaseOrderApi.PurchaseOrder>(
+ getPurchaseOrderPage,
+ );
+ purchaseSummary.value = aggregatePrice(purchaseOrders);
+ } catch {
+ /* 鎺ュ彛寮傚父鎴栨棤鏉冮檺 */
+ }
+}
+
+async function loadHomeSummary() {
+ try {
+ homeSummary.value = await getHomeSummary();
+ } catch {
+ /* 鎺ュ彛寮傚父鎴栨棤鏉冮檺 */
+ }
}
onMounted(() => {
- loadSummary();
+ loadHomeSummary();
+ loadStatistics();
});
</script>
@@ -71,35 +169,19 @@
</div>
</div>
- <!-- MES 鐢熶骇 KPI -->
- <KpiCards :summary="summary" @navigate="handleNavigate" />
+ <!-- 璐ㄩ噺 / 璁惧 KPI -->
+ <KpiCards :summary="homeSummary" @navigate="handleNavigate" />
<!-- ERP/WMS/BPM 缁忚惀 KPI -->
<BizCards @navigate="handleNavigate" />
- <!-- AI 鏅鸿兘鍒嗘瀽 -->
- <AiInsights
- :active-order-count="summary.workOrderActiveCount"
- @navigate="handleNavigate"
- />
-
- <!-- 鐢熶骇瓒嬪娍 + 棰勮闈㈡澘 -->
- <Row :gutter="16" class="mb-4">
- <Col :lg="14" :md="24" :sm="24" :xl="14" :xs="24" class="mb-4">
- <div class="glass-card rounded-2xl p-5">
- <h3 class="mb-4 text-base font-semibold text-gray-800 dark:text-gray-100">
- 鐢熶骇瓒嬪娍锛堣繎7澶╋級
- </h3>
- <ProductionTrend />
- </div>
- </Col>
- <Col :lg="10" :md="24" :sm="24" :xl="10" :xs="24" class="mb-4">
- <AlertPanel
- :repair-active-count="summary.repairActiveCount"
- @navigate="handleNavigate"
- />
- </Col>
- </Row>
+ <!-- 閿�鍞� / 閲囪喘 閲戦姒傝 -->
+ <div class="mb-4">
+ <SummaryCard
+ :purchase-summary="purchaseSummary"
+ :sale-summary="saleSummary"
+ />
+ </div>
<!-- 蹇嵎鎿嶄綔 -->
<Row :gutter="16" class="mb-4">
--
Gitblit v1.9.3