十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Uni-APP跨端与Spring Boot宠物领养系统:从状态机到token鉴权实战

Uni-APP跨端与Spring Boot宠物领养系统:从状态机到token鉴权实战 简介一份面向计算机专业毕业设计或课程设计的完整论文文档内容围绕基于安卓平台的宠物领养App系统展开。该论文以真实需求为背景系统采用Uni-APP跨平台框架构建小程序端Java与Spring Boot搭建后端服务MySQL作为数据库存储宠物与用户数据功能覆盖用户注册登录、首页宠物浏览、宠物资讯与交流论坛、个人账户管理以及后台管理中的用户管理、宠物分类管理、宠物信息维护、领养申请处理、论坛内容审核和系统设置等模块结构清晰、层次完整。论述从研究背景、开发意义到关键技术、系统设计、实现与测试层层展开能帮助读者快速理解前后端分离架构、RESTful API设计以及跨平台移动应用开发思路对解决流浪宠物问题、搭建便捷领养平台具有明确参考价值。资源整体为1个doc文件压缩包约2.72MB下载后可直接阅读中英文摘要、关键词、目录与完整章节内容便于编辑修改适合作为论文写作、答辩演示或项目说明的参考底座。目前已有791人学习下载尤其适合准备宠物领养类管理系统论文、需要参考Uni-APP与Spring Boot整合方案的计算机学生或开发者。1. 从流浪宠物到线上领养这个项目到底在解决什么流浪宠物问题的本质是信息不对称想弃养的人找不到可靠的接手方想领养的人不知道哪里有健康的宠物而中间缺少一个带审核、带记录的流转渠道。这套基于 Uni-APP 的宠物领养系统把领养流程拆成「信息发布 → 浏览筛选 → 提交申请 → 后台审核 → 线下交接」五个环节用 Spring Boot 做服务端MySQL 存业务数据前端用 Uni-APP 一套代码同时编译到微信小程序和 Android 端。对开发者而言真正值得拆解的不是页面长什么样而是跨端工程怎么组织、领养状态机怎么设计、token 鉴权怎么贯穿小程序和后台。下面按架构选型、数据结构、接口实现、上线调试四层展开。2. Uni-APP 跨端架构与 Spring Boot 后端的分工边界2.1 为什么选 Uni-APP 而不是纯微信小程序原生开发微信小程序原生语法是 WXML WXSS JS写出来的代码只能跑在微信里。Uni-APP 的编译链路是开发时写 Vue 单文件组件发布时按平台条件编译——mp-weixin目标产出微信小程序包app-plus目标产出 Android 和 iOS 的离线打包资源。同一套业务代码差异只体现在条件编译块里比如登录时微信走uni.loginApp 端走uni.getProvider。这对宠物领养这种需要同时覆盖微信流量和独立 App 的场景维护成本低了一个量级。后端选 Spring Boot 的理由更直接宠物领养系统的权限模型并不复杂核心是用户、宠物、领养申请、论坛帖子四类实体Spring Boot 的自动配置能把项目从零跑到接口可用压缩在十分钟内。它的spring-boot-starter-web内嵌 Tomcat配合 RESTful 风格接口小程序端通过uni.request直接消费 JSON不需要额外的视图渲染层。B/S 架构在这里的表现形式是小程序是瘦客户端所有业务判断都在服务端完成客户端只负责展示和收集用户操作。2.2 工程目录怎么划分才能让前后端不互相干扰前端工程和后端工程建议物理分离不要放在同一个代码仓库的根目录下否则 HBuilder 和 IDEA 的构建缓存会互相污染。常见做法是平级放两个目录pet-adoption/ ├── frontend/ # Uni-APP 工程HBuilder 打开 │ ├── pages/ │ │ ├── index/ # 首页宠物推荐列表 │ │ ├── pet/ # 宠物详情与领养申请 │ │ ├── forum/ # 交流论坛 │ │ └── user/ # 登录、注册、我的 │ ├── api/ # 统一封装 uni.request │ ├── static/ # 静态图片等 │ └── manifest.json # 配置 App 打包信息 └── server/ # Spring Boot 工程IDEA 打开 ├── src/main/java/com/pet/ │ ├── controller/ # REST 接口层 │ ├── service/ # 业务逻辑层 │ ├── mapper/ # MyBatis 数据访问层 │ └── entity/ # 数据库实体 └── src/main/resources/ ├── mapper/ # XML 映射文件 └── application.yml这个划分的逻辑是前端按页面组织一个页面一个目录方便定位后端按经典三层分包Controller 只做参数接收和结果封装Service 处理领养审核这类有状态流转的逻辑Mapper 层对 SQL 负责。小程序端所有请求都走api/目录下的统一封装好处是 token 过期时可以在一个地方做统一跳转而不是在几十个页面里分别判断。2.3 前后端联调的请求封装与响应格式约定小程序端所有网络请求统一走封装后的request方法避免每个页面重复写uni.request的完整参数。这个封装同时处理 baseURL 切换、token 注入、错误码拦截三件事// frontend/api/request.js const BASE_URL http://192.168.1.100:8080 // 真机调试时改成电脑局域网 IP export function request({ url, method GET, data {} }) { return new Promise((resolve, reject) { uni.request({ url: BASE_URL url, method, data, header: { Content-Type: application/json, token: uni.getStorageSync(token) || }, success: (res) { if (res.data.code 200) { resolve(res.data.data) } else if (res.data.code 401) { uni.navigateTo({ url: /pages/login/login }) reject(new Error(登录已过期)) } else { uni.showToast({ title: res.data.msg, icon: none }) reject(new Error(res.data.msg)) } }, fail: (err) { uni.showToast({ title: 网络异常, icon: none }) reject(err) } }) }) }代码里的BASE_URL是本地联调阶段最容易踩坑的地方。微信开发者工具里勾选「不校验合法域名」后可以用 localhost但真机预览时手机访问的是开发机的局域网 IP必须把地址改成http://192.168.x.x:8080。token从本地存储读取后放进 header服务端通过拦截器校验401 表示 token 失效统一跳转登录页。后端所有接口返回固定结构{ code: 200, msg: success, data: {} }前端只处理业务数据不关心 HTTP 状态码与业务状态码的映射。3. 数据库设计一张领养主表如何串联十五张业务表3.1 核心表的字段逻辑与关联关系系统的数据库包含 15 张表覆盖用户、宠物、领养、论坛、收藏、资讯六大模块。其中最关键的不是用户表而是宠物信息表和宠物预约表——前者承载宠物档案的增删改查后者承载领养申请的完整生命周期。宠物信息表中的jingdianleixing字段存储的是类型名称而非类型 ID这在规范化设计里属于冗余但实际开发中为了方便列表页直接展示、减少一次关联查询很多此类系统会保留这个冗余字段。宠物预约表则是领养流程的主线字段设计如下字段名类型说明idint主键自增dingdanbianhaovarchar(200)订单编号前端生成或后端生成jingdianmingchengvarchar(200)宠物名称下单时冗余jingdianleixingvarchar(200)宠物类型piaojiafloat领养费用可为 0表示免费piaoshuint领养数量一般固定为 1zongjiagefloat总费用piaojia 乘以 piaoshuyuyueyuyuevarchar(200)预约时间yonghumingvarchar(200)用户名关联用户表可以看出预约表把宠物名称、类型、费用都冗余了一份这样做的目的是让后台管理页面的列表查询不需要 JOIN 多张表直接单表查询就能渲染。代价是当宠物信息修改时历史预约记录不会同步更新——在领养场景里这是可以接受的因为预约单生成后应保留下单时的快照避免宠物信息变更导致历史单据数据错乱。3.2 建表 SQL 与领养状态字段的补全原论文中的预约表没有显式的状态字段但实际开发中领养需要经历「待审核 → 已通过 → 已拒绝 → 已完成」的状态流转否则后台无法区分新申请和历史申请。常见的做法是在建表时补充一个status字段CREATE TABLE jingdianyuyue ( id int(11) NOT NULL AUTO_INCREMENT, addtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 创建时间, dingdanbianhao varchar(200) DEFAULT NULL COMMENT 订单编号, jingdianmingcheng varchar(200) DEFAULT NULL COMMENT 宠物名称, jingdianleixing varchar(200) DEFAULT NULL COMMENT 宠物类型, piaojia float DEFAULT NULL COMMENT 领养费用, piaoshu int(11) DEFAULT NULL COMMENT 领养数量, zongjiage float DEFAULT NULL COMMENT 总费用, status varchar(50) DEFAULT 待审核 COMMENT 领养状态, yonghuming varchar(200) DEFAULT NULL COMMENT 用户名, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8 COMMENT宠物预约表;status字段用字符串而不是 TINYINT是因为领养状态的可读性比空间占用更重要后台管理页面直接展示这个字段不需要做数字到文字的映射。addtime设置默认值CURRENT_TIMESTAMP插入记录时不需要手动传时间MyBatis 插入语句里也不该出现这个字段。dingdanbianhao建议用「日期 随机数」拼接例如202401151030 4位随机数避免并发时主键业务冲突。3.3 token 表和用户表的鉴权设计系统里有专门的一张token表这在很多小型管理系统中会被忽略但在这里它是连接微信小程序端和后台管理的鉴权枢纽。小程序端用户登录后后端生成一个 UUID 作为 token 存入该表同时返回给前端前端每次请求携带 token后端拦截器去 token 表里查记录是否存在且未过期。使用数据表而不是 Redis 存 token是因为这个系统的并发量不高MySQL 完全扛得住且逻辑更直观——管理后台可以直接查看当前在线用户。用户表yonghu与users并存是这类系统的常见设计users表面向后台管理员字段较少yonghu表面向小程序用户包含头像、昵称、联系方式等。两套用户体系互不干扰后台登录走users表小程序登录走yonghu表。宠物信息评论表discussjingdianxinxi通过refid关联宠物 ID通过userid关联评论用户评论内容存longtext类型避免内容过长时被截断。4. 从注册到领养申请核心接口实现与状态流转4.1 注册登录的接口实现与密码处理小程序端的注册接口接收用户名、密码、昵称、手机号四个字段。密码不能明文入库常见的做法是用 MD5 加盐或 BCrypt 加密。考虑到这个系统的技术栈是 Spring Boot 2.x MyBatis接入spring-security-crypto依赖只使用其中的BCryptPasswordEncoder比较轻量// server/src/main/java/com/pet/controller/UserController.java RestController RequestMapping(/api/user) public class UserController { Autowired private UserService userService; PostMapping(/register) public Result register(RequestBody Yonghu yonghu) { // 检查用户名是否已存在 Yonghu existing userService.findByUsername(yonghu.getYonghuming()); if (existing ! null) { return Result.error(用户名已存在); } // 密码加密后存储 BCryptPasswordEncoder encoder new BCryptPasswordEncoder(); yonghu.setMima(encoder.encode(yonghu.getMima())); userService.register(yonghu); return Result.success(null); } PostMapping(/login) public Result login(RequestBody Yonghu yonghu) { Yonghu user userService.findByUsername(yonghu.getYonghuming()); if (user null) { return Result.error(用户不存在); } BCryptPasswordEncoder encoder new BCryptPasswordEncoder(); if (!encoder.matches(yonghu.getMima(), user.getMima())) { return Result.error(密码错误); } // 生成 token 并存入 token 表 String token UUID.randomUUID().toString().replace(-, ); userService.saveToken(token, user.getId()); return Result.success(token); } }注册接口先查重再加密后入库避免数据库唯一索引抛出异常变成 500 错误。登录接口用encoder.matches验证明文与密文不能用equals直接比较因为 BCrypt 每次生成的盐不同同一密码的密文也不相同。生成 token 后需要同时记录用户 ID后续请求通过 token 反查用户时不需要前端再传用户 ID。4.2 宠物列表与领养申请的前后端对接首页宠物列表是典型的列表页接口需要支持分类筛选和关键词搜索。Controller 层接收type和keyword两个可选参数MyBatis 动态 SQL 拼接查询条件-- server/src/main/resources/mapper/JingdianxinxiMapper.xml select idqueryPetList resultTypecom.pet.entity.Jingdianxinxi SELECT * FROM jingdianxinxi where if testtype ! null and type ! AND jingdianleixing #{type} /if if testkeyword ! null and keyword ! AND jingdianmingcheng LIKE CONCAT(%, #{keyword}, %) /if AND is_adopt 0 /where ORDER BY addtime DESC LIMIT #{pageNum}, #{pageSize} /selectis_adopt字段是宠物信息表中用来标记是否已被领养的标识0表示可领养1表示已领养。列表页只查询is_adopt 0的数据已领养的宠物自动从列表消失。LIMIT #{pageNum}, #{pageSize}是分页参数pageNum 从 0 开始前端传当前页码减 1。前端点击「申请领养」按钮后提交宠物 ID 和用户 ID 到预约接口服务端插入一条jingdianyuyue记录状态默认为待审核。小程序端提交领养申请的核心代码如下// frontend/pages/pet/detail.vue submitAdopt() { const petId this.petInfo.id const userInfo uni.getStorageSync(userInfo) if (!userInfo) { uni.navigateTo({ url: /pages/login/login }) return } request({ url: /api/adopt/apply, method: POST, data: { petId: petId, userId: userInfo.id, yonghuming: userInfo.yonghuming } }).then(() { uni.showToast({ title: 申请成功等待审核, icon: success }) }) }这段代码的处理要点在用户态判断上未登录用户点击申请时直接跳转登录页而不是提交一个必然失败的请求。userInfo在登录成功时存入本地存储包含用户 ID 和用户名提交时直接取出使用。服务端收到申请后应当先判断该宠物是否已被别人申请避免一宠多领。4.3 后台审核流程与宠物信息的 CRUD后台管理的宠物信息管理模块是典型的增删改查页面。管理端修改宠物描述后小程序端列表页不需要做任何缓存处理因为数据是实时从数据库读取的。宠物信息的删除需要考虑关联数据——如果宠物已被预约删除宠物表记录会导致预约单变成脏数据。常见的做法是逻辑删除增加is_delete字段列表查询时默认过滤该字段// server/src/main/java/com/pet/controller/AdminController.java DeleteMapping(/pet/{id}) public Result deletePet(PathVariable Integer id) { // 检查是否有未处理的领养申请 Integer count adoptService.countPendingByPetId(id); if (count 0) { return Result.error(该宠物有待审核的领养申请无法删除); } // 逻辑删除is_delete 1 petService.logicDelete(id); return Result.success(null); }删除前的状态检查是一个容易遗漏但必须有的环节。如果一个宠物同时有三个人提交了领养申请其中一条已经通过此时删除宠物信息会导致已通过的领养记录无法追溯。countPendingByPetId查询该宠物下状态为待审核的申请数量大于 0 时拒绝删除并提示管理员先处理申请。逻辑删除用is_delete 1标记而不是直接从表中 DELETE这样论坛帖子或收藏记录里引用的宠物 ID 依然能查到已下架的历史信息。5. 微信开发者工具联调与真机调试的边界问题5.1 小程序端网络请求的合法域名限制微信开发者工具中预览小程序时默认要求所有请求的域名都配置在微信公众平台的「开发设置 → 服务器域名」里且必须是 HTTPS。开发阶段可以在工具右上角「详情 → 本地设置」里勾选「不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书」这样就能用http://localhost:8080或局域网 IP 访问后端接口。但真机预览时手机上的微信小程序不受开发者工具设置影响必须在工具中点击「真机调试」此时音乐会走微信的调试通道请求可以访问局域网 IP。有一种常见误用需要避开把后端接口直接暴露到公网并挂 HTTP只为绕过合法域名校验。正确做法是开发阶段用「不校验」解决联调问题部署阶段把后端放到支持 HTTPS 的服务器上前端构建时通过环境变量切换接口地址。Uni-APP 的manifest.json里可以按平台配置不同的 baseURLprocess.env.NODE_ENV区分开发与生产环境。5.2 HBuilder 打包 Android 时与后端交互的两个配置点HBuilder 打包 Android 安装包时前端请求的 baseURL 不能写localhost因为手机上的 localhost 指向手机自身而非开发机。打包前需要将request.js里的BASE_URL改成服务器公网 IP 或域名。如果只是内网测试要保证手机和服务器在同一网段且服务器防火墙放行 8080 端口。Android 9 及以上系统默认禁止 HTTP 明文流量而开发阶段后端往往只有 HTTP 接口。HBuilder 打包时需要在manifest.json的 App 模块配置中开启「使用明网传输」或类似选项同时在后端配置跨域策略允许来自 App 的请求。application.yml里补充跨域配置server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/pet_adoption?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: 123456serverTimezoneAsia/Shanghai是连接 MySQL 8.x 必填的参数否则日期字段会报时区错误。useUnicode和characterEncoding保证宠物名字等中文内容不乱码。后端接口还需要配置跨域过滤器否则 App 端请求会被浏览器同源策略拦截微信小程序端因为不是浏览器环境不受同源策略限制但为了 H5 端也能复用同一套后端跨域过滤器建议直接加上。5.3 用 navicat 反向验证领养流程的数据落库联调完成后的验证手段用 Navicat 直接查数据库是最直观的。完整跑一遍领养流程小程序端注册新用户 → 首页浏览宠物 → 提交领养申请 → 后台审核通过。每步操作后在 Navicat 里执行相应的查询语句确认数据确实写入并更新-- 确认用户已创建 SELECT id, yonghuming, nickname FROM yonghu ORDER BY addtime DESC LIMIT 1; -- 确认领养申请已插入状态为待审核 SELECT jingdianmingcheng, yonghuming, status FROM jingdianyuyue ORDER BY addtime DESC LIMIT 1; -- 后台审核通过后确认状态变更和宠物标记 UPDATE jingdianyuyue SET status 已通过 WHERE id 1; UPDATE jingdianxinxi SET is_adopt 1 WHERE id 1;第一条查询验证注册链路是否完整如果用户表里没有新记录问题出在后端注册接口或数据库连接配置。第二条查询验证预约接口是否正常插入记录如果记录存在但状态为空检查建表时是否给status字段设置了默认值。第三条的手动 UPDATE 用来模拟后台审核操作确认宠物信息表的is_adopt标记能正常更新——审核通过后宠物下架前端列表对应宠物消失。这组 SQL 跑通后整个系统的核心链路就没有逻辑死角了。本文还有配套的精品资源点击获取
返回列表