资讯详情

资讯详情

SpringBoot+Vue+MySQL个人理财系统开发实战与部署指南

个人理财系统这个题目标题我看了很多遍——SpringBoot后端Vue前端MySQL标注“可直接运行”。说实话这类项目最大的价值恰恰就在“可直接运行”这四个字上但也是最大的坑。很多同学下载完源码对着 springboot 版本太高、vue安装及环境配置、mysql安装这些热搜词来回折腾最后卡在一个小细节上项目打开了却跑不起来然后就开始怀疑是代码有问题还是自己的环境有问题。我前后帮人排查过不少同类项目也亲手把一套个人理财系统从零搭起来跑通过今天就把整个跑通的经历、代码结构、设计逻辑和那些搜索引擎查不到的小经验一次性讲清楚。这篇内容适合谁适合拿到个人理财系统源码但不知道怎么启动的初学者也适合准备用 SpringBootVueMySQL 做毕业设计或课程项目的人还适合对前后端分离项目结构没有完整把握、想借一个实际项目把 SpringBoot、Vue、MySQL 串起来的人。我会从项目结构讲到环境配置、从启动顺序讲到核心模块最后把几个高频运行报错和排查思路也一并整理出来保证你看完能跑通也能说出个子丑寅卯来。1. 拿到源码之后先把项目结构搞清楚再动手很多人的习惯是双击压缩包、解压、打开 IDEA然后直接点运行。这不是不行而是容易踩出“莫名其妙”的错误——比如前端请求后端 404比如数据库找不到表比如页面能打开但登录不进去。这些问题的根源基本都是不理解这个项目的组织方式。所以拿到代码后别急着启动先用十分钟把目录看一遍。1.1 前端和后端是两套独立工程个人理财系统这种项目基本都是前后端分离后端是一个 SpringBoot 工程用 Maven 管理依赖前端是一个 Vue 工程用 npm 或 yarn 管理依赖。两个工程独立启动、独立运行前端通过 HTTP 请求访问后端的 API 接口后端通过 JDBC 访问 MySQL 数据库。从实践来看这类项目的目录大致长这样finance-system/ ├── backend/ # SpringBoot 后端工程 │ ├── pom.xml │ └── src/main/java/com/finance/... │ └── src/main/resources/ │ ├── application.yml │ └── mapper/... ├── frontend/ # Vue 前端工程 │ ├── package.json │ └── src/ │ ├── api/... │ ├── views/... │ └── router/... └── sql/ └── finance.sql # 数据库初始化脚本有的项目会把数据库脚本放在后端工程的 resources 目录里有的会放成单独的 sql 文件夹还有的干脆放在 README 里截图展示。拿到源码后第一时间找三样东西pom.xml、package.json、.sql文件。这三样决定了整个项目能不能跑起来。1.2 从前端视角看它调用了哪些接口打开前端src/api目录里的请求文件能看到类似request({ url: /user/login, method: post })这样的写法。这里的关键是理解 URL 是拼接出来的前端请求的/user/login在实际发送时会被代理到后端服务器。所以前端工程里的vite.config.js或vue.config.js里通常会有proxy配置把/api开头的请求转发到http://localhost:8080这类地址。不清楚这点的人往往会直接在浏览器地址栏输入http://localhost:8080/user/login去测后端这当然能通但属于绕过前端直接调接口不是真实用户路径。真实路径是浏览器加载前端页面比如 5173 端口然后前端代码用 axios 带着相对路径去请求开发环境由 Vite 代理转发到后端 8080 端口。1.3 后端是标准的 Controller → Service → Mapper 三层结构SpringBoot 的代码结构不会太花哨打开src/main/java基本就是controller包接收前端请求做参数封装service包业务逻辑比如记账、算账、统计mapper包MyBatis 或 MyBatis-Plus 的数据库操作接口entity包或pojo包对应数据库表的实体类config包跨域配置、拦截器配置之类个人理财系统核心逻辑集中在账目记录和统计聚合上所以你会在 service 里看到addIncome、addExpense、getMonthlySummary、queryBillList这类方法Controller 里对应的是PostMapping(/bill/add)、GetMapping(/bill/list)这样的接口。提示启动之前先打开application.yml确认端口号、数据库名、用户名密码。我见过最多的问题是端口被占用或者项目默认连的是root/123456而你本机 MySQL 密码不是这个。2. 环境配置这一步才是大多数人被拦下的地方标题里写的是“可直接运行”这不代表“双击就能运行”而是说代码本身不需要额外改造、数据库脚本是完整的你只要把基础环境配好就能跑。但这个“基础环境”恰恰是新手最容易出问题的地方。2.1 JDK 版本SpringBoot 2.x 和 3.x 是两回事打开后端pom.xml先看parent节点里 SpringBoot 的版本。SpringBoot 2.x 时代主流搭配 JDK 8 或 JDK 11SpringBoot 3.x 要求 JDK 17 起。现在网上下到的源码如果是近两年的新项目很多用了 SpringBoot 2.7.x 或 3.x前者配 JDK 8 很稳后者用 JDK 8 会直接编译失败。个人经验不确定 JDK 版本时直接装 JDK 11 或 JDK 17都能兼容 SpringBoot 2.4 以上的大部分项目。但如果你用的 IDE 是 IDEA记得在File → Project Structure里把 Project SDK 和 Java 版本调成一致不然经常出现“明明装了 JDK 17 也报错”的情况。2.2 MySQL 8.x 的安装和连接细节MySQL 是另一个重灾区。个人理财系统现在基本都默认适配 MySQL 8.0下载时别贪新就选 8.0 这个版本线上最稳的版本比如 8.0.36 或 8.0.37而不要为了追新装 9.x。安装时注意编码选 utf8mb4否则后面插入中文可能乱码端口默认 3306 保持不变root 密码自己记住别设太难本地开发用123456并不丢人装完后在命令行里执行mysql -uroot -p测一下能否登录后端连数据库时application.yml的配置大概是这样spring: datasource: url: jdbc:mysql://localhost:3306/finance_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver注意看 URL 里的serverTimezoneAsia/Shanghai如果日期字段总是少 8 个小时或者报时间相关错误多半就是没加这个参数。这个细节是新手最容易忽略的。2.3 Node.js 与 Vue 环境版本不对会导致依赖安装失败前端是 Vue 项目的话按项目用的 Vue 版本选 Node。Vue 2 项目一般用 Node 14 或 16Vue 3 Vite 项目建议 Node 16.15 以上或 Node 18。装太新的 Node比如 20在个别老项目里也会因为node-sass编译失败而中断。所以拿到package.json后先看依赖里有没有node-sass有的话建议直接用 Node 16。依赖安装命令是npm install如果你是在国内网络环境这一步最容易超时或卡住。建议先切换镜像源npm config set registry https://registry.npmmirror.com然后再npm install。如果之前已经装了一半可以把node_modules文件夹删掉重新来。前端启动命令一般是npm run dev或npm run serve启动成功后终端会打印一个本地访问地址比如http://localhost:5173。2.4 Maven 仓库配置后端依赖由 Maven 管理。IDEA 打开项目后Maven 会自动扫描pom.xml并下载依赖但默认源在国外下载慢到怀疑人生。在maven/conf/settings.xml里加一段阿里云镜像即可mirror idaliyunmaven/id mirrorOf*/mirrorOf urlhttps://maven.aliyun.com/repository/public/url /mirror配置好后在 IDEA 右侧 Maven 面板点刷新按钮让它重新拉取依赖。看到依赖列表里没有红色下划线、BUILD SUCCESS之类的字样后端环境就备好了。3. 从零开始把系统真正跑起来数据库初始化、后端启动、前端启动的顺序和验证我见过一种很典型的失败方式先把前后端都启动然后打开页面发现登录会报错再回头去看数据库——发现表还没创建。整个过程绕了一大圈。正确顺序应该是先初始化数据库再启动后端再启动前端。3.1 用 SQL 脚本初始化数据库打开 MySQL 命令行或 Navicat新建一个数据库名称要与application.yml里的库名一致。比如配置里写的finance_db执行CREATE DATABASE finance_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;然后选中这个库用source命令导入后端源码里带的.sql文件或者直接在 Navicat 里右键运行 SQL 文件。导入之后检查一下表是否齐全。个人理财系统的表一般包括user用户表存用户名、密码account账户表比如现金、银行卡、信用卡余额category收支分类表比如餐饮、交通、工资bill或transaction收支流水表金额、类型、日期、备注budget预算表按月设置某项支出的上限如果某些表是空表不要慌这正常系统会在你注册新用户和记账时写入数据。但如果任何表都不存在那就要检查是不是选错数据库了。3.2 启动后端并验证接口在 IDEA 里打开后端主类也就是名字带Application结尾的类光标放到main方法上右键 Run。看到控制台出现类似这样的日志就是启动成功Tomcat started on port(s): 8080 (http) with context path 此时不要急着启动前端先在浏览器输入http://localhost:8080/user/login按实际接口路径如果返回 401 或 JSON 错误信息说明后端已经通了。如果浏览器直接报“无法访问此网站”按顺序排查端口是否真的监听、防火墙是否拦截、后端是否闪退看控制台最后几行报错。3.3 启动前端并确认代理转发前后端分离项目最怕一个问题后端通了前端也打开了但前端页面调接口时报 404 或 500。404 一般是路径没转发对500 多半是参数或数据库问题。启动前端后按 F12 打开浏览器开发者工具切到 Network 面板然后在页面上登录一次。点击登录按钮后观察发出的 XHR 请求地址。如果请求地址是http://localhost:8080/...且状态 200说明一切正常如果请求地址是http://localhost:5173/api/...且也被前端接住了那说明代理生效。看请求是否成功、是否有 CORS 相关报错这一步比看页面是否显示更重要。3.4 注册一个新用户完整走一遍主流程不要用源码里自带的测试账号直接查数据建议你自己注册一个新用户把“记账-查账-统计”这条主链路完整走一遍。注册时密码一般会加密存储你第二次用同样密码登录能通就说明加密逻辑没问题。然后添加几笔支出和收入比如早餐 -15、打车 -20、工资 5000再到统计页面看饼图或折线图是否有数据。如果统计页面没数据而账单列表有数据那大概率是时间格式或统计 SQL 的问题如果账单列表都没数据那可能要确认你当前登录用户 ID 与账单表里 user_id 是否匹配。这些都是可以按日志和数据库倒推的。4. 个人理财系统是怎么“思考”的核心功能与数据设计跑通只是第一步更值钱的是理解这个系统为什么这样设计。个人理财系统的核心痛点是怎么让用户持续记录每一笔钱的来龙去脉并且能回答“我这个月花在哪了、超没超预算”这个问题。为此它的表结构和后端逻辑是围绕“分类、流水、聚合”三个层次设计的。4.1 余额不是算出来的是流水推出来的很多人看个人理财系统会觉得奇怪账户表里不是有 balance余额字段吗那我每次记账时更新它不就行了逻辑上可行但实践中依赖余额字段会带来对账问题。比如你手动改了余额或者一笔账单被删除了余额和流水明细就对不上了。更稳妥的做法是账户余额仅作展示核心数据全部以流水表bill为准。计算某个账户的总资产时用初始金额加上所有收入流水的和、减去所有支出流水的和。这样做的好处是每一笔变化都有迹可循坏处是统计查询场景变多。实际项目中大部分同学是用账户表存余额、流水表存明细没有花太多力气保证两边强一致所以你要知道这个局限记账和改余额是两件事容易产生误差。4.2 分类表的设计二级分类不要硬编码我在一些项目里见过把分类直接写死在前端下拉框里的做法比如“餐饮”“交通”“购物”三项。这在小项目里省事但用户一旦想增加一个“宠物”分类就要改前端代码很不灵活。分类表存在的意义就是让分类可维护。一般分类表会带type字段标记是收入还是支出或者带parent_id支持两级分类。比如一级分类“餐饮”下面有“早餐”“午餐”“下午茶”。查询账单时通过类型和分类 ID 关联。你看源码时如果发现分类是写死的可以自己动手改成表驱动这是很好的练手点。4.3 月度统计是个人理财系统的核心卖点个人理财系统值钱的功能在统计而不在记账这个增删改查。常见的统计维度有三个本月支出总额、收入总额、结余按分类汇总的支出占比近 6 个月的支出趋势这些统计在后端实现一般是用 SQL 的聚合函数。比如按分类汇总本月支出SELECT category_id, SUM(amount) AS total FROM bill WHERE user_id #{userId} AND type 1 AND date BETWEEN #{monthStart} AND #{monthEnd} GROUP BY category_id ORDER BY total DESC如果你发现源码里用group by category_id之后前端拿到的分类名称是一串 ID那就说明后端没有把分类名称 join 进来。这是一个非常常见的接口设计缺陷但不难修。4.4 预算预警可以自己动手加的功能很多基础版个人理财系统只做了流水记录和统计没有预算功能或者预算只是个摆设。预算的改进思路是在budget表存month如 2025-06、category_id、limit_amount三个字段然后写一个定时任务或查询时实时计算当月该分类已经花了多少剩余额度是多少。当实际支出超过预算的 80% 时系统在首页弹一个提示。这部分源码如果没有你自己加也不复杂核心 SQL 就是SELECT IFNULL(SUM(amount), 0) FROM bill WHERE user_id #{userId} AND category_id #{categoryId} AND type 1 AND DATE_FORMAT(date, %Y-%m) #{month}把预算表建好、接口写好这就是一个能写进简历的完善点。5. 源码里最值得读透的几个关键代码点我不建议把整个项目每个文件都读一遍那样既累又没效率。重点是挑几个“出问题最多”的位置去看金额字段类型、Controller 返回值结构、跨域处理、密码加密方式、时间处理。5.1 金额字段为什么必须用 BigDecimal 而不是 double个人理财系统的核心数据有两个数量和金额。金额如果在 Java 里用double定义很可能会出现0.1 0.2 0.30000000000000004这种问题。虽然单笔差额极小但累计起来账目就对不上了。正确做法是Java 实体类用BigDecimal数据库用decimal(10,2)这种精度明确的类型前端传参用字符串或保留两位小数你在看源码时如果发现Double类型的金额字段建议第一时间改成BigDecimal。这也常是一个项目是否专业的判断标准。5.2 统一返回体和异常处理后端接口一般不会直接返回裸数据而是包一层统一返回对象格式像{ code: 200, data: {...}, msg: success }。前端 axios 拦截器里通常会对code做统一判断比如非 200 就直接弹出错误提示。看源码时找一下这个统一返回类比如Result.java然后你就会知道为什么前端每次调接口都在response.data.data里取数据了。如果你做的项目里后端直接return list前端取数据也会很别扭不够规范。好的返回体设计能简化前端很多判断逻辑。5.3 跨域的两种处理方式前后端分离后假如前端跑在 5173 端口、后端跑在 8080 端口浏览器默认会阻止不同端口之间的请求这叫跨域报错。解决方式有两种一是在后端加CrossOrigin注解或在 SpringBoot 配置类里写一个CorsFilter允许指定来源访问这是粗粒度方案。二是开发阶段通过 Vite/Vue 的 proxy 代理解决前端发的是相对路径Vite 开发服务器帮忙转发到后端这样浏览器看到的请求全来自同源也就不存在跨域了。源码如果两种都做了那算配置比较齐全你只需知道优先级是 proxy 优先生效于开发环节。5.4 密码加密的套路个人理财系统这种垂直业务系统不需要像银行一样做各种复杂风控但密码至少不能明文存储。现在的源码大多用 Spring Security 里的BCryptPasswordEncoder或 MyBatis 框架自带的工具对密码做哈希加密后再入库。你登录时输入明文密码后端把密码加密后再和数据库里存的密文比对。你自己从零搭的时候如果不想引入完整的 Spring Security太重可以用spring-security-crypto这个单独依赖只引入加密工具类也能做到同样效果。有一点要记清楚密码加密后长度固定在 60 位左右数据库字段记得留够长度别用varchar(20)存密码不然注册就直接报“Data too long”。6. 跑系统过程中最常遇到的几个报错与排查链路标题里“可直接运行”的说法到了真实环境会有各种意外。我把见过的高频问题按从出现概率高到低的顺序列出来每个都带上排查思路而不只是给结论。6.1 前端安装依赖失败或启动报 MODULE_NOT_FOUND这个问题的报错千奇百怪但原因往往是同一个Node 版本和依赖不兼容或者网络问题导致依赖只装了一半。排查链路如下删除node_modules和package-lock.json用命令行执行node -v和npm -v确认版本根据package.json中依赖决定是否切换 Node 版本建议用 nvm-windows 管理设置镜像源后重新npm install启动观察缺失模块提示按需单独安装对应依赖有时候项目里用的是 yarn启动命令就是yarn install和yarn serve别混用 npm 和 yarn 去锁文件会出意料之外的错。6.2 后端启动失败端口被占用这个最直观。SpringBoot 启动日志最后一行会提示Port already in use: 8080。处理方式有两种找到占用进程杀掉或者改后端端口。Windows 下查看占用netstat -ano | findstr :8080然后杀进程taskkill /PID 你的进程号 /F如果改用新端口比如改成 8081要同步修改两处后端的application.yml里的端口配置还有前端代理配置里的 target 地址。不然你会一直卡在“后端看起来起来了但前端永远连不上”的怪圈里。6.3 MySQL 连接报 Public Key Retrieval is not allowed这个错误在使用 MySQL 8 时很常见。原因默认是连接用的认证方式允许在线获取公钥但你 URL 没有放开权限。在application.yml的 JDBC URL 基础上加allowPublicKeyRetrievaltrue完整 URL 变成url: jdbc:mysql://localhost:3306/finance_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalseallowPublicKeyRetrievaltrue另外MySQL 8 默认的认证插件是caching_sha2_password老一点的驱动不支持会报错。SpringBoot 2.7 自带 MySQL 驱动版本是 8.0.x一般没问题。如果用的非常老的 5.x 驱动就要换成com.mysql.cj.jdbc.Driver并调高驱动版本。6.4 页面能打开但登录后立刻跳回登录页这个现象看起来像登录失败实际可能是登录成功但后续读取用户信息时出了问题。可能的原因有后端保存用户信息的 Session 域中 key 与前端读取的不一致Token 在本地存储后前端请求拦截器没把 Token 加到请求头后端跨域配置没有允许携带凭证导致每次请求都认为是新会话排查时按这个顺序先看 Network 面板里登录接口返回的数据是否包含 Token 或用户对象再看后续接口请求头里是否带上了Authorization最后看后端控制台是否有异常。6.5 中文乱码个人理财系统里会出现中文乱码的位置主要是两个数据写入 MySQL 后乱码以及接口返回给前端时乱码。第一个问题建库时字符集必须是 utf8mb4连接 URL 里带上characterEncodingutf8。第二个问题后端返回 JSON 时注意配置server.servlet.encoding.forcetrue。大部分情况检查这两个点就可以解决。7. 项目跑通之后可以往哪些方向继续扩展源码不是终点它更像一个起跑器。如果你是为了毕业设计跑通只是保底想在答辩时有亮点可以在这些点上做一两个深度扩展。建议一给预算加上“智能提醒”。不必用复杂的定时任务在查询首页数据时实时计算每个分类的剩余预算前端在预算条上做颜色标识。实现简单演示效果却很直观老师会觉得你考虑了产品逻辑。建议二加一个“账户间转账”的功能。转账本质上是一条流水同时记录两笔账转出账户减、转入账户加。但真实系统里转账不应被统计为收入和支出所以通常用同样的type标记成“转账”或靠transfer_id关联两条流水。这个功能能补全系统的健壮性。建议三对报表做“时间维度下钻”。把统计从月维度细化到周、日维度并允许用户在首页选择一个日期范围。这需要你在 SQL 层面处理好起始时间和结束时间以及跨年跨月的边界条件。建议四把项目部署到真实服务器。本地跑通和线上部署完全两回事涉及打包、Nginx 静态资源托管、反向代理、MySQL 数据迁移。你可以用mvn package打包后端 jar用npm run build打包前端 dist再用 Nginx 配置一个站点指向 dist 目录同时把/api路径代理到后端端口。这一套走完整个项目才算真正落地。我在实际运行中发现最容易被低估的是数据一致性尤其是修改和删除历史账单时余额的同步问题。很多人只做了增删改查没考虑对账逻辑短期看不出毛病数据多了之后账就对不上了。如果你有意愿可以自己写个对账接口定期比较账户余额和流水汇总。这也是区分“能跑的项目”和“像样的项目”的分水岭。最后分享一个我个人的操作习惯拿到任何一套全栈源码先花半小时把环境变量梳理清楚再花半小时把数据库脚本读一遍最后花一小时把前后端的核心请求链走通。整个过程听起来慢实际是跑通了之后少折腾几天的捷径。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →