From 32a7bdfd6cd20caeae91bcd6ecaab3adcd3bb0cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= Date: Mon, 22 Sep 2025 14:44:36 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=8E=88=20perf:=20=E5=9B=BE=E8=A1=A8?= =?UTF-8?q?=E7=AE=80=E5=8D=95=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/components/TimeFilter.vue | 8 +- .../src/views/finance/dashboard/index.vue | 264 +++++++----------- 2 files changed, 106 insertions(+), 166 deletions(-) diff --git a/gear-ui3/src/views/finance/dashboard/components/TimeFilter.vue b/gear-ui3/src/views/finance/dashboard/components/TimeFilter.vue index bada856..4a24900 100644 --- a/gear-ui3/src/views/finance/dashboard/components/TimeFilter.vue +++ b/gear-ui3/src/views/finance/dashboard/components/TimeFilter.vue @@ -201,9 +201,9 @@ const handleQuery = () => { // 重置按钮点击 const handleReset = () => { - timeGranularity.value = ''; - startDate.value = ''; - endDate.value = ''; + timeGranularity.value = 'week'; + startDate.value = new Date().toISOString().split('T')[0] + ' 00:00:00'; + calculateEndDate(); emit('reset'); }; @@ -219,7 +219,7 @@ watch(timeGranularity, (newVal) => { // 初始时间设置为今天,触发一次qeury onMounted(() => { - startDate.value = new Date().toISOString().split('T')[0] + ' 00:00:00'; + handleReset(); handleQuery(); }); diff --git a/gear-ui3/src/views/finance/dashboard/index.vue b/gear-ui3/src/views/finance/dashboard/index.vue index 6dfa08a..5ce5bf6 100644 --- a/gear-ui3/src/views/finance/dashboard/index.vue +++ b/gear-ui3/src/views/finance/dashboard/index.vue @@ -3,11 +3,7 @@ - + @@ -36,7 +32,7 @@
- 净现金流 + 净收益
{{ netCashflow | formatCurrency }}
@@ -60,7 +56,7 @@ - +
收入支出趋势 @@ -70,6 +66,16 @@
+ + +
+ 按供应商区分的支出 +
+
+
+
+
+
@@ -95,19 +101,6 @@
- - - - -
- 按供应商区分的支出 -
-
-
-
-
-
-
@@ -116,80 +109,25 @@
回款(应收未收)任务信息
- - - - - - - - - - + + + + + + + + + +
- +
@@ -252,7 +190,7 @@ const initCharts = () => { if (supplierChart.value) { supplierChartInstance.value = echarts.init(supplierChart.value); } - + // 监听窗口大小变化,调整图表 window.addEventListener('resize', () => { trendChartInstance.value?.resize(); @@ -266,21 +204,21 @@ const initCharts = () => { const fetchData = async (timeParams) => { tableLoading.value = true; currentTimeParams.value = timeParams || currentTimeParams.value; - + try { // 获取应收数据 const receivableRes = await listReceivable({ pageSize: 9999, pageNum: 1 }); receivableData.value = receivableRes.rows || []; receivableTasks.value = receivableData.value.filter(item => item.status === '未结清'); receivableTotal.value = receivableRes.total || 0; - + // 获取应付数据 const payableRes = await listPayable({ pageSize: 9999, pageNum: 1 }); payableData.value = payableRes.rows || []; - + // 处理数据并更新指标 processData(); - + // 更新图表 updateCharts(); } catch (error) { @@ -297,15 +235,15 @@ const processData = () => { totalIncome.value = receivableData.value.reduce((sum, item) => { return sum + parseFloat(item.amount || 0); }, 0); - + // 计算总支出(应付金额总和) totalExpense.value = payableData.value.reduce((sum, item) => { return sum + parseFloat(item.amount || 0); }, 0); - + // 计算净现金流 netCashflow.value = totalIncome.value - totalExpense.value; - + // 计算未结清应收总额和数量 const outstanding = receivableData.value.filter(item => item.status === '未结清'); outstandingReceivable.value = outstanding.reduce((sum, item) => { @@ -326,12 +264,12 @@ const updateCharts = () => { const updateTrendChart = () => { // 按时间粒度处理数据 const timeGroups = groupDataByTime(); - + // 准备图表数据 const xAxisData = Object.keys(timeGroups); const incomeData = xAxisData.map(key => timeGroups[key].income); const expenseData = xAxisData.map(key => timeGroups[key].expense); - + // 设置图表配置 const option = { tooltip: { @@ -391,7 +329,7 @@ const updateTrendChart = () => { } ] }; - + trendChartInstance.value.setOption(option); }; @@ -399,7 +337,7 @@ const updateTrendChart = () => { const updateOrderChart = () => { // 按订单ID合并数据 const orderMap = {}; - + // 处理应收数据 receivableData.value.forEach(item => { if (!orderMap[item.orderId]) { @@ -410,7 +348,7 @@ const updateOrderChart = () => { } orderMap[item.orderId].income += parseFloat(item.amount || 0); }); - + // 处理应付数据 payableData.value.forEach(item => { if (!orderMap[item.orderId]) { @@ -421,7 +359,7 @@ const updateOrderChart = () => { } orderMap[item.orderId].expense += parseFloat(item.amount || 0); }); - + // 转换为图表数据 const orderList = Object.entries(orderMap) .map(([orderId, data]) => ({ @@ -432,11 +370,11 @@ const updateOrderChart = () => { })) .sort((a, b) => b.net - a.net) .slice(0, 10); // 只展示前10个订单 - + const xAxisData = orderList.map(item => `订单 ${item.orderId.slice(-6)}`); const incomeData = orderList.map(item => item.income); const expenseData = orderList.map(item => item.expense); - + // 设置图表配置 const option = { tooltip: { @@ -494,7 +432,7 @@ const updateOrderChart = () => { } ] }; - + orderChartInstance.value.setOption(option); }; @@ -502,7 +440,7 @@ const updateOrderChart = () => { const updateCustomerChart = () => { // 按客户分组计算收入 const customerMap = {}; - + receivableData.value.forEach(item => { if (!customerMap[item.customerId]) { customerMap[item.customerId] = { @@ -512,12 +450,12 @@ const updateCustomerChart = () => { } customerMap[item.customerId].amount += parseFloat(item.amount || 0); }); - + // 转换为图表数据并排序 const customerList = Object.values(customerMap) .sort((a, b) => b.amount - a.amount) .slice(0, 10); // 只展示前10个客户 - + // 设置图表配置 const option = { tooltip: { @@ -560,7 +498,7 @@ const updateCustomerChart = () => { } ] }; - + customerChartInstance.value.setOption(option); }; @@ -568,7 +506,7 @@ const updateCustomerChart = () => { const updateSupplierChart = () => { // 按供应商分组计算支出 const supplierMap = {}; - + payableData.value.forEach(item => { if (!supplierMap[item.supplierId]) { supplierMap[item.supplierId] = { @@ -578,12 +516,12 @@ const updateSupplierChart = () => { } supplierMap[item.supplierId].amount += parseFloat(item.amount || 0); }); - + // 转换为图表数据并排序 const supplierList = Object.values(supplierMap) .sort((a, b) => b.amount - a.amount) .slice(0, 10); // 只展示前10个供应商 - + // 设置图表配置 const option = { tooltip: { @@ -623,7 +561,7 @@ const updateSupplierChart = () => { } ] }; - + supplierChartInstance.value.setOption(option); }; @@ -631,37 +569,37 @@ const updateSupplierChart = () => { const groupDataByTime = () => { const timeGroups = {}; const granularity = currentTimeParams.value.timeGranularity || 'month'; - + // 处理应收数据 receivableData.value.forEach(item => { const date = new Date(item.dueDate); const timeKey = getTimeKey(date, granularity); - + if (!timeGroups[timeKey]) { timeGroups[timeKey] = { income: 0, expense: 0 }; } - + timeGroups[timeKey].income += parseFloat(item.amount || 0); }); - + // 处理应付数据 payableData.value.forEach(item => { const date = new Date(item.dueDate); const timeKey = getTimeKey(date, granularity); - + if (!timeGroups[timeKey]) { timeGroups[timeKey] = { income: 0, expense: 0 }; } - + timeGroups[timeKey].expense += parseFloat(item.amount || 0); }); - + // 排序时间分组 return Object.keys(timeGroups).sort().reduce((obj, key) => { obj[key] = timeGroups[key]; @@ -673,7 +611,7 @@ const groupDataByTime = () => { const getTimeKey = (date, granularity) => { const year = date.getFullYear(); const month = date.getMonth() + 1; - + if (granularity === 'year') { return `${year}`; } else if (granularity === 'month') { @@ -719,14 +657,14 @@ const handleFilterReset = () => { } .page-header { - margin-bottom: 20px; - + margin-bottom: 10px; + h1 { font-size: 24px; color: #1f2d3d; margin-bottom: 5px; } - + p { font-size: 14px; color: #8392a5; @@ -735,51 +673,51 @@ const handleFilterReset = () => { .content-container { .time-filter { - margin-bottom: 20px; + margin-bottom: 10px; } - + .indicator-cards { - margin-bottom: 20px; - + margin-bottom: 10px; + .indicator-card { height: 100%; - padding: 15px; + padding: 5px; position: relative; overflow: hidden; - + .card-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 10px; + margin-bottom: 5px; color: #8392a5; font-size: 14px; - + i { - font-size: 16px; + font-size: 12px; } } - + .card-value { font-size: 24px; font-weight: bold; margin-bottom: 5px; color: #1f2d3d; } - + .card-desc { font-size: 12px; color: #8392a5; - + .rise { color: #f56c6c; } - + .drop { color: #409eff; } } - + &::after { content: ''; position: absolute; @@ -791,70 +729,70 @@ const handleFilterReset = () => { opacity: 0.1; } } - + .total-income { &::after { background-color: #4e79a7; } } - + .total-expense { &::after { background-color: #e15759; } } - + .net-cashflow { &::after { background-color: #59a14f; } } - + .outstanding-receivable { &::after { background-color: #9c755f; } } } - + .charts-container { - margin-bottom: 20px; - + margin-bottom: 10px; + .chart-row { - margin-bottom: 20px; + margin-bottom: 10px; } - + .chart-card { height: 100%; - + .chart-header { font-size: 16px; font-weight: 500; color: #1f2d3d; - padding: 15px 20px; + padding: 5px 10px; border-bottom: 1px solid #eee; } - + .chart-content { - padding: 20px; + padding: 10px; } - + .chart-wrapper { width: 100%; height: 400px; } } } - + .table-container { .table-header { font-size: 16px; font-weight: 500; color: #1f2d3d; - padding: 15px 20px; + padding: 5px 10px; border-bottom: 1px solid #eee; } - + .pagination-container { margin-top: 15px; text-align: right; @@ -874,12 +812,14 @@ const handleFilterReset = () => { @media (max-width: 992px) { .indicator-cards { .el-col { - &:nth-child(1), &:nth-child(2) { + + &:nth-child(1), + &:nth-child(2) { margin-bottom: 20px; } } } - + .charts-container { .chart-row { .el-col { @@ -888,7 +828,7 @@ const handleFilterReset = () => { } } } - + .chart-wrapper { height: 300px; } @@ -903,7 +843,7 @@ const handleFilterReset = () => { } } } - + .charts-container { .chart-wrapper { height: 250px;