From de0b2cf892667c6e9fa71d1c3bbc9205de766035 Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期五, 22 五月 2026 11:46:11 +0800
Subject: [PATCH] 采购报表接口暂时注释
---
src/views/financialManagement/financialStatements/index.vue | 1654 ++++++++++++++++++++++++++++++----------------------------
1 files changed, 851 insertions(+), 803 deletions(-)
diff --git a/src/views/financialManagement/financialStatements/index.vue b/src/views/financialManagement/financialStatements/index.vue
index cf4eee5..32520dc 100644
--- a/src/views/financialManagement/financialStatements/index.vue
+++ b/src/views/financialManagement/financialStatements/index.vue
@@ -1,82 +1,78 @@
<template>
<div style="padding: 20px;">
<!-- 椤甸潰鏍囬鍜屾湀浠界瓫閫� -->
- <div class="w-full md:w-auto flex items-center gap-3" style="margin-bottom: 20px;">
- <el-date-picker
- v-model="dateRange"
- type="monthrange"
- format="YYYY-MM"
- value-format="YYYY-MM"
- range-separator="鑷�"
- start-placeholder="寮�濮嬫湀浠�"
- end-placeholder="缁撴潫鏈堜唤"
- :disabled-date="disabledDate"
- @change="handleDateChange"
- class="w-full md:w-auto"
- style="margin-right: 30px;"
- />
-
- <el-button
- type="primary"
- icon="Refresh"
- @click="resetDateRange"
- size="default"
- >
+ <div class="w-full md:w-auto flex items-center gap-3"
+ style="margin-bottom: 20px;">
+ <el-date-picker v-model="dateRange"
+ type="monthrange"
+ format="YYYY-MM"
+ value-format="YYYY-MM"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫湀浠�"
+ end-placeholder="缁撴潫鏈堜唤"
+ :disabled-date="disabledDate"
+ @change="handleDateChange"
+ class="w-full md:w-auto"
+ style="margin-right: 30px;" />
+ <el-button type="primary"
+ icon="Refresh"
+ @click="resetDateRange"
+ size="default">
閲嶇疆
</el-button>
</div>
-
<main class="container mx-auto px-4 pb-10">
<!-- 璐㈠姟鎸囨爣鍗$墖 -->
<div class="stats-cards">
<!-- 鎬昏惀鏀� -->
<div class="stat-card stat-card-blue">
<div class="stat-icon">
- <img src="@/assets/icons/png/walletBlue@2x.png" alt="鎬昏惀鏀�" />
+ <img src="@/assets/icons/png/walletBlue@2x.png"
+ alt="鎬昏惀鏀�" />
</div>
<div class="stat-content">
<div class="stat-label">鎬昏惀鏀�</div>
<div class="stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }} 鍏�</div>
</div>
</div>
-
<!-- 鎬绘敮鍑� -->
<div class="stat-card stat-card-orange">
<div class="stat-icon">
- <img src="@/assets/icons/png/walletOrange@2x.png" alt="鎬绘敮鍑�" />
+ <img src="@/assets/icons/png/walletOrange@2x.png"
+ alt="鎬绘敮鍑�" />
</div>
<div class="stat-content">
<div class="stat-label">鎬绘敮鍑�</div>
<div class="stat-value">{{ formatMoney(pageInfo.totalExpense || 0) }} 鍏�</div>
</div>
</div>
-
<!-- 鎬绘敹鍏ョ瑪鏁� -->
<div class="stat-card stat-card-green">
<div class="stat-icon">
- <img src="@/assets/icons/png/walletGreen@2x.png" alt="鎬绘敹鍏ョ瑪鏁�" />
+ <img src="@/assets/icons/png/walletGreen@2x.png"
+ alt="鎬绘敹鍏ョ瑪鏁�" />
</div>
<div class="stat-content">
<div class="stat-label">鎬绘敹鍏ョ瑪鏁�</div>
<div class="stat-value">{{ pageInfo.incomeNumber || 0 }} 绗�</div>
</div>
</div>
-
<!-- 鎬绘敮鍑虹瑪鏁� -->
<div class="stat-card stat-card-red">
<div class="stat-icon">
- <img src="@/assets/icons/png/walletRed@2x.png" alt="鎬绘敮鍑虹瑪鏁�" />
+ <img src="@/assets/icons/png/walletRed@2x.png"
+ alt="鎬绘敮鍑虹瑪鏁�" />
</div>
<div class="stat-content">
<div class="stat-label">鎬绘敮鍑虹瑪鏁�</div>
<div class="stat-value">{{ pageInfo.expenseNumber || 0 }} 绗�</div>
</div>
</div>
-
<!-- 鍑�鏀跺叆 -->
<div class="stat-card stat-card-yellow">
<div class="stat-icon">
- <img src="@/assets/icons/png/walletYellow@2x.png" alt="鍑�鏀跺叆" />
+ <img src="@/assets/icons/png/walletYellow@2x.png"
+ alt="鍑�鏀跺叆" />
</div>
<div class="stat-content">
<div class="stat-label">鍑�鏀跺叆</div>
@@ -84,19 +80,17 @@
</div>
</div>
</div>
-
<!-- 涓棿鍥捐〃鍖哄煙 -->
<div class="charts-row">
<!-- 宸︿晶锛氭敹鍏ユ敮鍑哄垎鏋� -->
<el-card class="chart-card">
<h2 class="section-title">鏀跺叆鏀嚭鍒嗘瀽</h2>
<div class="pie-chart-container">
- <Echarts
- :legend="pieLegendIncomeExpense"
- :chartStyle="chartStylePie"
- :series="pieSeriesIncomeExpense"
- :tooltip="pieTooltipIncomeExpense"
- style="height: 320px; width: 100%;">
+ <Echarts :legend="pieLegendIncomeExpense"
+ :chartStyle="chartStylePie"
+ :series="pieSeriesIncomeExpense"
+ :tooltip="pieTooltipIncomeExpense"
+ style="height: 320px; width: 100%;">
</Echarts>
<div class="pie-stats">
<div class="bar-stat-item">
@@ -110,7 +104,6 @@
</div>
</div>
</el-card>
-
<!-- 鍙充晶锛氳椤圭泩鍒╁垎鏋� -->
<el-card class="chart-card">
<h2 class="section-title">琛岄」鐩堝埄鍒嗘瀽</h2>
@@ -128,33 +121,30 @@
<span class="bar-stat-value">{{ formatMoney(pageInfo.totalIncome || 0) }}</span>
</div>
</div>
- <Echarts
- ref="barChart"
- :chartStyle="chartStyle"
- :grid="barGrid"
- :legend="barLegend"
- :series="barSeries"
- :tooltip="barTooltip"
- :xAxis="barXAxis"
- :yAxis="barYAxis"
- style="height: 300px; width: 100%;">
+ <Echarts ref="barChart"
+ :chartStyle="chartStyle"
+ :grid="barGrid"
+ :legend="barLegend"
+ :series="barSeries"
+ :tooltip="barTooltip"
+ :xAxis="barXAxis"
+ :yAxis="barYAxis"
+ style="height: 300px; width: 100%;">
</Echarts>
</el-card>
</div>
-
<!-- 搴曢儴锛氳惀鏀惰秼鍔垮垎鏋� -->
<el-card class="trend-chart-card">
<h2 class="section-title">钀ユ敹瓒嬪娍鍒嗘瀽</h2>
- <Echarts
- ref="trendChart"
- :chartStyle="chartStyle"
- :grid="grid"
- :legend="trendLegend"
- :series="trendSeries"
- :tooltip="tooltip"
- :xAxis="xAxis0"
- :yAxis="trendYAxis"
- style="height: 350px; width: 100%;">
+ <Echarts ref="trendChart"
+ :chartStyle="chartStyle"
+ :grid="grid"
+ :legend="trendLegend"
+ :series="trendSeries"
+ :tooltip="tooltip"
+ :xAxis="xAxis0"
+ :yAxis="trendYAxis"
+ style="height: 350px; width: 100%;">
</Echarts>
</el-card>
</main>
@@ -162,728 +152,817 @@
</template>
<script setup>
-import { ref, computed, onMounted, reactive, nextTick, getCurrentInstance } from 'vue';
-import 'element-plus/dist/index.css';
-import Echarts from "@/components/Echarts/echarts.vue";
-import { reportForms,reportIncome,reportExpense } from "@/api/financialManagement/financialStatements";
-import dayjs from "dayjs";
+ import {
+ ref,
+ computed,
+ onMounted,
+ reactive,
+ nextTick,
+ getCurrentInstance,
+ } from "vue";
+ import "element-plus/dist/index.css";
+ import Echarts from "@/components/Echarts/echarts.vue";
+ import {
+ reportForms,
+ reportIncome,
+ reportExpense,
+ } from "@/api/financialManagement/financialStatements";
+ import dayjs from "dayjs";
-// 鏃ユ湡鑼冨洿
-const dateRange = ref(null);
-const { proxy } = getCurrentInstance();
-const chartStyle = {
- width: '100%',
- height: '100%', // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
- position:'relative',
-}
-const grid = {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
-}
-const lineLegend = {
- show: false,
-}
-// 鎶樼嚎鍥炬彁绀烘
-const tooltip = reactive({
- trigger: 'axis',
- axisPointer: {
- type: 'line',
- lineStyle: { color: '#aaa' }
- },
- // 鑷畾涔夊唴瀹�
- formatter: function (params) {
- if (!params || !params.length) return ''
- const axisLabel = params[0].axisValueLabel || params[0].axisValue || ''
- const rows = params
- .map(p => {
- const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`
- return `${colorDot}${p.seriesName}: ${p.value}`
- })
- .join('<br/>')
- return `<div>${axisLabel}</div><div>${rows}</div>`
- }
-})
-const lineSeries0 = ref([])
-const lineSeries1 = ref([])
-
-// 鏍规嵁鏈堜唤鑼冨洿鐢熸垚 x 杞存暟鎹�
-const generateMonthLabels = (startMonth, endMonth) => {
- const labels = [];
- let current = dayjs(startMonth);
- const end = dayjs(endMonth);
-
- while (current.isBefore(end) || current.isSame(end, 'month')) {
- labels.push(`${current.month() + 1}鏈坄);
- current = current.add(1, 'month');
- }
-
- return labels;
-};
-
-const xAxis0 = ref([
- {
- type: 'category',
- axisTick: { show: true, alignWithLabel: true },
- data: [],
- },
-]);
-const xAxis1 = ref([
- {
- type: 'category',
- axisTick: { show: true, alignWithLabel: true },
- data: [],
- },
-]);
-const yAxis0 = [
-{
- type: 'value',
- name: '鏀跺叆缁熻', // 宸︿晶y杞�
- position: 'left',
- min: 0,
- // 鍧愭爣杞村悕绉版牱寮�
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
+ // 鏃ユ湡鑼冨洿
+ const dateRange = ref(null);
+ const { proxy } = getCurrentInstance();
+ const chartStyle = {
+ width: "100%",
+ height: "100%", // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+ position: "relative",
+ };
+ const grid = {
+ left: "3%",
+ right: "4%",
+ bottom: "3%",
+ containLabel: true,
+ };
+ const lineLegend = {
+ show: false,
+ };
+ // 鎶樼嚎鍥炬彁绀烘
+ const tooltip = reactive({
+ trigger: "axis",
+ axisPointer: {
+ type: "line",
+ lineStyle: { color: "#aaa" },
},
- }
-]
-
-const yAxis1 = [
-{
- type: 'value',
- name: '鏀嚭缁熻', // 宸︿晶y杞�
- position: 'left',
- min: 0,
- // 鍧愭爣杞村悕绉版牱寮�
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
+ // 鑷畾涔夊唴瀹�
+ formatter: function (params) {
+ if (!params || !params.length) return "";
+ const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
+ const rows = params
+ .map(p => {
+ const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
+ return `${colorDot}${p.seriesName}: ${p.value}`;
+ })
+ .join("<br/>");
+ return `<div>${axisLabel}</div><div>${rows}</div>`;
},
- }
-]
+ });
+ const lineSeries0 = ref([]);
+ const lineSeries1 = ref([]);
-const chartStylePie = {
- width: '100%',
- height: '100%' // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
-}
-const pieColors = ['#F04864','#FACC14', '#8543E0', '#1890FF', '#13C2C2','#2FC25B']; // 鍙牴鎹疄闄呰皟鏁�
-const pieData0 = ref([]);
-const pieData1 = ref([]);
+ // 鏍规嵁鏈堜唤鑼冨洿鐢熸垚 x 杞存暟鎹�
+ const generateMonthLabels = (startMonth, endMonth) => {
+ const labels = [];
+ let current = dayjs(startMonth);
+ const end = dayjs(endMonth);
-const pieLegend0 = computed(() => ({
- show: true,
- top: 'center',
- left: '60%',
- orient: 'vertical',
- icon: 'circle',
- data: (pieData0.value || []).filter(item => item && item.name).map(item => item.name),
- formatter: function(name) {
- if (!name) return '';
- const item = pieData0.value.find(i => i && i.name === name);
- if (!item) return name;
- return `${name} | ${item.percent} ${item.amount}`;
- },
- textStyle: {
- color: '#333',
- fontSize: 14,
- lineHeight: 26,
- }
-}));
-const pieLegend1 = computed(() => ({
- show: true,
- top: 'center',
- left: '60%',
- orient: 'vertical',
- icon: 'circle',
- data: (pieData1.value || []).filter(item => item && item.name).map(item => item.name),
- formatter: function(name) {
- if (!name) return '';
- const item = pieData1.value.find(i => i && i.name === name);
- if (!item) return name;
- return `${name} | ${item.percent} ${item.amount}`;
- },
- textStyle: {
- color: '#333',
- fontSize: 14,
- lineHeight: 26,
- }
-}));
+ while (current.isBefore(end) || current.isSame(end, "month")) {
+ labels.push(`${current.month() + 1}鏈坄);
+ current = current.add(1, "month");
+ }
-const materialPieSeries0 = computed(() => [
- {
- type: 'pie',
- radius: ['50%', '65%'],
- center: ['25%', '50%'],
- avoidLabelOverlap: false,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 2
+ return labels;
+ };
+
+ const xAxis0 = ref([
+ {
+ type: "category",
+ axisTick: { show: true, alignWithLabel: true },
+ data: [],
},
- label: {
- show: false
+ ]);
+ const xAxis1 = ref([
+ {
+ type: "category",
+ axisTick: { show: true, alignWithLabel: true },
+ data: [],
},
- data: (pieData0.value || []).filter(item => item && item.name),
- color: pieColors
- }
-]);
-const materialPieSeries1 = computed(() => [
- {
- type: 'pie',
- radius: ['50%', '65%'],
- center: ['25%', '50%'],
- avoidLabelOverlap: false,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 2
- },
- label: {
- show: false
- },
- data: (pieData1.value || []).filter(item => item && item.name),
- color: pieColors
- }
-]);
-const pieTooltip = reactive({
- trigger: 'item',
- formatter: function(params) {
- // 妫�鏌ユ暟鎹槸鍚﹀瓨鍦�
- if (!params.data) return params.name;
- // 鎷兼帴瀹屾暣鍐呭
- return `
- <div>
- <div style="color:${params.color};font-size:16px;">鈼�</div>
- <div>${params.name}</div>
- <div>鍗犳瘮锛�${params.data.percent}</div>
- <div>閲戦锛�${params.data.amount}</div>
- </div>
- `;
- }
-})
-
-
-const pageInfo = ref({
-})
-
-// 鏍煎紡鍖栭噾棰�
-const formatMoney = (value) => {
- if (!value && value !== 0) return '0';
- return Number(value).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
-};
-
-// 鏀跺叆鏀嚭鍒嗘瀽楗煎浘
-const pieDataIncomeExpense = computed(() => {
- const totalIncome = Number(pageInfo.value.totalIncome) || 0;
- const totalExpense = Number(pageInfo.value.totalExpense) || 0;
- const total = totalIncome + totalExpense;
- if (total === 0) {
- return [
- { name: '鏀跺叆', value: 0, percent: '0%' },
- { name: '鏀嚭', value: 0, percent: '0%' }
- ];
- }
- const incomePercent = ((totalIncome / total) * 100).toFixed(0);
- const expensePercent = ((totalExpense / total) * 100).toFixed(0);
- return [
- { name: '鏀跺叆', value: totalIncome, percent: `${incomePercent}%` },
- { name: '鏀嚭', value: totalExpense, percent: `${expensePercent}%` }
- ];
-});
-
-const pieLegendIncomeExpense = computed(() => ({
- show: false
-}));
-
-const pieTooltipIncomeExpense = reactive({
- trigger: 'item',
- formatter: function(params) {
- if (!params.data) return params.name;
- return `${params.name}鍗犳瘮 ${params.percent}%`;
- }
-});
-
-const pieSeriesIncomeExpense = computed(() => [
- {
- type: 'pie',
- radius: ['0%', '70%'],
- center: ['50%', '50%'],
- avoidLabelOverlap: true,
- itemStyle: {
- borderColor: '#fff',
- borderWidth: 2
- },
- label: {
- show: true,
- position: 'outside',
- formatter: function(params) {
- return `${params.name}鍗犳瘮 ${params.percent}%`;
+ ]);
+ const yAxis0 = [
+ {
+ type: "value",
+ name: "鏀跺叆缁熻", // 宸︿晶y杞�
+ position: "left",
+ min: 0,
+ // 鍧愭爣杞村悕绉版牱寮�
+ nameTextStyle: {
+ color: "#000",
+ fontSize: 14,
},
+ },
+ ];
+
+ const yAxis1 = [
+ {
+ type: "value",
+ name: "鏀嚭缁熻", // 宸︿晶y杞�
+ position: "left",
+ min: 0,
+ // 鍧愭爣杞村悕绉版牱寮�
+ nameTextStyle: {
+ color: "#000",
+ fontSize: 14,
+ },
+ },
+ ];
+
+ const chartStylePie = {
+ width: "100%",
+ height: "100%", // 璁剧疆鍥捐〃瀹瑰櫒鐨勯珮搴�
+ };
+ const pieColors = [
+ "#F04864",
+ "#FACC14",
+ "#8543E0",
+ "#1890FF",
+ "#13C2C2",
+ "#2FC25B",
+ ]; // 鍙牴鎹疄闄呰皟鏁�
+ const pieData0 = ref([]);
+ const pieData1 = ref([]);
+
+ const pieLegend0 = computed(() => ({
+ show: true,
+ top: "center",
+ left: "60%",
+ orient: "vertical",
+ icon: "circle",
+ data: (pieData0.value || [])
+ .filter(item => item && item.name)
+ .map(item => item.name),
+ formatter: function (name) {
+ if (!name) return "";
+ const item = pieData0.value.find(i => i && i.name === name);
+ if (!item) return name;
+ return `${name} | ${item.percent} ${item.amount}`;
+ },
+ textStyle: {
+ color: "#333",
fontSize: 14,
- color: '#333'
+ lineHeight: 26,
},
- labelLine: {
- show: true,
- length: 15,
- length2: 10,
- lineStyle: {
- color: '#333'
- }
+ }));
+ const pieLegend1 = computed(() => ({
+ show: true,
+ top: "center",
+ left: "60%",
+ orient: "vertical",
+ icon: "circle",
+ data: (pieData1.value || [])
+ .filter(item => item && item.name)
+ .map(item => item.name),
+ formatter: function (name) {
+ if (!name) return "";
+ const item = pieData1.value.find(i => i && i.name === name);
+ if (!item) return name;
+ return `${name} | ${item.percent} ${item.amount}`;
},
- emphasis: {
+ textStyle: {
+ color: "#333",
+ fontSize: 14,
+ lineHeight: 26,
+ },
+ }));
+
+ const materialPieSeries0 = computed(() => [
+ {
+ type: "pie",
+ radius: ["50%", "65%"],
+ center: ["25%", "50%"],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderColor: "#fff",
+ borderWidth: 2,
+ },
+ label: {
+ show: false,
+ },
+ data: (pieData0.value || []).filter(item => item && item.name),
+ color: pieColors,
+ },
+ ]);
+ const materialPieSeries1 = computed(() => [
+ {
+ type: "pie",
+ radius: ["50%", "65%"],
+ center: ["25%", "50%"],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderColor: "#fff",
+ borderWidth: 2,
+ },
+ label: {
+ show: false,
+ },
+ data: (pieData1.value || []).filter(item => item && item.name),
+ color: pieColors,
+ },
+ ]);
+ const pieTooltip = reactive({
+ trigger: "item",
+ formatter: function (params) {
+ // 妫�鏌ユ暟鎹槸鍚﹀瓨鍦�
+ if (!params.data) return params.name;
+ // 鎷兼帴瀹屾暣鍐呭
+ return `
+ <div>
+ <div style="color:${params.color};font-size:16px;">鈼�</div>
+ <div>${params.name}</div>
+ <div>鍗犳瘮锛�${params.data.percent}</div>
+ <div>閲戦锛�${params.data.amount}</div>
+ </div>
+ `;
+ },
+ });
+
+ const pageInfo = ref({});
+
+ // 鏍煎紡鍖栭噾棰�
+ const formatMoney = value => {
+ if (!value && value !== 0) return "0";
+ return Number(value).toLocaleString("zh-CN", {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2,
+ });
+ };
+
+ // 鏀跺叆鏀嚭鍒嗘瀽楗煎浘
+ const pieDataIncomeExpense = computed(() => {
+ const totalIncome = Number(pageInfo.value.totalIncome) || 0;
+ const totalExpense = Number(pageInfo.value.totalExpense) || 0;
+ const total = totalIncome + totalExpense;
+ if (total === 0) {
+ return [
+ { name: "鏀跺叆", value: 0, percent: "0%" },
+ { name: "鏀嚭", value: 0, percent: "0%" },
+ ];
+ }
+ const incomePercent = ((totalIncome / total) * 100).toFixed(0);
+ const expensePercent = ((totalExpense / total) * 100).toFixed(0);
+ return [
+ { name: "鏀跺叆", value: totalIncome, percent: `${incomePercent}%` },
+ { name: "鏀嚭", value: totalExpense, percent: `${expensePercent}%` },
+ ];
+ });
+
+ const pieLegendIncomeExpense = computed(() => ({
+ show: false,
+ }));
+
+ const pieTooltipIncomeExpense = reactive({
+ trigger: "item",
+ formatter: function (params) {
+ if (!params.data) return params.name;
+ return `${params.name}鍗犳瘮 ${params.percent}%`;
+ },
+ });
+
+ const pieSeriesIncomeExpense = computed(() => [
+ {
+ type: "pie",
+ radius: ["0%", "70%"],
+ center: ["50%", "50%"],
+ avoidLabelOverlap: true,
+ itemStyle: {
+ borderColor: "#fff",
+ borderWidth: 2,
+ },
label: {
show: true,
- fontSize: 16,
- fontWeight: 'bold'
- }
+ position: "outside",
+ formatter: function (params) {
+ return `${params.name}鍗犳瘮 ${params.percent}%`;
+ },
+ fontSize: 14,
+ color: "#333",
+ },
+ labelLine: {
+ show: true,
+ length: 15,
+ length2: 10,
+ lineStyle: {
+ color: "#333",
+ },
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: 16,
+ fontWeight: "bold",
+ },
+ },
+ data: pieDataIncomeExpense.value,
+ color: ["#1890FF", "#FACC14"],
},
- data: pieDataIncomeExpense.value,
- color: ['#1890FF', '#FACC14']
- }
-]);
+ ]);
-// 琛岄」鐩堝埄鍒嗘瀽鏌辩姸鍥�
-const barXAxis = computed(() => {
- return [{
- type: 'category',
- data: (allBarTypes.value && allBarTypes.value.length > 0) ? allBarTypes.value : ['椤圭洰1', '椤圭洰2', '椤圭洰3', '椤圭洰4', '椤圭洰5', '椤圭洰6', '椤圭洰7'],
- axisTick: { show: true, alignWithLabel: true },
- }];
-});
-
-const barYAxis = [{
- type: 'value',
- name: '鍗曚綅: 鍏�',
- position: 'left',
- min: 0,
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
- },
-}];
-
-const barGrid = {
- left: '3%',
- right: '4%',
- bottom: '3%',
- containLabel: true
-};
-
-const barLegend = {
- show: true,
- top: 10,
- right: 10,
-};
-
-// 鑾峰彇鎵�鏈夌被鍨嬪悕绉�
-const allBarTypes = computed(() => {
- const incomeTypes = (lineSeries0.value || []).map(item => item.name || item.typeName).filter(Boolean);
- const expenseTypes = (lineSeries1.value || []).map(item => item.name || item.typeName).filter(Boolean);
- return [...new Set([...incomeTypes, ...expenseTypes])];
-});
-
-const barSeries = computed(() => {
- if (allBarTypes.value.length === 0) {
+ // 琛岄」鐩堝埄鍒嗘瀽鏌辩姸鍥�
+ const barXAxis = computed(() => {
return [
{
- name: '鏀嚭',
- type: 'bar',
- data: [],
- itemStyle: { color: '#1890FF' }
+ type: "category",
+ data:
+ allBarTypes.value && allBarTypes.value.length > 0
+ ? allBarTypes.value
+ : ["椤圭洰1", "椤圭洰2", "椤圭洰3", "椤圭洰4", "椤圭洰5", "椤圭洰6", "椤圭洰7"],
+ axisTick: { show: true, alignWithLabel: true },
+ },
+ ];
+ });
+
+ const barYAxis = [
+ {
+ type: "value",
+ name: "鍗曚綅: 鍏�",
+ position: "left",
+ min: 0,
+ nameTextStyle: {
+ color: "#000",
+ fontSize: 14,
+ },
+ },
+ ];
+
+ const barGrid = {
+ left: "3%",
+ right: "4%",
+ bottom: "3%",
+ containLabel: true,
+ };
+
+ const barLegend = {
+ show: true,
+ top: 10,
+ right: 10,
+ };
+
+ // 鑾峰彇鎵�鏈夌被鍨嬪悕绉�
+ const allBarTypes = computed(() => {
+ const incomeTypes = (lineSeries0.value || [])
+ .map(item => item.name || item.typeName)
+ .filter(Boolean);
+ const expenseTypes = (lineSeries1.value || [])
+ .map(item => item.name || item.typeName)
+ .filter(Boolean);
+ return [...new Set([...incomeTypes, ...expenseTypes])];
+ });
+
+ const barSeries = computed(() => {
+ if (allBarTypes.value.length === 0) {
+ return [
+ {
+ name: "鏀嚭",
+ type: "bar",
+ data: [],
+ itemStyle: { color: "#1890FF" },
+ },
+ {
+ name: "鏀跺叆",
+ type: "bar",
+ data: [],
+ itemStyle: { color: "#13C2C2" },
+ },
+ ];
+ }
+
+ // 璁$畻姣忎釜椤圭洰鐨勬�绘敹鍏ワ紙姹囨�绘墍鏈夋湀浠斤級
+ const incomeData = allBarTypes.value.map(typeName => {
+ const incomeItem = (lineSeries0.value || []).find(
+ item => (item.name || item.typeName) === typeName
+ );
+ if (incomeItem && incomeItem.data && Array.isArray(incomeItem.data)) {
+ return incomeItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
+ }
+ return 0;
+ });
+
+ // 璁$畻姣忎釜椤圭洰鐨勬�绘敮鍑猴紙姹囨�绘墍鏈夋湀浠斤級
+ const expenseData = allBarTypes.value.map(typeName => {
+ const expenseItem = (lineSeries1.value || []).find(
+ item => (item.name || item.typeName) === typeName
+ );
+ if (expenseItem && expenseItem.data && Array.isArray(expenseItem.data)) {
+ return expenseItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
+ }
+ return 0;
+ });
+
+ return [
+ {
+ name: "鏀嚭",
+ type: "bar",
+ data: expenseData,
+ itemStyle: { color: "#1890FF" },
},
{
- name: '鏀跺叆',
- type: 'bar',
- data: [],
- itemStyle: { color: '#13C2C2' }
- }
+ name: "鏀跺叆",
+ type: "bar",
+ data: incomeData,
+ itemStyle: { color: "#13C2C2" },
+ },
];
- }
-
- // 璁$畻姣忎釜椤圭洰鐨勬�绘敹鍏ワ紙姹囨�绘墍鏈夋湀浠斤級
- const incomeData = allBarTypes.value.map(typeName => {
- const incomeItem = (lineSeries0.value || []).find(item => (item.name || item.typeName) === typeName);
- if (incomeItem && incomeItem.data && Array.isArray(incomeItem.data)) {
- return incomeItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
- }
- return 0;
});
-
- // 璁$畻姣忎釜椤圭洰鐨勬�绘敮鍑猴紙姹囨�绘墍鏈夋湀浠斤級
- const expenseData = allBarTypes.value.map(typeName => {
- const expenseItem = (lineSeries1.value || []).find(item => (item.name || item.typeName) === typeName);
- if (expenseItem && expenseItem.data && Array.isArray(expenseItem.data)) {
- return expenseItem.data.reduce((sum, val) => sum + (Number(val) || 0), 0);
- }
- return 0;
- });
-
- return [
- {
- name: '鏀嚭',
- type: 'bar',
- data: expenseData,
- itemStyle: { color: '#1890FF' }
+
+ const barTooltip = reactive({
+ trigger: "axis",
+ axisPointer: {
+ type: "shadow",
},
- {
- name: '鏀跺叆',
- type: 'bar',
- data: incomeData,
- itemStyle: { color: '#13C2C2' }
- }
- ];
-});
-
-const barTooltip = reactive({
- trigger: 'axis',
- axisPointer: {
- type: 'shadow'
- },
- formatter: function (params) {
- if (!params || !params.length) return '';
- const axisLabel = params[0].axisValueLabel || params[0].axisValue || '';
- const rows = params
- .map(p => {
- const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
- const value = typeof p.value === 'number' ? p.value.toFixed(2) : p.value;
- return `${colorDot}${p.seriesName} ${value}`;
- })
- .join('<br/>');
- return `<div>${axisLabel}</div><div>${rows}</div>`;
- }
-});
-
-// 钀ユ敹瓒嬪娍鍒嗘瀽
-const trendLegend = {
- show: true,
- top: 10,
- right: 10,
-};
-
-const trendYAxis = [{
- type: 'value',
- name: '鍗曚綅: 鍏�',
- position: 'left',
- min: 0,
- nameTextStyle: {
- color: '#000',
- fontSize: 14,
- },
-}];
-
-const trendSeries = computed(() => {
- // 姹囨�绘墍鏈夋敮鍑虹被鍨嬬殑鏁版嵁
- let expenseTrend = [];
- if (lineSeries1.value.length > 0) {
- const monthCount = Math.max(...lineSeries1.value.map(item => item.data?.length || 0));
- expenseTrend = Array(monthCount).fill(0);
- lineSeries1.value.forEach(item => {
- if (item.data && Array.isArray(item.data)) {
- item.data.forEach((val, index) => {
- if (index < monthCount) {
- expenseTrend[index] += Number(val) || 0;
- }
- });
- }
- });
- }
-
- // 姹囨�绘墍鏈夋敹鍏ョ被鍨嬬殑鏁版嵁
- let incomeTrend = [];
- if (lineSeries0.value.length > 0) {
- const monthCount = Math.max(...lineSeries0.value.map(item => item.data?.length || 0));
- incomeTrend = Array(monthCount).fill(0);
- lineSeries0.value.forEach(item => {
- if (item.data && Array.isArray(item.data)) {
- item.data.forEach((val, index) => {
- if (index < monthCount) {
- incomeTrend[index] += Number(val) || 0;
- }
- });
- }
- });
- }
-
- return [
- {
- name: '鏀嚭',
- type: 'line',
- data: expenseTrend,
- itemStyle: { color: '#1890FF' },
- smooth: true
+ formatter: function (params) {
+ if (!params || !params.length) return "";
+ const axisLabel = params[0].axisValueLabel || params[0].axisValue || "";
+ const rows = params
+ .map(p => {
+ const colorDot = `<span style="display:inline-block;margin-right:6px;width:8px;height:8px;border-radius:50%;background:${p.color}"></span>`;
+ const value =
+ typeof p.value === "number" ? p.value.toFixed(2) : p.value;
+ return `${colorDot}${p.seriesName} ${value}`;
+ })
+ .join("<br/>");
+ return `<div>${axisLabel}</div><div>${rows}</div>`;
},
- {
- name: '鏀跺叆',
- type: 'line',
- data: incomeTrend,
- itemStyle: { color: '#13C2C2' },
- smooth: true
- }
- ];
-});
-
-// 鑾峰彇鏈�杩戝叚涓湀鐨勮寖鍥�
-const getLastSixMonths = () => {
- const endMonth = dayjs().format('YYYY-MM');
- const startMonth = dayjs().subtract(5, 'month').format('YYYY-MM');
- return [startMonth, endMonth];
-};
-
-const getData = async () => {
- if (!dateRange.value || !Array.isArray(dateRange.value) || dateRange.value.length !== 2) {
- return;
- }
- const startDateStr = dateRange.value[0];
- const endDateStr = dateRange.value[1];
- if (!startDateStr || !endDateStr) {
- return;
- }
-
- // 楠岃瘉鏃ユ湡鏍煎紡骞惰浆鎹负瀹屾暣鏃ユ湡
- const startDate = dayjs(startDateStr);
- const endDate = dayjs(endDateStr);
- if (!startDate.isValid() || !endDate.isValid()) {
- console.error('鏃犳晥鐨勬棩鏈熸牸寮�');
- return;
- }
-
- // 鏇存柊 x 杞存暟鎹�
- const monthLabels = generateMonthLabels(startDateStr, endDateStr);
- xAxis0.value[0].data = monthLabels;
- xAxis1.value[0].data = monthLabels;
-
- // 寮�濮嬫湀浠芥嫾鎺ョ涓�澶╋紝缁撴潫鏈堜唤鎷兼帴鏈�鍚庝竴澶�
- const entryDateStart = startDate.startOf('month').format('YYYY-MM-DD');
- const entryDateEnd = endDate.endOf('month').format('YYYY-MM-DD');
-
- try {
- const {code,data} = await reportForms({entryDateStart, entryDateEnd});
- if(code === 200 && data) {
- pageInfo.value = data || {};
- // 瀹夊叏澶勭悊鏁版嵁锛岃繃婊ゆ帀 null 鎴� undefined
- pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
- name:item.typeName || '',
- value:item.account || 0,
- percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
- amount:`楼${(item.account || 0).toFixed(2)}`
- }))
- pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
- name:item.typeName || '',
- value:item.account || 0,
- percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
- amount:`楼${(item.account || 0).toFixed(2)}`
- }))
- }
- } catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
- try{
- const {code,data} = await reportIncome({entryDateStart, entryDateEnd});
- if(code==200 && data && Array.isArray(data)){
- lineSeries0.value = data.filter(item => item && item.typeName).map(item=>({
- name:item.typeName || '',
- type: 'line',
- data:(item.account || []).map(val => Number(val) || 0)
- }))
- }
- }catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
- try{
- const {code,data} = await reportExpense({entryDateStart, entryDateEnd});
- if(code==200 && data && Array.isArray(data)){
- lineSeries1.value = data.filter(item => item && item.typeName).map(item=>({
- name:item.typeName || '',
- type: 'line',
- data:(item.account || []).map(val => Number(val) || 0)
- }))
- }
- }catch (error) {
- console.error('鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�', error);
- }
-};
-
-
-// 鍒濆鍖�
-onMounted(() => {
- // 璁剧疆榛樿鍊间负鏈�杩戝叚涓湀
- const defaultRange = getLastSixMonths();
- dateRange.value = defaultRange;
- // 浣跨敤 nextTick 纭繚缁勪欢瀹屽叏娓叉煋鍚庡啀璋冪敤
- nextTick(() => {
- getData();
});
-});
-// 闄愬埗鏈堜唤閫夋嫨鑼冨洿锛堟渶澶�12涓湀锛�
-const disabledDate = (time) => {
- // 濡傛灉娌℃湁閫夋嫨寮�濮嬫湀浠斤紝涓嶇鐢ㄤ换浣曟棩鏈�
- if (!dateRange.value || !Array.isArray(dateRange.value) || !dateRange.value[0]) {
- return false;
- }
-
- const startMonth = dayjs(dateRange.value[0]);
- const currentMonth = dayjs(time);
-
- // 濡傛灉褰撳墠鏈堜唤鍦ㄥ紑濮嬫湀浠戒箣鍓嶏紝绂佺敤
- if (currentMonth.isBefore(startMonth, 'month')) {
- return true;
- }
-
- // 璁$畻鏈�澶у厑璁哥殑鏈堜唤锛堝紑濮嬫湀浠� + 11涓湀 = 12涓湀锛�
- const maxMonth = startMonth.add(11, 'month');
-
- // 绂佺敤瓒呰繃12涓湀鐨勬湀浠�
- return currentMonth.isAfter(maxMonth, 'month');
-};
+ // 钀ユ敹瓒嬪娍鍒嗘瀽
+ const trendLegend = {
+ show: true,
+ top: 10,
+ right: 10,
+ };
-// 澶勭悊鏈堜唤鑼冨洿鍙樺寲
-const handleDateChange = (newRange) => {
- if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
- return;
- }
-
- // 楠岃瘉鏈堜唤鑼冨洿涓嶈秴杩�12涓湀
- const startDate = dayjs(newRange[0]);
- const endDate = dayjs(newRange[1]);
- const monthDiff = endDate.diff(startDate, 'month');
-
- if (monthDiff > 11) {
- proxy.$modal.msgWarning('鏈�澶氬彧鑳介�夋嫨12涓湀浠�');
- // 鑷姩璋冩暣涓�12涓湀
- const adjustedEnd = startDate.add(11, 'month').format('YYYY-MM');
- dateRange.value = [newRange[0], adjustedEnd];
+ const trendYAxis = [
+ {
+ type: "value",
+ name: "鍗曚綅: 鍏�",
+ position: "left",
+ min: 0,
+ nameTextStyle: {
+ color: "#000",
+ fontSize: 14,
+ },
+ },
+ ];
+
+ const trendSeries = computed(() => {
+ // 姹囨�绘墍鏈夋敮鍑虹被鍨嬬殑鏁版嵁
+ let expenseTrend = [];
+ if (lineSeries1.value.length > 0) {
+ const monthCount = Math.max(
+ ...lineSeries1.value.map(item => item.data?.length || 0)
+ );
+ expenseTrend = Array(monthCount).fill(0);
+ lineSeries1.value.forEach(item => {
+ if (item.data && Array.isArray(item.data)) {
+ item.data.forEach((val, index) => {
+ if (index < monthCount) {
+ expenseTrend[index] += Number(val) || 0;
+ }
+ });
+ }
+ });
+ }
+
+ // 姹囨�绘墍鏈夋敹鍏ョ被鍨嬬殑鏁版嵁
+ let incomeTrend = [];
+ if (lineSeries0.value.length > 0) {
+ const monthCount = Math.max(
+ ...lineSeries0.value.map(item => item.data?.length || 0)
+ );
+ incomeTrend = Array(monthCount).fill(0);
+ lineSeries0.value.forEach(item => {
+ if (item.data && Array.isArray(item.data)) {
+ item.data.forEach((val, index) => {
+ if (index < monthCount) {
+ incomeTrend[index] += Number(val) || 0;
+ }
+ });
+ }
+ });
+ }
+
+ return [
+ {
+ name: "鏀嚭",
+ type: "line",
+ data: expenseTrend,
+ itemStyle: { color: "#1890FF" },
+ smooth: true,
+ },
+ {
+ name: "鏀跺叆",
+ type: "line",
+ data: incomeTrend,
+ itemStyle: { color: "#13C2C2" },
+ smooth: true,
+ },
+ ];
+ });
+
+ // 鑾峰彇鏈�杩戝叚涓湀鐨勮寖鍥�
+ const getLastSixMonths = () => {
+ const endMonth = dayjs().format("YYYY-MM");
+ const startMonth = dayjs().subtract(5, "month").format("YYYY-MM");
+ return [startMonth, endMonth];
+ };
+
+ const getData = async () => {
+ if (
+ !dateRange.value ||
+ !Array.isArray(dateRange.value) ||
+ dateRange.value.length !== 2
+ ) {
+ return;
+ }
+ const startDateStr = dateRange.value[0];
+ const endDateStr = dateRange.value[1];
+ if (!startDateStr || !endDateStr) {
+ return;
+ }
+
+ // 楠岃瘉鏃ユ湡鏍煎紡骞惰浆鎹负瀹屾暣鏃ユ湡
+ const startDate = dayjs(startDateStr);
+ const endDate = dayjs(endDateStr);
+ if (!startDate.isValid() || !endDate.isValid()) {
+ console.error("鏃犳晥鐨勬棩鏈熸牸寮�");
+ return;
+ }
+
+ // 鏇存柊 x 杞存暟鎹�
+ const monthLabels = generateMonthLabels(startDateStr, endDateStr);
+ xAxis0.value[0].data = monthLabels;
+ xAxis1.value[0].data = monthLabels;
+
+ // 寮�濮嬫湀浠芥嫾鎺ョ涓�澶╋紝缁撴潫鏈堜唤鎷兼帴鏈�鍚庝竴澶�
+ const entryDateStart = startDate.startOf("month").format("YYYY-MM-DD");
+ const entryDateEnd = endDate.endOf("month").format("YYYY-MM-DD");
+
+ try {
+ // const {code,data} = await reportForms({entryDateStart, entryDateEnd});
+ // if(code === 200 && data) {
+ // pageInfo.value = data || {};
+ // // 瀹夊叏澶勭悊鏁版嵁锛岃繃婊ゆ帀 null 鎴� undefined
+ // pieData0.value = (data.incomeType || []).filter(item => item && item.typeName).map(item=>({
+ // name:item.typeName || '',
+ // value:item.account || 0,
+ // percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+ // amount:`楼${(item.account || 0).toFixed(2)}`
+ // }))
+ // pieData1.value = (data.expenseType || []).filter(item => item && item.typeName).map(item=>({
+ // name:item.typeName || '',
+ // value:item.account || 0,
+ // percent:`${((item.proportion || 0) * 100).toFixed(2)}%`,
+ // amount:`楼${(item.account || 0).toFixed(2)}`
+ // }))
+ // }
+ } catch (error) {
+ console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
+ }
+ try {
+ // const { code, data } = await reportIncome({ entryDateStart, entryDateEnd });
+ // if (code == 200 && data && Array.isArray(data)) {
+ // lineSeries0.value = data
+ // .filter(item => item && item.typeName)
+ // .map(item => ({
+ // name: item.typeName || "",
+ // type: "line",
+ // data: (item.account || []).map(val => Number(val) || 0),
+ // }));
+ // }
+ } catch (error) {
+ console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
+ }
+ try {
+ // const { code, data } = await reportExpense({
+ // entryDateStart,
+ // entryDateEnd,
+ // });
+ // if (code == 200 && data && Array.isArray(data)) {
+ // lineSeries1.value = data
+ // .filter(item => item && item.typeName)
+ // .map(item => ({
+ // name: item.typeName || "",
+ // type: "line",
+ // data: (item.account || []).map(val => Number(val) || 0),
+ // }));
+ // }
+ } catch (error) {
+ console.error("鑾峰彇璐㈠姟鎸囨爣鏁版嵁澶辫触锛�", error);
+ }
+ };
+
+ // 鍒濆鍖�
+ onMounted(() => {
+ // 璁剧疆榛樿鍊间负鏈�杩戝叚涓湀
+ const defaultRange = getLastSixMonths();
+ dateRange.value = defaultRange;
+ // 浣跨敤 nextTick 纭繚缁勪欢瀹屽叏娓叉煋鍚庡啀璋冪敤
+ nextTick(() => {
+ getData();
+ });
+ });
+
+ // 闄愬埗鏈堜唤閫夋嫨鑼冨洿锛堟渶澶�12涓湀锛�
+ const disabledDate = time => {
+ // 濡傛灉娌℃湁閫夋嫨寮�濮嬫湀浠斤紝涓嶇鐢ㄤ换浣曟棩鏈�
+ if (
+ !dateRange.value ||
+ !Array.isArray(dateRange.value) ||
+ !dateRange.value[0]
+ ) {
+ return false;
+ }
+
+ const startMonth = dayjs(dateRange.value[0]);
+ const currentMonth = dayjs(time);
+
+ // 濡傛灉褰撳墠鏈堜唤鍦ㄥ紑濮嬫湀浠戒箣鍓嶏紝绂佺敤
+ if (currentMonth.isBefore(startMonth, "month")) {
+ return true;
+ }
+
+ // 璁$畻鏈�澶у厑璁哥殑鏈堜唤锛堝紑濮嬫湀浠� + 11涓湀 = 12涓湀锛�
+ const maxMonth = startMonth.add(11, "month");
+
+ // 绂佺敤瓒呰繃12涓湀鐨勬湀浠�
+ return currentMonth.isAfter(maxMonth, "month");
+ };
+
+ // 澶勭悊鏈堜唤鑼冨洿鍙樺寲
+ const handleDateChange = newRange => {
+ if (!newRange || !Array.isArray(newRange) || newRange.length !== 2) {
+ return;
+ }
+
+ // 楠岃瘉鏈堜唤鑼冨洿涓嶈秴杩�12涓湀
+ const startDate = dayjs(newRange[0]);
+ const endDate = dayjs(newRange[1]);
+ const monthDiff = endDate.diff(startDate, "month");
+
+ if (monthDiff > 11) {
+ proxy.$modal.msgWarning("鏈�澶氬彧鑳介�夋嫨12涓湀浠�");
+ // 鑷姩璋冩暣涓�12涓湀
+ const adjustedEnd = startDate.add(11, "month").format("YYYY-MM");
+ dateRange.value = [newRange[0], adjustedEnd];
+ getData();
+ return;
+ }
+
+ dateRange.value = newRange;
getData();
- return;
- }
-
- dateRange.value = newRange;
- getData();
-};
+ };
-// 閲嶇疆鏈堜唤鑼冨洿
-const resetDateRange = () => {
- // 閲嶇疆涓烘渶杩戝叚涓湀
- dateRange.value = getLastSixMonths();
- getData();
-};
-
+ // 閲嶇疆鏈堜唤鑼冨洿
+ const resetDateRange = () => {
+ // 閲嶇疆涓烘渶杩戝叚涓湀
+ dateRange.value = getLastSixMonths();
+ getData();
+ };
</script>
<style scoped lang="scss">
-/* 鍩虹鏍峰紡琛ュ厖 */
-:root {
- --el-color-primary: #4f46e5;
-}
-
-/* 缁熻鍗$墖鏍峰紡 */
-.stats-cards {
- display: grid;
- grid-template-columns: repeat(5, 1fr);
- gap: 20px;
- margin-bottom: 20px;
-}
-
-.stat-card {
- background: #fff;
- border: 1px solid #e4e7ed;
- border-radius: 8px;
- padding: 20px;
- display: flex;
- align-items: center;
- gap: 15px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
- transition: all 0.3s;
-
- &:hover {
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
- transform: translateY(-2px);
+ /* 鍩虹鏍峰紡琛ュ厖 */
+ :root {
+ --el-color-primary: #4f46e5;
}
-
- .stat-icon {
- width: 48px;
- height: 48px;
- flex-shrink: 0;
-
- img {
- width: 100%;
- height: 100%;
- object-fit: contain;
- }
+
+ /* 缁熻鍗$墖鏍峰紡 */
+ .stats-cards {
+ display: grid;
+ grid-template-columns: repeat(5, 1fr);
+ gap: 20px;
+ margin-bottom: 20px;
}
-
- .stat-content {
- flex: 1;
+
+ .stat-card {
+ background: #fff;
+ border: 1px solid #e4e7ed;
+ border-radius: 8px;
+ padding: 20px;
display: flex;
- flex-direction: column;
- gap: 8px;
- }
-
- .stat-label {
- font-size: 14px;
- color: #666;
- line-height: 1.2;
- }
-
- .stat-value {
- font-size: 24px;
- font-weight: 600;
- color: #333;
- line-height: 1.2;
- }
-
- .stat-trend {
- font-size: 12px;
- line-height: 1.2;
-
- &.trend-up {
- color: #f56c6c;
+ align-items: center;
+ gap: 15px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+ transition: all 0.3s;
+
+ &:hover {
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+ transform: translateY(-2px);
}
-
- &.trend-down {
- color: #67c23a;
+
+ .stat-icon {
+ width: 48px;
+ height: 48px;
+ flex-shrink: 0;
+
+ img {
+ width: 100%;
+ height: 100%;
+ object-fit: contain;
+ }
+ }
+
+ .stat-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ .stat-label {
+ font-size: 14px;
+ color: #666;
+ line-height: 1.2;
+ }
+
+ .stat-value {
+ font-size: 24px;
+ font-weight: 600;
+ color: #333;
+ line-height: 1.2;
+ }
+
+ .stat-trend {
+ font-size: 12px;
+ line-height: 1.2;
+
+ &.trend-up {
+ color: #f56c6c;
+ }
+
+ &.trend-down {
+ color: #67c23a;
+ }
}
}
-}
-/* 鍥捐〃琛屽竷灞� */
-.charts-row {
- display: grid;
- grid-template-columns: 1fr 1fr;
- gap: 20px;
- margin-bottom: 20px;
-}
-
-.chart-card {
- border: 1px solid #e4e7ed;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-
- :deep(.el-card__body) {
- padding: 20px !important;
+ /* 鍥捐〃琛屽竷灞� */
+ .charts-row {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 20px;
+ margin-bottom: 20px;
}
-}
-.trend-chart-card {
- border: 1px solid #e4e7ed;
- border-radius: 8px;
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
-
- :deep(.el-card__body) {
- padding: 20px !important;
+ .chart-card {
+ border: 1px solid #e4e7ed;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+ :deep(.el-card__body) {
+ padding: 20px !important;
+ }
}
-}
-/* 楗煎浘瀹瑰櫒 */
-.pie-chart-container {
- position: relative;
-
- .pie-stats {
+ .trend-chart-card {
+ border: 1px solid #e4e7ed;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+
+ :deep(.el-card__body) {
+ padding: 20px !important;
+ }
+ }
+
+ /* 楗煎浘瀹瑰櫒 */
+ .pie-chart-container {
+ position: relative;
+
+ .pie-stats {
+ display: flex;
+ justify-content: space-between;
+ gap: 20px;
+ margin-top: 20px;
+
+ .bar-stat-item {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+ padding: 15px;
+ background: #f5f7fa;
+ border-radius: 6px;
+ flex: 1;
+
+ .bar-stat-label {
+ font-size: 14px;
+ color: #666;
+ }
+
+ .bar-stat-value {
+ font-size: 18px;
+ font-weight: 600;
+ color: #333;
+ }
+ }
+ }
+ }
+
+ /* 鏌辩姸鍥惧ご閮ㄧ粺璁� */
+ .bar-chart-header {
display: flex;
justify-content: space-between;
gap: 20px;
- margin-top: 20px;
-
+ margin-bottom: 20px;
+
.bar-stat-item {
display: flex;
flex-direction: column;
@@ -893,12 +972,12 @@
background: #f5f7fa;
border-radius: 6px;
flex: 1;
-
+
.bar-stat-label {
font-size: 14px;
color: #666;
}
-
+
.bar-stat-value {
font-size: 18px;
font-weight: 600;
@@ -906,81 +985,50 @@
}
}
}
-}
-/* 鏌辩姸鍥惧ご閮ㄧ粺璁� */
-.bar-chart-header {
- display: flex;
- justify-content: space-between;
- gap: 20px;
- margin-bottom: 20px;
-
- .bar-stat-item {
- display: flex;
- flex-direction: column;
- align-items: center;
- gap: 8px;
- padding: 15px;
- background: #f5f7fa;
- border-radius: 6px;
- flex: 1;
-
- .bar-stat-label {
- font-size: 14px;
- color: #666;
- }
-
- .bar-stat-value {
- font-size: 18px;
- font-weight: 600;
- color: #333;
+ /* 鏍囬鏍峰紡 */
+ .section-title {
+ position: relative;
+ font-size: 18px;
+ color: #333;
+ padding-left: 12px;
+ margin-bottom: 20px;
+ font-weight: 700;
+
+ &::before {
+ position: absolute;
+ left: 0;
+ top: 2px;
+ content: "";
+ width: 4px;
+ height: 18px;
+ background-color: #002fa7;
+ border-radius: 2px;
}
}
-}
-/* 鏍囬鏍峰紡 */
-.section-title {
- position: relative;
- font-size: 18px;
- color: #333;
- padding-left: 12px;
- margin-bottom: 20px;
- font-weight: 700;
-
- &::before {
- position: absolute;
- left: 0;
- top: 2px;
- content: '';
- width: 4px;
- height: 18px;
- background-color: #002FA7;
- border-radius: 2px;
+ /* 鍝嶅簲寮忚璁� */
+ @media (max-width: 1400px) {
+ .stats-cards {
+ grid-template-columns: repeat(3, 1fr);
+ }
}
-}
-/* 鍝嶅簲寮忚璁� */
-@media (max-width: 1400px) {
- .stats-cards {
- grid-template-columns: repeat(3, 1fr);
- }
-}
+ @media (max-width: 1024px) {
+ .stats-cards {
+ grid-template-columns: repeat(2, 1fr);
+ }
-@media (max-width: 1024px) {
- .stats-cards {
- grid-template-columns: repeat(2, 1fr);
+ .charts-row {
+ grid-template-columns: 1fr;
+ }
}
-
- .charts-row {
- grid-template-columns: 1fr;
- }
-}
-@media (max-width: 640px) {
- .stats-cards {
- grid-template-columns: 1fr;
+ @media (max-width: 640px) {
+ .stats-cards {
+ grid-template-columns: 1fr;
+ }
}
-}
</style>
--
Gitblit v1.9.3