资讯详情

微信小程序疫苗预约接种系统全栈源码实战拆解

📅 2026/10/10 15:20:24 | 华诺云谱 👁 阅读
微信小程序疫苗预约接种系统全栈源码实战拆解
简介基于微信小程序的疫苗预约接种系统完整源码包面向小程序开发者、Java后端学习者及高校毕设/课设人群。系统在既有疫苗预约项目基础上重构并二次开发业务覆盖预约、支付、签到、预检、接种、留观全流程。管理员端支持查看数据分析图对接种点、医护人员、疫苗、预约计划进行增删改查可查询接种者的六类历史记录接种者端支持疫苗与接种点信息查阅、提交预约申请、模拟支付并查看接种二维码状态。资源包共644个文件以html与vue构成前端页面java与xml担纲后端接口和配置js负责交互逻辑另含scss/css样式、json数据配置及sql脚本压缩包仅3.56MB导入IDE后修改MySQL驱动与数据库配置即可启动。已有1054人学习适合作为毕业设计、课程设计的完整参考或二次开发练习。1. 微信小程序疫苗预约接种系统一套直接能改的课设级全栈源码疫苗预约这事难点不在「能预约」而在「约了不重、约了能查、库存不超卖」。这套基于微信小程序的疫苗预约接种系统源码小程序端用原生 WXML/WXSS/JS 开发后端走 PHP MySQL把用户登录、疫苗列表、在线预约、接种记录、管理员后台一整条链路做齐了。拆完代码的第一感觉是它没有堆炫技组件但对预约系统最核心的「日期 时段 库存 状态」四个要素处理得相当扎实状态机、事务扣库存、角色权限都有覆盖。适合正在做毕设、课设或者想把小程序全栈流程完整跑通的人。拿它改业务比从零写至少省一半时间而且代码结构足够让答辩老师问到哪都能接住话。2. 先看骨架页面结构、角色权限与六张核心数据表拿到源码压缩包先别急着导入开发者工具。我习惯先把目录结构和数据库脚本捋一遍搞清楚这套系统是谁在用什么角色操作数据是怎么流转的后面改起来才不迷路。这套系统的设计思路很典型小程序端面向普通用户管理后台面向接种点管理员两边共用同一套后端接口和数据库。2.1 页面结构与角色边界前端 pages 目录与后端 admin 两个世界小程序端的 pages 目录一般按业务划分常见的是 index首页疫苗列表、booking预约提交、appointment我的预约、vaccine疫苗详情、profile个人中心。底部 tabBar 通常是首页、预约、我的三个入口。管理端一般是独立的页面目录或者直接做成 Web 后台但核心业务表共用。角色权限上系统里至少有三类角色。普通用户只能浏览疫苗、提交预约、查看自己的预约记录和接种记录接种点管理员负责审核预约、登记实际接种信息、维护疫苗库存系统管理员负责维护疫苗数据、接种点信息、发布公告。这套源码里角色字段存在 user 表的 role 字段里接口层通过 token 里的用户身份做权限判断。我拆的时候特别看了下预约创建接口和接种登记接口不是同一个权限级别这点做得是对的不然普通用户就能自己把状态改成已接种。2.2 核心数据表预约状态从 pending 到 completed 的流转数据库脚本文件大概率叫 vaccine_system.sql 或类似名字导入后主要就是下面这六张表。我先用一张表把这六张表的职责说清楚。表名核心字段职责说明useropenid, nickname, phone, id_card, role, token用户表openid 是微信侧唯一标识role 区分权限vaccinename, manufacturer, dosage, stock, description, status疫苗表stock 是剩余库存status 控制上下架pointname, address, work_time接种点表一个疫苗可以对应多个接种点appointmentuser_id, vaccine_id, point_id, appoint_date, time_slot, status预约表状态是这套系统的核心recordappointment_id, user_id, vaccine_id, dose, vaccinated_time, operator_id接种记录表接种完成后生成noticetitle, content, create_time公告表首页轮播或列表展示预约表里的 status 字段是整个系统最值得看的地方。一般用字符串存四种状态pending 待接种、completed 已接种、canceled 已取消、expired 已过期。已过期这个状态容易被忽略但实际场景里用户约了没来预约单不能永远挂在 pending 上需要一个定时任务或者在查询时按日期判断自动标记过期。源码里大概率是在查询接口里动态判断的也就是 appointment 表里没有真的去 UPDATE 过期状态而是 SELECT 时用 appoint_date 和当前日期比对。这种做法省事但如果你要做后台统计报表建议还是写个定时脚本把过期状态落库。2.3 接口对应关系wx.request 的 URL 和后端 PHP 路由怎么对齐小程序端所有网络请求都走 wx.request后端是 PHP 写的没有用框架的话就是每个接口一个 PHP 文件路由规则是/api/文件名.php。我拆下来的接口对应关系大概是下面这样你拿到源码后可以对照着改。前端模块请求 URL方法说明登录/api/login.phpPOSTcode 换 openid生成 token疫苗列表/api/vaccine_list.phpGET分页返回疫苗和剩余库存疫苗详情/api/vaccine_detail.phpGET单支疫苗详情、适用人群创建预约/api/appointment_create.phpPOST三要素校验后生成预约单我的预约/api/appointment_list.phpGET当前用户的预约记录列表取消预约/api/appointment_cancel.phpPOST把 pending 改成 canceled接种记录/api/record_list.phpGET已完成的接种历史注意看前端请求 URL 和后端文件名的对应方式改接口时两头都要动。前端在 utils/config.js 或 app.js 里有个 baseURL 全局变量所有 wx.request 都基于它拼 URL。后端 PHP 文件里统一 require 数据库连接和鉴权公共文件一般是 include/db.php 和 include/auth.php。鉴权部分看的是请求头里的 X-Token 字段后端从 user 表查出对应用户再做权限判断。这个套路不高级但很实用课程设计答辩时被问到「你怎么做登录态保持的」照着这个链路讲就能说清楚。3. 三个核心流程的代码拆解登录、疫苗列表与预约提交搞清楚了骨架接下来就是把最核心的三个流程一行行看明白。这三个流程分别是登录换 openid、疫苗列表加载、预约提交它们基本决定了这套系统能不能正常跑。我按照前端调用的先后顺序来拆每个流程都会把前端和后端的代码拿出来讲参数和逻辑。3.1 登录不是拿 code 就完事jscode2session 换 openid 的完整链路微信小程序登录的第一步是 wx.login 拿到临时 code但这个 code 不能直接当身份用。正确做法是把 code 发给后端后端拿着 code 加上 appid 和 secret 去微信的 jscode2session 接口换 openid。openid 是用户在当前小程序下的唯一标识后端拿到它去 user 表里查查不到就自动注册一条然后生成一个 token 返回前端存起来。前端登录页面的核心逻辑大概长这样// pages/login/login.js const app getApp(); Page({ onLoad() { wx.login({ success: (res) { if (res.code) { this.exchangeOpenid(res.code); } else { wx.showToast({ title: 登录失败, icon: none }); } } }); }, // 用 code 换 openid拿到 token 后存本地 exchangeOpenid(code) { wx.request({ url: ${app.globalData.baseURL}/api/login.php, method: POST, data: { code }, success: (res) { if (res.data.code 0) { wx.setStorageSync(token, res.data.data.token); wx.setStorageSync(userId, res.data.data.userId); wx.switchTab({ url: /pages/index/index }); } else { wx.showToast({ title: res.data.msg, icon: none }); } } }); } });前端这段逻辑坑点主要在 url 拼接上。app.globalData.baseURL 如果忘了加请求路径或者 baseURL 配的是http://localhost:8080而不是http://localhost:8080/api那所有请求都会 404。另外 wx.setStorageSync 存的 token 和 userId后续所有需要登录态的接口都会从 storage 里取这两个 key 不要改改了你得把全工程引用一起改。后端 login.php 的代码是整套系统的登录基石// api/login.php ?php require_once ../include/DB.php; $code $_POST[code] ?? ; if (!$code) { echo json_encode([code -1, msg 缺少 code]); exit; } // 改成你自己的小程序 appid 和 secret $appid wx1234567890abcdef; $secret your_app_secret; $url https://api.weixin.qq.com/sns/jscode2session . ?appid{$appid}secret{$secret}js_code{$code}grant_typeauthorization_code; $resp json_decode(file_get_contents($url), true); if (!isset($resp[openid])) { echo json_encode([code -2, msg code 无效或已过期]); exit; } $pdo DB::getInstance(); // 先查用户是否存在不存在则自动注册 $stmt $pdo-prepare(SELECT id, openid FROM user WHERE openid ?); $stmt-execute([$resp[openid]]); $user $stmt-fetch(); if (!$user) { $pdo-prepare(INSERT INTO user (openid, nickname, role) VALUES (?, ?, user)) -execute([$resp[openid]]); $userId $pdo-lastInsertId(); } else { $userId $user[id]; } // 生成 token 并写回 user 表 $token md5($resp[openid] . time()); $pdo-prepare(UPDATE user SET token ? WHERE id ?)-execute([$token, $userId]); echo json_encode([code 0, data [token $token, userId $userId]]);后端这段逻辑有几个参数要解释清楚。file_get_contents 直接请求微信接口是 PHP 环境最省事的做法但生产环境建议换 curl因为 file_get_contents 在对方接口响应慢时会阻塞较久。token 生成用 md5 加时间戳安全性够课设用但正式上线建议用 openssl_random_pseudo_bytes 之类的随机源。appid 和 secret 必须从后端发请求绝不要在前端代码里出现 secret这是底线答辩时老师可能专门问这个。3.2 疫苗列表与下拉刷新剩余库存的一次性返回疫苗列表页是用户打开小程序看到的第一个页面。前端用 onLoad 拉数据同时支持 onPullDownRefresh 下拉刷新。注意疫苗列表接口返回的不只是疫苗基本信息还要带上剩余库存因为用户需要在列表页就能判断这支疫苗还能不能约。// pages/vaccine/vaccine.js const app getApp(); Page({ data: { list: [], loading: false }, onLoad() { this.fetchList(); }, // 下拉刷新结束后要手动关闭刷新动画 onPullDownRefresh() { this.fetchList(() { wx.stopPullDownRefresh(); }); }, fetchList(callback) { this.setData({ loading: true }); wx.request({ url: ${app.globalData.baseURL}/api/vaccine_list.php, method: GET, data: { page: 1, pageSize: 20 }, success: (res) { if (res.data.code 0) { this.setData({ list: res.data.data.list }); } else { wx.showToast({ title: res.data.msg, icon: none }); } }, complete: () { this.setData({ loading: false }); if (callback) callback(); } }); } });这段代码注意两个细节。data 里的 loading 状态要配合 wx.showLoading 或列表页的加载中占位图我见过很多课设直接忽略 loading弱网环境下用户会以为页面卡死了。onPullDownRefresh 要求 app.json 里对应页面配置enablePullDownRefresh: true忘了配的话这个回调永远不会触发这是新手最容易翻车的地方。疫苗列表后端返回的库存字段一般不是查 vaccine 表里的 stock 原值而是 stock 减去已预约未完成的数量。如果源码里是直接返回 stock那要注意它有没有在创建预约时同步 UPDATE stock。正确做法是预约创建成功就把 stock 减一取消预约再加回来这样 stock 始终表示当前实际可预约量列表页查询不需要再做减法性能更好。3.3 预约提交日期、时段、库存的三层校验与原子扣减预约提交是整个系统技术含量最高的一段。前端用 picker 组件选日期用 radio-group 渲染微信小程序单选框来选时段比如上午 8:00-11:00、下午 14:00-17:00。提交时前端先做空值校验后端再做三重校验该用户当天该时段是否已有预约、疫苗库存是否足够、疫苗是否还在架。前端预约页的核心提交逻辑// pages/booking/booking.js const app getApp(); Page({ data: { vaccineId: , vaccineName: , date: , timeSlot: , slotList: [上午 8:00-11:00, 下午 14:00-17:00, 晚间 18:00-20:00] }, // 日期选择picker 的 value 会绑定到 data.date onDateChange(e) { this.setData({ date: e.detail.value }); }, // 时段选择radio-group 的变更事件 onTimeSlotChange(e) { this.setData({ timeSlot: e.detail.value }); }, submitBooking() { const userId wx.getStorageSync(userId); const token wx.getStorageSync(token); const { vaccineId, date, timeSlot } this.data; if (!vaccineId) { wx.showToast({ title: 请先选择疫苗, icon: none }); return; } if (!date) { wx.showToast({ title: 请选择接种日期, icon: none }); return; } if (!timeSlot) { wx.showToast({ title: 请选择时间段, icon: none }); return; } wx.request({ url: ${app.globalData.baseURL}/api/appointment_create.php, method: POST, header: { X-Token: token }, data: { user_id: userId, vaccine_id: vaccineId, appoint_date: date, time_slot: timeSlot }, success: (res) { if (res.data.code 0) { wx.showToast({ title: 预约成功, icon: success }); wx.redirectTo({ url: /pages/appointment/list }); } else { wx.showToast({ title: res.data.msg, icon: none }); } } }); } });这里把 userId 和 token 都传给了后端。有一种做法是不传 userId、只靠请求头里的 token 识别身份这样更安全因为 userId 在请求体里可以被篡改。源码里如果两个都传了后端鉴权逻辑应该是从 token 查出用户 id再和 $_POST[user_id] 比对不一致就拒绝。我建议你自己改代码时直接删掉 user_id 参数后端只认 token少一个被攻击的面。后端预约创建接口用事务和行锁保证不超卖// api/appointment_create.php ?php require_once ../include/DB.php; require_once ../include/auth.php; // auth.php 里从 X-Token 解析出当前用户 id $userId getCurrentUserId(); if (!$userId) { echo json_encode([code 401, msg 未登录]); exit; } $vaccineId intval($_POST[vaccine_id] ?? 0); $date $_POST[appoint_date] ?? ; $timeSlot $_POST[time_slot] ?? ; if (!$vaccineId || !$date || !$timeSlot) { echo json_encode([code -1, msg 参数不完整]); exit; } $pdo DB::getInstance(); $pdo-beginTransaction(); try { // 同一天同一时段一个用户只能有一条未完成预约 $stmt $pdo-prepare( SELECT id FROM appointment WHERE user_id ? AND appoint_date ? AND time_slot ? AND status IN (pending, completed) FOR UPDATE ); $stmt-execute([$userId, $date, $timeSlot]); if ($stmt-fetch()) { throw new Exception(该时段已有预约请勿重复提交); } // 原子扣减库存只允许 stock 0 时减少 $stmt $pdo-prepare( UPDATE vaccine SET stock stock - 1 WHERE id ? AND stock 0 ); $stmt-execute([$vaccineId]); if ($stmt-rowCount() 0) { throw new Exception(疫苗库存不足); } // 插入预约单 $pdo-prepare( INSERT INTO appointment (user_id, vaccine_id, appoint_date, time_slot, status) VALUES (?, ?, ?, ?, pending) )-execute([$userId, $vaccineId, $date, $timeSlot]); $pdo-commit(); echo json_encode([code 0, msg 预约成功]); } catch (Exception $e) { $pdo-rollBack(); echo json_encode([code -1, msg $e-getMessage()]); }这段代码是整套系统的核心几个点必须讲透。FOR UPDATE 是行级锁锁住的是 appointment 表里满足条件的那一行防止两个请求同时查到「没有预约」然后都插入成功。UPDATE vaccine SET stock stock - 1 WHERE stock 0 是原子扣减数据库层面保证库存不会减成负数。这两步放在一个事务里任何一个失败就回滚预约单不会出现「库存扣了但预约没建成功」的脏数据。提示事务里的 FOR UPDATE 一定要配合索引否则会升级成表锁。appointment 表的 user_id、appoint_date、time_slot 这三个字段应该建联合索引脚本里如果没有自己加上不然并发一高整张表卡死。4. 避坑与常见问题最容易让课设翻车的五个现场代码能跑通是一回事部署到真机能稳定跑是另一回事。我拆这套源码的过程中把最容易让初学者卡住的问题按「现象 → 原因 → 解决」整理成了五条踩坑记录。前四条几乎每个做小程序课设的人都会遇到第五条属于不容易想到但一旦踩了很头疼的类型。4.1 微信小程序开发工具接口访问正常、真机接口访问失败现象开发者工具里所有接口都通预约流程走得很顺一换到真机预览页面空白Network 面板里请求全部报错。原因开发者工具默认开启了「不校验合法域名」选项所以 http 明文请求也能过。真机上这个选项不生效微信强制要求所有请求域名必须是 HTTPS并且要在小程序后台配置到 request 合法域名里。如果你是用局域网 IP 访问本地 PHP 服务真机连的根本不是同一网络请求直接失败。解决本地调试时在真机预览面板打开「不校验合法域名」调试开关或者用wx.setEnableDebug({ enable: true })临时开启。但这只能用于开发正式上线必须走 HTTPS 域名。我一般建议课设阶段直接用开发者工具演示要上真机就临时勾选调试选项别在这上面死磕域名配置。4.2 picker 选出来的「今天」到后端变成昨天现象用户在日期选择器里选了当天日期提交预约后后台管理端看到预约日期是前一天。原因picker 组件返回的 value 是本地时区的YYYY-MM-DD字符串但如果你在提交前用new Date(dateString)转成 Date 对象再用toISOString()或直接 JSON.stringify 传输时区会被转成 UTC。国内是 UTC8转 UTC 后日期自然就前一天晚 16 点。解决日期字符串不要转 Date 对象直接原样传给后端。后端 PHP 也不要再用strtotime($date)做转换直接按字符串存 date 类型字段。如果非要转用new Date(${date}T00:00:00)固定本地时区或者后端接收后用date(Y-m-d, strtotime($date . 1 day))补偿。最省心的方案就是全程字符串别碰时间对象。4.3 微信小程序登录获取手机号个人主体接不进去的兜底方案现象按网上的教程写了获取手机号的 button但真机上点击没有任何反应或者提示「未配置该接口的权限」。原因微信小程序登录获取手机号这个能力要求小程序必须通过企业认证个人主体的小程序没有这个接口权限。很多课设用的是个人注册的账号自然接不通。这是平台规则问题不是你代码的问题。解决源码里如果依赖手机号大概率有兜底方案。常见做法是在个人中心提供一个表单让用户手动填写手机号配合短信验证码可以用阿里云短信或腾讯云短信免费额度。openid 做登录凭证手机号只做业务联系和接种通知用。这套方案在任何主体下都能跑而且答辩时能讲出一套完整的「实名信息绑定」逻辑反而加分。4.4 库存先查再减并发预约时超卖怎么发生现象疫苗库存剩最后 1 支两个用户同时提交预约两个人都预约成功库存变成 -1。原因如果源码里的预约逻辑是「先 SELECT stock判断大于 0再 UPDATE stock stock - 1」这两步之间存在时间窗口。两个请求同时读到 stock 为 1都通过判断然后都执行 UPDATE库存被减两次。这就是经典的先查后减并发问题。解决用第 3 章那段代码里的原子扣减写法UPDATE vaccine SET stock stock - 1 WHERE stock 0让数据库判断库存是否足够配合 rowCount() 判断是否真的减成功了。再往上就是事务里对疫苗行加 FOR UPDATE 锁双保险。这条经验做任何带库存的系统都适用不只是疫苗预约。4.5 疫苗名称带中文GET 请求查出来乱码现象列表页搜索框输入「乙肝疫苗」提交后后端查不到结果换成英文关键词就能查到。原因wx.request 的 GET 请求data 里的中文参数默认不会做 URL 编码或者后端 PHP 没有正确设置字符集。MySQL 连接串少了charsetutf8mb4时中文条件查询会直接失败。解决前端手动编码encodeURIComponent(keyword)后端在 DB.php 建立连接后执行SET NAMES utf8mb4。另外 PHP 文件头部的header(Content-Type: application/json; charsetutf-8)别漏不然返回的中文在开发者工具里显示成乱码排查起来很迷惑。这条属于基础配置问题但每年都有不少人被卡住。5. 本地部署与联调把源码从压缩包跑到真机预览的完整动作源码拿到手第一步是让它先跑起来。这套系统的前后端是分离的后端 PHP MySQL 负责接口和数据小程序端负责界面交互。部署顺序是先起后端再导前端最后联调。每一步都有固定的检查点按顺序来能省很多排查时间。5.1 后端环境SQL 导入与 PHP 内置服务器后端依赖 PHP 和 MySQL。Windows 上建议用 phpStudy 或 XAMPPMac 上可以用内置 PHP。先把 SQL 脚本导入数据库mysql -u root -p vaccine_system.sql导入后确认一下表是否建全。用 phpStudy 的话把项目放到WWW目录下保证api目录能通过http://localhost/api/xxx.php访问。不装 Apache 也可以用 PHP 内置服务器项目目录下执行php -S localhost:8080 -t .-t 后面的点表示当前目录作为 Web 根目录这样api/login.php就对应http://localhost:8080/api/login.php。启动后先在浏览器验证一个接口比如直接访问http://localhost:8080/api/vaccine_list.php能返回 JSON 就说明后端通了。这个步骤很多人跳过结果前端折腾半天发现是后端没起来。改数据库连接配置。DB.php 里的主机、用户名、密码、库名四项必须和你本地环境一致常见错误是默认密码是 root 但本地 MySQL 设了别的密码或者库名和 SQL 脚本里建的不一致。连接后执行一句SET NAMES utf8mb4这一步别删第 4 章刚说过中文乱码的坑。5.2 小程序端AppID 与 baseURL 两个必改项小程序端用微信开发者工具导入项目目录。导入时 AppID 可以先选「测试号」测试号不影响本地预览和真机调试只是不能发布上线。如果源码里有project.config.json直接用它打开能保留原有的编译配置。打开utils/config.js或者app.js找到 baseURL 改成你的后端地址// utils/config.js module.exports { // 后端接口地址本地调试用局域网 IP // 真机预览时把这个 IP 换成电脑的局域网 IP baseURL: http://localhost:8080, version: 1.0.0 };这里有两个细节。第一开发者工具里用localhost没问题但真机预览时手机访问不到电脑的 localhost必须改成电脑的局域网 IP比如http://192.168.1.101:8080。第二微信开发者工具的项目详情里本地设置必须勾选「不校验合法域名」否则所有 http 请求在模拟器里都会被拦截。改完之后点编译首页疫苗列表能刷出来就说明前后端连上了。如果列表空白打开开发者工具的调试器看 Network 面板请求有没有发出、返回什么状态码这一步能定位 80% 的问题。5.3 全链路验证从注册到接种记录的闭环检查前后端连通后别急着收工。我习惯按用户真实动线走一遍全流程每个节点都检查数据库里的数据落没落对。第一步登录。打开小程序确认 user 表里自动插入了一条记录role 是 usertoken 有值。第二步预约。选一支疫苗、挑日期和时段提交后去 appointment 表看状态是不是 pendingvaccine 表的 stock 是否减一。第三步取消预约。在预约记录页取消确认 stock 加回来没。如果取消后库存没恢复说明 cancel 接口里漏了 UPDATE这是常见 bug。第四步模拟接种。管理端把预约单状态改成 completed确认 record 表里多了一条接种记录接种时间是当前时间。这条链路全通说明这套源码的核心功能是完整的后面改业务逻辑就在这个框架上加代码。提示走全链路的时候每操作一步就去看一眼 MySQL 里的数据比只看前端界面靠谱得多。很多接口返回成功但数据落库不对只有查表才能发现。6. 进阶优化导航栏适配、请求封装与 token 过期的三个顺手改进源码跑通之后如果想让它更接近生产环境我推荐做三个小改进。这三个改动都不大但能明显提升代码质量和演示效果。第一个是微信小程序顶部导航栏高度适配。默认导航栏在 iPhone 和安卓刘海屏机型上的高度不一样如果页面用了自定义导航栏胶囊按钮的位置会顶到状态栏。通用做法是用wx.getMenuButtonBoundingClientRect拿到胶囊的位置信息// utils/navbar.js function getNavBarInfo() { const windowInfo wx.getWindowInfo(); const menuInfo wx.getMenuButtonBoundingClientRect(); return { statusBarHeight: windowInfo.statusBarHeight, navBarHeight: (menuInfo.top - windowInfo.statusBarHeight) * 2 menuInfo.height, menuTop: menuInfo.top, menuHeight: menuInfo.height }; } module.exports { getNavBarInfo };navBarHeight 的算法逻辑是胶囊顶部到状态栏底部的距离乘以 2再加胶囊本身高度得到整个导航栏高度。按这个值去做占位视图的高度自定义导航栏在任何机型上都不会错位。我见过太多人写死 44px结果在带刘海的机型上按钮直接被截掉。第二个是请求统一封装。现在前端到处是 wx.request每个页面重复写 header 和错误处理。抽一个 Promise 封装的请求方法所有接口调用都走它// utils/request.js const app getApp(); function request(options) { return new Promise((resolve, reject) { wx.request({ url: ${app.globalData.baseURL}${options.url}, method: options.method || GET, data: options.data || {}, header: { Content-Type: application/json, X-Token: wx.getStorageSync(token) || }, success: (res) { if (res.data.code 401) { // token 失效清掉本地缓存并跳回登录页 wx.removeStorageSync(token); wx.removeStorageSync(userId); wx.navigateTo({ url: /pages/login/login }); reject(res.data); return; } resolve(res.data); }, fail: reject }); }); } module.exports request;第三个是 token 过期处理。很多课设源码的登录态是永久的后端不校验 token 有效期。改进方式是 user 表里加一个 token_expire 字段登录时设置比如 7 天过期接口鉴权时判断当前时间是否超过过期时间超了就返回 401。上面的 request 封装里看到 401 就自动清缓存跳登录页用户无感知地重新登录体验比报错弹窗好得多。这三个改进做完这套疫苗预约接种系统从功能到代码质量就都拿得出手了。我每次拆完一套源码都会强制自己走一遍「跑通全流程 → 补并发和边界 → 抽公共封装」这三步这套习惯帮我避掉了很多上线后才暴露的坑。希望你拿到这份源码后也能按这个路子把它吃透而不是只跑通演示就完事。希望帮到你。本文还有配套的精品资源点击获取
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑