院預(yù)約掛號系統(tǒng)實戰(zhàn):Spring Boot+SSM全棧項目從搭建到二次開發(fā))
簡介這份資源是面向高校計算機專業(yè)畢業(yè)設(shè)計場景的微信小程序醫(yī)院預(yù)約掛號系統(tǒng)源碼與配套文檔適合正在準(zhǔn)備畢設(shè)或課程設(shè)計的學(xué)生參考。項目以微信小程序為前端后端采用Java結(jié)合Spring Boot與SSM框架數(shù)據(jù)層使用MySQL完整覆蓋用戶管理、醫(yī)生管理、預(yù)約掛號、通知提醒等核心模塊并涉及HTTPS加密、緩存優(yōu)化與高并發(fā)處理等設(shè)計思路。資源包共1個docx文件約883KB內(nèi)容包含項目背景、技術(shù)選型、系統(tǒng)架構(gòu)與關(guān)鍵模塊實現(xiàn)等論述可作為論文撰寫與系統(tǒng)搭建的參考藍本。目前已有382人學(xué)習(xí)下載讀者可從中獲取完整的選題方案、技術(shù)棧說明與模塊設(shè)計思路便于快速理解預(yù)約掛號系統(tǒng)的整體流程與實現(xiàn)要點為畢設(shè)開發(fā)與文檔寫作提供借鑒。1. 從排隊三小時到手機點兩下這套醫(yī)院預(yù)約掛號小程序到底解決了什么早上七點去醫(yī)院掛號窗口排隊前面已經(jīng)站了四十多人專家號放出來不到十分鐘就沒了——這個場景對很多患者來說太熟悉了。這套基于微信小程序的醫(yī)院預(yù)約掛號系統(tǒng)核心目標(biāo)就是把這件事搬到手機上患者打開微信就能查科室、看醫(yī)生排班、在線預(yù)約后臺管理員統(tǒng)一維護醫(yī)生信息和號源。項目采用微信小程序做前端Java Spring Boot SSM 做后端MySQL 存數(shù)據(jù)是一套典型的畢業(yè)設(shè)計級全棧項目適合正在找小程序Java 后端練手項目的開發(fā)者也適合想理解預(yù)約類業(yè)務(wù)完整鏈路的同學(xué)。源碼包里有小程序端、后臺管理端和數(shù)據(jù)庫腳本拿到手就能跑。2. 技術(shù)選型與整體架構(gòu)為什么是 Spring Boot SSM 小程序2.1 前后端分離的 B/S 結(jié)構(gòu)這個項目采用的是典型的前后端分離架構(gòu)。小程序端負責(zé)頁面渲染和用戶交互后端提供 RESTful 接口處理業(yè)務(wù)邏輯MySQL 做數(shù)據(jù)持久化。整個數(shù)據(jù)流向是小程序發(fā)請求 → Spring Boot 接收并處理 → MyBatis 操作數(shù)據(jù)庫 → 結(jié)果逐層返回。為什么選 B/S 而不是 C/S因為小程序本身就是 B/S 的變體——用戶不需要安裝獨立客戶端微信掃一下或搜一下就能打開。后端部署在服務(wù)器上更新維護只需要動服務(wù)端小程序端通過審核后自動生效這對醫(yī)院這種需要頻繁調(diào)整號源和科室信息的場景非常合適。2.2 Spring Boot 與 SSM 的分工這里有一個容易混淆的點Spring Boot 和 SSM 不是二選一的關(guān)系。SSM 指的是 Spring Spring MVC MyBatis 這套組合而 Spring Boot 是在此基礎(chǔ)上做了自動配置和起步依賴的封裝。實際項目里底層用的還是 Spring 的 IoC 容器、Spring MVC 的請求映射、MyBatis 的 SQL 映射只是 Spring Boot 幫你省掉了大量 XML 配置。具體到代碼層面啟動類上標(biāo)注SpringBootApplicationController 層用RestController和RequestMapping定義接口Service 層用Service注入業(yè)務(wù)邏輯Dao 層用Mapper標(biāo)注 MyBatis 接口。這種分層方式在中小型項目里非常常見結(jié)構(gòu)清晰后續(xù)加模塊也方便。2.3 數(shù)據(jù)庫選型與核心表設(shè)計MySQL 8.0 作為數(shù)據(jù)存儲主要涉及幾張核心表用戶表存患者和admin、醫(yī)生表、科室表、預(yù)約記錄表、公告表。表與表之間通過外鍵關(guān)聯(lián)比如醫(yī)生表里有科室 ID 字段預(yù)約表里有用戶 ID 和醫(yī)生 ID。常見做法是給預(yù)約表加聯(lián)合唯一索引防止同一用戶對同一醫(yī)生同一時段重復(fù)下單。這個細節(jié)在源碼的 SQL 腳本里一般會有體現(xiàn)跑之前可以先看一眼建表語句。注意MySQL 8.0 默認的認證插件是caching_sha2_password如果后端連接報認證錯誤需要在數(shù)據(jù)庫里執(zhí)行ALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密碼;切換認證方式。2.4 項目目錄結(jié)構(gòu)一覽拿到源碼后先看目錄結(jié)構(gòu)能幫你快速定位關(guān)鍵文件。后端典型的 Maven 項目結(jié)構(gòu)如下hospital-registration/ ├── src/main/java/com/hospital/ │ ├── controller/ # 接口層處理小程序和后臺的 HTTP 請求 │ ├── service/ # 業(yè)務(wù)邏輯層 │ │ └── impl/ # 業(yè)務(wù)實現(xiàn)類 │ ├── mapper/ # MyBatis 數(shù)據(jù)訪問接口 │ ├── entity/ # 數(shù)據(jù)庫實體類 │ ├── config/ # 配置類跨域、攔截器等 │ └── HospitalApplication.java # 啟動類 ├── src/main/resources/ │ ├── application.yml # 數(shù)據(jù)庫連接、端口等配置 │ ├── mapper/ # MyBatis XML 映射文件 │ └── static/ # 后臺管理頁面的靜態(tài)資源 ├── sql/ │ └── hospital.sql # 數(shù)據(jù)庫建表與初始數(shù)據(jù)腳本 └── pom.xml # Maven 依賴管理小程序端的目錄結(jié)構(gòu)則是微信開發(fā)者工具的標(biāo)準(zhǔn)格式pages目錄下按功能模塊分文件夾每個頁面包含.js、.wxml、.wxss、.json四個文件。app.js里通常封裝了全局的請求方法app.json里配置頁面路由和 tabBar。3. 環(huán)境搭建與啟動從零把項目跑起來3.1 后端環(huán)境準(zhǔn)備與數(shù)據(jù)庫初始化先把后端跑通因為小程序端需要調(diào)后端接口才能看到數(shù)據(jù)。需要準(zhǔn)備的環(huán)境JDK 1.8 或以上、Maven 3.6、MySQL 8.0、IDEA 或 Eclipse。第一步創(chuàng)建數(shù)據(jù)庫并導(dǎo)入 SQL 腳本# 登錄 MySQL mysql -u root -p # 創(chuàng)建數(shù)據(jù)庫字符集用 utf8mb4支持 emoji CREATE DATABASE hospital_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # 導(dǎo)入建表腳本 USE hospital_db; SOURCE /path/to/sql/hospital.sql;第二步修改application.yml里的數(shù)據(jù)庫連接信息spring: datasource: url: jdbc:mysql://localhost:3306/hospital_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密碼 driver-class-name: com.mysql.cj.jdbc.Driver這里有幾個參數(shù)容易翻車serverTimezone必須設(shè)置否則 MySQL 8.0 會報時區(qū)錯誤characterEncodingutf8保證中文不亂碼useSSL在本地開發(fā)可以設(shè)為 false 減少警告。第三步在 IDEA 里以 Maven 項目導(dǎo)入等依賴下載完成后運行啟動類??刂婆_出現(xiàn)Started HospitalApplication in x.x seconds就說明后端起來了默認端口一般是 8080。3.2 小程序端配置與聯(lián)調(diào)小程序端用微信開發(fā)者工具打開。導(dǎo)入項目后第一件事是改請求地址。在app.js或封裝的request.js里把 baseUrl 改成你本機的地址// app.js 中全局請求配置 const BASE_URL http://localhost:8080/api; const request (url, method, data) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL url, method: method, data: data, header: { content-type: application/json }, success: res resolve(res.data), fail: err reject(err) }); }); };開發(fā)階段需要在微信開發(fā)者工具里勾選「不校驗合法域名」否則 localhost 的請求會被攔截。上線時才需要配置 HTTPS 域名并備案。3.3 后臺管理端的訪問后臺管理端一般是集成在后端項目里的靜態(tài)頁面啟動后端后直接訪問http://localhost:8080/admin或類似路徑。默認管理員賬號密碼通常在 SQL 腳本的初始數(shù)據(jù)里常見的是 admin/123456。登錄后能看到醫(yī)生管理、科室管理、預(yù)約管理、公告管理等菜單。3.4 啟動順序與驗證清單正確的啟動順序是MySQL → 后端服務(wù) → 小程序端。驗證時按這個清單走一遍檢查項預(yù)期結(jié)果失敗時看哪里數(shù)據(jù)庫連接啟動無報錯application.yml 的 url/密碼后端接口瀏覽器訪問 /api/dept/list 返回 JSONController 映射路徑小程序首頁科室列表正常加載開發(fā)者工具 Network 面板預(yù)約流程能選醫(yī)生、選時段、提交成功預(yù)約表是否有新記錄后臺登錄能進入管理界面初始賬號密碼是否正確4. 核心模塊拆解預(yù)約掛號從選科室到下單的完整鏈路4.1 科室與醫(yī)生列表接口小程序首頁加載時第一步是拉取科室列表。后端對應(yīng)的 Controller 方法大致長這樣RestController RequestMapping(/api/dept) public class DeptController { Autowired private DeptService deptService; // 查詢所有科室按排序字段升序 GetMapping(/list) public Result list() { ListDept depts deptService.listAll(); return Result.success(depts); } // 根據(jù)科室ID查醫(yī)生列表 GetMapping(/doctors/{deptId}) public Result doctors(PathVariable Integer deptId) { ListDoctor doctors deptService.getDoctorsByDept(deptId); return Result.success(doctors); } }GetMapping對應(yīng)小程序端的 GET 請求PathVariable把 URL 里的科室 ID 綁定到方法參數(shù)。返回的Result是統(tǒng)一響應(yīng)封裝包含 code、msg、data 三個字段前端根據(jù) code 判斷成功與否。MyBatis 的 XML 映射里查醫(yī)生列表的 SQL 一般會關(guān)聯(lián)科室表select idgetDoctorsByDept resultTypecom.hospital.entity.Doctor SELECT d.*, dept.name AS deptName FROM doctor d LEFT JOIN dept ON d.dept_id dept.id WHERE d.dept_id #{deptId} AND d.status 1 ORDER BY d.level DESC /selectstatus 1過濾掉已停診的醫(yī)生ORDER BY d.level DESC讓高級職稱的醫(yī)生排在前面。這些細節(jié)在源碼里不一定完全一樣但思路是通用的。4.2 預(yù)約下單的業(yè)務(wù)邏輯預(yù)約是整個系統(tǒng)的核心。用戶選好醫(yī)生和時段后小程序提交預(yù)約請求后端需要做幾件事校驗該時段是否還有余號、檢查用戶是否重復(fù)預(yù)約、扣減號源、生成預(yù)約記錄。Service public class AppointmentServiceImpl implements AppointmentService { Autowired private AppointmentMapper appointmentMapper; Autowired private ScheduleMapper scheduleMapper; Override Transactional public Result makeAppointment(Integer userId, Integer scheduleId) { // 1. 查詢排班信息并加行鎖防止并發(fā)超賣 Schedule schedule scheduleMapper.selectForUpdate(scheduleId); if (schedule null || schedule.getRemain() 0) { return Result.error(該時段號源已滿); } // 2. 檢查是否重復(fù)預(yù)約 int count appointmentMapper.countByUserAndSchedule(userId, scheduleId); if (count 0) { return Result.error(您已預(yù)約過該時段); } // 3. 扣減余號 scheduleMapper.decreaseRemain(scheduleId); // 4. 生成預(yù)約記錄 Appointment appt new Appointment(); appt.setUserId(userId); appt.setScheduleId(scheduleId); appt.setStatus(0); // 0待就診 appt.setCreateTime(new Date()); appointmentMapper.insert(appt); return Result.success(預(yù)約成功); } }這段代碼有幾個關(guān)鍵點。Transactional保證扣號和插入記錄在同一個事務(wù)里要么都成功要么都回滾。selectForUpdate是數(shù)據(jù)庫層面的行鎖防止兩個用戶同時搶最后一個號。實際項目里如果并發(fā)量不大用樂觀鎖版本號也可以但行鎖更直觀。4.3 個人中心與預(yù)約記錄查詢個人中心頁面需要展示當(dāng)前用戶的預(yù)約記錄按狀態(tài)區(qū)分待就診、已完成、已取消。后端接口根據(jù)用戶 ID 查預(yù)約表關(guān)聯(lián)醫(yī)生和科室信息GetMapping(/my) public Result myAppointments(RequestParam Integer userId, RequestParam(defaultValue 0) Integer status) { ListAppointmentVO list appointmentService.getByUser(userId, status); return Result.success(list); }AppointmentVO是視圖對象比實體類多了醫(yī)生姓名、科室名稱、就診時間等字段這些通過 SQL 的 JOIN 查詢直接組裝避免前端多次請求。小程序端的預(yù)約記錄頁面用wx:for渲染列表每條記錄顯示醫(yī)生頭像、姓名、科室、預(yù)約時間和狀態(tài)標(biāo)簽。狀態(tài)標(biāo)簽的顏色根據(jù) status 值動態(tài)切換待就診是藍色已完成是灰色已取消是紅色。4.4 后臺醫(yī)生信息管理后臺管理端的醫(yī)生管理模塊核心是增刪改查。新增醫(yī)生時需要選擇所屬科室上傳頭像填寫職稱和簡介。后端接收表單數(shù)據(jù)后插入醫(yī)生表PostMapping(/doctor/add) public Result addDoctor(RequestBody Doctor doctor) { // 參數(shù)校驗 if (StringUtils.isEmpty(doctor.getName()) || doctor.getDeptId() null) { return Result.error(醫(yī)生姓名和科室不能為空); } doctor.setCreateTime(new Date()); doctor.setStatus(1); doctorMapper.insert(doctor); return Result.success(添加成功); }RequestBody接收 JSON 格式的請求體前端提交時 header 要設(shè)content-type: application/json。醫(yī)生頭像一般存文件路徑文件上傳單獨走一個接口存到服務(wù)器本地目錄或?qū)ο蟠鎯Α?. 避坑與排查跑這個項目最容易翻車的幾個地方5.1 小程序請求全部失敗Network 面板顯示 404現(xiàn)象是小程序頁面空白或提示網(wǎng)絡(luò)錯誤開發(fā)者工具 Network 面板里每個請求都是紅色。原因通常是 baseUrl 配置不對或者后端沒啟動。先確認后端控制臺有沒有報錯瀏覽器直接訪問http://localhost:8080/api/dept/list看能不能返回 JSON。如果瀏覽器能訪問但小程序不行檢查開發(fā)者工具是否勾選了「不校驗合法域名」。另外注意端口號有些項目后端配的是 8081 或 9090不是默認的 8080。5.2 數(shù)據(jù)庫中文亂碼科室名稱顯示問號建庫時字符集沒設(shè)對。MySQL 8.0 默認字符集已經(jīng)是 utf8mb4但如果 SQL 腳本里寫了DEFAULT CHARSETlatin1就會出問題。解決方法是重新建庫指定utf8mb4或者用ALTER DATABASE hospital_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;修改。連接 URL 里也要帶上characterEncodingutf8。5.3 預(yù)約提交后余號沒變或者出現(xiàn)超賣這是并發(fā)場景下的經(jīng)典問題。如果扣減余號的 SQL 是UPDATE schedule SET remain remain - 1 WHERE id ?在高并發(fā)下可能出現(xiàn)余號變成負數(shù)。解決思路有兩種一是用UPDATE schedule SET remain remain - 1 WHERE id ? AND remain 0根據(jù)影響行數(shù)判斷是否扣減成功二是在 Service 層加鎖用synchronized或 Redis 分布式鎖。畢業(yè)設(shè)計級別用第一種就夠了。5.4 后臺登錄后操作報 403 或跳回登錄頁一般是攔截器或 Spring Security 配置問題。檢查攔截器有沒有放行登錄接口和靜態(tài)資源session 或 token 有沒有正確攜帶。如果用的是 JWT檢查前端請求頭里有沒有加Authorization字段。有些項目在跨域配置里漏了allowCredentials導(dǎo)致 session 丟失。5.5 Maven 依賴下載失敗或版本沖突國內(nèi)網(wǎng)絡(luò)環(huán)境下 Maven 中央倉庫可能很慢在settings.xml里配阿里云鏡像能解決大部分問題。如果報NoSuchMethodError或ClassNotFoundException通常是依賴版本沖突用mvn dependency:tree查看依賴樹排除掉重復(fù)的舊版本。6. 二次開發(fā)改造從能跑到好用幾個實用的改造方向6.1 把號源管理從手動改成排班模板原項目的號源一般是管理員手動一條條添加醫(yī)生多了之后非常繁瑣。我一般會改成排班模板的方式管理員設(shè)置醫(yī)生的常規(guī)出診時間比如每周一三五上午系統(tǒng)自動生成未來兩周的排班記錄。核心邏輯是用LocalDate遍歷日期匹配星期幾批量插入 schedule 表。這樣管理員只需要維護模板號源自動生成。// 根據(jù)模板批量生成排班 public void generateSchedule(Integer doctorId, LocalDate startDate, int days) { DoctorScheduleTemplate template templateMapper.selectByDoctorId(doctorId); ListSchedule list new ArrayList(); for (int i 0; i days; i) { LocalDate date startDate.plusDays(i); // 判斷該日期是否在模板的出診星期內(nèi) if (template.getWeekdays().contains(date.getDayOfWeek().getValue())) { Schedule s new Schedule(); s.setDoctorId(doctorId); s.setWorkDate(date); s.setTotal(template.getTotalPerDay()); s.setRemain(template.getTotalPerDay()); list.add(s); } } scheduleMapper.batchInsert(list); }6.2 加一層 Redis 緩存科室和醫(yī)生列表科室和醫(yī)生信息變動頻率很低但小程序每次打開都要請求。用 Redis 緩存這些數(shù)據(jù)設(shè)置 10 分鐘過期能明顯減少數(shù)據(jù)庫壓力。改造方式是在 Service 層加緩存邏輯先查 Redis命中就返回沒命中就查數(shù)據(jù)庫并寫入 Redis。Spring Boot 里用Cacheable注解就能實現(xiàn)配合EnableCaching開啟緩存支持。6.3 預(yù)約提醒用微信訂閱消息替代短信原項目可能沒有提醒功能或者用的是短信需要付費。微信小程序提供了訂閱消息接口用戶預(yù)約時授權(quán)一次到就診前一天推送提醒。后端調(diào)用微信的subscribeMessage.send接口傳入用戶的 openid、模板 ID 和消息內(nèi)容。這個改造不需要額外費用用戶體驗也更好。6.4 改造時怎么驗證沒改壞每次改完一個模塊按這個順序驗證先跑單元測試如果有再用 Postman 調(diào)接口確認返回正確然后在小程序端走一遍完整流程最后看后臺管理端數(shù)據(jù)是否同步。我自己的習(xí)慣是改數(shù)據(jù)庫相關(guān)邏輯時先在測試庫跑一遍 SQL確認影響行數(shù)符合預(yù)期再上代碼。提示二次開發(fā)前先用 Git 建一個分支改壞了隨時能回退。數(shù)據(jù)庫改動也建議先備份一份 SQL。從那以后我每次拿到這類預(yù)約系統(tǒng)源碼都先把數(shù)據(jù)庫腳本單獨跑一遍確認表結(jié)構(gòu)和初始數(shù)據(jù)沒問題再動代碼。這個習(xí)慣幫我省了很多「以為是代碼問題其實是數(shù)據(jù)問題」的排查時間。希望幫到你。本文還有配套的精品資源點擊獲取