1. 项目概述:SSM+Vue家庭财务管理系统开发实录
去年帮表弟家搭建私人财务系统时,发现市面上的记账软件要么功能臃肿,要么数据要上传云端。这促使我萌生了开发轻量级私有化财务系统的想法。本文将分享基于SSM+Vue技术栈的家庭财务管理系统完整开发过程,这套系统已稳定运行8个月,日均处理200+笔交易记录。
系统核心解决三大痛点:一是分散记账导致月末对账困难(表弟曾因5个支付平台对账花了3小时);二是预算执行缺乏实时监控(舅妈去年超支3万才发现);三是理财收益计算不直观(朋友买理财时经常算错实际收益率)。采用SpringBoot+MyBatisPlus+Vue3的组合,在保证扩展性的同时,将安装包控制在28MB以内。
2. 技术选型与架构设计
2.1 为什么选择SSM+Vue组合
后端选用SSM框架而非SpringBoot单体架构,主要考虑教学场景的渐进式学习需求。实际开发中我们做了两点改良:
- 用Spring5的JavaConfig替代XML配置(减少60%的配置代码)
- 集成MyBatis-Plus 3.5.3(简化90%的单表CRUD操作)
前端选择Vue3而非React,出于三点考量:
- 学习曲线更平缓(适合家庭用户二次开发)
- 组合式API更适合财务模块化开发
- 与ECharts的集成更简便(理财图表是关键功能)
2.2 系统架构图解
code复制[用户层]
│
▼
[表现层] Vue3 + Element Plus + Axios
│
▼
[网关层] Nginx反向代理(解决跨域)
│
▼
[业务层] SpringMVC + JWT鉴权
│
▼
[持久层] MyBatis-Plus + SM4加密插件
│
▼
[存储层] MySQL5.7 + 定时本地备份
特别说明架构设计中的三个关键决策:
- 采用Nginx而非SpringCloud Gateway,因家庭场景无需服务治理
- 自研SM4加密插件而非使用Hutool,避免引入不必要依赖
- 选择MySQL5.7而非8.0,因多数家庭服务器环境较旧
3. 核心功能实现细节
3.1 多账户资金联动设计
账户模块采用"余额快照+流水明细"的双存储模式:
java复制// 账户实体设计
public class Account {
private Long id;
private String accountName; // 账户名称
private BigDecimal currentBalance; // 当前余额快照
private String currencyType; // 币种
private LocalDateTime updateTime;
}
// 流水记录实体
public class Transaction {
private Long id;
private Long accountId;
private BigDecimal amount;
private TransactionType type; // IN/OUT/TRANSFER
private String targetAccount; // 转账目标账户
private String remark;
}
资金变动采用事务注解保证一致性:
java复制@Transactional
public void transfer(Long fromId, Long toId, BigDecimal amount) {
accountMapper.decreaseBalance(fromId, amount);
accountMapper.increaseBalance(toId, amount);
transactionMapper.insertTransferRecord(fromId, toId, amount);
}
踩坑记录:初期未加@Transactional导致资金不同步,测试时出现1/1000的概率余额不平
3.2 智能预算预警实现
支出模块采用"预算池"设计思路:
- 按周/月/年设置预算总额
- 支出时实时计算剩余额度
- 达80%阈值发送微信通知
关键SQL查询:
sql复制SELECT
c.category_name,
SUM(e.amount) AS actual,
b.budget_amount AS plan,
(b.budget_amount - SUM(e.amount)) AS remaining
FROM
expense e
JOIN
category c ON e.category_id = c.id
LEFT JOIN
budget b ON c.id = b.category_id
WHERE
e.user_id = #{userId}
AND e.create_time BETWEEN #{start} AND #{end}
GROUP BY
c.id
3.3 理财收益可视化方案
采用ECharts实现三种计算模型对比:
javascript复制// 复利计算核心算法
function compoundInterest(principal, rate, years) {
let result = [];
for (let i = 1; i <= years; i++) {
let value = principal * Math.pow(1 + rate/100, i);
result.push({year: i, value: value.toFixed(2)});
}
return result;
}
图表配置特别注意:
- 使用双Y轴显示金额和收益率
- 添加阈值标记线标识通胀率
- 移动端适配rem单位
4. 安全与性能优化
4.1 数据安全方案
采用国密SM4加密敏感字段:
xml复制<!-- MyBatis加密拦截器配置 -->
<plugin interceptor="com.encrypt.SM4Interceptor">
<property name="encryptColumns" value="bank_card,mobile,id_card"/>
<property name="key" value="${encrypt.key}"/>
</plugin>
实现细节:
- 加密密钥按家庭单位独立生成
- 数据库备份文件使用AES256二次加密
- 登录采用JWT+双因子认证
4.2 性能调优记录
通过JMeter测试发现的三个性能瓶颈及解决方案:
-
收支查询慢(原始1200ms)
- 添加复合索引:
ALTER TABLE expense ADD INDEX idx_user_time (user_id, create_time) - 结果:降至280ms
- 添加复合索引:
-
理财计算CPU占用高
- 引入BigDecimal替代double计算
- 添加计算结果缓存(Guava Cache)
- 结果:CPU占用下降65%
-
首页加载资源多
- 使用Webpack分块打包
- 启用Gzip压缩
- 结果:首屏加载从4.2s→1.8s
5. 部署与运维实践
5.1 家庭服务器部署方案
推荐硬件配置:
- 树莓派4B(4G内存)
- 32GB存储卡
- 配备UPS电源
Docker-compose部署文件示例:
yaml复制version: '3'
services:
db:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
volumes:
- ./mysql-data:/var/lib/mysql
app:
image: openjdk:8-jre
ports:
- "8080:8080"
volumes:
- ./app.jar:/app.jar
depends_on:
- db
5.2 日常维护技巧
- 数据库自动备份脚本:
bash复制#!/bin/bash
mysqldump -u${USER} -p${PASS} finance | openssl enc -aes-256-cbc -salt -out /backups/finance_$(date +%Y%m%d).sql.enc -k ${ENC_KEY}
find /backups/ -type f -mtime +30 -delete
- 内存泄漏排查经验:
- 使用Arthas的
memory命令监控堆内存 - 发现Chart对象未释放,添加
dispose()方法调用 - 定期执行
System.gc()(仅限桌面环境)
6. 扩展开发建议
基于实际使用反馈,推荐三个增值功能开发方向:
-
发票OCR识别
- 集成Tesseract实现拍照识别
- 自动匹配支出记录
-
多账本协同
- 家庭组共享部分账目
- 权限精细化控制
-
语音记账
- 微信语音快速录入
- NLP分类识别
这套系统在开发过程中最大的体会是:技术方案必须匹配真实使用场景。比如最初设计的复杂权限系统,实际发现家庭用户只需要"管理员-普通成员"两级角色。建议开发者多与目标用户保持沟通,避免过度设计。