1. 项目概述
"家庭个人收支管理系统"这个项目名称乍看简单,但背后蕴含着现代家庭财务管理的关键需求。作为一个基于SpringBoot和SSM框架开发的管理系统,它要解决的核心问题是帮助普通家庭实现收支的数字化、可视化和智能化管理。
我在实际开发中发现,很多家庭至今仍在用Excel甚至纸质账本记录收支,这种方式存在数据易丢失、统计困难、无法多端同步等痛点。而市面上的商业财务软件要么功能过于复杂,要么存在隐私顾虑。因此,这个开源项目正好填补了家庭级轻量财务管理的空白。
2. 技术架构解析
2.1 为什么选择SpringBoot+SSM组合
SpringBoot作为基础框架提供了快速启动的能力,省去了传统Spring项目繁琐的配置。SSM(Spring+SpringMVC+MyBatis)则是经过验证的经典组合:
- Spring:负责依赖注入和事务管理
- SpringMVC:处理Web层请求和响应
- MyBatis:作为ORM框架操作数据库
这种架构的优势在于:
- 开发效率高:SpringBoot的starter可以快速集成常用组件
- 性能稳定:SSM组合经过大量项目验证
- 易于维护:分层清晰,代码结构规范
2.2 数据库设计要点
家庭收支系统的核心是数据模型设计。主要包含以下几张表:
- 用户表(user):存储家庭成员账号信息
sql复制CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(100) NOT NULL,
`family_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 收支记录表(transaction):核心数据表
sql复制CREATE TABLE `transaction` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`amount` decimal(10,2) NOT NULL,
`type` tinyint(1) NOT NULL COMMENT '1收入 0支出',
`category_id` int(11) NOT NULL,
`remark` varchar(255) DEFAULT NULL,
`create_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- 分类表(category):管理收支分类
sql复制CREATE TABLE `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`icon` varchar(100) DEFAULT NULL,
`type` tinyint(1) NOT NULL COMMENT '1收入 0支出',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
提示:数据库设计时特别注意金额字段使用decimal而非float,避免浮点计算精度问题。
3. 核心功能实现
3.1 收支记录管理
这是系统的核心功能,主要涉及:
- 记录新增
- 记录修改
- 记录删除
- 记录查询
Controller层示例代码:
java复制@RestController
@RequestMapping("/api/transaction")
public class TransactionController {
@Autowired
private TransactionService transactionService;
@PostMapping
public Result addTransaction(@RequestBody Transaction transaction) {
transaction.setCreateTime(new Date());
return transactionService.addTransaction(transaction);
}
@GetMapping("/{id}")
public Result getTransaction(@PathVariable Integer id) {
return transactionService.getTransactionById(id);
}
@GetMapping
public Result listTransactions(
@RequestParam(required = false) Integer userId,
@RequestParam(required = false) Date startDate,
@RequestParam(required = false) Date endDate) {
return transactionService.listTransactions(userId, startDate, endDate);
}
}
3.2 统计报表功能
家庭财务管理的关键是数据可视化。我们实现了:
- 月度收支趋势图
- 分类占比饼图
- 收支对比柱状图
使用ECharts实现前端展示,后端提供统计数据接口:
java复制@GetMapping("/stat/monthly")
public Result getMonthlyStat(
@RequestParam Integer userId,
@RequestParam String year) {
Map<String, Object> result = new HashMap<>();
// 获取月度收入数据
List<BigDecimal> income = transactionService.getMonthlyAmount(userId, year, 1);
// 获取月度支出数据
List<BigDecimal> expense = transactionService.getMonthlyAmount(userId, year, 0);
result.put("income", income);
result.put("expense", expense);
return Result.success(result);
}
3.3 多用户家庭共享
支持家庭成员共同使用是特色功能:
- 家庭组创建
- 成员邀请
- 权限控制
- 数据共享
实现要点:
java复制@Service
public class FamilyServiceImpl implements FamilyService {
@Autowired
private UserMapper userMapper;
@Override
public Result createFamily(Integer userId, String familyName) {
Family family = new Family();
family.setName(familyName);
family.setCreateTime(new Date());
familyMapper.insert(family);
// 设置创建者为管理员
User user = userMapper.selectById(userId);
user.setFamilyId(family.getId());
user.setRole(1); // 1表示管理员
userMapper.updateById(user);
return Result.success(family);
}
}
4. 开发中的关键问题与解决方案
4.1 事务一致性处理
收支记录涉及多个表的操作,必须保证事务。例如添加支出记录时:
- 在transaction表插入记录
- 更新用户或家庭的总支出字段
使用Spring声明式事务确保一致性:
java复制@Service
public class TransactionServiceImpl implements TransactionService {
@Transactional
@Override
public Result addTransaction(Transaction transaction) {
// 插入交易记录
transactionMapper.insert(transaction);
// 更新家庭总支出
if(transaction.getType() == 0) {
familyMapper.updateExpense(transaction.getUserId(), transaction.getAmount());
}
return Result.success();
}
}
4.2 数据安全性考虑
家庭财务数据敏感,我们采取了以下措施:
- 密码加密存储:使用BCryptPasswordEncoder
- 接口权限控制:Spring Security + JWT
- 数据隔离:确保用户只能访问自己的数据
安全配置示例:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.addFilter(new JwtAuthorizationFilter(authenticationManager()))
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
4.3 性能优化实践
随着数据量增加,我们做了以下优化:
- 收支记录分页查询
- 高频统计结果缓存
- 数据库索引优化
分页查询实现:
java复制@GetMapping
public Result listTransactions(
@RequestParam(required = false) Integer userId,
@RequestParam(required = false) Date startDate,
@RequestParam(required = false) Date endDate,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer size) {
PageHelper.startPage(page, size);
List<Transaction> list = transactionMapper.selectByCondition(userId, startDate, endDate);
PageInfo<Transaction> pageInfo = new PageInfo<>(list);
return Result.success(pageInfo);
}
5. 部署与使用指南
5.1 环境准备
系统要求:
- JDK 1.8+
- MySQL 5.7+
- Maven 3.6+
部署步骤:
- 克隆代码仓库
- 导入Maven依赖
- 创建数据库并执行初始化SQL
- 修改application.properties配置
- 启动应用
5.2 配置文件说明
关键配置项:
properties复制# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/family_finance?useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
# MyBatis配置
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.type-aliases-package=com.example.familyfinance.entity
# JWT配置
jwt.secret=your-secret-key
jwt.expiration=86400000
5.3 前端对接
系统提供RESTful API,前端可以使用Vue/React等框架开发。接口规范:
- 请求方式:GET/POST/PUT/DELETE
- 数据格式:JSON
- 认证方式:JWT
示例接口调用:
javascript复制// 获取月度统计
axios.get('/api/transaction/stat/monthly', {
params: {
userId: 1,
year: '2023'
},
headers: {
'Authorization': 'Bearer ' + token
}
})
6. 项目扩展方向
基于当前系统,还可以进一步扩展:
- 多端同步:开发移动端APP,实现随时随地记账
- 智能分析:引入机器学习算法,自动识别消费模式
- 账单提醒:集成消息服务,提醒定期账单
- 数据导出:支持Excel/PDF格式导出报表
技术实现考虑:
- 移动端:React Native/Flutter
- 消息服务:阿里云短信/邮件服务
- 文件导出:Apache POI/iText
7. 开发经验分享
在开发这个系统过程中,我总结了以下几点经验:
-
分类设计要合理:初期分类过于简单,后来增加了二级分类,大大提升了实用性。建议设计时考虑:
- 收入分类:工资、理财、兼职等
- 支出分类:餐饮、交通、教育、医疗等
-
数据校验要全面:特别是金额输入,前端后端都要验证:
java复制@NotBlank(message = "金额不能为空")
@DecimalMin(value = "0.01", message = "金额必须大于0")
private BigDecimal amount;
-
备份功能很重要:用户强烈要求的数据备份功能,后来增加了定期自动备份到云存储的功能。
-
性能监控不可少:使用Spring Boot Actuator监控系统健康状态,及时发现性能瓶颈。
这个项目从技术角度看不算复杂,但真正做好一个实用的家庭财务管理系统,需要充分考虑真实使用场景和用户体验。建议开发者多与实际用户沟通,不断迭代优化功能。