源碼:課程設(shè)計(jì)級實(shí)戰(zhàn)與二次開發(fā)指南)
簡介這是一套面向Java開發(fā)者與美容行業(yè)信息化從業(yè)者的美容管理系統(tǒng)源碼采用多端架構(gòu)包含后臺(tái)管理、商家端與微信端適合用于二次開發(fā)、畢業(yè)設(shè)計(jì)或商業(yè)項(xiàng)目參考。系統(tǒng)以消費(fèi)者關(guān)注服務(wù)號(hào)后在線預(yù)約項(xiàng)目、到店消費(fèi)服務(wù)為主線集成威富通第三方支付覆蓋微信、支付寶、掃碼槍掃碼及微信H5支付并接入微信JSSDK實(shí)現(xiàn)分享、地圖定位與模板消息推送同時(shí)集成阿里大于短信功能。技術(shù)棧方面后臺(tái)基于IMS框架搭配EasyUI商家端使用EasyUI美化主題包微信端采用AUI框架開發(fā)。壓縮包為zip格式共約2000個(gè)文件整體約85.05MB其中png、gif、jpg等圖片資源用于界面展示js、css、scss、less負(fù)責(zé)前端交互與樣式j(luò)ava、jsp、xml構(gòu)成后端業(yè)務(wù)邏輯另有jar依賴、sql腳本及各類配置文件目錄結(jié)構(gòu)完整。目前已有303人學(xué)習(xí)下載適合希望研究多端協(xié)同、支付集成與微信生態(tài)開發(fā)的讀者參考借鑒。1. 三端分離的 Java 美容管理系統(tǒng)一份能直接跑起來的課程設(shè)計(jì)級源碼最近在整理手頭的 Java 課程設(shè)計(jì)素材時(shí)翻到一套美容管理系統(tǒng)的源碼包結(jié)構(gòu)挺典型后臺(tái)管理端、商家端、微信端三個(gè)入口共用一套 Java 服務(wù)端。這類系統(tǒng)在畢設(shè)和課程設(shè)計(jì)里出現(xiàn)頻率很高但真正把三端拆清楚、權(quán)限分明白的并不多。它解決的核心問題是一個(gè)美容門店既要總部管項(xiàng)目、管會(huì)員、管訂單又要讓門店自己排班、核銷還得讓顧客在微信里預(yù)約、查卡。三端各管一段數(shù)據(jù)卻要一致。適合正在找 Java 課程設(shè)計(jì)案例源碼的人也適合想拿一套完整業(yè)務(wù)系統(tǒng)練手 MyBatis、Spring 前后端分離的開發(fā)者。下面按「它是什么 → 怎么跑起來 → 坑在哪 → 怎么改」的順序拆一遍。2. 三端架構(gòu)拆解后臺(tái)、商家端、微信端各自管什么2.1 三端的職責(zé)邊界與數(shù)據(jù)流向先把三端的分工說清楚不然后面改代碼會(huì)迷路。后臺(tái)端是平臺(tái)運(yùn)營視角管的是全局基礎(chǔ)數(shù)據(jù)美容項(xiàng)目分類、項(xiàng)目定價(jià)、會(huì)員等級規(guī)則、優(yōu)惠券模板、門店入駐審核。商家端是單個(gè)門店視角管的是本店資源美容師排班、預(yù)約時(shí)段、到店核銷、本店訂單和業(yè)績。微信端是顧客視角管的是個(gè)人行為瀏覽項(xiàng)目、在線預(yù)約、查看會(huì)員卡余額、消費(fèi)記錄。數(shù)據(jù)流向是單向收斂的微信端產(chǎn)生的預(yù)約和訂單先落到商家端確認(rèn)再匯總到后臺(tái)端做統(tǒng)計(jì)。反過來后臺(tái)端配置的項(xiàng)目和價(jià)格下發(fā)到商家端展示再透傳到微信端。這個(gè)方向不能反反了就會(huì)出現(xiàn)門店私自改價(jià)、顧客看到未審核項(xiàng)目的問題。常見做法是用一個(gè) Spring Boot 單體服務(wù)承載三端接口通過 URL 前綴或請求頭區(qū)分端類型比如/api/admin/**、/api/merchant/**、/api/wx/**。權(quán)限用攔截器加角色判斷后臺(tái)角色是ROLE_ADMIN商家是ROLE_MERCHANT微信端走ROLE_CUSTOMER或直接放行部分只讀接口。2.2 技術(shù)棧與目錄結(jié)構(gòu)速覽這套源碼的技術(shù)棧是典型的 Java Web 組合Spring Boot 做服務(wù)端MyBatis 做持久層MySQL 存數(shù)據(jù)前端后臺(tái)和商家端大概率是 Vue 或 Layui 這類管理后臺(tái)模板微信端是 H5 頁面。目錄結(jié)構(gòu)一般長這樣src/main/java/com/example/beauty/ ├── controller/ │ ├── admin/ # 后臺(tái)端接口 │ ├── merchant/ # 商家端接口 │ └── wx/ # 微信端接口 ├── service/ ├── mapper/ ├── entity/ └── config/ src/main/resources/ ├── mapper/ # MyBatis XML ├── application.yml └── static/ # 前端靜態(tài)資源拿到包先別急著跑先看application.yml里的數(shù)據(jù)庫配置和端口再看pom.xml里的依賴版本。Java 版本建議用 8 或 11Spring Boot 版本如果是 2.x 就別硬升 3.xJDK 17 以上會(huì)有兼容問題。前端如果是 Vue2Node 版本控制在 14 到 16 之間Node 18 以上跑老項(xiàng)目容易報(bào) OpenSSL 錯(cuò)誤。2.3 數(shù)據(jù)庫表設(shè)計(jì)的幾個(gè)關(guān)鍵點(diǎn)美容管理系統(tǒng)的表不算多但有幾張核心表必須看懂。member表存會(huì)員信息關(guān)鍵字段是phone、level_id、balance。appointment表存預(yù)約記錄關(guān)鍵字段是member_id、technician_id、start_time、status。order表存消費(fèi)訂單關(guān)鍵字段是order_no、member_id、amount、pay_status。這里有個(gè)容易忽略的點(diǎn)預(yù)約和訂單是兩張表不是一張。預(yù)約是意向訂單是實(shí)際消費(fèi)。顧客預(yù)約后到店商家核銷預(yù)約生成訂單訂單支付后扣會(huì)員卡余額或走微信支付。如果源碼里把預(yù)約和訂單合成一張表改起來會(huì)很痛苦因?yàn)闋顟B(tài)機(jī)混在一起了。提示導(dǎo)入 SQL 文件時(shí)注意字符集美容項(xiàng)目名稱里常有中文和特殊符號(hào)用utf8mb4避免亂碼。3. 本地跑通三端環(huán)境配置、啟動(dòng)順序與接口驗(yàn)證3.1 數(shù)據(jù)庫導(dǎo)入與配置修改第一步永遠(yuǎn)是數(shù)據(jù)庫。找到源碼包里的.sql文件用 Navicat 或命令行導(dǎo)入。命令行方式mysql -u root -p --default-character-setutf8mb4 -e CREATE DATABASE beauty_ms DEFAULT CHARACTER SET utf8mb4; mysql -u root -p beauty_ms beauty_ms.sql導(dǎo)入后檢查表數(shù)量一般核心表在 15 到 25 張之間。如果只有幾張表可能是分庫腳本沒導(dǎo)全。然后改application.ymlspring: datasource: url: jdbc:mysql://localhost:3306/beauty_ms?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 你的密碼 driver-class-name: com.mysql.cj.jdbc.Driver server: port: 8080serverTimezone必須設(shè)不設(shè)的話預(yù)約時(shí)間會(huì)差 8 小時(shí)這是血淚經(jīng)驗(yàn)。characterEncodingutf8配合數(shù)據(jù)庫的utf8mb4能覆蓋大部分中文場景。3.2 服務(wù)端啟動(dòng)與常見報(bào)錯(cuò)處理配置改完直接跑主類。如果報(bào)Table beauty_ms.xxx doesnt exist說明 SQL 沒導(dǎo)全或者表名大小寫不一致。Linux 下 MySQL 默認(rèn)表名區(qū)分大小寫Windows 不區(qū)分跨平臺(tái)遷移時(shí)容易翻車。解決辦法是在my.cnf里加lower_case_table_names1或者統(tǒng)一表名小寫。如果報(bào)Access denied for user檢查密碼和權(quán)限。如果是Public Key Retrieval is not allowed在 JDBC URL 后面加allowPublicKeyRetrievaltrue。啟動(dòng)成功后訪問http://localhost:8080看是否能出登錄頁。后臺(tái)端默認(rèn)賬號(hào)一般是admin/123456商家端是merchant/123456微信端直接訪問 H5 路徑。3.3 三端接口的驗(yàn)證順序不要三端一起點(diǎn)按依賴順序來。先驗(yàn)后臺(tái)端登錄后看項(xiàng)目列表、會(huì)員列表是否能加載。再驗(yàn)商家端用商家賬號(hào)登錄看本店預(yù)約列表是否有數(shù)據(jù)。最后驗(yàn)微信端打開 H5 頁面看項(xiàng)目列表是否展示預(yù)約提交是否成功。接口驗(yàn)證可以用 Postman 或?yàn)g覽器直接訪問。比如后臺(tái)端項(xiàng)目列表curl -X POST http://localhost:8080/api/admin/project/list \ -H Content-Type: application/json \ -H token: 登錄后返回的token \ -d {page:1,size:10}如果返回 401說明 token 沒帶或過期。如果返回 403說明角色不對檢查登錄時(shí)用的賬號(hào)角色。如果返回 500看服務(wù)端日志大概率是 SQL 映射字段和實(shí)體類對不上。3.4 前端資源打包與聯(lián)調(diào)如果源碼里前端是獨(dú)立目錄需要單獨(dú)跑。Vue 項(xiàng)目常見命令npm install npm run servenpm install如果卡住換淘寶源npm config set registry https://registry.npmmirror.com。跑起來后前端默認(rèn)端口 8081 或 8082需要在vue.config.js里配代理指向后端 8080否則跨域報(bào)錯(cuò)。// vue.config.js module.exports { devServer: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } }changeOrigin: true必須加不加的話后端收到的 Host 頭不對某些攔截器會(huì)攔掉。前端跑通后三端頁面應(yīng)該都能正常加載數(shù)據(jù)。4. 避坑與排查三端聯(lián)調(diào)時(shí)最容易翻車的五個(gè)點(diǎn)4.1 預(yù)約時(shí)間差 8 小時(shí)現(xiàn)象微信端提交預(yù)約選的是下午 3 點(diǎn)商家端看到的是晚上 11 點(diǎn)。原因JDBC 連接沒設(shè)serverTimezone或者設(shè)成了 UTC。解決URL 里加serverTimezoneAsia/Shanghai同時(shí)檢查 MySQL 全局時(shí)區(qū)SELECT global.time_zone;如果是 UTC 就改成08:00。4.2 商家端看不到微信端的預(yù)約現(xiàn)象微信端提示預(yù)約成功商家端預(yù)約列表為空。原因預(yù)約表里merchant_id字段沒寫對或者微信端提交時(shí)沒傳門店 ID。解決查appointment表最新一條記錄看merchant_id是不是 null 或 0。如果是檢查微信端提交接口的參數(shù)門店 ID 應(yīng)該從項(xiàng)目詳情里帶過來。4.3 后臺(tái)改價(jià)后微信端不更新現(xiàn)象后臺(tái)把某個(gè)項(xiàng)目價(jià)格從 198 改成 168微信端還是顯示 198。原因微信端接口做了緩存或者前端把價(jià)格寫死了。解決先看微信端接口返回的 JSON 里價(jià)格字段是不是新值。如果是新值但頁面沒變清瀏覽器緩存或看前端有沒有l(wèi)ocalStorage緩存。如果接口返回舊值檢查 MyBatis 二級緩存配置關(guān)掉cache/標(biāo)簽。4.4 會(huì)員卡余額扣減不對現(xiàn)象顧客消費(fèi)后余額扣了兩次或者扣了但訂單沒生成。原因扣余額和生成訂單不在同一個(gè)事務(wù)里。解決在 Service 層方法上加Transactional確??塾囝~、寫訂單、寫流水三件事要么全成要么全敗。同時(shí)檢查是不是有重復(fù)提交前端按鈕加防抖后端加冪等判斷。4.5 微信端頁面白屏現(xiàn)象H5 頁面打開一片白控制臺(tái)報(bào)Uncaught SyntaxError。原因前端打包路徑不對或者后端靜態(tài)資源映射沒配。解決如果是 Vue 項(xiàng)目檢查vue.config.js里的publicPath部署到子路徑時(shí)改成./。如果是后端直接放靜態(tài)文件檢查application.yml里spring.resources.static-locations是否指向了正確的目錄。5. 二次開發(fā)切入點(diǎn)從改一個(gè)字段到加一個(gè)模塊5.1 最快上手改項(xiàng)目分類名稱和圖標(biāo)想快速看到自己的改動(dòng)生效從最簡單的開始。找到后臺(tái)端項(xiàng)目分類管理頁面改分類名稱和圖標(biāo)。數(shù)據(jù)庫里對應(yīng)project_category表改name和icon字段。前端如果圖標(biāo)是字體圖標(biāo)改 class 名如果是圖片替換static目錄下的文件。改完刷新后臺(tái)端和微信端確認(rèn)兩邊都變了。這一步能幫你摸清「后臺(tái)改數(shù)據(jù) → 前端展示」的完整鏈路。5.2 中等難度給預(yù)約加一個(gè)備注字段預(yù)約表加字段是常見的二次開發(fā)需求。步驟ALTER TABLE appointment ADD COLUMN remark VARCHAR(255) DEFAULT NULL COMMENT 顧客備注 AFTER status;然后改實(shí)體類Appointment.java加remark屬性改 Mapper XML 的resultMap和insert、update語句改微信端提交預(yù)約的表單加輸入框改商家端預(yù)約列表加備注列。四個(gè)地方缺一不可漏一個(gè)就出現(xiàn)「填了沒存」或「存了不顯示」。5.3 進(jìn)階接入微信支付的回調(diào)處理如果源碼里微信支付是模擬的想接真實(shí)支付核心是回調(diào)接口。微信支付回調(diào)會(huì) POST 一個(gè) XML 或 JSON 到你的notify_url你需要驗(yàn)簽、解析、更新訂單狀態(tài)。常見做法是單獨(dú)寫一個(gè)WxPayNotifyController不經(jīng)過登錄攔截器因?yàn)槲⑿欧?wù)器不會(huì)帶你的 token。PostMapping(/api/wx/pay/notify) public String payNotify(RequestBody String notifyData) { // 1. 驗(yàn)簽確認(rèn)是微信發(fā)來的 // 2. 解析出 out_trade_no 和 result_code // 3. 根據(jù) out_trade_no 查訂單更新 pay_status // 4. 返回 SUCCESS否則微信會(huì)重復(fù)通知 return xmlreturn_code![CDATA[SUCCESS]]/return_code/xml; }注意回調(diào)接口必須返回微信要求的格式返回錯(cuò)了微信會(huì)一直重試。另外訂單狀態(tài)更新要加鎖或冪等防止重復(fù)通知導(dǎo)致重復(fù)加積分。5.4 驗(yàn)證改動(dòng)是否生效的通用方法每次改完按這個(gè)順序驗(yàn)先看數(shù)據(jù)庫字段有沒有、數(shù)據(jù)對不對再看接口返回的 JSON 有沒有新字段最后看前端頁面有沒有展示。三步都過了才算改完。如果中間斷了就停在斷的那一步排查不要跳步。我一般會(huì)在改之前先備份數(shù)據(jù)庫和源碼改崩了直接回滾比一點(diǎn)點(diǎn)修快得多。6. 從這套源碼里能帶走什么一個(gè)可復(fù)用的三端權(quán)限模型這套美容管理系統(tǒng)最值得帶走的不是美容業(yè)務(wù)本身而是三端權(quán)限模型。后臺(tái)、商家、微信端共用一套用戶體系但角色隔離接口按前綴分權(quán)數(shù)據(jù)按merchant_id做行級過濾。這個(gè)模型換成餐飲、健身、教培都能用。具體做法是用戶表加role字段區(qū)分端類型登錄時(shí)返回不同角色的 token攔截器根據(jù) URL 前綴和 token 里的角色做雙重校驗(yàn)。商家端所有查詢強(qiáng)制帶merchant_id條件這個(gè)條件從 token 里解析不從前端傳防止越權(quán)查別家數(shù)據(jù)。// 商家端查詢預(yù)約時(shí)merchantId 從 token 取不信任前端參數(shù) Long merchantId TokenUtil.getMerchantId(request); queryWrapper.eq(merchant_id, merchantId);這個(gè)習(xí)慣我每次做多端系統(tǒng)都強(qiáng)制走一遍凡是涉及數(shù)據(jù)隔離的查詢隔離字段必須從服務(wù)端會(huì)話取絕不從前端參數(shù)取。吃過一次虧前端傳了別家門店 ID把人家會(huì)員列表拉出來了雖然只是測試環(huán)境但那種后背發(fā)涼的感覺記到現(xiàn)在。希望這套源碼和上面的拆解能幫到你跑通之后試著把權(quán)限模型抽出來比單純改業(yè)務(wù)代碼值錢得多。本文還有配套的精品資源點(diǎn)擊獲取