ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

SpringBoot+Vue构建记账管理系统的实践与优化

SpringBoot+Vue构建记账管理系统的实践与优化

1. 项目背景与技术选型

记账管理系统作为个人财务管理的数字化工具,在移动互联网时代呈现出爆发式需求。传统单机版记账软件存在数据同步困难、多端访问不便等问题,而基于B/S架构的Web应用正好能解决这些痛点。这也是为什么我们选择SpringBoot+Vue这套技术栈来构建这个系统。

SpringBoot作为后端框架具有明显优势:

  • 自动配置特性大幅减少XML配置
  • 内嵌Tomcat容器实现开箱即用
  • Starter依赖机制简化依赖管理
  • Actuator提供完善的监控端点

Vue.js作为前端框架的核心价值:

  • 响应式数据绑定简化DOM操作
  • 组件化开发提升代码复用率
  • Vue CLI提供标准化的项目脚手架
  • 丰富的生态系统(Vuex、Vue Router等)

这套技术组合的协同效应体现在:

  1. 前后端完全解耦,通过RESTful API交互
  2. 开发效率高,SpringBoot的约定优于配置原则与Vue的渐进式特性完美契合
  3. 部署灵活,前端可单独部署在Nginx,后端可打包为JAR独立运行

2. 系统架构设计

2.1 整体架构图

[前端层] Vue2 + ElementUI Axios Vue Router Vuex [网关层] Nginx反向代理 HTTPS加密 请求分发 [应用层] SpringBoot2 MyBatis Shiro Jackson [数据层] MySQL 5.7 Redis缓存

2.2 关键设计决策

前后端分离架构的选择基于以下考虑:

  • 前端可独立开发部署,不依赖后端环境
  • 接口定义清晰后两端可并行开发
  • 更利于实现多终端适配(Web/App/小程序)

RESTful API设计规范:

  • 资源定位:/api/v1/transactions
  • HTTP方法:GET/POST/PUT/DELETE
  • 状态码:200/400/401/500等标准状态
  • 数据格式:JSON统一交互格式

数据库设计原则:

  • 三范式基础适当反范式化(如账单明细包含分类名称)
  • 建立合适索引(用户ID、账单日期等查询条件)
  • 事务控制确保数据一致性

3. 核心功能实现

3.1 用户认证模块

采用Shiro实现安全控制:

// Shiro配置类 @Bean public ShiroFilterFactoryBean shiroFilter(){ ShiroFilterFactoryBean factory = new ShiroFilterFactoryBean(); factory.setSecurityManager(securityManager()); factory.setLoginUrl("/login"); factory.setUnauthorizedUrl("/403"); Map<String,String> filterMap = new LinkedHashMap<>(); filterMap.put("/static/**","anon"); filterMap.put("/api/login","anon"); filterMap.put("/**","authc"); factory.setFilterChainDefinitionMap(filterMap); return factory; }

前端axios拦截器处理token:

// 请求拦截器 axios.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = `Bearer ${token}` } return config }) // 响应拦截器 axios.interceptors.response.use( response => response.data, error => { if (error.response.status === 401) { router.push('/login') } return Promise.reject(error) } )

3.2 账单管理功能

核心数据库表设计:

CREATE TABLE `transaction` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `user_id` bigint(20) NOT NULL, `category_id` bigint(20) NOT NULL, `amount` decimal(10,2) NOT NULL, `transaction_date` date NOT NULL, `remark` varchar(255) DEFAULT NULL, `type` tinyint(1) NOT NULL COMMENT '1-收入 2-支出', PRIMARY KEY (`id`), KEY `idx_user_date` (`user_id`,`transaction_date`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

多表关联查询示例:

@Select("SELECT t.*, c.name as category_name " + "FROM transaction t LEFT JOIN category c ON t.category_id = c.id " + "WHERE t.user_id = #{userId} AND t.transaction_date BETWEEN #{start} AND #{end}") List<TransactionVO> listByDateRange(@Param("userId") Long userId, @Param("start") LocalDate start, @Param("end") LocalDate end);

3.3 数据统计可视化

使用ECharts实现消费趋势图:

<template> <div ref="chart" style="width:100%;height:400px"></div> </template> <script> import * as echarts from 'echarts' export default { mounted() { this.initChart() }, methods: { async initChart() { const res = await this.$api.getConsumeTrend() const chart = echarts.init(this.$refs.chart) chart.setOption({ xAxis: { data: res.data.dates }, yAxis: { type: 'value' }, series: [{ data: res.data.amounts, type: 'line' }] }) } } } </script>

4. 开发中的关键技术点

4.1 前后端联调技巧

Swagger接口文档集成:

@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.example.controller")) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("记账系统API文档") .description("RESTful接口说明") .version("1.0") .build(); } }

跨域解决方案:

@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins("*") .allowedMethods("*") .allowedHeaders("*") .maxAge(3600); } }

4.2 性能优化实践

二级缓存配置:

@Configuration @EnableCaching public class RedisConfig { @Bean public RedisCacheManager cacheManager(RedisConnectionFactory factory) { RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .entryTtl(Duration.ofMinutes(30)) .disableCachingNullValues(); return RedisCacheManager.builder(factory) .cacheDefaults(config) .transactionAware() .build(); } }

SQL优化案例:

<!-- 原查询 --> <select id="listUserTransactions" resultType="Transaction"> SELECT * FROM transaction WHERE user_id = #{userId} </select> <!-- 优化后 --> <select id="listUserTransactions" resultType="Transaction"> SELECT id,amount,transaction_date,type FROM transaction WHERE user_id = #{userId} ORDER BY transaction_date DESC LIMIT 100 </select>

5. 部署与运维方案

5.1 生产环境部署

后端打包与启动:

# 打包 mvn clean package -DskipTests # 启动 java -jar -Xms512m -Xmx1024m bookkeeping.jar \ --spring.profiles.active=prod \ --server.port=8080

Nginx配置示例:

server { listen 80; server_name bookkeeping.example.com; location / { root /var/www/bookkeeping; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }

5.2 监控与日志

SpringBoot Actuator配置:

management: endpoints: web: exposure: include: health,info,metrics endpoint: health: show-details: always

日志收集方案:

<!-- logback-spring.xml --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>logs/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>30</maxHistory> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender>

6. 项目扩展方向

6.1 功能扩展建议

  1. 多账本支持:允许用户创建多个独立账本(如家庭账本、旅行账本等)
  2. 预算管理:设置月度预算并实时监控执行情况
  3. 账单图片识别:通过OCR技术识别消费小票自动生成记录
  4. 数据备份:支持导出Excel/PDF,同步到云存储

6.2 技术演进路线

  1. 微服务化改造:

    • 拆分为用户服务、账单服务、统计服务等独立模块
    • 采用Spring Cloud Alibaba体系(Nacos+Sentinel+Seata)
  2. 大数据分析:

    • 使用Flink实现实时消费分析
    • 集成Superset构建自助分析平台
  3. 移动端适配:

    • 基于Uniapp开发跨平台移动应用
    • 使用Capacitor实现PWA特性

在实际开发过程中,有几个关键经验值得分享:

  1. 接口文档要随开发实时更新,使用Swagger或YAPI等工具维护
  2. 前端组件要合理划分,避免出现"上帝组件"
  3. 数据库字段注释要完整,特别是枚举类型的含义
  4. 重要业务操作必须记录操作日志
  5. 分页查询一定要考虑性能,避免全表扫描
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进