简介:一套面向毕业设计场景的微信小程序家庭理财系统完整源码包,包含前端小程序、基于Java的后端服务和SQL数据库脚本,以家庭为单位动态反映收支情况,覆盖用户注册登录、工资管理、记账本管理、贷款管理及理财分析等核心模块。后台管理员可删除普通用户、修改账号密码及用户信息,贷款管理支持建立账目并跟踪贷款金额、日期、还款日期和利率,同时提供提醒功能。整体以蓝色为基调,理财分析和贷款管理模块采用绿色区分,界面简洁、业务流程合理。资源共4个文件,含2个zip源码包、1个SQL脚本和1个text说明文档,压缩包仅4.62MB,SQL脚本可直接导入,text说明文档可帮助快速理解项目结构。目前已有314人学习使用,尤其适合需要快速完成微信小程序毕业设计、Java后端开发或理财类系统项目的学生参考,可借鉴其模块划分、后台管理逻辑、界面配色方案及数据表设计思路,便于在此基础上二次开发。
1. 家庭理财毕设资源能跑通什么:微信小程序、Java后端与毕业论文一体交付
毕业设计用微信小程序做家庭理财系统,后端走 Java 那套,前端要能注册登录、记账、看报表,最后还得交一篇论文——这份资源把这几件事理在了一条链路上。拆开看是四份文件加一份说明:family_bank.zip 装小程序前端,client.zip 装管理端页面,server.zip 是 Java 后端服务,jizhang.sql 是初始化数据库脚本。把这几份按顺序跑起来,就是一个「用户端记账、管理员管人、系统自动算利息和收支」的完整闭环。适合两类人:想在一周内把系统跑起来准备答辩的学生,以及第一次用微信小程序接 Java 接口、想找个完整案例抄作业的从业者。
2. 把四份文件跑起来:环境版本、数据库导入与服务端启动
2.1 先读 readme,再解压文件,确认发行方给的部署顺序
很多同学拿到压缩包第一反应是直接解压运行,结果卡在第一步。我一般会先把 readme.text 打开看部署顺序,因为每个毕设项目的起包方式不一样,有的是先导数据库再改后端配置,有的是先配小程序 AppID。
按这套资源的常见结构:family_bank.zip 是小程序端,用微信开发者工具打开;client.zip 通常是后台管理页面,本地起一个 Web 服务或直接静态文件访问;server.zip 放的是 Java 后端,用 Maven 打包;jizhang.sql 是数据库初始化脚本,要先在 MySQL 里建库再导入。
建议解压后分三个目录放,前端、后端、数据库脚本不要混在同一层。资源包里没有附带 README 以外的部署文档时,就按「先建库→再起后端→再开小程序」的顺序来,哪里报错就回看哪一部分。
2.2 数据库导入:建库、字符集、执行 jizhang.sql
后端连不上数据库,九成是字符集问题。jizhang.sql 里如果建表语句指定了 utf8mb4,那数据库本身也要用 utf8mb4,否则中文全是问号。
用命令行导入是最稳的方式,避免可视化工具图形界面里的字符集坑。打开终端先登录 MySQL:
mysql -u root -p然后执行建库和导入:
CREATE DATABASE IF NOT EXISTS family_bank DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE family_bank; SOURCE /your/path/jizhang.sql;注意SOURCE后面写你本地实际的路径,Windows 系统要写成反斜杠路径或用正斜杠转义。导入完成后查看表数量:
SHOW TABLES;正常会看到 user、bill、loan、salary、family_member 之类的基础表,具体表名以 jizhang.sql 里的实际内容为准。如果没有 family_member 表,说明这套项目的权限模型里没有家庭维度,需要看 server 端代码里怎么关联用户。
2.3 服务端配置:数据源、端口、日志路径
打开 server.zip 解压后的目录,先找 application.yml 或 application.properties。重点改三处:数据库地址、数据库密码、服务端口。
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/family_bank?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver密码改成你本机 MySQL 的实际密码。serverTimezone=Asia/Shanghai尽量保留,MySQL 8.0 以上的驱动不配时区会直接报错。driver-class-name 如果后端用的是 MySQL 8 驱动,要写成com.mysql.cj.jdbc.Driver,否则启动日志会给你看一眼连接失败的堆栈,然后默默退出。
启动方式取决于项目用的框架。如果是 Spring Boot,在根目录执行:
mvn spring-boot:run如果是传统 SSM 项目,需要打包成 war 丢进 Tomcat:
mvn clean package看 target 目录下产出的是 jar 还是 war 再决定下一步。启动日志里看到Started且没有 Exception,基本可以进入下一步对接小程序。
2.4 小程序端导入:AppID、基础库、网络请求域名
微信开发者工具里导入 family_bank 目录。AppID 先用测试号,等要发布或预览到手机时再换成自己的小程序 AppID。关键设置:在「详情 → 本地设置」里勾选「不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书」。
这一步不做,本地请求 http://localhost:8080 的接口会被拦成白屏,很多新手在这一步反复查代码,其实是开发者工具的安全校验在挡。
小程序端的接口地址一般在 utils/request.js 或 api.js 里统一定义,搜baseUrl或BASE_URL:
const BASE_URL = 'http://localhost:8080';改成你后端实际地址。如果后端跑在云服务器或局域网另一台机器上,就填对应 IP,比如http://192.168.1.20:8080。真机预览时 localhost 指手机自己,不是你的电脑,必须先改成局域网 IP 并保证手机和电脑同网段。
3. 用户注册到后台管理:登录 Token、改密和删除用户的实现
3.1 注册登录的核心流程与密码加密方式
这套系统的用户端从注册开始。user 表里通常有 username、password、phone、create_time 这几个基本字段。密码存储不能明文,用 MD5 加盐是毕设项目里最常见的做法。加盐的意思是在密码后面拼一段随机字符串再做摘要,防止两个相同密码的用户得到同一个哈希值。
登录接口是前后端联调的第一关,一般写法如下:
@RestController @RequestMapping("/user") public class UserController { @PostMapping("/register") public Result register(@RequestBody User user) { String salt = UUID.randomUUID().toString().substring(0, 6); user.setPassword(MD5Util.md5(user.getPassword() + salt)); user.setSalt(salt); user.setRole(1); // 1 普通用户, 0 管理员 userService.insert(user); return Result.success(); } @PostMapping("/login") public Result login(@RequestBody User user) { User dbUser = userService.findByUsername(user.getUsername()); if (dbUser == null || !dbUser.getPassword() .equals(MD5Util.md5(user.getPassword() + dbUser.getSalt()))) { return Result.error("用户名或密码错误"); } String token = UUID.randomUUID().toString(); redisService.set(token, dbUser.getId(), 7 * 24 * 3600); return Result.success(token); } }参数说明:/user/register里 salt 取 UUID 前 6 位,保证每个用户盐值不同;/user/login用数据库里查出来的盐重新拼接校验,不直接用前端传的盐。登录成功后生成 token,有效期设 7 天。项目里没接 Redis 的话,常见做法是存一个内存 Map,或者把 token 写进一张 token 表,弊端是重启后失效,但答辩解释成「用户强制重新登录」也能圆的过去。
注册时注意字段校验:用户名重复要返回明确提示,手机号格式用正则校验。很多毕设只在后端写了非空判断,前端反而把格式校验做得很复杂,这个和实际生产相反,会显得业务逻辑不完整。
3.2 管理员端的分权控制和用户管理
管理后台在 client.zip 里,角色靠 user 表里的 role 字段区分。管理员账户在 jizhang.sql 初始化数据里预置,登录入口和普通用户分开或同一个登录接口,按 role 值跳转不同页面。普通用户进的是记账主页,管理员看到的是用户列表和管理操作。
删除用户和修改密码这两个操作是后台管理的核心。后端接口一般长这样:
@PutMapping("/admin/users/{id}") public Result updateUser(@PathVariable Long id, @RequestBody User user) { if (!isAdmin(getCurrentUser())) { return Result.error("无权限"); } if (StringUtils.hasText(user.getPassword())) { String salt = UUID.randomUUID().toString().substring(0, 6); user.setSalt(salt); user.setPassword(MD5Util.md5(user.getPassword() + salt)); } userService.updateById(id, user); return Result.success(); } @DeleteMapping("/admin/users/{id}") public Result deleteUser(@PathVariable Long id) { if (!isAdmin(getCurrentUser())) { return Result.error("无权限"); } userService.deleteById(id); return Result.success(); }逻辑说明:isAdmin判断当前登录用户的 role 是否为 0,不是直接拒绝。修改密码前要看传来的 password 是否为空,为空说明管理员只改了手机号或昵称,不需要动密码;有值才重新加盐加密。删除用户要考虑关联数据,bill 和 loan 表里通过 user_id 关联账单和贷款,直接删 user 会留下孤儿数据,常见做法是软删:给 user 表加一个 deleted 字段,删除时置 1,查询时过滤。
3.3 工资管理:按月记录、家庭多成员拆分
工资管理模块是这套系统相对独立的业务域。核心场景是每个家庭成员各有一条工资记录,按月录入,然后家庭总收入和人均收入才能算得出来。
工资表的设计我见过两类:一类是薪资字段和家庭成员一一对应,一行一个成员当月收入;另一类是单独一张 salary 表,用 user_id 关联用户,member_name 记录成员姓名。后者更灵活,因为家庭成员可能没有登录小程序的账号。
前端页面录入工资时一般提交这四个字段:成员姓名、所属月份、基本工资、绩效奖金。后端计算总计时,先把 12 个月的数据按月份分组,再做合计。注意 month 字段建议存成2025-06这种格式,而不是单纯存 int 6,否则跨年统计时会混淆 2024 年 6 月和 2025 年 6 月。
工资数据和记账本数据的关系在理财分析里会汇合,工资属于 income 来源的一种,记账本里的工资入账是另一条明细记录。很多同学分不清这两个模块的边界,实际设计逻辑是:工资管理管的是「每个家庭成员赚了多少」,记账本管的是「每笔钱实际入账了没有」,前者是主数据,后者是流水。理财分析优先展示后者。
4. 记账本与贷款管理:SQL 怎么算利息、怎么聚合成家庭收支
4.1 记账本模块的表结构与分页查询
记账本是用户最常用的模块,表结构一般包含这几个关键字段:id、user_id、type、category、amount、bill_date、remark、create_time。type 只有两个值:income 和 expense。category 则分细类:餐饮、交通、购物、工资、理财收益、其他收入。
新增账单的插入接口不复杂,但分页查询时列表要和月份筛选、类型筛选一起做。分页查询的 SQL 建议写成这样:
SELECT id, type, category, amount, bill_date, remark FROM bill WHERE user_id = ? AND DATE_FORMAT(bill_date, '%Y-%m') = ? AND type = IF(? = '', type, ?) ORDER BY bill_date DESC, id DESC LIMIT #{offset}, #{pageSize};逻辑说明:用户点哪个月就看哪个月,筛选所有类型时前端传空字符串,IF条件直接放行;页码从 0 开始算 offset,页面从 1 开始传时后端要offset = (pageNum - 1) * pageSize。这个 SQL 在数据量大时会有索引失效风险,但毕设数据量最多几千条,够用了。
列表接口返回时建议带上分类名称的中文映射。如果后端是直接查数据库原始类别代码(比如food、transport),小程序端在渲染前要做一次 map 转换,否则页面上显示英文字段。
提示:记账本的删除和修改一定要带 user_id 条件,防止用户改别人账单。这个坑在答辩时容易被老师点名。
4.2 贷款管理:利息计算和到期提醒的实现
贷款管理模块有四个核心字段:贷款金额、贷款日期、还款日期、年利率。设计表结构时还要加一个还款状态字段,比如0 未结清、1 已结清,这样渲染列表时可以区分展示。
利息按月计算,常见做法是按「剩余本金 × 月利率 × 使用天数/30」估算。由于毕设项目不接真实银行系统,利息公式只要说得通就可以。我见过一种简化写法:
// 计算到期应还利息 public Double calcInterest(Loan loan, LocalDate settleDate) { Long days = ChronoUnit.DAYS.between(loan.getLoanDate(), settleDate); // 年利率转日利率,按 360 天计算 double dailyRate = loan.getRate() / 360.0; return loan.getAmount() * dailyRate * days; }代码说明:ChronoUnit.DAYS.between算贷款日期到结清日期的天数;年利率除以 360 是银行常用计息口径。还款提醒用定时任务或者查询时动态计算:WHERE repay_date BETWEEN NOW() AND DATE_ADD(NOW(), INTERVAL 7 DAY)查出 7 天内到期的贷款,然后在首页的提醒列表里展示。没有定时任务框架的话,就靠用户每次打开小程序时自动拉一遍这个接口,够用。
前端页面里贷款管理用绿色基调,金额显示重点突出到期日期,剩下几天用倒计时的形式显示。还款日期已经过了的,状态字段要显示「已逾期」。
5. 常见问题与避坑记录:导入失败、白屏、图表空白的四个修复点
5.1 MySQL 导入 jizhang.sql 时报 1064 语法错误
现象:SOURCE执行到一半报错,提示某个字段或 KEY 附近有语法错误。
原因:MySQL 版本不匹配。jizhang.sql 可能是 5.7 环境导出的,本地装了 8.0 后,某些字段默认值写法(比如DEFAULT ''配合TIMESTAMP字段)会触发严格模式限制。另一个常见原因是执行前没有USE family_bank;,导致表建到了别的库里。
解决:先执行SET sql_mode = '';关掉严格模式,再重新SOURCE。如果还报错,用文本编辑器打开 jizhang.sql,找到报错行改掉对应的默认值语法,改成 MySQ L 8.0 能识别的写法。导入完成后,至少抽查三张表的结构是否完整,避免只导入一半数据。
5.2 小程序页面一直 loading,请求根本打不到后端
现象:开发者工具里网络请求显示 failed,报ERR_CONNECTION_REFUSED,后端日志没有任何访问记录。
原因:BASE_URL 还是默认的 localhost,而开发者工具模拟器里的 localhost 指向的是你的开发机没错,但如果你后端没启动,或者启动端口和 BASE_URL 不一致,就会出现连接拒绝。更多的情况是后端启动了、端口也对,但 BASE_URL 写成了https://,而后端起来的是 http。
解决:先浏览器直接访问http://localhost:8080/user/login试接口通不通;浏览器通了再检查小程序 BASE_URL 里有没有http://前缀;本地联调不要开「合法域名校验」,真机预览要改局域网 IP 并关闭开发者工具的域名校验开关。
5.3 理财分析页面图表空白,数据接口有返回但渲染不出来
现象:接口返回的 JSON 里数据是正常的,但小程序页面里的图表区域一片空白,控制台报undefined is not a function或 canvas 相关错误。
原因:项目引入的图表库版本和小程序基础库版本不兼容。常见的是用 ECharts 组件时 canvas 类型写错,或者用的是老版本 ec-canvas,在基础库 2.x 以下还能跑,换了新版基础库就崩。还有一个隐蔽原因是图表的数据格式没做适配,接口直接返回了 Java 对象字段(比如pieData),而图表组件要的是[{name: '', value: ''}]结构。
解决:先单独写死一组示例数据塞进图表组件,看能不能渲染;能渲染就是数据映射问题,写一个转换函数把接口字段转成图表要求的格式。不能渲染就去查引入的图表组件版本,换成项目初始预期的那个版本,或者迁移到适配新版基础库的图表方案。
5.4 管理员改了用户密码,用户拿新密码登录却提示错误
现象:管理后台提示修改成功,但小程序端用新密码登录时始终报「用户名或密码错误」。
原因:改密接口没有做加盐处理,直接把新密码明文存进数据库了。用户登录时后端的校验逻辑是用老 salt 拼接新密码再 MD5,和数据库里的值对不上。
解决:修改管理后台的改密接口,加盐逻辑要和注册接口一致。改完之后写段测试脚本验证,先注册一个临时用户,然后走管理员改密流程,再用新密码登录。毕设答辩前把这条链路完整走一遍,比临时抱佛脚查代码要省时间。
6. 把理财分析做成答辩亮点:蓝绿配色和八项自测收尾
6.1 全局配色的实现方式与模块差异化
整体基调是蓝色,这个不起眼的要求实际上是小程序端最容易出效果的地方。全局主要色调用蓝色,App 的 tabBar 选中态、按钮背景、导航栏标题都用同一个色值,避免在多个页面里散落不同深浅的蓝。具体实现可以在 app.wxss 里定义全局变量:
page { --primary-color: #1e6fff; --success-color: #00b578; --bg-danger: #ff4d4f; }页面里用var(--primary-color)引用,这样后面要调色只改一个文件。理财分析和贷款管理两个模块用绿色做局部主题,页面进来时给根节点加一个 class,把按钮的主色替换成--success-color,其余页面保持蓝色不变。答辩时这套实现可以明确讲:不是分了两套主题,而是基于一个 CSS 变量体系做的模块级状态切换。
6.2 理财分析页面的数据聚合逻辑
理财分析按时间维度统计收入、支出、结余和分类占比。后端接口一般返回月度汇总数据,SQL 聚合可以一次查出来:
SELECT DATE_FORMAT(bill_date, '%Y-%m') AS month, SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END) AS total_income, SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END) AS total_expense, SUM(CASE WHEN type = 'income' THEN amount ELSE -amount END) AS net_surplus FROM bill WHERE user_id = #{userId} GROUP BY month ORDER BY month DESC LIMIT 6;参数说明:CASE WHEN实现行转列,把收入和支出两个值放到同一行里,方便前端直接渲染月度和结余。net_surplus是收入减支出的结余,负数说明这个月超支了。用LIMIT 6取最近六个月的趋势数据,前端用折线图展示三条线:收入、支出、结余。分类占比单独查一张bill表按类别分组:
SELECT category, SUM(amount) AS total FROM bill WHERE type = 'expense' AND DATE_FORMAT(bill_date, '%Y-%m') = #{month} GROUP BY category ORDER BY total DESC;这个结果直接映射到环形图的 name/value 字段。注意 category 分组出来的值是英文代码,前端渲染前要做一层中文映射。我把这个映射放在后端统一处理,返回给小程序时就是中文分类名,减少前端代码量。
6.3 验收前强制走一遍的八项自测
这套资源拿到手,我建议按下面顺序过一遍再决定要不要开始改代码:第一,重新注册一个新用户,确认能注册成功并能登录。第二,新用户录入一笔工资和一笔支出,回到首页看收支总览是否正确。第三,创建一个贷款记录,看利息是否自动计算、到期提醒是否出现在首页。第四,用管理员账户登录后台,改一个新用户的密码,再用新密码登录。第五,管理员删除新用户,确认删除后该用户登录被挡。第六,切到理财分析页面,看月度统计有没有把刚才的账算进去。第七,用开发者工具的真机预览模式,连局域网跑一遍完整流程,确认不是只在模拟器里正常。第八,清理测试数据,改成自己答辩时想展示的干净模板,再跑一遍注册登录。
八项自测里最容易翻车的是第三项,因为贷款利息涉及日期计算,跨月或跨年时边界条件容易出问题。我从那以后每次拿到别人的源码包,都强制自己先把自测清单过一遍再动手改业务,这个习惯救了我好几次临时换项目的场子。希望帮到你。
本文还有配套的精品资源,点击获取