1. 项目背景与核心价值
去年帮朋友改造他的个人记账Excel时,发现手工统计收支效率太低。正好最近在整理全栈技术栈的实战案例,就决定用SpringBoot+Vue这套黄金组合开发一个轻量级理财系统。这个项目特别适合想要实践前后端分离开发的Java开发者,整套技术栈包含了企业级开发中最常用的组件:后端用SpringBoot快速搭建RESTful API,前端用Vue3组合式API开发响应式界面,数据层采用MyBatis-Plus简化CRUD操作,MySQL作为可靠的数据存储方案。
提示:系统已实现多账本管理、智能分类统计、收支趋势可视化等核心功能,源码包含完整的权限控制和异常处理机制。
2. 技术架构解析
2.1 后端技术栈设计
采用SpringBoot 3.1.5作为基础框架,其自动配置特性让开发效率提升明显。我在pom.xml中精选了这些核心依赖:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>2.0.34</version>
</dependency>
数据库设计遵循理财业务的核心实体关系:
- 用户表(user)包含基础信息和加密后的密码
- 账本表(account_book)支持多账本隔离
- 交易记录表(transaction)使用DECIMAL类型存储金额
- 分类表(category)采用树形结构存储多级分类
2.2 前端技术方案
Vue3的组合式API让代码组织更灵活。项目中使用这些关键插件:
bash复制npm install echarts@5.4.3 # 可视化图表
npm install dayjs@1.11.9 # 日期处理
npm install pinia@2.0.36 # 状态管理
特别优化了这些交互细节:
- 金额输入框自动格式化为千分位显示
- 分类选择支持模糊搜索和最近使用
- 表格数据采用虚拟滚动优化性能
3. 核心功能实现
3.1 智能交易分类
通过MyBatis的TypeHandler实现分类自动匹配:
java复制public class CategoryTypeHandler extends BaseTypeHandler<Category> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
Category parameter, JdbcType jdbcType) {
ps.setInt(i, parameter.getId());
}
@Override
public Category getNullableResult(ResultSet rs, String columnName) {
return categoryService.matchCategory(rs.getString(columnName));
}
}
匹配算法包含三级规则:
- 关键词完全匹配(如"星巴克"匹配"餐饮-咖啡")
- 金额范围匹配(大额支出默认归入"其他")
- 历史行为学习(用户手动修正后记忆模式)
3.2 数据可视化分析
使用ECharts实现动态报表,核心配置包括:
javascript复制const initChart = () => {
chartInstance.value = echarts.init(domRef.value)
chartInstance.value.setOption({
tooltip: { trigger: 'axis' },
xAxis: { type: 'category' },
yAxis: { type: 'value' },
dataset: { source: props.data },
series: [{ type: 'line', smooth: true }]
})
}
特别处理了这些边界情况:
- 无数据时显示友好提示
- 超大数据量时自动降采样
- 时间范围切换时平滑过渡
4. 部署与优化实践
4.1 数据库性能调优
交易记录表添加了复合索引:
sql复制ALTER TABLE transaction
ADD INDEX idx_user_date (user_id, transaction_date DESC);
配置了MyBatis-Plus的乐观锁插件:
java复制@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
4.2 前端性能优化
实现这些提升体验的措施:
- 路由懒加载拆分代码包
javascript复制const routes = [
{
path: '/report',
component: () => import('./views/Report.vue')
}
]
- 使用Web Worker处理大数据计算
- 关键接口添加SWR缓存策略
5. 典型问题解决方案
5.1 金额计算精度问题
使用BigDecimal处理金融计算:
java复制@Getter
@Setter
public class TransactionDTO {
@JsonSerialize(using = BigDecimalSerializer.class)
private BigDecimal amount;
}
自定义序列化器处理前端显示:
java复制public class BigDecimalSerializer extends JsonSerializer<BigDecimal> {
@Override
public void serialize(BigDecimal value,
JsonGenerator gen, SerializerProvider provider) {
gen.writeString(value.setScale(2, RoundingMode.HALF_UP).toString());
}
}
5.2 多账本数据隔离
通过ThreadLocal实现租户隔离:
java复制public class TenantContext {
private static final ThreadLocal<Integer> currentTenant = new ThreadLocal<>();
public static void setTenantId(Integer tenantId) {
currentTenant.set(tenantId);
}
public static Integer getTenantId() {
return currentTenant.get();
}
}
在MyBatis拦截器中自动添加过滤条件:
java复制@Intercepts(@Signature(type= Executor.class, method="query",
args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class TenantInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) {
if (TenantContext.getTenantId() != null) {
// 动态修改SQL
}
return invocation.proceed();
}
}
6. 扩展开发建议
- 增加微信/支付宝账单导入功能:
- 解析账单CSV文件
- 自动匹配已有分类
- 差异对比提醒
- 实现多设备同步:
- 采用WebSocket实时推送变更
- 冲突解决策略(最后修改优先)
- 离线模式支持
- 开发移动端适配:
- 使用Vant组件库
- PWA离线访问
- 指纹/面部识别登录
这个项目最让我惊喜的是MyBatis-Plus的动态表名功能,通过简单的逻辑就能实现按年月分表存储交易记录。建议新手重点研究下SpringBoot的自动配置原理和Vue的响应式机制,这两个知识点能大幅提升全栈开发效率。
