1. 项目概述:个人理财系统的技术架构与价值
这个基于SpringBoot+Vue+MyBatis+MySQL的个人理财系统,是我在2022年疫情期间开发的一个全栈项目。当时发现身边很多朋友都在用Excel手动记账,既不方便统计又难以长期坚持,于是决定开发一个轻量级的解决方案。系统采用前后端分离架构,前端用Vue实现响应式界面,后端用SpringBoot提供RESTful API,数据持久层采用MyBatis+MySQL组合。经过半年多的迭代,目前已经实现了收支记录、分类统计、预算管理、数据可视化等核心功能。
提示:这个项目的代码完全开源,文末会提供GitHub仓库地址和详细的部署指南。即使你是刚接触全栈开发的新手,按照教程也能在2小时内完成本地环境搭建。
系统最大的特点是"够用就好"的设计理念。相比市面上功能繁杂的理财APP,这个系统只保留最核心的记账功能,操作流程优化到三步以内完成一笔记录。技术选型上也刻意避开了复杂的微服务架构,采用单体应用模式,使得部署和维护成本大幅降低。
2. 技术栈深度解析
2.1 后端技术组合
SpringBoot 2.7.4作为后端框架,主要考虑了以下几个因素:
- 内嵌Tomcat服务器,无需单独配置
- 自动配置特性大幅减少XML配置
- 丰富的Starter依赖简化集成过程
- 与MyBatis的兼容性经过大量项目验证
数据库操作层采用MyBatis 3.5.6而非JPA,主要因为:
- 理财业务涉及复杂的统计查询,需要精细控制SQL
- 已有MySQL数据库设计经验,直接写SQL效率更高
- 动态SQL功能便于实现多条件筛选查询
数据库选用MySQL 8.0而非MongoDB等NoSQL方案,因为:
- 理财数据关联性强,需要事务支持
- 历史数据查询频繁,关系型数据库索引优化更成熟
- 社区支持完善,遇到问题容易找到解决方案
2.2 前端技术选型
Vue 3.x作为前端框架的优势体现在:
- 组合式API更适合复杂交互的理财页面
- 响应式系统自动处理数据绑定
- 丰富的生态系统(Vue Router、Pinia等)
- 渐进式特性便于功能扩展
UI组件库最终选择Element Plus而非Ant Design Vue,主要基于:
- 表单组件更符合记账场景的需求
- 主题定制更简单(只需修改SCSS变量)
- 文档中文支持更好
图表库使用ECharts 5.3.2实现数据可视化,因其:
- 丰富的图表类型满足各种统计需求
- 社区活跃,问题解决速度快
- 配置项式API与Vue的响应式系统配合良好
3. 核心功能实现细节
3.1 收支记录模块
数据库表设计关键字段:
CREATE TABLE `transaction` ( `id` bigint NOT NULL AUTO_INCREMENT, `user_id` bigint NOT NULL, `amount` decimal(12,2) NOT NULL COMMENT '金额', `type` tinyint NOT NULL COMMENT '1收入 2支出', `category_id` int NOT NULL COMMENT '分类ID', `remark` varchar(255) DEFAULT NULL COMMENT '备注', `transaction_date` date NOT NULL COMMENT '交易日期', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`), KEY `idx_user_date` (`user_id`,`transaction_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;后端API设计遵循RESTful规范:
- POST /api/transactions - 创建记录
- GET /api/transactions - 分页查询
- GET /api/transactions/{id} - 获取详情
- PUT /api/transactions/{id} - 更新记录
- DELETE /api/transactions/{id} - 删除记录
前端实现的关键代码片段(Vue3 Composition API):
const formData = reactive({ amount: 0, type: 2, // 默认支出 categoryId: null, remark: '', transactionDate: dayjs().format('YYYY-MM-DD') }) const submitForm = async () => { try { await axios.post('/api/transactions', formData) ElMessage.success('记录添加成功') resetForm() // 刷新列表数据 loadTransactions() } catch (err) { ElMessage.error(err.response?.data?.message || '操作失败') } }3.2 统计报表模块
核心SQL查询示例(按月统计支出):
SELECT c.name AS category, SUM(t.amount) AS total, ROUND(SUM(t.amount) / t_month.total * 100, 1) AS percentage FROM transaction t JOIN category c ON t.category_id = c.id JOIN (SELECT SUM(amount) AS total FROM transaction WHERE type = 2 AND user_id = #{userId} AND transaction_date BETWEEN #{startDate} AND #{endDate}) t_month WHERE t.type = 2 AND t.user_id = #{userId} AND t.transaction_date BETWEEN #{startDate} AND #{endDate} GROUP BY c.id, c.name ORDER BY total DESCECharts配置核心代码:
const initChart = () => { const chartDom = document.getElementById('chart-container') const myChart = echarts.init(chartDom) const option = { tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' }, series: [{ name: '支出占比', type: 'pie', radius: ['40%', '70%'], avoidLabelOverlap: false, itemStyle: { borderRadius: 10, borderColor: '#fff', borderWidth: 2 }, label: { show: true, formatter: '{b}: {c} ({d}%)' }, data: chartData.value }] } myChart.setOption(option) window.addEventListener('resize', myChart.resize) }4. 部署实战指南
4.1 开发环境搭建
后端环境准备:
- JDK 11+(推荐Amazon Corretto)
- Maven 3.8.1+
- MySQL 8.0(注意配置utf8mb4字符集)
- 导入初始化SQL脚本(项目docs目录下)
前端环境要求:
- Node.js 16.14+
- pnpm 7.x(比npm/yarn更快)
- 建议使用VSCode + Volar插件
4.2 生产环境部署
使用Docker Compose一键部署:
version: '3.8' services: mysql: image: mysql:8.0 container_name: finance-mysql environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD} MYSQL_DATABASE: finance MYSQL_USER: ${DB_USER} MYSQL_PASSWORD: ${DB_PASSWORD} volumes: - mysql_data:/var/lib/mysql ports: - "3306:3306" restart: always backend: build: ./backend container_name: finance-backend depends_on: - mysql environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/finance?useSSL=false&characterEncoding=utf8 SPRING_DATASOURCE_USERNAME: ${DB_USER} SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD} ports: - "8080:8080" restart: always frontend: build: ./frontend container_name: finance-frontend ports: - "80:80" restart: always volumes: mysql_data:Nginx配置要点:
server { listen 80; server_name yourdomain.com; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }5. 常见问题解决方案
5.1 数据库连接问题
症状:应用启动时报"Communications link failure" 排查步骤:
- 检查MySQL服务是否运行
- 验证连接字符串中的IP、端口、用户名密码
- 确认MySQL用户有远程连接权限(如果是docker部署)
- 检查防火墙设置
5.2 前端跨域问题
开发环境解决方案:
// vite.config.js export default defineConfig({ server: { proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, rewrite: path => path.replace(/^\/api/, '') } } } })生产环境确保:
- 前端和后端使用相同域名
- Nginx正确配置API代理
- 后端CORS配置允许前端域名
5.3 性能优化实践
数据库优化措施:
- 为常用查询字段添加复合索引
- 大表考虑分区(按用户ID或时间范围)
- 定期使用EXPLAIN分析慢查询
前端性能技巧:
- 路由懒加载组件
- 使用keep-alive缓存常用页面
- 大数据量表格采用虚拟滚动
6. 项目扩展方向
6.1 功能扩展建议
- 多账本支持(个人/家庭/项目独立账本)
- 周期性账单自动生成
- 银行账单导入解析(支持CSV/Excel)
- 移动端PWA应用
6.2 技术升级路径
- 后端迁移到Spring Cloud微服务架构
- 引入Redis缓存热点数据
- 使用Prometheus+Grafana实现监控
- 前端尝试TypeScript强化类型检查
项目源码已托管在GitHub(仓库地址见评论区),包含完整文档和问题跟踪系统。部署过程中遇到任何问题,欢迎提交issue讨论。对于想要学习全栈开发的朋友,这个项目提供了从数据库设计到前端展示的完整链路实践,特别推荐按照commit历史一步步回看开发过程。