From 1cf342fa23a6c34bd9dd1ff4e416cd255c044fdd Mon Sep 17 00:00:00 2001
From: yyb <995253665@qq.com>
Date: 星期四, 02 四月 2026 11:41:17 +0800
Subject: [PATCH] Merge branch 'dev_银川_中盛建材' of http://114.132.189.42:9002/r/product-inventory-management into dev_银川_中盛建材
---
src/views/reportAnalysis/salesStatistics/index.vue | 2156 ++++++++++++++++++++++++++++++++++++++++++++++-------------
1 files changed, 1,667 insertions(+), 489 deletions(-)
diff --git a/src/views/reportAnalysis/salesStatistics/index.vue b/src/views/reportAnalysis/salesStatistics/index.vue
index c9412c1..f500213 100644
--- a/src/views/reportAnalysis/salesStatistics/index.vue
+++ b/src/views/reportAnalysis/salesStatistics/index.vue
@@ -1,169 +1,268 @@
<template>
- <div ref="screenRoot" class="sales-statistics-container" :class="{ 'is-fullscreen': isFullscreen }">
+ <div ref="screenRoot"
+ class="sales-statistics-container"
+ :class="{ 'is-fullscreen': isFullscreen }">
<div class="bi-bg"></div>
-
<div class="bi-topbar">
- <img class="bi-topbar-title-bg" src="@/assets/BI/biaoti.png" alt="閿�鍞湅鏉跨粺璁�" />
+ <img class="bi-topbar-title-bg"
+ src="@/assets/BI/biaoti.png"
+ alt="閿�鍞粺璁$湅鏉�" />
<div class="bi-topbar-content">
<div class="bi-topbar-left">
- <span class="status-sun">鈽�</span>
+ <button class="fullscreen-btn"
+ @click="toggleFullscreen"
+ :title="isFullscreen ? '閫�鍑哄叏灞�' : '鍏ㄥ睆鏄剧ず'">
+ <svg v-if="!isFullscreen"
+ width="1.6vh"
+ height="1.6vh"
+ viewBox="0 0 24 24"
+ fill="none"
+ stroke="currentColor"
+ stroke-width="2">
+ <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3" />
+ </svg>
+ <svg v-else
+ width="1.6vh"
+ height="1.6vh"
+ viewBox="0 0 24 24"
+ fill="none"
+ stroke="currentColor"
+ stroke-width="2">
+ <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />
+ </svg>
+ </button>
+ <!-- <span class="status-sun">鈽�</span>
<span>26鈩�</span>
- <span class="bi-topbar-sep">婀垮害锛�1</span>
+ <span class="bi-topbar-sep">婀垮害锛�1</span> -->
</div>
- <div class="bi-topbar-title">閿�鍞湅鏉跨粺璁�</div>
+ <div class="bi-topbar-title">閿�鍞粺璁$湅鏉�</div>
<div class="bi-topbar-meta">
<span class="bi-topbar-time">{{ currentTime }}</span>
<span class="bi-topbar-sep">|</span>
<span class="bi-topbar-date">{{ currentDateText }}</span>
</div>
- <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '閫�鍑哄叏灞�' : '鍏ㄥ睆鏄剧ず'">
- <svg v-if="!isFullscreen" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"/>
- </svg>
- <svg v-else width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
- <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/>
- </svg>
- </button>
</div>
</div>
-
<div class="bi-dashboard-grid">
<!-- 宸︿笂锛氶攢閲忚秼鍔� -->
<div class="bi-panel bi-panel-top-left">
- <PanelHeader title="閿�鍞垎鏋�-鐮屽潡" />
+ <PanelHeader :isFullscreen="true"
+ title="閿�閲忓垎鏋愯秼鍔垮浘" />
<div class="panel-tabs">
- <span class="tab-item active">骞�</span>
- <span class="tab-item">鏈�</span>
+ <span class="tab-item"
+ :class="{ active: chartTimeDimension === '骞�' }"
+ @click="handleChartTimeDimensionChange('骞�')">骞�</span>
+ <span class="tab-item"
+ :class="{ active: chartTimeDimension === '鏈�' }"
+ @click="handleChartTimeDimensionChange('鏈�')">鏈�</span>
+ </div>
+ <div class="panel-tabs2">
+ <span class="tab-item"
+ :class="{ active: chartProductType === '鐮屽潡' }"
+ @click="handleChartProductTypeChange('鐮屽潡')">鐮屽潡</span>
+ <span class="tab-item"
+ :class="{ active: chartProductType === '鏉挎潗' }"
+ @click="handleChartProductTypeChange('鏉挎潗')">鏉挎潗</span>
</div>
<div class="bi-panel-body">
- <div class="chart-filter-tabs">
- <span class="cf-tab active">***閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- </div>
<div class="chart-unit-row">
<span>鍗曚綅锛氱珛鏂圭背</span>
- <span class="dot-legend">鏉挎潗</span>
</div>
- <div ref="salesVolumeChart" class="echart-fill"></div>
+ <div ref="salesVolumeChart"
+ class="echart-fill"></div>
</div>
</div>
-
<!-- 鍙充笂锛氶攢鍞噾棰� -->
<div class="bi-panel bi-panel-top-right">
- <PanelHeader title="閿�鍞垎鏋�-鏉挎潗" />
+ <PanelHeader :isFullscreen="true"
+ title="閿�鍞噾棰濆垎鏋�" />
<div class="panel-tabs">
- <span class="tab-item active">骞�</span>
- <span class="tab-item">鏈�</span>
+ <span class="tab-item"
+ :class="{ active: chartTimeDimension2 === '骞�' }"
+ @click="handleChartTimeDimensionChange2('骞�')">骞�</span>
+ <span class="tab-item"
+ :class="{ active: chartTimeDimension2 === '鏈�' }"
+ @click="handleChartTimeDimensionChange2('鏈�')">鏈�</span>
+ </div>
+ <div class="panel-tabs2">
+ <span class="tab-item"
+ :class="{ active: chartProductType2 === '鐮屽潡' }"
+ @click="handleChartProductTypeChange2('鐮屽潡')">鐮屽潡</span>
+ <span class="tab-item"
+ :class="{ active: chartProductType2 === '鏉挎潗' }"
+ @click="handleChartProductTypeChange2('鏉挎潗')">鏉挎潗</span>
</div>
<div class="bi-panel-body">
- <div class="chart-filter-tabs">
- <span class="cf-tab active">***閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- </div>
<div class="chart-unit-row">
- <span>鍗曚綅锛氫欢</span>
- <span class="dot-legend">鏉挎潗</span>
+ <span>鍗曚綅锛氬厓</span>
</div>
- <div ref="salesAmountChart" class="echart-fill"></div>
+ <div ref="salesAmountChart"
+ class="echart-fill"></div>
</div>
</div>
-
<!-- 涓棿涓績鐜� -->
<div class="center-ring">
- <img
- class="center-ring-bg"
- src="@/assets/BI/zonghetongbingtubiankuang@2x.png"
- alt=""
- />
- <div class="center-ring-content">
- <div class="center-ring-title">閿�鍞�<br />涓績</div>
-
+ <div class="center-ring-box">
<div class="center-metric m1">
- <div class="center-metric-label">鏂板瀹㈡埛</div>
- <div class="center-metric-value">{{ centerNewCustomerCount }}</div>
- <div class="center-metric-unit">浜�</div>
+ <div class="center-metric-label">鎬婚攢鍞噾棰�</div>
+ <div class="center-metric-value">{{ totalSalesAmount.toFixed(0) }}</div>
+ <div class="center-metric-unit">涓囧厓</div>
</div>
-
<div class="center-metric m2">
<div class="center-metric-label">鎴愪氦鎬昏鍗�</div>
<div class="center-metric-value">{{ completedOrders }}</div>
<div class="center-metric-unit">鍗�</div>
</div>
-
<div class="center-metric m3">
- <div class="center-metric-label">鏂板璁㈠崟</div>
- <div class="center-metric-value">{{ salesOrderCount }}</div>
- <div class="center-metric-unit">鍗�</div>
+ <div class="center-metric-label">绱瀹㈡埛</div>
+ <div class="center-metric-value">{{ centerNewCustomerCount }}</div>
+ <div class="center-metric-unit">瀹�</div>
</div>
-
<div class="center-metric m4">
- <div class="center-metric-label">鎬婚攢鍞尯</div>
- <div class="center-metric-value">{{ totalSalesAreaCount }}</div>
- <div class="center-metric-unit">鍖�</div>
+ <div class="center-metric-label">閿�鍞柟鏁�</div>
+ <div class="center-metric-value">{{ totalSalesAreaCount.toFixed(0) }}</div>
+ <div class="center-metric-unit">鏂�</div>
</div>
</div>
</div>
-
<!-- 宸︿笅锛氫骇鍝佺被鍨嬮攢閲� -->
<div class="bi-panel bi-panel-bottom-left">
- <PanelHeader title="瀹㈡埛閿�閲忔帓鍚嶅垎鏋�-鐮屽潡" />
+ <PanelHeader :isFullscreen="true"
+ title="閿�閲忔暟鎹粺璁�" />
<div class="panel-tabs">
- <span class="tab-item active">骞�</span>
- <span class="tab-item">鏈�</span>
+ <span class="tab-item"
+ :class="{ active: tableTimeDimension === '骞�' }"
+ @click="handleTableTimeDimensionChange('骞�')">骞�</span>
+ <span class="tab-item"
+ :class="{ active: tableTimeDimension === '鏈�' }"
+ @click="handleTableTimeDimensionChange('鏈�')">鏈�</span>
+ </div>
+ <div class="panel-tabs2">
+ <span class="tab-item"
+ :class="{ active: tableProductType === '鐮屽潡' }"
+ @click="handleTableProductTypeChange('鐮屽潡')">鐮屽潡</span>
+ <span class="tab-item"
+ :class="{ active: tableProductType === '鏉挎潗' }"
+ @click="handleTableProductTypeChange('鏉挎潗')">鏉挎潗</span>
</div>
<div class="bi-panel-body">
<div class="chart-filter-tabs">
- <span class="cf-tab active">***閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
+ <span v-for="area in tableSalesAreas"
+ :key="area"
+ class="cf-tab"
+ :class="{ active: tableSelectedArea === area }"
+ @click="handleTableAreaChange(area)">{{ area }}</span>
</div>
- <div ref="productTypeChart" class="echart-fill"></div>
+ <div class="scroll-table-container">
+ <table class="scroll-table">
+ <thead>
+ <tr>
+ <th>搴忓彿</th>
+ <th>浜у搧绫诲瀷</th>
+ <th>骞存湀</th>
+ <th>閿�鍞尯</th>
+ <th>閿�閲忥紙m鲁锛�</th>
+ </tr>
+ </thead>
+ <div class="scroll-table-content">
+ <tbody ref="blockTableBody">
+ <tr :class="(index + 1) % 2 === 0 ? 'evenTableTr' : 'oddTableTr'"
+ v-for="(item, index) in filteredTableSalesData"
+ :key="item.period + item.area + index">
+ <td>{{ index + 1 }}</td>
+ <td>{{ item.productType }}</td>
+ <td>{{ item.period }}</td>
+ <td>{{ item.area }}</td>
+ <td>{{ item.sales }}</td>
+ </tr>
+ </tbody>
+ </div>
+ </table>
+ </div>
+ <div class="panel-summary-row">
+ <div class="summary-label">鍚堣</div>
+ <div class="summary-value">{{ filteredTableSalesTotal }} m鲁</div>
+ </div>
</div>
</div>
-
<!-- 涓笅锛氭柊澧炲鎴峰垎鏋愶紙鍒嗕骇鍝佺被鍨嬭秼鍔匡級 -->
<div class="bi-panel bi-panel-bottom-center">
- <PanelHeader title="鏂板瀹㈡埛瓒嬪娍鍒嗘瀽" />
+ <PanelHeader :isFullscreen="true"
+ title="鏂板瀹㈡埛瓒嬪娍鍒嗘瀽" />
<div class="panel-tabs">
- <span class="tab-item active">骞�</span>
- <span class="tab-item">鏈�</span>
+ <span class="tab-item"
+ :class="{ active: customerTimeDimension === '骞�' }"
+ @click="handleCustomerTimeDimensionChange('骞�')">骞�</span>
+ <span class="tab-item"
+ :class="{ active: customerTimeDimension === '鏈�' }"
+ @click="handleCustomerTimeDimensionChange('鏈�')">鏈�</span>
</div>
<div class="bi-panel-body">
- <div class="chart-mini-title">
- <span class="diamond"></span>
- <span>鏂板瀹㈡埛鏁�</span>
- </div>
<div class="chart-unit-row chart-unit-single">
- <span>鍗曚綅锛氫汉</span>
+ <span>鍗曚綅锛氬</span>
</div>
- <div ref="productTypeTrendChart" class="echart-fill"></div>
+ <div ref="productTypeTrendChart"
+ class="echart-fill"></div>
</div>
</div>
-
<!-- 鍙充笅锛氶攢鍞尯鍩熼攢閲� -->
<div class="bi-panel bi-panel-bottom-right">
- <PanelHeader title="瀹㈡埛閿�閲忔帓鍚嶅垎鏋�-鏉挎潗" />
+ <PanelHeader :isFullscreen="true"
+ title="閿�鍞鏁版嵁缁熻" />
<div class="panel-tabs">
- <span class="tab-item active">骞�</span>
- <span class="tab-item">鏈�</span>
+ <span class="tab-item"
+ :class="{ active: tableTimeDimension2 === '骞�' }"
+ @click="handleTableTimeDimensionChange2('骞�')">骞�</span>
+ <span class="tab-item"
+ :class="{ active: tableTimeDimension2 === '鏈�' }"
+ @click="handleTableTimeDimensionChange2('鏈�')">鏈�</span>
+ </div>
+ <div class="panel-tabs2">
+ <span class="tab-item"
+ :class="{ active: tableProductType2 === '鐮屽潡' }"
+ @click="handleTableProductTypeChange2('鐮屽潡')">鐮屽潡</span>
+ <span class="tab-item"
+ :class="{ active: tableProductType2 === '鏉挎潗' }"
+ @click="handleTableProductTypeChange2('鏉挎潗')">鏉挎潗</span>
</div>
<div class="bi-panel-body">
<div class="chart-filter-tabs">
- <span class="cf-tab active">***閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
- <span class="cf-tab">xxx閿�鍞尯</span>
+ <span v-for="area in tableSalesAreas"
+ :key="area"
+ class="cf-tab"
+ :class="{ active: tableSelectedArea === area }"
+ @click="handleTableAreaChange2(area)">{{ area }}</span>
</div>
- <div ref="salesAreaChart" class="echart-fill"></div>
+ <div class="scroll-table-container">
+ <table class="scroll-table">
+ <thead>
+ <tr>
+ <th>搴忓彿</th>
+ <th>浜у搧绫诲瀷</th>
+ <th>骞存湀</th>
+ <th>閿�鍞尯</th>
+ <th>閿�鍞锛堝厓锛�</th>
+ </tr>
+ </thead>
+ <div class="scroll-table-content">
+ <tbody ref="boardTableBody">
+ <tr :class="(index + 1) % 2 === 0 ? 'evenTableTr' : 'oddTableTr'"
+ v-for="(item, index) in filteredAmountSalesData"
+ :key="item.period + item.area + index">
+ <td>{{ index + 1 }}</td>
+ <td>{{ item.productType }}</td>
+ <td>{{ item.period }}</td>
+ <td>{{ item.area }}</td>
+ <td>{{ item.sales }}</td>
+ </tr>
+ </tbody>
+ </div>
+ </table>
+ </div>
+ <div class="panel-summary-row">
+ <div class="summary-label">鍚堣</div>
+ <div class="summary-value2">{{ filteredAmountSalesTotal }} 鍏�</div>
+ </div>
</div>
</div>
</div>
@@ -183,14 +282,20 @@
import * as echarts from "echarts";
import dayjs from "dayjs";
import PanelHeader from "@/views/reportAnalysis/PSIDataAnalysis/components/PanelHeader.vue";
+ import {
+ getDashboardStatistics,
+ getCustomerTrends,
+ getSalesAnalysisTrend,
+ getSalesAmountAnalysis,
+ } from "@/api/reportAnalysis/salesStatistics";
const router = useRouter();
const screenRoot = ref(null);
const isFullscreen = ref(false);
// 椤堕儴鏍忔椂闂达紙鐢ㄤ簬鍖归厤BI澶у睆鏁堟灉鍥撅級
- const now = ref(dayjs())
- const currentTime = computed(() => now.value.format("HH:mm:ss"))
+ const now = ref(dayjs());
+ const currentTime = computed(() => now.value.format("HH:mm:ss"));
const currentDateText = computed(() => {
const weekMap = {
0: "鏄熸湡鏃�",
@@ -200,10 +305,10 @@
4: "鏄熸湡鍥�",
5: "鏄熸湡浜�",
6: "鏄熸湡鍏�",
- }
- return `${now.value.format("YYYY-MM-DD")} ${weekMap[now.value.day()] || ""}`
- })
- let timeTicker = null
+ };
+ return `${now.value.format("YYYY-MM-DD")} ${weekMap[now.value.day()] || ""}`;
+ });
+ let timeTicker = null;
const handleFullscreenChange = () => {
isFullscreen.value = !!document.fullscreenElement;
@@ -238,6 +343,64 @@
const productTypeChart = ref(null);
const salesAreaChart = ref(null);
const productTypeTrendChart = ref(null);
+ const blockTableBody = ref(null);
+ const boardTableBody = ref(null);
+
+ // 閫夋嫨鍣ㄦ暟鎹�
+ // 閿�閲忓垎鏋愯秼鍔垮浘
+ const chartTimeDimension = ref("骞�");
+ const chartTimeDimension2 = ref("骞�");
+
+ const chartSelectedArea = ref("鍏ㄩ儴");
+ const chartProductType = ref("鐮屽潡");
+ const chartProductType2 = ref("鐮屽潡");
+
+ // 閿�閲忔暟鎹粺璁�
+ const tableTimeDimension = ref("骞�");
+ const tableSelectedArea = ref("鍏ㄩ儴");
+ const tableSelectedArea2 = ref("鍏ㄩ儴");
+
+ const tableProductType = ref("鐮屽潡");
+ const boardTimeDimension = ref("骞�");
+ const boardSelectedArea = ref("鍏ㄩ儴");
+ const boardProductType = ref("鏉挎潗");
+ const customerTimeDimension = ref("骞�");
+
+ const salesAreas = [
+ "鍏ㄩ儴",
+ "A閿�鍞尯",
+ "B閿�鍞尯",
+ "C閿�鍞尯",
+ "D閿�鍞尯",
+ "E閿�鍞尯",
+ ];
+
+ // 琛ㄦ牸鏁版嵁
+ const blockSalesData = ref([
+ { period: "2024-01", area: "***閿�鍞尯", sales: 1250, sort: 1 },
+ { period: "2024-02", area: "xxx閿�鍞尯", sales: 1180, sort: 2 },
+ { period: "2024-03", area: "xxx閿�鍞尯", sales: 1050, sort: 3 },
+ { period: "2024-04", area: "xxx閿�鍞尯", sales: 980, sort: 4 },
+ { period: "2024-05", area: "xxx閿�鍞尯", sales: 920, sort: 5 },
+ { period: "2024-06", area: "***閿�鍞尯", sales: 880, sort: 6 },
+ { period: "2024-07", area: "xxx閿�鍞尯", sales: 850, sort: 7 },
+ { period: "2024-08", area: "***閿�鍞尯", sales: 820, sort: 8 },
+ { period: "2024-09", area: "xxx閿�鍞尯", sales: 790, sort: 9 },
+ { period: "2024-10", area: "***閿�鍞尯", sales: 750, sort: 10 },
+ ]);
+
+ const boardSalesData = ref([
+ { period: "2024-01", area: "***閿�鍞尯", sales: 980, sort: 1 },
+ { period: "2024-02", area: "xxx閿�鍞尯", sales: 920, sort: 2 },
+ { period: "2024-03", area: "***閿�鍞尯", sales: 880, sort: 3 },
+ { period: "2024-04", area: "xxx閿�鍞尯", sales: 850, sort: 4 },
+ { period: "2024-05", area: "xxx閿�鍞尯", sales: 820, sort: 5 },
+ { period: "2024-06", area: "***閿�鍞尯", sales: 790, sort: 6 },
+ { period: "2024-07", area: "xxx閿�鍞尯", sales: 750, sort: 7 },
+ { period: "2024-08", area: "xxx閿�鍞尯", sales: 720, sort: 8 },
+ { period: "2024-09", area: "***閿�鍞尯", sales: 690, sort: 9 },
+ { period: "2024-10", area: "xxx閿�鍞尯", sales: 650, sort: 10 },
+ ]);
const cumulativeSalesVolumeChart = ref(null);
const cumulativeSalesAmountChart = ref(null);
@@ -504,11 +667,10 @@
return filteredData.value.reduce((sum, item) => sum + item.salesVolume, 0);
});
- const totalSalesAmount = computed(() => {
- return filteredData.value
- .reduce((sum, item) => sum + item.salesAmount, 0)
- .toFixed(2);
- });
+ const totalSalesAmount = ref(1299);
+ const centerNewCustomerCount = ref(112);
+ const completedOrders = ref(1829);
+ const totalSalesAreaCount = ref(12);
const newCustomerCount = computed(() => {
return filteredData.value.reduce((sum, item) => sum + item.newCustomers, 0);
@@ -526,17 +688,177 @@
return Object.values(customerMap).reduce((sum, count) => sum + count, 0);
});
- // 涓棿涓績鐜寚鏍囷紙鐢ㄤ簬澶у睆灞曠ず锛屼娇鐢ㄧ幇鏈夌粺璁℃暟鎹仛鏄犲皠锛�
- const centerNewCustomerCount = computed(() => 112);
- const completedOrders = computed(() => 1829);
- const salesOrderCount = computed(() => 34);
- const totalSalesAreaCount = computed(() => 12);
+ // 瀹㈡埛瓒嬪娍鏁版嵁
+ const customerTrendsData = ref([]);
+ // 閿�閲忓垎鏋愯秼鍔挎暟鎹�
+ const salesAnalysisTrendData = ref([]);
+ // 閿�閲忔暟鎹粺璁¤〃鏍兼暟鎹�
+ const tableSalesData = ref([]);
+ // 閿�閲忔暟鎹粺璁¤〃鏍兼�昏
+ const tableSalesTotal = ref(0);
+ // 鍔ㄦ�侀攢鍞尯鍩熷垪琛�
+ const tableSalesAreas = ref([]);
// 鍙樺寲鐜囪绠楋紙妯℃嫙锛�
const salesVolumeChange = ref("+5.2");
const salesAmountChange = ref("+7.8");
const customerCountChange = ref("+3.5");
const totalCustomerChange = ref("+2.1");
+
+ // 鑾峰彇涓績鐪嬫澘鏁版嵁
+ const fetchDashboardData = async () => {
+ try {
+ const response = await getDashboardStatistics();
+ if (response && response.data) {
+ totalSalesAmount.value = response.data.price || 0;
+ completedOrders.value = response.data.delivery || 0;
+ centerNewCustomerCount.value = response.data.customer || 0;
+ totalSalesAreaCount.value = response.data.volume || 0;
+ }
+ } catch (error) {
+ console.error("鑾峰彇涓績鐪嬫澘鏁版嵁澶辫触:", error);
+ }
+ };
+
+ // 鑾峰彇瀹㈡埛瓒嬪娍鏁版嵁
+ const fetchCustomerTrendsData = async () => {
+ try {
+ const response = await getCustomerTrends({
+ days: customerTimeDimension.value,
+ });
+ if (response && response.data) {
+ // API杩斿洖鐨勬暟鎹粨鏋勫涓嬶細
+ // {
+ // "dates": ["2026-01-01", "2025-01-01", ...],
+ // "customerTrends": [{"ALLIN": 4, "閾跺窛": 3, ...}, ...]
+ // }
+ customerTrendsData.value = response.data;
+ updateCharts();
+ }
+ } catch (error) {
+ console.error("鑾峰彇瀹㈡埛瓒嬪娍鏁版嵁澶辫触:", error);
+ }
+ };
+
+ // 鑾峰彇閿�閲忓垎鏋愯秼鍔挎暟鎹�
+ const fetchSalesAnalysisTrendData = async () => {
+ try {
+ const response = await getSalesAnalysisTrend({
+ type: chartProductType.value, // 鐮屽潡鎴栨澘鏉�
+ days: chartTimeDimension.value, // 骞存垨鏈�
+ });
+ if (response && response.data) {
+ // API杩斿洖鐨勬暟鎹粨鏋勫涓嬶細
+ // {
+ // "dates": ["2026-01-01", "2025-01-01", ...],
+ // "customerTrends": [{"鍐呰挋鍙�": 470, "閾跺窛": 3600, ...}, ...]
+ // }
+ salesAnalysisTrendData.value = response.data;
+ updateCharts();
+ }
+ } catch (error) {
+ console.error("鑾峰彇閿�閲忓垎鏋愯秼鍔挎暟鎹け璐�:", error);
+ }
+ };
+
+ // 鑾峰彇閿�閲忔暟鎹粺璁¤〃鏍兼暟鎹�
+ const fetchTableSalesData = async () => {
+ try {
+ const response = await getSalesAnalysisTrend({
+ type: tableProductType.value, // 鐮屽潡鎴栨澘鏉�
+ days: tableTimeDimension.value, // 骞存垨鏈�
+ });
+ if (response && response.data) {
+ // API杩斿洖鐨勬暟鎹粨鏋勫涓嬶細
+ // {
+ // "dates": ["2026-01-01", "2025-01-01", ...],
+ // "customerTrends": [{"鍐呰挋鍙�": 470, "閾跺窛": 3600, ...}, ...]
+ // }
+ updateTableSalesData(response.data);
+ }
+ } catch (error) {
+ console.error("鑾峰彇閿�閲忔暟鎹粺璁¤〃鏍兼暟鎹け璐�:", error);
+ }
+ };
+
+ // 鏇存柊閿�閲忔暟鎹粺璁¤〃鏍�
+ const updateTableSalesData = data => {
+ if (!data || !data.dates || !data.customerTrends) {
+ return;
+ }
+ console.log(data, "datas");
+ const dates = data.dates;
+ const customerTrends = data.customerTrends;
+ const tableData = [];
+ let total = 0;
+ const areaSet = new Set();
+
+ dates.forEach((date, index) => {
+ const trend = customerTrends[index];
+ if (trend) {
+ // 鎻愬彇鎵�鏈夐攢鍞尯鍩�
+ Object.keys(trend).forEach(area => {
+ if (area !== "鍏ㄩ儴") {
+ areaSet.add(area);
+ const sales = trend[area] || 0;
+ tableData.push({
+ period: date,
+ area: area,
+ productType: tableProductType.value,
+ sales: sales,
+ sort: tableData.length + 1,
+ });
+ total += sales;
+ }
+ });
+ }
+ });
+
+ // 鏇存柊閿�鍞尯鍩熷垪琛紝娣诲姞"鍏ㄩ儴"閫夐」
+ tableSalesAreas.value = ["鍏ㄩ儴", ...Array.from(areaSet)];
+ // 纭繚 tableSelectedArea 鍦ㄩ攢鍞尯鍩熷垪琛ㄤ腑
+ if (
+ tableSalesAreas.value.length > 0 &&
+ !tableSalesAreas.value.includes(tableSelectedArea.value)
+ ) {
+ tableSelectedArea.value = "鍏ㄩ儴";
+ }
+
+ console.log(tableData);
+ tableSalesData.value = tableData;
+ tableSalesTotal.value = total;
+ };
+
+ // 澶勭悊鍥捐〃鏃堕棿缁村害鍙樺寲
+ const handleChartTimeDimensionChange = dimension => {
+ chartTimeDimension.value = dimension;
+ fetchSalesAnalysisTrendData();
+ };
+
+ // 澶勭悊鍥捐〃浜у搧绫诲瀷鍙樺寲
+ const handleChartProductTypeChange = type => {
+ chartProductType.value = type;
+ fetchSalesAnalysisTrendData();
+ };
+
+ // 澶勭悊琛ㄦ牸鏃堕棿缁村害鍙樺寲
+ const handleTableTimeDimensionChange = dimension => {
+ tableTimeDimension.value = dimension;
+ fetchTableSalesData();
+ // 閲嶆柊鍚姩婊氬姩锛屾牴鎹椂闂寸淮搴﹀喅瀹氭槸鍚︽粴鍔�
+ startBlockTableScroll();
+ };
+
+ // 澶勭悊琛ㄦ牸浜у搧绫诲瀷鍙樺寲
+ const handleTableProductTypeChange = type => {
+ tableProductType.value = type;
+ fetchTableSalesData();
+ };
+
+ // 澶勭悊琛ㄦ牸閿�鍞尯鍩熷彉鍖�
+ const handleTableAreaChange = area => {
+ tableSelectedArea.value = area;
+ };
// 琛ㄦ牸鏁版嵁
const tableData = computed(() => {
@@ -555,10 +877,157 @@
});
});
+ // 绛涢�夊悗鐨勮〃鏍兼暟鎹�
+ const filteredTableSalesData = computed(() => {
+ if (tableSelectedArea.value === "鍏ㄩ儴") {
+ // 鎸夊勾鏈堝垎缁勬眹鎬绘暟鎹�
+ const groupedData = {};
+ tableSalesData.value.forEach(item => {
+ const key = item.period;
+ if (!groupedData[key]) {
+ groupedData[key] = {
+ period: item.period,
+ area: "鍏ㄩ儴",
+ productType: item.productType,
+ sales: 0,
+ sort: 0,
+ };
+ }
+ groupedData[key].sales += item.sales;
+ });
+ // 杞崲涓烘暟缁勫苟鎸夊勾鏈堟帓搴�
+ return Object.values(groupedData).sort((a, b) => {
+ return new Date(b.period) - new Date(a.period);
+ });
+ } else {
+ return tableSalesData.value.filter(
+ item => item.area === tableSelectedArea.value
+ );
+ }
+ });
+
+ // 绛涢�夊悗鐨勮〃鏍兼暟鎹�昏
+ const filteredTableSalesTotal = computed(() => {
+ return filteredTableSalesData.value.reduce(
+ (total, item) => total + item.sales,
+ 0
+ );
+ });
+
// 閿�閲忚秼鍔垮浘琛ㄩ厤缃�
const salesVolumeChartOption = computed(() => {
- const periods = ["6/9", "6/10", "6/11", "6/12", "6/12", "6/13"];
- const values = [132, 168, 168, 198, 168, 198];
+ const colors = [
+ "#00A4ED",
+ "#34D8F7",
+ "#4A8BFF",
+ "#8A6BFF",
+ "#C8C447",
+ "#FF6B6B",
+ "#FF9500",
+ "#4CD964",
+ "#5AC8FA",
+ ];
+ const periodType = blockTimeDimension.value;
+
+ // 鐢熸垚鏃堕棿娈�
+ let periods = [];
+ let salesAreas = [];
+ let series = [];
+
+ if (
+ salesAnalysisTrendData.value &&
+ salesAnalysisTrendData.value.dates &&
+ salesAnalysisTrendData.value.customerTrends
+ ) {
+ // 浣跨敤API杩斿洖鐨勬棩鏈�
+ periods = salesAnalysisTrendData.value.dates;
+ // 鎻愬彇閿�鍞尯鍩�
+ const customerTrends = salesAnalysisTrendData.value.customerTrends;
+ if (customerTrends.length > 0) {
+ // 鎻愬彇閿�鍞尯鍩熷苟纭繚"鍏ㄩ儴"鍦ㄧ涓�涓綅缃�
+ const allAreas = Object.keys(customerTrends[0]);
+ salesAreas = allAreas.sort((a, b) => {
+ if (a === "鍏ㄩ儴") return -1;
+ if (b === "鍏ㄩ儴") return 1;
+ return 0;
+ });
+ // 涓烘瘡涓攢鍞尯鐢熸垚鏁版嵁
+ series = salesAreas.map((area, index) => {
+ const data = customerTrends.map(trend => trend[area] || 0);
+ return {
+ name: area,
+ data: data,
+ type: "line",
+ smooth: false,
+ // symbolSize: getResponsiveValue(8),
+ lineStyle: {
+ width: getResponsiveValue(1),
+ color: colors[index % colors.length],
+ },
+ itemStyle: { color: colors[index % colors.length] },
+ areaStyle: {
+ opacity: 0.4,
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: colors[index % colors.length] + "80" },
+ { offset: 1, color: colors[index % colors.length] + "00" },
+ ]),
+ },
+ };
+ });
+ }
+ } else {
+ // 妯℃嫙鏁版嵁
+ salesAreas = [
+ "鍏ㄩ儴",
+ "A閿�鍞尯",
+ "B閿�鍞尯",
+ "C閿�鍞尯",
+ "D閿�鍞尯",
+ "E閿�鍞尯",
+ ];
+ const year = 2024;
+ if (periodType === "year") {
+ // 骞村害鏁版嵁锛�12涓湀
+ for (let month = 1; month <= 12; month++) {
+ periods.push(`${year}-${month.toString().padStart(2, "0")}`);
+ }
+ } else {
+ // 鏈堝害鏁版嵁锛�30澶�
+ const month = 1;
+ for (let day = 1; day <= 30; day++) {
+ periods.push(
+ `${year}-${month.toString().padStart(2, "0")}-${day
+ .toString()
+ .padStart(2, "0")}`
+ );
+ }
+ }
+ // 涓烘瘡涓攢鍞尯鐢熸垚鏁版嵁
+ series = salesAreas.map((area, index) => {
+ const data = periods.map(() => {
+ return periodType === "year"
+ ? Math.floor(Math.random() * 500) + 800
+ : Math.floor(Math.random() * 50) + 20;
+ });
+
+ return {
+ name: area,
+ data: data,
+ type: "line",
+ smooth: false,
+ // symbolSize: getResponsiveValue(8),
+ lineStyle: { width: getResponsiveValue(1), color: colors[index] },
+ itemStyle: { color: colors[index] },
+ areaStyle: {
+ opacity: 0.4,
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: colors[index] + "80" },
+ { offset: 1, color: colors[index] + "00" },
+ ]),
+ },
+ };
+ });
+ }
return {
backgroundColor: "transparent",
@@ -566,14 +1035,31 @@
trigger: "axis",
backgroundColor: "rgba(0,0,0,0.55)",
borderColor: "rgba(64,158,255,0.25)",
- borderWidth: 1,
- textStyle: { color: "#B8C8E0" },
- formatter: "{b}: {c} 绔嬫柟绫�",
+ borderWidth: getResponsiveValue(1),
+ textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
+ formatter: function (params) {
+ let result = params[0].name + "<br/>";
+ params.forEach(param => {
+ result += `${param.marker}${param.seriesName}: ${param.value} 绔嬫柟绫�<br/>`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: salesAreas,
+ top: "10%",
+ right: "1%",
+ textStyle: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(10),
+ },
+ itemWidth: getResponsiveValue(10),
+ itemHeight: getResponsiveValue(10),
},
grid: {
- left: "10%",
- right: "4%",
- bottom: "16%",
+ left: "1%",
+ right: "1%",
+ bottom: "1%",
top: "28%",
containLabel: true,
},
@@ -582,40 +1068,76 @@
data: periods,
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
axisTick: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 10 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(10),
+ },
splitLine: { show: false },
},
yAxis: {
type: "value",
name: "",
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 8 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(8),
+ },
splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } },
},
- series: [
- {
- data: values,
- type: "line",
- smooth: true,
- symbolSize: 8,
- lineStyle: { width: 3, color: "#00A4ED" },
- itemStyle: { color: "#00A4ED" },
- areaStyle: {
- opacity: 1,
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: "rgba(0,164,237,0.35)" },
- { offset: 1, color: "rgba(0,164,237,0)" },
- ]),
- },
- },
- ],
+ series: series,
};
});
// 閿�鍞噾棰濊秼鍔垮浘琛ㄩ厤缃�
const salesAmountChartOption = computed(() => {
- const periods = ["6/9", "6/10", "6/11", "6/12", "6/12", "6/13"];
- const values = [132, 168, 168, 198, 168, 198];
+ const { dates = [], customerTrends = [] } = salesAmountChartData.value;
+
+ // 鎻愬彇鎵�鏈夐攢鍞尯鍩�
+ const areaSet = new Set();
+ customerTrends.forEach(item => {
+ Object.keys(item).forEach(key => areaSet.add(key));
+ });
+ // 纭繚"鍏ㄩ儴"鍦ㄧ涓�涓綅缃�
+ const salesAreas = Array.from(areaSet).sort((a, b) => {
+ if (a === "鍏ㄩ儴") return -1;
+ if (b === "鍏ㄩ儴") return 1;
+ return 0;
+ });
+
+ const colors = [
+ "#00A4ED",
+ "#34D8F7",
+ "#4A8BFF",
+ "#8A6BFF",
+ "#C8C447",
+ "#FF6B6B",
+ ];
+
+ // 涓烘瘡涓攢鍞尯鐢熸垚鏁版嵁
+ const series = salesAreas.map((area, index) => {
+ const data = customerTrends.map(item => item[area] || 0);
+
+ return {
+ name: area,
+ data: data,
+ type: "bar",
+ smooth: true,
+ lineStyle: {
+ width: getResponsiveValue(3),
+ color: colors[index % colors.length],
+ },
+ itemStyle: { color: colors[index % colors.length] },
+ areaStyle: {
+ opacity: 0.2,
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: colors[index % colors.length] + "80" },
+ { offset: 1, color: colors[index % colors.length] + "00" },
+ ]),
+ },
+ };
+ });
return {
backgroundColor: "transparent",
@@ -623,50 +1145,58 @@
trigger: "axis",
backgroundColor: "rgba(0,0,0,0.55)",
borderColor: "rgba(64,158,255,0.25)",
- borderWidth: 1,
- textStyle: { color: "#B8C8E0" },
- formatter: "{b}: {c} 涓囧厓",
+ borderWidth: getResponsiveValue(1),
+ textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
+ formatter: function (params) {
+ let result = params[0]?.name + "<br/>" || "";
+ params.forEach(param => {
+ result += `${param.marker}${param.seriesName}: ${param.value} 鍏�<br/>`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: salesAreas,
+ top: "10%",
+ right: "1%",
+ textStyle: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(10),
+ },
+ itemWidth: getResponsiveValue(10),
+ itemHeight: getResponsiveValue(10),
},
grid: {
- left: "10%",
- right: "4%",
- bottom: "16%",
+ left: "1%",
+ right: "1%",
+ bottom: "1%",
top: "28%",
containLabel: true,
},
xAxis: {
type: "category",
- data: periods,
+ data: dates,
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
axisTick: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 10 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(10),
+ },
+ splitLine: { show: false },
},
yAxis: {
type: "value",
name: "",
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 8 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(8),
+ },
splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } },
},
- series: [
- {
- data: values,
- type: "line",
- smooth: true,
- symbolSize: 8,
- itemStyle: {
- color: "#00A4ED",
- },
- lineStyle: { width: 3, color: "#00A4ED" },
- areaStyle: {
- opacity: 1,
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: "rgba(0,164,237,0.35)" },
- { offset: 1, color: "rgba(0,164,237,0)" },
- ]),
- },
- },
- ],
+ series: series,
};
});
@@ -674,7 +1204,14 @@
const productTypeChartOption = computed(() => {
const types = ["瀹㈡埛BB", "瀹㈡埛AA", "瀹㈡埛CC", "瀹㈡埛DD", "瀹㈡埛DD", "瀹㈡埛DD"];
const values = [130, 120, 102, 90, 90, 70];
- const barColors = ["#34D8F7", "#4A8BFF", "#8A6BFF", "#C8C447", "#C8C447", "#C8C447"];
+ const barColors = [
+ "#34D8F7",
+ "#4A8BFF",
+ "#8A6BFF",
+ "#C8C447",
+ "#C8C447",
+ "#C8C447",
+ ];
return {
backgroundColor: "transparent",
@@ -683,8 +1220,8 @@
axisPointer: { type: "shadow" },
backgroundColor: "rgba(0,0,0,0.55)",
borderColor: "rgba(64,158,255,0.25)",
- borderWidth: 1,
- textStyle: { color: "#B8C8E0" },
+ borderWidth: getResponsiveValue(1),
+ textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
formatter: "{b}: {c} 绔嬫柟绫�",
},
grid: {
@@ -697,7 +1234,7 @@
xAxis: {
type: "value",
axisLine: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11 },
+ axisLabel: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } },
},
yAxis: {
@@ -705,17 +1242,26 @@
data: types,
axisTick: { show: false },
axisLine: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 8 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(8),
+ },
},
series: [
{
name: "閿�閲忥紙绔嬫柟绫筹級",
type: "bar",
- barWidth: 14,
+ barWidth: getResponsiveValue(14),
data: values,
itemStyle: {
color: params => barColors[params.dataIndex] || "#00A4ED",
- borderRadius: [6, 6, 6, 6],
+ borderRadius: [
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ ],
},
label: {
show: false,
@@ -729,7 +1275,14 @@
const salesAreaChartOption = computed(() => {
const areas = ["瀹㈡埛BB", "瀹㈡埛AA", "瀹㈡埛CC", "瀹㈡埛DD", "瀹㈡埛DD", "瀹㈡埛DD"];
const values = [130, 120, 102, 90, 90, 70];
- const barColors = ["#34D8F7", "#4A8BFF", "#8A6BFF", "#C8C447", "#C8C447", "#C8C447"];
+ const barColors = [
+ "#34D8F7",
+ "#4A8BFF",
+ "#8A6BFF",
+ "#C8C447",
+ "#C8C447",
+ "#C8C447",
+ ];
return {
backgroundColor: "transparent",
@@ -738,8 +1291,8 @@
axisPointer: { type: "shadow" },
backgroundColor: "rgba(0,0,0,0.55)",
borderColor: "rgba(64,158,255,0.25)",
- borderWidth: 1,
- textStyle: { color: "#B8C8E0" },
+ borderWidth: getResponsiveValue(1),
+ textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
formatter: "{b}: {c} 绔嬫柟绫�",
},
grid: {
@@ -752,7 +1305,7 @@
xAxis: {
type: "value",
axisLine: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11 },
+ axisLabel: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } },
},
yAxis: {
@@ -760,86 +1313,164 @@
data: areas,
axisTick: { show: false },
axisLine: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 8 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(8),
+ },
},
series: [
{
name: "閿�閲忥紙绔嬫柟绫筹級",
type: "bar",
- barWidth: 14,
+ barWidth: getResponsiveValue(14),
data: values,
itemStyle: {
color: params => barColors[params.dataIndex] || "#00A4ED",
- borderRadius: [6, 6, 6, 6],
+ borderRadius: [
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ getResponsiveValue(6),
+ ],
},
},
],
};
});
- // 鏂板瀹㈡埛瓒嬪娍鍥捐〃閰嶇疆锛堟寜浜у搧绫诲瀷澶氭姌绾匡級
+ // 鏂板瀹㈡埛瓒嬪娍鍥捐〃閰嶇疆锛堟寜閿�鍞尯鍜屽勾鏈堢淮搴︼級
const productTypeTrendChartOption = computed(() => {
- const typeOrder = ["AAA閿�鍞尯", "BBB閿�鍞尯", "CCC閿�鍞尯", "DDD閿�鍞尯"];
- const colorMap = {
- "AAA閿�鍞尯": "#65A0FF",
- "BBB閿�鍞尯": "#33F5FF",
- "CCC閿�鍞尯": "#FFD54A",
- "DDD閿�鍞尯": "#EE52FF",
- };
- const areaColorMap = {
- "AAA閿�鍞尯": "rgba(101,160,255,0.28)",
- "BBB閿�鍞尯": "rgba(51,245,255,0.30)",
- "CCC閿�鍞尯": "rgba(255,213,74,0.25)",
- "DDD閿�鍞尯": "rgba(238,82,255,0.25)",
- };
- const periods = ["6/9", "6/10", "6/11", "6/12", "6/12", "6/13", "6/14", "6/15"];
- const map = {
- "AAA閿�鍞尯": [85, 112, 112, 112, 140, 112, 112, 140],
- "BBB閿�鍞尯": [140, 180, 180, 180, 230, 180, 180, 230],
- "CCC閿�鍞尯": [112, 140, 140, 140, 180, 140, 140, 180],
- "DDD閿�鍞尯": [200, 165, 200, 200, 165, 165, 140, 140],
- };
+ const colors = [
+ "#00A4ED",
+ "#34D8F7",
+ "#4A8BFF",
+ "#8A6BFF",
+ "#C8C447",
+ "#FF6B6B",
+ "#FF8B6B",
+ "#FFCB6B",
+ "#8BC34A",
+ "#4CAF50",
+ ];
+ const periodType = customerTimeDimension.value;
- const series = typeOrder.map((t) => ({
- name: t,
- type: "line",
- smooth: true,
- symbolSize: 7,
- showSymbol: true,
- data: map[t] || [],
- lineStyle: { width: 3, color: colorMap[t] },
- itemStyle: { color: colorMap[t] },
- areaStyle: {
- opacity: 0.25,
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
- { offset: 0, color: areaColorMap[t] },
- { offset: 1, color: "rgba(0,0,0,0)" },
- ]),
- },
- }));
+ // 鐢熸垚鏃堕棿娈�
+ let periods = [];
+ let salesAreas = [];
+ let series = [];
+
+ if (
+ customerTrendsData.value &&
+ customerTrendsData.value.dates &&
+ customerTrendsData.value.customerTrends
+ ) {
+ // 浣跨敤API杩斿洖鐨勬暟鎹�
+ periods = customerTrendsData.value.dates;
+
+ // 鎻愬彇鎵�鏈夐攢鍞尯鍩�
+ const areaSet = new Set();
+ customerTrendsData.value.customerTrends.forEach(item => {
+ Object.keys(item).forEach(key => {
+ areaSet.add(key);
+ });
+ });
+ // 纭繚"鍏ㄩ儴"鍦ㄧ涓�涓綅缃�
+ salesAreas = Array.from(areaSet).sort((a, b) => {
+ if (a === "鍏ㄩ儴") return -1;
+ if (b === "鍏ㄩ儴") return 1;
+ return 0;
+ });
+
+ // 涓烘瘡涓攢鍞尯鍩熺敓鎴愭暟鎹�
+ series = salesAreas.map((area, index) => {
+ const data = customerTrendsData.value.customerTrends.map((item, i) => {
+ return item[area] || 0;
+ });
+
+ return {
+ name: area,
+ data: data,
+ type: "line",
+ smooth: false,
+ lineStyle: {
+ width: getResponsiveValue(1),
+ color: colors[index % colors.length],
+ },
+ itemStyle: { color: colors[index % colors.length] },
+ };
+ });
+ } else {
+ // 妯℃嫙鏁版嵁
+ const year = 2024;
+ if (periodType === "year") {
+ // 骞村害鏁版嵁锛�12涓湀
+ for (let month = 1; month <= 12; month++) {
+ periods.push(`${year}-${month.toString().padStart(2, "0")}`);
+ }
+ } else {
+ // 鏈堝害鏁版嵁锛�30澶�
+ const month = 1;
+ for (let day = 1; day <= 30; day++) {
+ periods.push(
+ `${year}-${month.toString().padStart(2, "0")}-${day
+ .toString()
+ .padStart(2, "0")}`
+ );
+ }
+ }
+
+ salesAreas = [];
+ series = salesAreas.map((area, index) => {
+ const data = periods.map(() => {
+ return periodType === "year"
+ ? Math.floor(Math.random() * 10) + 2
+ : Math.floor(Math.random() * 3) + 1;
+ });
+
+ return {
+ name: area,
+ data: data,
+ type: "line",
+ smooth: false,
+ lineStyle: { width: getResponsiveValue(1), color: colors[index] },
+ itemStyle: { color: colors[index] },
+ };
+ });
+ }
return {
backgroundColor: "transparent",
- legend: {
- top: 10,
- left: "center",
- textStyle: { color: "#B8C8E0", fontSize: 11, padding: [0, 0, 0, 2] },
- itemWidth: 12,
- itemHeight: 10,
- itemGap: 18,
- },
tooltip: {
trigger: "axis",
backgroundColor: "rgba(0,0,0,0.55)",
borderColor: "rgba(64,158,255,0.25)",
- borderWidth: 1,
- textStyle: { color: "#B8C8E0" },
+ borderWidth: getResponsiveValue(1),
+ textStyle: { color: "#B8C8E0", fontSize: getResponsiveValue(11) },
+ formatter: function (params) {
+ let result = params[0].name + "<br/>";
+ params.forEach(param => {
+ result += `${param.marker}${param.seriesName}: ${param.value} 瀹�<br/>`;
+ });
+ return result;
+ },
+ },
+ legend: {
+ data: salesAreas,
+ top: "10%",
+ right: "1%",
+ textStyle: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(10),
+ },
+ itemWidth: getResponsiveValue(10),
+ itemHeight: getResponsiveValue(10),
},
grid: {
- left: "10%",
- right: "6%",
- bottom: "14%",
- top: "26%",
+ left: "1%",
+ right: "1%",
+ bottom: "1%",
+ top: "28%",
containLabel: true,
},
xAxis: {
@@ -847,127 +1478,32 @@
data: periods,
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
axisTick: { show: false },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 10 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(10),
+ },
+ splitLine: { show: false },
},
yAxis: {
type: "value",
name: "",
axisLine: { lineStyle: { color: "rgba(184,200,224,0.25)" } },
- axisLabel: { color: "#B8C8E0", fontSize: 11, margin: 8 },
+ axisLabel: {
+ color: "#B8C8E0",
+ fontSize: getResponsiveValue(11),
+ margin: getResponsiveValue(8),
+ },
splitLine: { lineStyle: { color: "rgba(184,200,224,0.12)" } },
},
- series,
+ series: series,
};
});
- // 绱閿�閲忚秼鍔垮浘琛ㄩ厤缃�
- const cumulativeSalesVolumeChartOption = computed(() => {
- // 鎸夊懆鏈熷垎缁�
- const periodMap = {};
- let cumulativeValue = 0;
-
- // 鎸夊懆鏈熸帓搴�
- const sortedData = [...filteredData.value].sort((a, b) =>
- a.period.localeCompare(b.period)
- );
-
- sortedData.forEach(item => {
- cumulativeValue += item.salesVolume;
- periodMap[item.period] = cumulativeValue;
- });
-
- const periods = Object.keys(periodMap).sort();
- const values = periods.map(period => periodMap[period]);
-
- return {
- tooltip: {
- trigger: "axis",
- formatter: "{b}: {c} 绔嬫柟绫�",
- },
- xAxis: {
- type: "category",
- data: periods,
- },
- yAxis: {
- type: "value",
- name: "绱閿�閲忥紙绔嬫柟绫筹級",
- },
- series: [
- {
- data: values,
- type: "line",
- smooth: true,
- areaStyle: {
- opacity: 0.3,
- },
- itemStyle: {
- color: "#E6A23C",
- },
- lineStyle: {
- width: 3,
- },
- },
- ],
- };
- });
-
- // 绱閿�鍞噾棰濊秼鍔垮浘琛ㄩ厤缃�
- const cumulativeSalesAmountChartOption = computed(() => {
- // 鎸夊懆鏈熷垎缁�
- const periodMap = {};
- let cumulativeValue = 0;
-
- // 鎸夊懆鏈熸帓搴�
- const sortedData = [...filteredData.value].sort((a, b) =>
- a.period.localeCompare(b.period)
- );
-
- sortedData.forEach(item => {
- cumulativeValue += item.salesAmount;
- periodMap[item.period] = cumulativeValue;
- });
-
- const periods = Object.keys(periodMap).sort();
- const values = periods.map(period => periodMap[period]);
-
- return {
- tooltip: {
- trigger: "axis",
- formatter: "{b}: {c} 涓囧厓",
- },
- xAxis: {
- type: "category",
- data: periods,
- },
- yAxis: {
- type: "value",
- name: "绱閿�鍞噾棰濓紙涓囧厓锛�",
- },
- series: [
- {
- data: values,
- type: "bar",
- itemStyle: {
- color: "#F56C6C",
- },
- },
- ],
- };
- });
-
- // 鏂规硶
- const goBack = () => {
- router.back();
- };
-
- const handleDateChange = () => {
- // 澶勭悊鏃ユ湡鍙樺寲
- updateCharts();
- };
-
- const handleFilterChange = () => {
- // 澶勭悊绛涢�夋潯浠跺彉鍖�
- updateCharts();
+ const baseWidth = ref(1650);
+ // 璁$畻鍝嶅簲寮忓��
+ const getResponsiveValue = baseValue => {
+ return Math.round((baseValue * window.innerWidth) / baseWidth.value);
};
// 鍒濆鍖栧浘琛�
@@ -1013,12 +1549,13 @@
updateCharts();
};
-
// 鏇存柊鍥捐〃
const updateCharts = () => {
// 鏇存柊閿�閲忚秼鍔垮浘琛�
if (salesVolumeChartInstance) {
- salesVolumeChartInstance.setOption(salesVolumeChartOption.value);
+ salesVolumeChartInstance.setOption(
+ JSON.parse(JSON.stringify(salesVolumeChartOption.value))
+ );
}
// 鏇存柊閿�鍞噾棰濊秼鍔垮浘琛�
@@ -1056,8 +1593,213 @@
}
};
+ // 琛ㄦ牸鍔ㄧ敾鎺у埗
+ let blockScrollTimer = null;
+ let boardScrollTimer = null;
+ let blockCurrentIndex = 0;
+ let boardCurrentIndex = 0;
+ const startBlockTableScroll = () => {
+ if (blockScrollTimer) {
+ clearInterval(blockScrollTimer);
+ }
+
+ // 鍙湁褰撴椂闂寸淮搴︿笉鏄�"骞�"鏃舵墠鍚姩婊氬姩
+ if (tableTimeDimension.value === "骞�") {
+ return;
+ }
+
+ const scrollTable = () => {
+ if (!blockTableBody.value) return;
+ const rows = blockTableBody.value.querySelectorAll("tr");
+ if (rows.length === 0) return;
+
+ const rowHeight = rows[0].offsetHeight;
+
+ blockTableBody.value.style.transition = "transform 0.5s ease-in-out";
+ blockTableBody.value.style.transform = `translateY(-${rowHeight}px)`;
+
+ setTimeout(() => {
+ blockTableBody.value.style.transition = "none";
+ blockTableBody.value.style.transform = "translateY(0)";
+
+ // 鐩存帴鎿嶄綔DOM锛屽皢绗竴琛岀Щ鍒版渶鍚�
+ const firstRow = rows[0];
+ blockTableBody.value.removeChild(firstRow);
+ blockTableBody.value.appendChild(firstRow);
+ }, 500);
+ };
+
+ blockScrollTimer = setInterval(scrollTable, 2000);
+ };
+
+ const startBoardTableScroll = () => {
+ if (boardScrollTimer) {
+ clearInterval(boardScrollTimer);
+ }
+
+ const scrollTable = () => {
+ if (!boardTableBody.value || boardSalesData.value.length === 0) return;
+
+ const rows = boardTableBody.value.querySelectorAll("tr");
+ if (rows.length === 0) return;
+
+ const rowHeight = rows[0].offsetHeight;
+
+ boardTableBody.value.style.transition = "transform 0.5s ease-in-out";
+ boardTableBody.value.style.transform = `translateY(-${rowHeight}px)`;
+
+ setTimeout(() => {
+ boardTableBody.value.style.transition = "none";
+ boardTableBody.value.style.transform = "translateY(0)";
+
+ const firstItem = boardSalesData.value[0];
+ boardSalesData.value.shift();
+ boardSalesData.value.push(firstItem);
+ }, 500);
+ };
+
+ boardScrollTimer = setInterval(scrollTable, 2000);
+ };
+
+ const stopTableScroll = () => {
+ if (blockScrollTimer) {
+ clearInterval(blockScrollTimer);
+ blockScrollTimer = null;
+ }
+ if (boardScrollTimer) {
+ clearInterval(boardScrollTimer);
+ boardScrollTimer = null;
+ }
+ if (amountScrollTimer.value) {
+ clearInterval(amountScrollTimer.value);
+ amountScrollTimer.value = null;
+ }
+ };
+
+ // 澶勭悊鏃堕棿缁村害閫夋嫨
+ const handleBlockTimeDimensionChange = dimension => {
+ blockTimeDimension.value = dimension;
+ generateBlockSalesData();
+ };
+
+ const handleBoardTimeDimensionChange = dimension => {
+ boardTimeDimension.value = dimension;
+ generateBoardSalesData();
+ };
+ const blockProductType = ref("鐮屽潡");
+ // 澶勭悊浜у搧绫诲瀷閫夋嫨
+ const handleBlockProductTypeChange = type => {
+ blockProductType.value = type;
+ generateBlockSalesData();
+ };
+
+ const handleBoardProductTypeChange = type => {
+ boardProductType.value = type;
+ generateBoardSalesData();
+ };
+ const blockSelectedArea = ref("鍏ㄩ儴");
+ // 澶勭悊閿�鍞尯閫夋嫨
+ const handleBlockAreaChange = area => {
+ blockSelectedArea.value = area;
+ generateBlockSalesData();
+ };
+
+ const handleBoardAreaChange = area => {
+ boardSelectedArea.value = area;
+ generateBoardSalesData();
+ };
+
+ // 澶勭悊鏂板瀹㈡埛瓒嬪娍鏃堕棿缁村害鍒囨崲
+ const handleCustomerTimeDimensionChange = dimension => {
+ customerTimeDimension.value = dimension;
+ fetchCustomerTrendsData();
+ };
+ const blockTimeDimension = ref("骞�");
+
+ // 鐢熸垚鐮屽潡閿�鍞暟鎹�
+ const generateBlockSalesData = () => {
+ const data = [];
+ const year = 2024;
+
+ if (blockTimeDimension.value === "year") {
+ // 骞村害鏁版嵁锛�12涓湀
+ for (let month = 1; month <= 12; month++) {
+ const period = `${year}-${month.toString().padStart(2, "0")}`;
+ data.push({
+ period: period,
+ area: blockSelectedArea.value,
+ productType: blockProductType.value,
+ sales: Math.floor(Math.random() * 500) + 800,
+ sort: month,
+ });
+ }
+ } else {
+ // 鏈堝害鏁版嵁锛�30澶�
+ const month = 1;
+ for (let day = 1; day <= 30; day++) {
+ const period = `${year}-${month.toString().padStart(2, "0")}-${day
+ .toString()
+ .padStart(2, "0")}`;
+ data.push({
+ period: period,
+ area: blockSelectedArea.value,
+ productType: blockProductType.value,
+ sales: Math.floor(Math.random() * 50) + 20,
+ sort: day,
+ });
+ }
+ }
+
+ blockSalesData.value = data;
+ // 鏇存柊鍥捐〃
+ updateCharts();
+ };
+
+ // 鐢熸垚鏉挎潗閿�鍞暟鎹�
+ const generateBoardSalesData = () => {
+ const data = [];
+ const year = 2024;
+
+ if (boardTimeDimension.value === "year") {
+ // 骞村害鏁版嵁锛�12涓湀
+ for (let month = 1; month <= 12; month++) {
+ const period = `${year}-${month.toString().padStart(2, "0")}`;
+ data.push({
+ period: period,
+ area: boardSelectedArea.value,
+ productType: boardProductType.value,
+ sales: Math.floor(Math.random() * 400) + 600,
+ sort: month,
+ });
+ }
+ } else {
+ // 鏈堝害鏁版嵁锛�30澶�
+ const month = 1;
+ for (let day = 1; day <= 30; day++) {
+ const period = `${year}-${month.toString().padStart(2, "0")}-${day
+ .toString()
+ .padStart(2, "0")}`;
+ data.push({
+ period: period,
+ area: boardSelectedArea.value,
+ productType: boardProductType.value,
+ sales: Math.floor(Math.random() * 40) + 15,
+ sort: day,
+ });
+ }
+ }
+
+ boardSalesData.value = data;
+ // 鏇存柊鍥捐〃
+ updateCharts();
+ };
+
// 鐩戝惉绐楀彛澶у皬鍙樺寲
const handleResize = () => {
+ console.log("resize");
+ // 鍏堟洿鏂板浘琛ㄩ�夐」锛岄噸鏂拌绠楀搷搴斿紡鍊�
+ updateCharts();
+ // 鐒跺悗璋冩暣鍥捐〃澶у皬
if (salesVolumeChartInstance) {
salesVolumeChartInstance.resize();
}
@@ -1082,7 +1824,7 @@
};
// 鐢熷懡鍛ㄦ湡
- onMounted(() => {
+ onMounted(async () => {
// 鍚姩椤堕儴鏍忔椂闂村埛鏂�
if (!timeTicker) {
timeTicker = setInterval(() => {
@@ -1098,14 +1840,276 @@
endDate.format("YYYY-MM-DD"),
];
+ // 鐢熸垚鍒濆鏁版嵁
+ generateBlockSalesData();
+ generateBoardSalesData();
+
+ // 鑾峰彇鏁版嵁
+ await fetchDashboardData();
+ await fetchCustomerTrendsData();
+ await fetchSalesAnalysisTrendData();
+ await fetchTableSalesData();
+ await fetchSalesAmountChartData();
+ await fetchSalesAmountTableData();
+
// 绛夊緟DOM鏇存柊鍚庡垵濮嬪寲鍥捐〃
nextTick(() => {
initCharts();
+ // 鍚姩琛ㄦ牸婊氬姩鍔ㄧ敾
+ startBlockTableScroll();
+ startAmountTableScroll();
});
// 娣诲姞绐楀彛澶у皬鍙樺寲鐩戝惉
window.addEventListener("resize", handleResize);
document.addEventListener("fullscreenchange", handleFullscreenChange);
+ });
+
+ // 鐩戝惉鍥捐〃鏃堕棿缁村害鍜屼骇鍝佺被鍨嬪彉鍖�
+ watch([chartTimeDimension, chartProductType], async () => {
+ await fetchSalesAnalysisTrendData();
+ });
+
+ // 鐩戝惉琛ㄦ牸鏃堕棿缁村害鍜屼骇鍝佺被鍨嬪彉鍖�
+ watch([tableTimeDimension, tableProductType], async () => {
+ await fetchTableSalesData();
+ });
+
+ // 閿�鍞噾棰濆垎鏋愬浘琛ㄦ暟鎹紙鍙充笂锛�
+ const salesAmountChartData = ref({
+ dates: [],
+ customerTrends: [],
+ });
+
+ // 閿�鍞鏁版嵁缁熻琛ㄦ牸鏁版嵁锛堝彸涓嬶級
+ const salesAmountTableData = ref({
+ dates: [],
+ customerTrends: [],
+ });
+
+ // 閿�鍞鏁版嵁缁熻琛ㄦ牸绛涢�夌姸鎬侊紙鍙充笅锛�
+ const tableTimeDimension2 = ref("骞�");
+ const tableProductType2 = ref("鐮屽潡");
+
+ // 閿�鍞鏁版嵁缁熻琛ㄦ牸鏁版嵁
+ const amountSalesData = ref([]);
+ const amountScrollTimer = ref(null);
+
+ // 鑾峰彇閿�鍞噾棰濆垎鏋愬浘琛ㄦ暟鎹紙鍙充笂锛�
+ const fetchSalesAmountChartData = async () => {
+ try {
+ const response = await getSalesAmountAnalysis({
+ type: chartProductType2.value,
+ days: chartTimeDimension2.value,
+ });
+ if (response?.data) {
+ salesAmountChartData.value = response.data;
+ updateCharts();
+ }
+ } catch (error) {
+ console.error("鑾峰彇閿�鍞噾棰濆垎鏋愬浘琛ㄦ暟鎹け璐�:", error);
+ // 浣跨敤妯℃嫙鏁版嵁
+ salesAmountChartData.value = {
+ dates: [
+ "2026-01-01",
+ "2025-01-01",
+ "2024-01-01",
+ "2023-01-01",
+ "2022-01-01",
+ ],
+ customerTrends: [
+ { 鍐呰挋鍙�: 100, 閾跺窛: 200, 鑷彁: 300, 鍏朵粬: 150, 鍏ㄩ儴: 750 },
+ { 鍐呰挋鍙�: 80, 閾跺窛: 180, 鑷彁: 280, 鍏朵粬: 130, 鍏ㄩ儴: 670 },
+ { 鍐呰挋鍙�: 90, 閾跺窛: 190, 鑷彁: 290, 鍏朵粬: 140, 鍏ㄩ儴: 710 },
+ { 鍐呰挋鍙�: 70, 閾跺窛: 170, 鑷彁: 270, 鍏朵粬: 120, 鍏ㄩ儴: 630 },
+ { 鍐呰挋鍙�: 110, 閾跺窛: 210, 鑷彁: 310, 鍏朵粬: 160, 鍏ㄩ儴: 790 },
+ ],
+ };
+ }
+ };
+
+ // 鑾峰彇閿�鍞鏁版嵁缁熻琛ㄦ牸鏁版嵁锛堝彸涓嬶級
+ const fetchSalesAmountTableData = async () => {
+ try {
+ const response = await getSalesAmountAnalysis({
+ type: tableProductType2.value,
+ days: tableTimeDimension2.value,
+ });
+ if (response?.data) {
+ salesAmountTableData.value = response.data;
+ updateAmountSalesData();
+ }
+ } catch (error) {
+ console.error("鑾峰彇閿�鍞鏁版嵁缁熻琛ㄦ牸鏁版嵁澶辫触:", error);
+ // 浣跨敤妯℃嫙鏁版嵁
+ salesAmountTableData.value = {
+ dates: [
+ "2026-01-01",
+ "2025-01-01",
+ "2024-01-01",
+ "2023-01-01",
+ "2022-01-01",
+ ],
+ customerTrends: [
+ { 鍐呰挋鍙�: 100, 閾跺窛: 200, 鑷彁: 300, 鍏朵粬: 150, 鍏ㄩ儴: 750 },
+ { 鍐呰挋鍙�: 80, 閾跺窛: 180, 鑷彁: 280, 鍏朵粬: 130, 鍏ㄩ儴: 670 },
+ { 鍐呰挋鍙�: 90, 閾跺窛: 190, 鑷彁: 290, 鍏朵粬: 140, 鍏ㄩ儴: 710 },
+ { 鍐呰挋鍙�: 70, 閾跺窛: 170, 鑷彁: 270, 鍏朵粬: 120, 鍏ㄩ儴: 630 },
+ { 鍐呰挋鍙�: 110, 閾跺窛: 210, 鑷彁: 310, 鍏朵粬: 160, 鍏ㄩ儴: 790 },
+ ],
+ };
+ updateAmountSalesData();
+ }
+ };
+
+ // 鏇存柊閿�鍞噾棰濆垎鏋愯〃鏍兼暟鎹�
+ const updateAmountSalesData = () => {
+ const data = [];
+ const { dates, customerTrends } = salesAmountTableData.value;
+
+ // 鎻愬彇鎵�鏈夐攢鍞尯鍩�
+ const areaSet = new Set();
+ customerTrends.forEach(item => {
+ Object.keys(item).forEach(key => areaSet.add(key));
+ });
+
+ // 鏇存柊閿�鍞尯鍩熷垪琛紝纭繚"鍏ㄩ儴"鍦ㄧ涓�浣�
+ tableSalesAreas.value = [
+ "鍏ㄩ儴",
+ ...Array.from(areaSet).filter(area => area !== "鍏ㄩ儴"),
+ ];
+
+ // 纭繚閫変腑鐨勫尯鍩熷湪鍒楄〃涓�
+ if (!tableSalesAreas.value.includes(tableSelectedArea.value)) {
+ tableSelectedArea.value = "鍏ㄩ儴";
+ }
+
+ // 鐢熸垚琛ㄦ牸鏁版嵁
+ dates.forEach((date, index) => {
+ const trends = customerTrends[index] || {};
+ Object.keys(trends).forEach(area => {
+ data.push({
+ period: date,
+ area: area,
+ productType: tableProductType2.value,
+ sales: trends[area],
+ sort: data.length + 1,
+ });
+ });
+ });
+
+ amountSalesData.value = data;
+ };
+
+ // 绛涢�夊悗鐨勯攢鍞噾棰濆垎鏋愯〃鏍兼暟鎹�
+ const filteredAmountSalesData = computed(() => {
+ if (tableSelectedArea.value === "鍏ㄩ儴") {
+ // 鎸夊勾鏈堝垎缁勬眹鎬绘暟鎹�
+ const groupedData = {};
+ amountSalesData.value.forEach(item => {
+ const key = item.period;
+ if (!groupedData[key]) {
+ groupedData[key] = {
+ period: item.period,
+ area: "鍏ㄩ儴",
+ productType: tableProductType2.value,
+ sales: 0,
+ };
+ }
+ groupedData[key].sales += item.sales;
+ });
+ // 杞崲涓烘暟缁勫苟鎸夊勾鏈堟帓搴�
+ return Object.values(groupedData).sort((a, b) => {
+ return new Date(b.period) - new Date(a.period);
+ });
+ } else {
+ return amountSalesData.value.filter(
+ item => item.area === tableSelectedArea.value
+ );
+ }
+ });
+
+ // 閿�鍞噾棰濆垎鏋愯〃鏍兼�昏
+ const filteredAmountSalesTotal = computed(() => {
+ return filteredAmountSalesData.value.reduce(
+ (total, item) => total + item.sales,
+ 0
+ );
+ });
+
+ // 澶勭悊閿�鍞噾棰濆垎鏋愬浘琛ㄦ椂闂寸淮搴﹀彉鍖栵紙鍙充笂锛�
+ const handleChartTimeDimensionChange2 = dimension => {
+ chartTimeDimension2.value = dimension;
+ fetchSalesAmountChartData();
+ };
+
+ // 澶勭悊閿�鍞噾棰濆垎鏋愬浘琛ㄤ骇鍝佺被鍨嬪彉鍖栵紙鍙充笂锛�
+ const handleChartProductTypeChange2 = type => {
+ chartProductType2.value = type;
+ fetchSalesAmountChartData();
+ };
+
+ // 澶勭悊閿�鍞鏁版嵁缁熻琛ㄦ牸鏃堕棿缁村害鍙樺寲锛堝彸涓嬶級
+ const handleTableTimeDimensionChange2 = dimension => {
+ tableTimeDimension2.value = dimension;
+ fetchSalesAmountTableData();
+ // 閲嶆柊鍚姩婊氬姩锛屾牴鎹椂闂寸淮搴﹀喅瀹氭槸鍚︽粴鍔�
+ startAmountTableScroll();
+ };
+
+ // 澶勭悊閿�鍞鏁版嵁缁熻琛ㄦ牸浜у搧绫诲瀷鍙樺寲锛堝彸涓嬶級
+ const handleTableProductTypeChange2 = type => {
+ tableProductType2.value = type;
+ fetchSalesAmountTableData();
+ };
+
+ // 澶勭悊閿�鍞鏁版嵁缁熻琛ㄦ牸閿�鍞尯鍙樺寲锛堝彸涓嬶級
+ const handleTableAreaChange2 = area => {
+ tableSelectedArea.value = area;
+ };
+
+ // 鍚姩閿�鍞噾棰濆垎鏋愯〃鏍兼粴鍔�
+ const startAmountTableScroll = () => {
+ if (amountScrollTimer.value) {
+ clearInterval(amountScrollTimer.value);
+ }
+ // 鍙湁褰撴椂闂寸淮搴︿笉鏄�"骞�"鏃舵墠鍚姩婊氬姩
+ if (tableTimeDimension2.value === "骞�") {
+ return;
+ }
+
+ const scrollTable = () => {
+ if (!boardTableBody.value) return;
+ const rows = boardTableBody.value.querySelectorAll("tr");
+ if (rows.length === 0) return;
+
+ const rowHeight = rows[0].offsetHeight;
+
+ boardTableBody.value.style.transition = "transform 0.5s ease-in-out";
+ boardTableBody.value.style.transform = `translateY(-${rowHeight}px)`;
+
+ setTimeout(() => {
+ boardTableBody.value.style.transition = "none";
+ boardTableBody.value.style.transform = "translateY(0)";
+
+ // 鐩存帴鎿嶄綔DOM锛屽皢绗竴琛岀Щ鍒版渶鍚�
+ const firstRow = rows[0];
+ boardTableBody.value.removeChild(firstRow);
+ boardTableBody.value.appendChild(firstRow);
+ }, 500);
+ };
+
+ amountScrollTimer.value = setInterval(scrollTable, 2000);
+ };
+
+ // 鐩戝惉閿�鍞噾棰濆垎鏋愬浘琛ㄦ椂闂寸淮搴﹀拰浜у搧绫诲瀷鍙樺寲锛堝彸涓婏級
+ watch([chartTimeDimension2, chartProductType2], async () => {
+ // await fetchSalesAmountChartData();
+ });
+
+ // 鐩戝惉閿�鍞鏁版嵁缁熻琛ㄦ牸鏃堕棿缁村害鍜屼骇鍝佺被鍨嬪彉鍖栵紙鍙充笅锛�
+ watch([tableTimeDimension2, tableProductType2], async () => {
+ // await fetchSalesAmountTableData();
});
// 鑾峰彇浜у搧绫诲瀷鏍囩绫诲瀷
@@ -1170,9 +2174,9 @@
.sales-statistics-container {
position: relative;
width: 100%;
- min-height: calc(100vh - 84px);
+ min-height: calc(100vh - 8.4vh);
overflow: hidden;
- color: #B8C8E0;
+ color: #b8c8e0;
background: #041026;
}
@@ -1185,7 +2189,7 @@
.bi-bg {
position: absolute;
inset: 0;
- background-image: url("@/assets/BI/backImage@2x.png");
+ /* background-image: url("@/assets/BI/backImage@2x.png"); */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
@@ -1196,7 +2200,7 @@
.bi-topbar {
position: relative;
z-index: 2;
- height: 58px;
+ height: 5.8vh;
display: flex;
align-items: center;
justify-content: center;
@@ -1206,7 +2210,7 @@
position: absolute;
top: 0;
left: 0;
- height: 58px;
+ height: 8vh;
width: 100%;
object-fit: cover;
z-index: 0;
@@ -1217,7 +2221,7 @@
position: relative;
z-index: 1;
width: 100%;
- padding: 0 28px;
+ padding: 0 2.8vh;
display: flex;
align-items: center;
justify-content: center;
@@ -1227,58 +2231,57 @@
position: absolute;
left: 50%;
transform: translateX(-50%);
- font-size: 26px;
+ font-size: 2.6vh;
font-weight: 800;
- letter-spacing: 1px;
- background: linear-gradient(180deg, #ffffff 0%, #B8DFFF 100%);
+ letter-spacing: 0.1vh;
+ background: linear-gradient(180deg, #ffffff 0%, #b8dfff 100%);
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
- text-shadow: 0 0 26px rgba(0, 164, 237, 0.55);
+ text-shadow: 0 0 2.6vh rgba(0, 164, 237, 0.55);
}
.bi-topbar-left {
position: absolute;
- left: 10px;
+ left: 1vh;
display: flex;
align-items: center;
- gap: 8px;
+ gap: 0.8vh;
color: rgba(208, 231, 255, 0.85);
- font-size: 13px;
+ font-size: 1.3vh;
}
.status-sun {
color: #ffd85e;
- text-shadow: 0 0 10px rgba(255, 216, 94, 0.8);
- font-size: 13px;
+ text-shadow: 0 0 1vh rgba(255, 216, 94, 0.8);
+ font-size: 1.3vh;
line-height: 1;
}
.bi-topbar-meta {
position: absolute;
- right: 52px;
- top: 16px;
- font-size: 12px;
+ right: 5.2vh;
+ /* top: 1.6vh; */
+ font-size: 1.2vh;
font-weight: 500;
- letter-spacing: 0.5px;
+ letter-spacing: 0.05vh;
color: rgba(208, 231, 255, 0.85);
display: flex;
align-items: center;
- gap: 10px;
+ gap: 1vh;
}
.fullscreen-btn {
position: absolute;
- right: 10px;
- top: 12px;
+ bottom: -1vh;
transform: none;
- border: 1px solid rgba(64, 158, 255, 0.45);
+ border: 0.1vh solid rgba(64, 158, 255, 0.45);
background: rgba(0, 164, 237, 0.14);
color: #d0e7ff;
- width: 34px;
- height: 34px;
- border-radius: 6px;
+ width: 3.4vh;
+ height: 3.4vh;
+ border-radius: 0.6vh;
padding: 0;
cursor: pointer;
transition: all 0.2s ease;
@@ -1290,7 +2293,7 @@
.fullscreen-btn:hover {
background: rgba(0, 164, 237, 0.24);
- box-shadow: 0 0 12px rgba(0, 164, 237, 0.3);
+ box-shadow: 0 0 1.2vh rgba(0, 164, 237, 0.3);
}
.bi-topbar-sep {
@@ -1301,62 +2304,70 @@
.bi-dashboard-grid {
position: relative;
z-index: 2;
- height: calc(100vh - 84px - 58px);
- min-height: 450px;
- padding: 10px 18px 14px;
+ height: calc(100vh - 8.4vh - 5.8vh);
+ min-height: 45vh;
+ padding: 1vh 1.8vh 1.4vh;
display: grid;
grid-template-columns: 1fr 1.05fr 1fr;
grid-template-rows: 1fr 1fr;
- gap: 12px;
+ gap: 1.2vh;
}
.sales-statistics-container.is-fullscreen .bi-dashboard-grid {
- height: calc(100vh - 58px);
+ height: calc(100vh - 5.8vh);
}
.bi-panel {
background: rgba(3, 18, 46, 0.62);
- border: 1px solid rgba(64, 158, 255, 0.35);
- border-radius: 4px;
+ border: 0.1vh solid rgba(64, 158, 255, 0.35);
+ border-radius: 0.4vh;
overflow: hidden;
- box-shadow: 0 0 22px rgba(0, 164, 237, 0.12);
+ box-shadow: 0 0 2.2vh rgba(0, 164, 237, 0.12);
display: flex;
flex-direction: column;
position: relative;
}
.bi-panel-title {
- height: 44px;
+ height: 4.4vh;
display: flex;
align-items: center;
- padding: 0 18px;
- font-size: 15px;
+ padding: 0 1.8vh;
+ font-size: 1.5vh;
font-weight: 700;
- color: #B8C8E0;
+ color: #b8c8e0;
background: linear-gradient(
90deg,
rgba(0, 164, 237, 0.2),
rgba(0, 164, 237, 0.04)
);
- border-bottom: 1px solid rgba(64, 158, 255, 0.25);
+ border-bottom: 0.1vh solid rgba(64, 158, 255, 0.25);
}
- .panel-tabs {
+ .panel-tabs,
+ .panel-tabs2 {
position: absolute;
- top: 8px;
- right: 12px;
+ top: 0.8vh;
display: flex;
- gap: 6px;
+ gap: 0.6vh;
z-index: 4;
}
+ .panel-tabs {
+ right: 1.2vh;
+ }
+
+ .panel-tabs2 {
+ right: 8vh;
+ }
.tab-item {
- font-size: 12px;
+ font-size: 1.2vh;
color: rgba(184, 200, 224, 0.75);
- padding: 1px 5px;
- border: 1px solid rgba(64, 158, 255, 0.25);
- border-radius: 3px;
+ padding: 0.1vh 0.5vh;
+ border: 0.1vh solid rgba(64, 158, 255, 0.25);
+ border-radius: 0.3vh;
line-height: 1.4;
+ cursor: pointer;
}
.tab-item.active {
@@ -1367,7 +2378,77 @@
.bi-panel-body {
flex: 1;
- padding: 8px 10px;
+ padding: 0.8vh 1vh;
+ position: relative;
+ }
+
+ .scroll-table-container {
+ height: 33vh;
+ overflow: hidden;
+ position: relative;
+ }
+
+ .scroll-table {
+ width: 100%;
+ border-collapse: collapse;
+ color: #b8c8e0;
+ }
+
+ .scroll-table th {
+ /* background-color: #0e2a54; */
+ padding: 1.2vh;
+ text-align: left;
+ font-size: 1.2vh;
+ font-weight: bold;
+ border: 1px solid rgba(184, 200, 224, 0.2);
+ }
+
+ .scroll-table td {
+ padding: 1vh;
+ font-size: 1.1vh;
+ border-bottom: 1px solid rgba(184, 200, 224, 0.1);
+ }
+
+ .scroll-table tbody {
+ display: block;
+ height: 35vh;
+ overflow: hidden;
+ }
+
+ .scroll-table thead,
+ .scroll-table tbody tr {
+ display: table;
+ width: 100%;
+ table-layout: fixed;
+ }
+
+ .scroll-table th,
+ .scroll-table td {
+ width: 25%;
+ box-sizing: border-box;
+ font-size: 1.4vh;
+ }
+
+ .scroll-table tbody tr {
+ transition: all 0.5s ease-in-out;
+ }
+
+ /* .scroll-table tbody tr:nth-child(odd) {
+ background-color: rgba(64, 158, 255, 0.05);
+ }
+
+ .scroll-table tbody tr:nth-child(even) {
+ background-color: rgba(64, 158, 255, 0.1);
+ } */
+ .oddTableTr {
+ background-color: rgba(64, 158, 255, 0.05);
+ }
+ .evenTableTr {
+ background-color: rgba(64, 158, 255, 0.1);
+ }
+
+ .scroll-table-container:hover tbody {
+ overflow: hidden;
}
.echart-fill {
@@ -1377,21 +2458,23 @@
.chart-filter-tabs {
display: flex;
- gap: 6px;
- margin: 0 0 5px 0;
+ gap: 0.6vh;
+ margin: 0 0 0.5vh 0;
+ justify-self: end;
}
.cf-tab {
- font-size: 11px;
+ font-size: 1.1vh;
color: rgba(184, 200, 224, 0.68);
background: rgba(18, 56, 106, 0.65);
- border: 1px solid rgba(64, 158, 255, 0.25);
- padding: 3px 9px;
+ border: 0.1vh solid rgba(64, 158, 255, 0.25);
+ padding: 0.3vh 0.9vh;
line-height: 1;
+ cursor: pointer;
}
.cf-tab.active {
- color: #D9ECFF;
+ color: #d9ecff;
background: rgba(0, 108, 208, 0.85);
border-color: rgba(64, 158, 255, 0.65);
}
@@ -1399,57 +2482,90 @@
.chart-unit-row {
display: flex;
justify-content: space-between;
- font-size: 12px;
+ font-size: 1.2vh;
color: rgba(208, 231, 255, 0.88);
- margin-bottom: 4px;
- padding: 0 2px;
+ margin-bottom: 0.4vh;
+ padding: 0 0.2vh;
}
.dot-legend::before {
content: "";
display: inline-block;
- width: 8px;
- height: 8px;
- background: #65A0FF;
- margin-right: 6px;
+ width: 0.8vh;
+ height: 0.8vh;
+ background: #65a0ff;
+ margin-right: 0.6vh;
}
.chart-mini-title {
display: flex;
align-items: center;
- gap: 8px;
- font-size: 18px;
- color: #D9ECFF;
- font-weight: 700;
- margin: 0 0 8px 0;
- line-height: 1;
+ gap: 0.8vh;
+ font-size: 1.8vh;
+ color: #d9ecff;
}
+ /* 闈㈡澘搴曢儴鍚堣琛� */
+ .panel-summary-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 0.8vh 1.2vh;
+ /* margin-top: 0.8vh; */
+ background: #041e3c;
+ border-top: 0.1vh solid rgba(64, 158, 255, 0.25);
+ border-radius: 0 0 0.4vh 0.4vh;
+ width: 100%;
+ position: absolute;
+ bottom: 0;
+ }
+
+ .summary-label {
+ font-size: 1.3vh;
+ font-weight: 700;
+ color: #b8c8e0;
+ }
+
+ .summary-value {
+ font-size: 1.4vh;
+ font-weight: 800;
+ color: #00a4ed;
+ margin-right: 3.8vh;
+ text-shadow: 0 0 1vh rgba(0, 164, 237, 0.5);
+ }
+
+ .summary-value2 {
+ font-size: 1.4vh;
+ font-weight: 800;
+ color: #00a4ed;
+ margin-right: 1.8vh;
+ text-shadow: 0 0 1vh rgba(0, 164, 237, 0.5);
+ }
.diamond {
- width: 10px;
- height: 10px;
- background: #1E8BFF;
+ width: 1vh;
+ height: 1vh;
+ background: #1e8bff;
transform: rotate(45deg);
display: inline-block;
}
.chart-unit-single {
justify-content: flex-start;
- margin-bottom: 2px;
+ margin-bottom: 0.2vh;
}
.bi-panel-top-left .echart-fill,
.bi-panel-top-right .echart-fill {
- height: calc(100% - 44px);
+ height: calc(100% - 4.4vh);
}
.bi-panel-bottom-left .echart-fill,
.bi-panel-bottom-right .echart-fill {
- height: calc(100% - 28px);
+ height: calc(100% - 2.8vh);
}
.bi-panel-bottom-center .echart-fill {
- height: calc(100% - 44px);
+ height: calc(100% - 4.4vh);
}
.bi-panel-top-left {
@@ -1467,6 +2583,11 @@
.bi-panel-bottom-left {
grid-column: 1;
grid-row: 2;
+ overflow-y: auto;
+ }
+ .bi-panel-bottom-left::-webkit-scrollbar {
+ width: 0vh;
+ height: 0vh;
}
.bi-panel-bottom-center {
@@ -1477,6 +2598,11 @@
.bi-panel-bottom-right {
grid-column: 3;
grid-row: 2;
+ overflow-y: auto;
+ }
+ .bi-panel-bottom-right::-webkit-scrollbar {
+ width: 0vh;
+ height: 0vh;
}
/* 涓績鐜诞灞傦紙缁濆瀹氫綅鍦ㄧ綉鏍间笂鏂癸級 */
@@ -1484,20 +2610,31 @@
grid-column: 2;
grid-row: 1 / span 2;
position: absolute;
- left:25%;
+ background: url("@/assets/BI/imageSS@2x.png") no-repeat bottom center;
+ background-size: 100% 30%;
+ left: 25%;
top: 25%;
transform: translate(-50%, -50%);
- width: 400px;
- height: 275px;
+ width: 60vh;
+ height: 40.5vh;
z-index: 3;
pointer-events: none;
+ }
+ .center-ring-box {
+ position: absolute;
+ /* inset: 0; */
+ height: 100%;
+ width: 100%;
+ /* background-color: #fff; */
+ background: url("@/assets/BI/imageSStop.png") no-repeat center center;
+ background-size: 80% 90%;
}
.center-ring-bg {
width: 100%;
height: 100%;
object-fit: contain;
- filter: drop-shadow(0 0 20px rgba(0, 164, 237, 0.35));
+ filter: drop-shadow(0 0 2vh rgba(0, 164, 237, 0.35));
}
.center-ring-content {
@@ -1511,18 +2648,18 @@
position: absolute;
left: 50%;
top: 56%;
- width: 370px;
- height: 146px;
+ width: 37vh;
+ height: 14.6vh;
transform: translate(-50%, -50%) rotate(-18deg);
- border: 2px solid rgba(40, 186, 255, 0.45);
+ border: 0.2vh solid rgba(40, 186, 255, 0.45);
border-radius: 50%;
- filter: drop-shadow(0 0 8px rgba(0, 164, 237, 0.35));
+ filter: drop-shadow(0 0 0.8vh rgba(0, 164, 237, 0.35));
opacity: 0.7;
}
.center-ring-content::after {
- width: 360px;
- height: 150px;
+ width: 36vh;
+ height: 15vh;
transform: translate(-50%, -50%) rotate(26deg);
border-color: rgba(80, 220, 255, 0.35);
opacity: 0.55;
@@ -1530,15 +2667,15 @@
.center-ring-title {
position: absolute;
- top: 116px;
+ top: 50%;
left: 50%;
- transform: translateX(-50%);
- font-size: 50px;
- line-height: 1.06;
+ transform: translate(-50%, -50%);
+ font-size: 3.6vh;
+ line-height: 1.05;
text-align: center;
font-weight: 900;
- color: #EAF6FF;
- text-shadow: 0 0 34px rgba(0, 164, 237, 0.6);
+ color: #eaf6ff;
+ text-shadow: 0 0 2.2vh rgba(0, 164, 237, 0.55);
z-index: 2;
}
@@ -1547,112 +2684,153 @@
position: absolute;
left: 50%;
top: 50%;
- width: 155px;
- height: 155px;
+ width: 15.5vh;
+ height: 15.5vh;
transform: translate(-50%, -50%);
- background: radial-gradient(circle, rgba(43, 199, 255, 0.26) 0%, rgba(8, 28, 61, 0.86) 70%);
- border: 2px solid rgba(39, 198, 255, 0.46);
+ background: radial-gradient(
+ circle,
+ rgba(43, 199, 255, 0.26) 0%,
+ rgba(8, 28, 61, 0.86) 70%
+ );
+ border: 0.2vh solid rgba(39, 198, 255, 0.46);
border-radius: 50%;
- box-shadow: 0 0 20px rgba(0, 164, 237, 0.45), inset 0 0 26px rgba(0, 164, 237, 0.2);
+ box-shadow: 0 0 2vh rgba(0, 164, 237, 0.45),
+ inset 0 0 2.6vh rgba(0, 164, 237, 0.2);
z-index: -1;
}
.center-metric {
position: absolute;
- width: 155px;
+ width: 15.5vh;
z-index: 3;
text-align: center;
- }
-
- .center-metric::before {
- content: "";
- position: absolute;
- left: 50%;
- top: 50%;
- width: 104px;
- height: 104px;
- transform: translate(-50%, -50%);
- border-radius: 50%;
- border: 2px solid rgba(71, 223, 255, 0.4);
- background: radial-gradient(circle, rgba(37, 177, 255, 0.25) 0%, rgba(8, 33, 69, 0.55) 70%);
- box-shadow: 0 0 18px rgba(0, 164, 237, 0.35), inset 0 0 18px rgba(0, 164, 237, 0.2);
- z-index: -1;
+ height: 12vh;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
}
.center-metric-label {
- font-size: 16px;
+ font-size: 1.2vh;
font-weight: 500;
color: rgba(234, 246, 255, 0.9);
- margin-top: 4px;
+ margin-top: 0;
}
.center-metric-value {
- font-size: 48px;
- font-weight: 700;
- color: #EAF6FF;
- text-shadow: 0 0 8px rgba(0, 229, 255, 0.22);
- line-height: 1.1;
+ font-size: 3.4vh;
+ font-weight: 800;
+ color: #eaf6ff;
+ text-shadow: 0 0 0.8vh rgba(0, 229, 255, 0.22);
+ line-height: 1;
}
.center-metric-unit {
- margin-top: 2px;
- font-size: 14px;
+ margin-top: 0;
+ font-size: 1.2vh;
color: rgba(208, 231, 255, 0.85);
}
.m1 {
- top: -6px;
- left: -26px;
+ top: 2.5vh;
+ left: 4.8vh;
text-align: left;
}
.m2 {
- top: -6px;
- right: -26px;
+ top: 4.1vh;
+ right: 8.6vh;
text-align: right;
}
.m3 {
- bottom: 66px;
- left: -30px;
+ bottom: 7.9vh;
+ left: 4vh;
text-align: left;
}
.m4 {
- bottom: 66px;
- right: -30px;
+ bottom: 7vh;
+ right: 5.4vh;
text-align: right;
}
@media (max-width: 1100px) {
.bi-topbar-content {
- padding: 0 14px;
+ padding: 0 1.4vh;
}
.center-ring {
left: 45.2%;
- width: 330px;
- height: 245px;
- top: 24px;
+ width: 33vh;
+ height: 24.5vh;
+ top: 2.4vh;
}
.center-ring-title {
- top: 122px;
- font-size: 26px;
+ top: 50%;
+ font-size: 2.8vh;
+ transform: translate(-50%, -50%);
+ }
+ .center-metric {
+ height: 10.5vh;
}
.m1 {
- top: 52px;
- left: 42px;
+ top: 5.2vh;
+ left: 4.2vh;
}
.m2 {
- top: 54px;
- right: 42px;
+ top: 5.4vh;
+ right: 4.2vh;
}
.m3 {
- bottom: 62px;
- left: 48px;
+ bottom: 6.2vh;
+ left: 4.8vh;
}
.m4 {
- bottom: 68px;
- right: 44px;
+ bottom: 6.8vh;
+ right: 4.4vh;
}
}
-</style>
\ No newline at end of file
+ .scroll-table-content {
+ height: 39vh;
+ overflow: auto;
+ }
+ .scroll-table-content::-webkit-scrollbar {
+ width: 0;
+ height: 0;
+ background-color: transparent;
+ }
+ .total-row {
+ position: absolute;
+ bottom: 0vh;
+ left: 0;
+ width: 100%;
+ display: flex;
+ height: 3.5vh;
+ justify-content: space-around;
+ align-items: center;
+ background-color: #081843;
+ }
+
+ .total-cell {
+ width: 20%;
+ font-size: 1.4vh;
+ margin-bottom: 0.5vh;
+ line-height: 3.5vh;
+ padding-left: 0.8vh;
+ color: #eaf6ff;
+ text-shadow: 0 0 0.8vh rgba(0, 229, 255, 0.22);
+ text-align: left;
+ color: #c3c3c3;
+ }
+ .total-cell2 {
+ width: 20%;
+ font-size: 1.4vh;
+ margin-bottom: 0.5vh;
+ line-height: 3.5vh;
+ color: #eaf6ff;
+ text-shadow: 0 0 0.8vh rgba(0, 229, 255, 0.22);
+ text-align: left;
+ color: #c3c3c3;
+ }
+</style>
--
Gitblit v1.9.3