完整復現(xiàn):SpringBoot+Vue+MySQL全棧實戰(zhàn))
簡介面向高校畢業(yè)設計、課程實踐或崗位實訓的宿舍報修管理系統(tǒng)項目資料適合需要完成同類課題的計算機專業(yè)學生與開發(fā)者參考。系統(tǒng)采用Java語言與SpringBoot框架構建后端搭配Vue前端與MySQL數(shù)據(jù)庫涵蓋用戶管理、維修員管理、宿舍信息管理、配件設備管理、報修接單、配件申請和維修進度跟蹤等完整業(yè)務模塊能夠支撐校園宿舍后勤報修的日常流程。資源為1個docx文檔大小4.78MB內容包括背景分析、國內外研究現(xiàn)狀、相關理論與技術、系統(tǒng)分析、功能設計與測試驗證等章節(jié)并給出了基于IDEA、Navicat、Tomcat等環(huán)境的開發(fā)與運行思路。已有433人學習下載通過查閱這篇論文可以較快梳理出宿舍報修系統(tǒng)的數(shù)據(jù)庫表結構、核心接口劃分與前后端交互邏輯對畢業(yè)設計答辯、系統(tǒng)二次開發(fā)或學習SpringBootVue項目都有直接的參考價值。1. 宿舍報修管理系統(tǒng)從論文到可運行源碼的一次完整復現(xiàn)做后勤類管理系統(tǒng)的人應該都有感觸報修流程看起來簡單但一旦涉及多角色協(xié)同業(yè)務狀態(tài)流轉就會迅速膨脹。這份基于 Java 的宿舍報修管理系統(tǒng)資源是一個把「報修」這件事做得很完整的畢業(yè)設計項目技術棧是 SpringBoot Vue MySQL角色分管理員、用戶、維修員三種覆蓋了從宿舍分配、配件申請到維修進度追蹤的完整閉環(huán)。論文部分把系統(tǒng)分析、數(shù)據(jù)庫設計、功能實現(xiàn)和測試用例都寫清楚了源碼部分則能直接跑起來做二次開發(fā)。適合正在做類似課題的學生或者想把校園報修場景數(shù)字化、需要一套基礎代碼的開發(fā)者。我拆完這套資源最大的感受是它的價值不在某個高深算法而在于把報修業(yè)務里那些容易被忽略的狀態(tài)節(jié)點設計得很完整這對課程設計和實際小規(guī)模部署都夠用。2. 技術棧選型拆解為什么是 SpringBoot Vue MySQL2.1 后端框架SpringBoot 在報修系統(tǒng)里的真實定位這套資源后端用 Java SpringBoot 搭建SpringBoot 在這里解決的核心問題不是高性能而是「開發(fā)效率」。報修管理這類業(yè)務系統(tǒng)本質上是圍繞數(shù)據(jù)庫表的增刪改查加上一點業(yè)務狀態(tài)流轉SpringBoot 的自動配置和約定優(yōu)于配置特性能極大減少 XML 配置和模板代碼讓開發(fā)者把精力集中在業(yè)務邏輯上。資源里的實現(xiàn)方式走的是典型的前后端分離思路。后端提供 RESTful API前端用 Vue 通過 HTTP 請求調用接口數(shù)據(jù)以 JSON 格式交互。這種模式的優(yōu)點是前端頁面調整不會影響后端邏輯對后續(xù)要擴展移動端或者小程序端也比較方便。在一個典型的報修信息查詢接口里你可以看到這樣的 Controller 層代碼RestController RequestMapping(/baoxiu) public class BaoxiuInfoController { Autowired private BaoxiuInfoService baoxiuInfoService; GetMapping(/page) public Result queryPage(RequestParam(defaultValue 1) Integer pageNum, RequestParam(defaultValue 10) Integer pageSize, RequestParam(required false) String baoxiuren) { QueryWrapperBaoxiuInfo wrapper new QueryWrapper(); if (StringUtils.isNotBlank(baoxiuren)) { wrapper.like(baoxiuren, baoxiuren); } wrapper.orderByDesc(addtime); PageBaoxiuInfo page new Page(pageNum, pageSize); baoxiuInfoService.page(page, wrapper); return Result.success(page); } }這里需要說明幾個關鍵點。QueryWrapper是 MyBatis-Plus 提供的條件構造器用like方法實現(xiàn)模糊查詢orderByDesc按時間倒序排列——報修信息通常需要展示最新記錄。分頁用的是 MyBatis-Plus 的Page對象前端傳入 pageNum 和 pageSize 兩個參數(shù)就能控制每頁數(shù)據(jù)量。Result.success是統(tǒng)一響應封裝把返回數(shù)據(jù)包一層前端就能根據(jù) code 判斷請求是否成功。資源里的后端結構不是簡單的單文件堆砌而是分包明確controller 層處理請求路由service 層寫業(yè)務邏輯mapper 層負責數(shù)據(jù)庫操作entity 層定義實體類。這種分層做法在應對報修業(yè)務里那些多表關聯(lián)查詢時很有用比如報修信息要關聯(lián)用戶表查姓名、關聯(lián)宿舍表查位置、關聯(lián)維修員表查分配情況。2.2 前端與數(shù)據(jù)庫Vue 組件化開發(fā)和 MySQL 表設計思路前端的 Vue 部分資源里用的是 Vue 2 Element UI 組件庫。Element UI 的表格、表單、彈窗組件能快速搭建管理后臺界面對做課設或者內部管理系統(tǒng)來說是最省力的方案。頁面結構上登錄頁、注冊頁、用戶報修頁、管理員后臺頁、維修員任務頁是分開的通過 Vue Router 做路由跳轉。數(shù)據(jù)庫設計是這套資源里比較扎實的部分。MySQL 數(shù)據(jù)庫配合 Navicat 可視化工具管理核心表包括管理員表 users、用戶表 yonghu、維修員表 weixiuyuan、宿舍信息表 sushexinxi、報修信息表 baoxiuxinxi、配件設備表 peijianshebei 等一共十幾張表每張表的字段設計都和業(yè)務場景對應。以報修信息表為例字段設計基本覆蓋了報修業(yè)務流程的所有節(jié)點字段名類型說明備注idbigint主鍵自增baoxiubianhaovarchar報修編號唯一baoxiurenvarchar報修人關聯(lián)用戶賬號baoxiuneirongtext報修內容故障描述baoxiushijiandatetime報修時間默認當前時間weixiuyuanvarchar維修員接單后回填weixiuzhuangtaivarchar維修狀態(tài)待接單/維修中/已完成wanchengshijiandatetime完成時間狀態(tài)變更時更新這套表設計的巧妙之處在于它把報修業(yè)務的狀態(tài)流轉直接體現(xiàn)在表的字段變更上。報修單創(chuàng)建時只有報修人和報修內容維修員接單后回填維修員字段維修過程中更新狀態(tài)完成后再寫入完成時間。這個思路比額外建一張狀態(tài)流轉表要簡單直接對業(yè)務規(guī)模不大的場景完全夠用。2.3 權限控制三種角色在資源里是怎么落地的角色權限是管理系統(tǒng)的核心這套資源在登錄接口里實現(xiàn)了基于角色的路由控制。登錄成功后后端根據(jù)不同角色返回不同菜單權限前端再根據(jù)權限渲染對應的導航欄。PostMapping(/login) public Result login(RequestBody Users user) { QueryWrapperUsers wrapper new QueryWrapper(); wrapper.eq(username, user.getUsername()) .eq(password, user.getPassword()); Users loginUser usersService.getOne(wrapper); if (loginUser null) { return Result.error(用戶名或密碼錯誤); } String token UUID.randomUUID().toString().replace(-, ); redisTemplate.opsForValue().set(token, loginUser.getUsername(), 2, TimeUnit.HOURS); MapString, Object data new HashMap(); data.put(token, token); data.put(role, loginUser.getRole()); data.put(username, loginUser.getUsername()); return Result.success(data); }這段登錄邏輯有幾個地方值得注意。密碼校驗用的是最簡單直接的等值查詢這是很多課設項目的常見做法但生產(chǎn)環(huán)境必須換成加密存儲。UUID.randomUUID()生成的隨機字符串作為 token存到 Redis 里并設置 2 小時過期時間這樣能控制會話有效期。返回的 role 字段告訴前端當前用戶是什么角色前端拿這個字段控制菜單顯示。資源里的權限控制粒度是「角色-菜單」級別的也就是不同角色看到不同菜單但同角色內沒有更細分的操作權限區(qū)分。對于課程設計和小型后勤系統(tǒng)來說這個粒度夠了但如果要做更嚴格的權限管理可以考慮引入 Spring Security 或者 Shiro 做細粒度控制。3. 數(shù)據(jù)庫物理設計從 E-R 圖到建表 SQL 的落地細節(jié)3.1 核心表關系用戶、宿舍、維修員、報修單怎么關聯(lián)這套資源的數(shù)據(jù)庫設計遵循了第三范式的基本要求各表之間通過外鍵邏輯建立關聯(lián)。用戶表 yonghu 和宿舍分配表 sushefenpei 通過用戶賬號字段關聯(lián)宿舍信息表 sushexinxi 和宿舍分配表通過宿舍名稱關聯(lián)報修信息表 baoxiuxinxi 同時關聯(lián)用戶表和維修員表。有一個設計細節(jié)值得展開說說。宿舍信息表和宿舍分配表是分開的宿舍信息表記錄的是靜態(tài)數(shù)據(jù)——宿舍名稱、類型、樓棟、房間號、可住人數(shù)、已住人數(shù)、床位數(shù)量宿舍分配表記錄的是動態(tài)數(shù)據(jù)——誰住在哪個宿舍的哪個床位、分配日期、備注。這種拆分避免了一個學生換宿舍時要去修改宿舍表的問題只需要在分配表里更新記錄。建表 SQL 里能看到一些常見的設計約定。所有表都有 id 主鍵和 addtime 時間戳字段id 用 bigint 類型自增addtime 默認值設為CURRENT_TIMESTAMP。這類約定在 MyBatis-Plus 的自動填充功能下很好用插入數(shù)據(jù)時不用手動維護創(chuàng)建時間字段。CREATE TABLE baoxiuxinxi ( id bigint(20) NOT NULL AUTO_INCREMENT, addtime timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, baoxiubianhao varchar(20) NOT NULL, baoxiuren varchar(20) DEFAULT NULL, baoxiuneirong longtext, weixiuyuan varchar(20) DEFAULT NULL, weixiuzhuangtai varchar(20) DEFAULT 待接單, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;這里有幾個細節(jié)要注意。longtext類型用于報修內容字段因為故障描述可能比較長。weixiuzhuangtai字段設置了默認值 待接單這樣創(chuàng)建報修單時不用顯式傳這個字段。字符集用utf8mb4而不是utf8原因是utf8mb4支持完整的 Unicode 字符包括 emoji 表情避免用戶在報修內容里輸入特殊字符時出現(xiàn)亂碼。3.2 權限表的 token 處理機制管理員表 users 和 token 表的設計有一個值得學習的地方。token 表和用戶表是一對一關系token 表里有 userid、username、tablename、role、token、expiratedtime 字段。這里的 tablename 字段有點意思它記錄的是當前 token 對應哪個用戶表的表名。為什么需要這個字段因為系統(tǒng)有三類用戶——管理員、普通用戶、維修員——他們可能存儲在三張不同的表里。token 表里的 tablename 字段就是為了區(qū)分這個 token 是哪個登錄主體的。這種設計在課設項目里比較常見雖然用統(tǒng)一的用戶表加角色字段也能實現(xiàn)但對于已有三張表的數(shù)據(jù)庫結構這種擴展方式改動最小。過期時間expiratedtime的處理邏輯也需要留意。資源里的實現(xiàn)是在登錄時生成過期時間在攔截器里校驗當前時間是否超過過期時間。如果你把這套代碼用于生產(chǎn)建議把這個校驗邏輯統(tǒng)一放到攔截器或者過濾器里避免在每個 Controller 里重復寫。3.3 常用查詢場景的索引視角從檢索能力角度看這套表設計報修信息表的 baoxiubianhao 字段值得建唯一索引因為業(yè)務上需要通過報修編號快速定位單子。用戶表的 yonghuzhanghao用戶賬號字段在登錄時做等值查詢也應該建索引。宿舍信息表的 sushemingcheng 字段在宿舍分配時做關聯(lián)查詢加普通索引就夠了。資源里的 SQL 腳本已經(jīng)包含了一些索引定義但在 Navicat 里導入后建議再檢查一遍重點看那些經(jīng)常出現(xiàn)在 WHERE 條件和 JOIN 條件里的字段是否建了索引。實際操作中我遇到過這種情況數(shù)據(jù)量小的時候感覺不到區(qū)別一旦報修記錄累積到幾千條全表掃描的查詢延遲就會明顯增加。4. 核心功能實現(xiàn)報修閉環(huán)的三個關鍵模塊4.1 報修流程從用戶提單到維修員接單的狀態(tài)機報修管理是這套系統(tǒng)的核心業(yè)務流整個流程可以抽象成一條狀態(tài)鏈用戶提交報修 → 管理員審核或直接進入待接單池 → 維修員接單 → 維修中 → 完成。資源里的實現(xiàn)方式是用戶在前端填寫報修內容提交報修單進入待接單狀態(tài)維修員在待接單列表里查看所有未接單的工單接單后狀態(tài)變?yōu)榫S修中維修完成后更新狀態(tài)為已完成。后端的接單接口是流程的關鍵節(jié)點代碼大致是PostMapping(/jiedan) public Result jiedan(RequestBody BaoxiuInfo baoxiuInfo) { BaoxiuInfo info baoxiuInfoService.getById(baoxiuInfo.getId()); if (info null) { return Result.error(報修單不存在); } if (!待接單.equals(info.getWeixiuzhuangtai())) { return Result.error(該報修單已被接單); } info.setWeixiuyuan(baoxiuInfo.getWeixiuyuan()); info.setWeixiuzhuangtai(維修中); info.setJiedanshijian(new Date()); baoxiuInfoService.updateById(info); return Result.success(接單成功); }這段代碼體現(xiàn)了一個容易被忽視的業(yè)務約束接單前的狀態(tài)校驗。如果在更新狀態(tài)前不檢查當前報修單是否已經(jīng)是「待接單」狀態(tài)就可能出現(xiàn)兩個維修員同時搶同一張單子后提交的人把前一個人的信息覆蓋掉。這種并發(fā)問題在這個資源里用的是「先查再改」的方式雖然不做數(shù)據(jù)庫層面的樂觀鎖但對課設場景夠用。如果你想做得更穩(wěn)可以在表里加一個 version 字段在更新 SQL 里加WHERE version #{oldVersion}的樂觀鎖條件。4.2 宿舍分配用戶、宿舍、床位三者關聯(lián)的精確度問題宿舍分配模塊解決的核心問題是「哪個學生住在哪個宿舍的哪個床位」。資源里的實現(xiàn)邏輯是管理員在后臺選擇宿舍再選擇用戶接著填入床位號保存后生成一條分配記錄同時更新宿舍表的已住人數(shù)。這里有一個容易踩坑的業(yè)務點宿舍的容量校驗。分配宿舍時應該校驗該宿舍當前已住人數(shù)是否小于可住人數(shù)否則會出現(xiàn)超員分配。我在拆解資源時看了一下這個校驗邏輯在源碼里并不完整需要自己補上。補上這個校驗的代碼邏輯如下// 查詢宿舍當前狀態(tài) Sushexinxi sushe sushexinxiService.getById(sushefenpei.getSusheId()); if (sushe null) { return Result.error(宿舍不存在); } int yizhu Integer.parseInt(sushe.getYizhurenshu()); int kezhu Integer.parseInt(sushe.getKezhurenshu()); if (yizhu kezhu) { return Result.error(該宿舍已住滿); } // 執(zhí)行分配 sushefenpeiService.save(sushefenpei); // 更新已住人數(shù) sushe.setYizhurenshu(String.valueOf(yizhu 1)); sushexinxiService.updateById(sushe);這里有個細節(jié)值得注意yizhurenshu和kezhurenshu在表設計里用的是 varchar 類型而不是 int。這在數(shù)據(jù)庫設計里其實不算最佳實踐因為要做數(shù)值比較時必須先轉型。這個資源這么設計可能是因為實體類里為了方便前端展示用了字符串類型。如果你在二次開發(fā)時要把這塊做嚴謹建議把這兩個字段改成 int 類型Mapper 層做一層類型轉換即可。4.3 配件申請與庫存聯(lián)動維修員領料的后臺邏輯配件申請模塊的連接點在維修員和配件設備之間。維修員接單后如果發(fā)現(xiàn)維修需要更換配件可以在線提交配件申請管理員審核通過后配件庫存數(shù)量需要相應減少。PostMapping(/shenqing) public Result shenqing(RequestBody Peijianshenqing peijianShenqing) { Peijianshebei peijian peijianshebeiService.getById(peijianShenqing.getPeijianId()); if (peijian null) { return Result.error(配件不存在); } int kucun Integer.parseInt(peijian.getKucun()); int shenqingshu Integer.parseInt(peijianShenqing.getShenqingshu()); if (kucun shenqingshu) { return Result.error(庫存不足); } // 減少庫存 peijian.setKucun(String.valueOf(kucun - shenqingshu)); peijianshebeiService.updateById(peijian); // 記錄申請單 peijianShenqing.setZhuangtai(已發(fā)放); peijianshenqingService.save(peijianShenqing); return Result.success(申請成功); }這個接口是「先扣庫存再保存申請單」的順序按正常事務語義來說應該在一個事務里執(zhí)行否則如果保存申請單失敗庫存已經(jīng)被扣掉了。資源里沒有顯式加Transactional注解這是一個潛在隱患。你在二次開發(fā)時建議加上這個注解讓這兩個數(shù)據(jù)庫操作處于同一事務中保證數(shù)據(jù)一致性。配件模塊還有一個值得提的設計配件分類表和配件設備表分離。分類表存配件類型設備表存具體配件通過分類 ID 關聯(lián)。這種設計的好處是新增配件時不用改表結構選擇已有分類就行。4.4 維修進度查詢用戶端的狀態(tài)可視化維修進度模塊是用戶體驗的加分項。用戶在提交報修單后可以在「維修進度查詢」頁面看到自己所有報修單的當前狀態(tài)。這里的實現(xiàn)思路很簡單就是按照當前登錄用戶的賬號查詢該用戶所有報修單按時間倒序展示狀態(tài)字段。進度展示的字段設計覆蓋了報修全生命周期提交時間、當前狀態(tài)、維修員姓名、維修完成時間。用戶在列表里能直觀看到自己的單子處于什么環(huán)節(jié)是待接單、維修中還是已完成。這塊功能實現(xiàn)不復雜但它是用戶視角里感知系統(tǒng)價值最直接的地方。需要注意的是維修進度查詢在資源里的實現(xiàn)是按報修單狀態(tài)字段實時讀取的不是寫一條進度日志表記錄每次狀態(tài)變更。如果你需要做「完整操作留痕」比如記錄誰在什么時間把狀態(tài)從 A 改成了 B那就需要額外建一張狀態(tài)變更日志表在每次狀態(tài)變化的代碼邏輯里插入一條日志記錄。5. 避坑指南五個讓系統(tǒng)在演示現(xiàn)場翻車的常見問題5.1 端口被占用導致 Tomcat 啟動失敗現(xiàn)象在 IDEA 里啟動 SpringBoot 項目控制臺直接報Port 8080 was already in use整個應用起不來。原因本機之前有別的程序占用了 8080 端口或者上一次運行項目的進程沒被完全殺掉。這在課設演示前最容易發(fā)生越急越找不到是哪個程序占的。解決Windows 系統(tǒng)用netstat -ano | findstr 8080查出占用端口的 PID然后到任務管理器里結束對應進程或者直接改application.properties里的server.port配置把端口換掉。我一般建議直接用后者省事改完重啟就行。5.2 MySQL 時區(qū)問題導致時間字段相差 8 小時現(xiàn)象系統(tǒng)里新增報修記錄的時間在頁面上顯示比當前時間晚了 8 小時。原因MySQL 8.0 版本之后的連接驅動對時區(qū)敏感如果 JDBC URL 里沒有指定 serverTimezone 參數(shù)默認使用服務器本地時區(qū)而國內環(huán)境經(jīng)常會匹配到 UTC 標準時間。解決在數(shù)據(jù)庫連接 URL 里明確加上?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8。這個問題在資源配套的數(shù)據(jù)庫連接配置文件里其實已經(jīng)處理過但如果你自己重裝了 MySQL 或者改了連接串很容易重新踩進去。配置改完重啟應用時間就正常了。5.3 登錄頁驗證碼或密碼校驗不走攔截器現(xiàn)象未登錄狀態(tài)直接訪問后端接口地址居然能拿到數(shù)據(jù)登錄功能形同虛設。原因SpringBoot 項目里的攔截器只對部分 URL 生效如果配置 WebMvcConfigurer 時攔截路徑寫得不對比如只攔截了/admin/**漏掉了/api/**或者登錄接口本身就在攔截名單里就會導致鑒權邏輯不生效。解決先看資源里的攔截器配置類把不需要登錄就能訪問的接口路徑全部加到放行列表里比如/login、/register其余接口全部攔截。放行列表怎么寫可以看一下攔截器的實現(xiàn)一般是在excludePathPatterns()方法后面追加。把攔截器的匹配規(guī)則改成/**再排除掉白名單路徑是最穩(wěn)妥的。5.4 Navicat 導入 SQL 腳本時外鍵約束失敗現(xiàn)象把資源里的數(shù)據(jù)庫腳本用 Navicat 導入過程中報錯提示Cannot add foreign key constraint導致部分表創(chuàng)建失敗。原因腳本里建表的順序可能有問題先創(chuàng)建了有外鍵的子表后創(chuàng)建了被引用的父表或者是兩張表的字段類型不完全匹配比如一邊是 bigint 另一邊是 int。解決不用 Navicat 直接導整份腳本改成先執(zhí)行建表語句創(chuàng)建所有表再單獨執(zhí)行外鍵約束的修改語句。或者干脆把腳本里所有外鍵約束刪掉表結構建好之后手動在 Navicat 里補外鍵關系。課設評審階段外鍵約束是否完整影響不大關鍵是表能建成功、數(shù)據(jù)能存進去。5.5 前端頁面請求跨域導致接口拿不到數(shù)據(jù)現(xiàn)象前端 Vue 項目啟動后頁面能打開但所有數(shù)據(jù)都是空的瀏覽器控制臺報Access to XMLHttpRequest has been blocked by CORS policy錯誤。原因前端運行在 8080 端口后端運行在 8081 端口瀏覽器出于同源策略限制禁止跨端口發(fā)起 AJAX 請求。解決后端加一個跨域配置類實現(xiàn) WebMvcConfigurer 接口并重寫 addCorsMappings 方法。代碼如下Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }注意allowedOriginPatterns和allowCredentials(true)要配合使用否則有的瀏覽器版本會報錯。6. 從課程設計到能用二次開發(fā)時我最先動刀的五個位置拿到這套資源如果你是拿來交作業(yè)跑通就完事了。但如果你想讓這個系統(tǒng)真正能放進一個宿舍樓里用我建議按下面的優(yōu)先級做改造。第一處是密碼加密。資源里的密碼是明文存儲的登錄也是直接WHERE username ? AND password ?查詢?,F(xiàn)實場景里哪怕只是內部系統(tǒng)明文密碼也是不可接受的。用 Spring Security 的 BCryptPasswordEncoder也就是一個加密工具類注冊時對密碼做哈希登錄時用matches方法做比對改動量在注冊接口和登錄接口兩個地方半小時能改完。第二處是報修單狀態(tài)的并發(fā)控制。之前提到接單接口的「先查再改」邏輯存在并發(fā)覆蓋風險加樂觀鎖是最省事的方案。在報修信息表加 version 字段更新時用UPDATE baoxiuxinxi SET weixiuzhuangtai 維修中, version version 1 WHERE id ? AND version ?受影響行數(shù)為 0 就說明有人搶先改過了提示用戶刷新后重試。第三處是文件上傳和圖片展示。報修單里如果能附帶現(xiàn)場照片會大幅減少溝通成本。資源里沒有實現(xiàn)圖片上傳需要自己補一個上傳接口把文件保存到服務器本地目錄訪問時通過一個映射路徑直接讀取。注意上傳目錄要放在應用外部不然重新部署的時候文件會丟。第四處是數(shù)據(jù)備份。很多課設系統(tǒng)跑著跑著數(shù)據(jù)庫就崩了崩了就沒有后悔藥。至少配置一個 MySQL 定時任務每天凌晨用mysqldump把整個庫導出一份 SQL 文件到備份目錄。這個操作不寫代碼一行 crontab 就能解決。從那以后我每次接手這類系統(tǒng)都強制自己先讀一遍數(shù)據(jù)庫表設計文檔再動手改代碼。表結構理順了業(yè)務邏輯八九不離十就能看懂。這套資源的表設計雖然不是完美的但它把報修業(yè)務的關鍵實體和狀態(tài)都覆蓋到了適合做基礎再去改。希望這篇拆解能幫你在自己的項目里少走幾步彎路。本文還有配套的精品資源點擊獲取