1. 项目背景与技术选型记账管理系统作为个人财务管理的数字化工具在移动互联网时代呈现出爆发式需求。传统单机版记账软件存在数据同步困难、多端访问不便等问题而基于B/S架构的Web应用正好能解决这些痛点。这也是为什么我们选择SpringBootVue这套技术栈来构建这个系统。SpringBoot作为后端框架具有明显优势自动配置特性大幅减少XML配置内嵌Tomcat容器实现开箱即用Starter依赖机制简化依赖管理Actuator提供完善的监控端点Vue.js作为前端框架的核心价值响应式数据绑定简化DOM操作组件化开发提升代码复用率Vue CLI提供标准化的项目脚手架丰富的生态系统Vuex、Vue Router等这套技术组合的协同效应体现在前后端完全解耦通过RESTful API交互开发效率高SpringBoot的约定优于配置原则与Vue的渐进式特性完美契合部署灵活前端可单独部署在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/transactionsHTTP方法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); MapString,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) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;多表关联查询示例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}) ListTransactionVO listByDateRange(Param(userId) Long userId, Param(start) LocalDate start, Param(end) LocalDate end);3.3 数据统计可视化使用ECharts实现消费趋势图template div refchart stylewidth: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 }] }) } } } /script4. 开发中的关键技术点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 idlistUserTransactions resultTypeTransaction SELECT * FROM transaction WHERE user_id #{userId} /select !-- 优化后 -- select idlistUserTransactions resultTypeTransaction SELECT id,amount,transaction_date,type FROM transaction WHERE user_id #{userId} ORDER BY transaction_date DESC LIMIT 100 /select5. 部署与运维方案5.1 生产环境部署后端打包与启动# 打包 mvn clean package -DskipTests # 启动 java -jar -Xms512m -Xmx1024m bookkeeping.jar \ --spring.profiles.activeprod \ --server.port8080Nginx配置示例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 nameFILE classch.qos.logback.core.rolling.RollingFileAppender filelogs/app.log/file rollingPolicy classch.qos.logback.core.rolling.TimeBasedRollingPolicy fileNamePatternlogs/app.%d{yyyy-MM-dd}.log/fileNamePattern maxHistory30/maxHistory /rollingPolicy encoder pattern%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n/pattern /encoder /appender6. 项目扩展方向6.1 功能扩展建议多账本支持允许用户创建多个独立账本如家庭账本、旅行账本等预算管理设置月度预算并实时监控执行情况账单图片识别通过OCR技术识别消费小票自动生成记录数据备份支持导出Excel/PDF同步到云存储6.2 技术演进路线微服务化改造拆分为用户服务、账单服务、统计服务等独立模块采用Spring Cloud Alibaba体系NacosSentinelSeata大数据分析使用Flink实现实时消费分析集成Superset构建自助分析平台移动端适配基于Uniapp开发跨平台移动应用使用Capacitor实现PWA特性在实际开发过程中有几个关键经验值得分享接口文档要随开发实时更新使用Swagger或YAPI等工具维护前端组件要合理划分避免出现上帝组件数据库字段注释要完整特别是枚举类型的含义重要业务操作必须记录操作日志分页查询一定要考虑性能避免全表扫描