SpringBoot+Vue全栈个人理财系统开发实践
1. 项目概述个人理财系统的技术架构与价值这个基于SpringBootVueMyBatisMySQL的个人理财系统是我在2022年疫情期间开发的一个全栈项目。当时发现身边很多朋友都在用Excel手动记账既不方便统计又难以长期坚持于是决定开发一个轻量级的解决方案。系统采用前后端分离架构前端用Vue实现响应式界面后端用SpringBoot提供RESTful API数据持久层采用MyBatisMySQL组合。经过半年多的迭代目前已经实现了收支记录、分类统计、预算管理、数据可视化等核心功能。提示这个项目的代码完全开源文末会提供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) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;后端API设计遵循RESTful规范POST /api/transactions - 创建记录GET /api/transactions - 分页查询GET /api/transactions/{id} - 获取详情PUT /api/transactions/{id} - 更新记录DELETE /api/transactions/{id} - 删除记录前端实现的关键代码片段Vue3 Composition APIconst 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 CorrettoMaven 3.8.1MySQL 8.0注意配置utf8mb4字符集导入初始化SQL脚本项目docs目录下前端环境要求Node.js 16.14pnpm 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?useSSLfalsecharacterEncodingutf8 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缓存热点数据使用PrometheusGrafana实现监控前端尝试TypeScript强化类型检查项目源码已托管在GitHub仓库地址见评论区包含完整文档和问题跟踪系统。部署过程中遇到任何问题欢迎提交issue讨论。对于想要学习全栈开发的朋友这个项目提供了从数据库设计到前端展示的完整链路实践特别推荐按照commit历史一步步回看开发过程。