feat: 增强财务管理系统功能与分析能力
主要更新: - 🎯 新增综合分析仪表板,包含关键指标卡片、预算对比、智能洞察等组件 - 📊 增强数据可视化能力,新增标签云分析、时间维度分析等图表 - 📱 优化移动端响应式设计,改进触控交互体验 - 🔧 新增多个API模块(base、budget、tag),完善数据管理 - 🗂️ 重构路由结构,新增贷款、快速添加、设置、统计等独立模块 - 🔄 优化数据导入导出功能,增强数据迁移能力 - 🐛 修复多个已知问题,提升系统稳定性 技术改进: - 使用IndexedDB提升本地存储性能 - 实现模拟API服务,支持离线开发 - 增加自动化测试脚本,确保功能稳定 - 优化打包配置,提升构建效率 文件变更: - 新增42个文件 - 修改55个文件 - 包含测试脚本、配置文件、组件和API模块 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,18 +1,13 @@
|
||||
<template>
|
||||
<div class="monthly-comparison-chart">
|
||||
<div ref="chartRef" class="chart-container"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { EChartsOption } from '#/components/charts/useChart';
|
||||
import type { Transaction } from '#/types/finance';
|
||||
|
||||
import { computed, onMounted, ref, watch } from 'vue';
|
||||
|
||||
import { useChart } from '#/components/charts/useChart';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { useChart } from '#/components/charts/useChart';
|
||||
|
||||
interface Props {
|
||||
transactions: Transaction[];
|
||||
year: number;
|
||||
@@ -24,17 +19,30 @@ const chartRef = ref<HTMLDivElement | null>(null);
|
||||
const { setOptions } = useChart(chartRef);
|
||||
|
||||
const chartData = computed(() => {
|
||||
const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'];
|
||||
const incomeData = new Array(12).fill(0);
|
||||
const expenseData = new Array(12).fill(0);
|
||||
const netData = new Array(12).fill(0);
|
||||
|
||||
const months = [
|
||||
'1月',
|
||||
'2月',
|
||||
'3月',
|
||||
'4月',
|
||||
'5月',
|
||||
'6月',
|
||||
'7月',
|
||||
'8月',
|
||||
'9月',
|
||||
'10月',
|
||||
'11月',
|
||||
'12月',
|
||||
];
|
||||
const incomeData = Array.from({ length: 12 }).fill(0);
|
||||
const expenseData = Array.from({ length: 12 }).fill(0);
|
||||
const netData = Array.from({ length: 12 }).fill(0);
|
||||
|
||||
// 统计每月数据
|
||||
props.transactions.forEach(transaction => {
|
||||
props.transactions.forEach((transaction) => {
|
||||
const date = dayjs(transaction.date);
|
||||
if (date.year() === props.year) {
|
||||
const monthIndex = date.month(); // 0-11
|
||||
|
||||
|
||||
if (transaction.type === 'income') {
|
||||
incomeData[monthIndex] += transaction.amount;
|
||||
} else {
|
||||
@@ -42,12 +50,12 @@ const chartData = computed(() => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// 计算净收入
|
||||
for (let i = 0; i < 12; i++) {
|
||||
netData[i] = incomeData[i] - expenseData[i];
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
months,
|
||||
income: incomeData,
|
||||
@@ -73,7 +81,8 @@ const chartOptions = computed<EChartsOption>(() => ({
|
||||
let html = `<div style="font-weight: bold">${params[0].name}</div>`;
|
||||
params.forEach((item: any) => {
|
||||
const value = item.value.toFixed(2);
|
||||
const prefix = item.seriesName === '净收入' && item.value > 0 ? '+' : '';
|
||||
const prefix =
|
||||
item.seriesName === '净收入' && item.value > 0 ? '+' : '';
|
||||
html += `<div>${item.marker} ${item.seriesName}: ${prefix}¥${value}</div>`;
|
||||
});
|
||||
return html;
|
||||
@@ -157,6 +166,12 @@ onMounted(() => {
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="monthly-comparison-chart">
|
||||
<div ref="chartRef" class="chart-container"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.monthly-comparison-chart {
|
||||
width: 100%;
|
||||
@@ -167,4 +182,4 @@ onMounted(() => {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user