)
每年開學季和期末季學生公寓的報修需求都會集中爆發(fā)——水龍頭漏水、空調不制冷、寢室燈管閃壞、柜門合不上各種報修單子從宿管、電話、微信群里涌進來靠人工登記和派單很容易漏單、錯單、響應慢。我之前帶團隊做過一個基于SpringBoot的學生公寓報修平臺從需求梳理、數據庫設計到前后端聯調、打包部署全部走了一遍過程中踩了不少坑也沉淀了一些比較實用的經驗。這篇博文就把整個項目的設計思路、核心模塊、數據庫表結構、關鍵代碼實現以及調試部署過程詳細拆開講希望對正在做類似管理系統(tǒng)、或者用SpringBoot做畢業(yè)設計的同學有幫助。這類平臺本質上是一個典型的多角色業(yè)務管理系統(tǒng)核心價值就是把“學生報修—管理員派單—維修工處理—學生驗收評價”這條鏈路搬到線上讓每一步都有記錄、可追蹤、能統(tǒng)計。先說清楚它解決了什么問題以前報修靠紙質登記本或者微信群接龍信息分散、狀態(tài)不透明學生不知道維修師傅什么時候來管理員也沒法快速統(tǒng)計各樓棟的維修頻率。有了平臺之后學生在線提交工單系統(tǒng)自動按樓棟、報修類型分類管理員一鍵指派維修工手機端接單、填寫維修結果學生確認后還能評價整套流程閉環(huán)數據也能沉淀下來做報表分析。適合誰來參考如果你正在做SpringBoot相關的課程設計、畢業(yè)設計或者想自己動手從零搭一個前后端分離的管理系統(tǒng)這個項目的完整度很合適如果你已經在寫代碼但不太清楚權限控制、工單狀態(tài)流轉這類業(yè)務怎么落地下面這些內容也能給你一些直接的參考。1.1 一個真實的學生公寓報修流程是什么樣在設計系統(tǒng)之前我專門去學校后勤部門蹲了幾天把線下流程摸了個清楚。真實場景大致是這樣的學生發(fā)現宿舍設施損壞先找宿管登記宿管手寫一張報修單然后電話聯系維修工。維修工有空就上門沒空就讓宿管盯著修完在單子上簽個字就算結束。這中間的痛點是樓棟一多報修單容易漏宿舍報修高峰期紙質單子堆積響應順序全靠人工判斷維修進度學生完全不知道。所以平臺在還原線下流程的基礎上做了數字化改造核心流程設計成四步學生提交工單 → 管理員分配維修工 → 維修工處理并填寫結果 → 學生確認驗收并評價。每一步都有對應的角色和狀態(tài)約束不允許跨狀態(tài)操作。比如維修工只能處理“待維修”狀態(tài)的工單處理完必須填寫維修耗時和材料消耗學生只能在狀態(tài)為“已完成”時進行驗收驗收不通過可以退回返修。這樣設計的好處是每個環(huán)節(jié)都有責任人出現糾紛時能直接通過系統(tǒng)日志定位。1.2 為什么選SpringBoot而不是其他框架很多人問做個報修平臺用SpringBoot是不是殺雞用牛刀其實不是。選SpringBoot有幾個很實在的理由第一它生態(tài)成熟MyBatis-Plus、Redis、Shiro、MinIO這些常用組件都有非常完善的和SpringBoot的整合文檔開發(fā)效率高第二它內置Tomcat打包成jar就能直接跑部署成本低對學生項目和中小型系統(tǒng)來說非常友好第三社區(qū)活躍面試和畢業(yè)答辯時也容易講清楚。另外我對比過SSHStrutsSpringHibernate和SpringMVC單體架構SSH現在已經很少有人用了配置XML太繁瑣純SpringMVC雖然更輕量但要做大量的手動配置比如數據源、事務、json轉換等。SpringBoot通過自動配置把這些全封裝掉了我們只需要關注業(yè)務代碼。當然SpringBoot也有弱點就是自動配置的黑盒機制出了問題排查起來比較費勁這個在后面“常見問題”部分我會專門講。1.3 這個項目交付物里到底包含哪些東西標題里提到的“程序源碼數據庫調試部署開發(fā)環(huán)境”拆開來看其實是五個層次程序是打包好的可運行物源碼是可讀、可改的工程代碼數據庫是建庫建表的SQL腳本和初始數據調試部署是詳細的啟動步驟和常見錯誤解決辦法開發(fā)環(huán)境就是JDK、MySQL、IDEA、Maven這些工具的版本和配置要求。我建議拿到項目后先按順序做先導入源碼到IDEA再執(zhí)行SQL腳本初始化數據庫然后修改application.yml里的數據庫連接信息最后啟動檢查控制臺日志。不要一上來就想改功能先把系統(tǒng)跑通再動手改代碼這樣出問題的時候你才知道是環(huán)境問題還是業(yè)務代碼問題。2. 整體架構與模塊設計拆解整個平臺采用的是經典的SSM微服務雛形不這里用的是SpringBoot單體架構。為什么不用微服務因為學生公寓報修平臺的核心業(yè)務是工單流轉和人員管理并發(fā)量不大單體架構部署簡單、維護成本低、事務控制容易完全夠用。如果硬拆成微服務反而會因為分布式事務、服務間調用等問題把項目復雜度拉高對學習和答辯都不利。這個選擇我覺得是合理的在實際項目中能用單體解決的絕對不上微服務。2.1 三種角色一張圖看懂權限邊界系統(tǒng)里一共三類角色學生普通用戶、維修工、管理員。權限邊界用一句話概括學生管自己的報修單維修工管被分給自己的任務管理員管全局配置和數據統(tǒng)計。角色核心權限主要操作學生報修、查詢、評價提交報修工單、查看處理進度、確認驗收、評價評分、修改個人信息維修工任務處理查看我的工單、接單/退單、填寫維修結果、上傳維修后照片管理員全站管理工單派發(fā)/改派、用戶管理、樓棟與報修類型維護、數據統(tǒng)計、公告發(fā)布三個角色共用一套登錄認證邏輯登錄成功后返回的角色碼不同前端根據角色碼渲染不同的菜單后端在接口層級做權限攔截。這里我建議權限校驗放在后端做前端隱藏菜單只是體驗優(yōu)化不是安全手段。實際操作中有些同學只在前端做路由判斷后端接口不攔結果有人直接調用接口繞過了權限這是很典型的安全漏洞。2.2 報修工單的生命周期設計工單是系統(tǒng)的核心實體我把它的狀態(tài)設計成七個待派單、待接單、維修中、已完成、已驗收、已駁回、已取消。狀態(tài)的變遷不是隨意的而是有嚴格的動作約束學生提交后工單進入“待派單”狀態(tài)此時只有管理員能看到并派單。管理員派單給某個維修工后狀態(tài)變?yōu)椤按訂巍本S修工可以接單狀態(tài)變?yōu)椤熬S修中”也可以申請退單退回給管理員。維修工處理完成并填寫結果后狀態(tài)變?yōu)椤耙淹瓿伞贝藭r學生端才會出現“驗收”按鈕。學生點擊驗收通過后狀態(tài)變?yōu)椤耙羊炇铡绷鞒探Y束如果驗收不通過可以填駁回意見工單重新回到“待派單”狀態(tài)管理員可重新派單或催辦?!耙讶∠睜顟B(tài)主要用于學生提交后發(fā)現填錯或自行解決了在沒有被派單之前取消。一旦派單學生就不能自行取消了得聯系管理員處理。這里有一個非常容易踩坑的地方狀態(tài)字段如果用int存代碼里每個數字代表什么含義很容易忘記特別容易改錯。我建議用枚舉統(tǒng)一管理代碼里只允許通過枚舉轉換數據庫里存字符串枚舉名這樣可讀性和維護性都好很多。后面我貼了具體代碼可以直接參考。2.3 功能模塊劃分與接口設計整個系統(tǒng)按業(yè)務域劃分成六大模塊用戶模塊、工單模塊、報修類型模塊、樓棟管理模塊、公告模塊、統(tǒng)計報表模塊。每個模塊的接口遵循RESTful風格返回統(tǒng)一格式的Result對象結構為code、message、data三件套。前端先判斷code是否等于200再取data這樣后端拋異常時也能統(tǒng)一返回code500前端彈一個錯誤提示不白屏。接口命名方面我按資源來設計比如POST /api/repair/order 提交工單GET /api/repair/order/list 查詢工單列表支持分頁和條件查詢PUT /api/repair/order/assign 管理員派單PUT /api/repair/order/processing 維修工接單/處理PUT /api/repair/order/accept 學生驗收這種以資源加動作為核心的命名方式前后端對接的時候非常直觀也方便寫接口文檔。開發(fā)期間我把接口文檔用Swagger生成寫接口的時候就順手加上注解省得后面還要單獨維護文檔。3. 數據庫設計與核心表結構數據庫設計是整個項目的地基地基沒打好后面寫接口的時候就會各種別扭。我在設計時遵循幾個原則一是表名和字段名用清晰的英文命名二是所有業(yè)務表都要有id、create_time、update_time這三個字段三是金額、狀態(tài)這類字段用int或decimal存不要用varchar存數字否則排序和統(tǒng)計都會出問題。3.1 核心表設計一覽系統(tǒng)核心共八張表我把最關鍵的列和說明列出來表名說明關鍵字段t_user用戶表id、username、password、real_name、role_id、phone、dormitory_idt_repair_order報修工單表id、order_no、student_id、dormitory_id、type_id、description、images、status、processor_id、process_time、apply_remarkt_repair_type報修類型表id、type_name、sortt_dormitory樓棟/宿舍表id、building_no、room_no、managert_repair_log工單操作日志表id、order_id、operator_id、action、remark、create_timet_announcement公告表id、title、content、publisher_id、create_timet_comment評價表id、order_id、student_id、score、content、create_timet_role角色表id、role_name、role_code3.2 工單表的設計細節(jié)t_repair_order是核心我把幾個容易出問題的地方單獨說一下。首先是order_no工單編號我用了“日期流水號”的生成規(guī)則格式是20250613001含義是2025年6月13日第1單。生成邏輯是查當天最大編號加1用Redis的incr做自增計數更穩(wěn)但如果沒有Redis用查詢鎖也能實現只是并發(fā)高時有可能會重復需要注意加數據庫唯一索引兜底。其次是images字段存的是用戶上傳的故障照片URL多個用逗號分隔。有些同學會單獨建一張圖片表也可以但在照片數量不多的小系統(tǒng)里直接用分隔符存儲更簡單查詢工單詳情時切分一下就能渲染。我實際開發(fā)時是把圖片傳到MinIO返回的URL直接存到images字段里包工時再把URL取出拼接成json傳給前端。第三是processor_id表示當前負責的維修工。一個工單在流轉中可能被多次改派所以processor_id只存當前處理人歷史流轉記錄全部記到t_repair_log里。這樣的設計讓工單表本身保持簡潔同時日志表可以追溯整個處理過程審計也方便。3.3 邏輯刪除與樂觀鎖的實踐開發(fā)過程中我踩過一個很經典的坑刪除用戶時直接delete結果把歷史工單里的學生關聯搞沒了導致工單統(tǒng)計的時候數據對不上。后來我給所有業(yè)務表都加了deleted字段用MyBatis-Plus的TableLogic做邏輯刪除。查詢時框架自動拼接deleted 0刪除操作實際是update歷史數據永遠保留。這個習慣我在做其他系統(tǒng)時也沿用強烈建議大家從一開始就加上。樂觀鎖則用在工單狀態(tài)的并發(fā)更新上。設想一個場景管理員在處理工單的同時維修工也點了接單兩個請求同時讀到狀態(tài)是“待接單”都執(zhí)行了update就可能出現狀態(tài)覆蓋。解決辦法是給t_repair_order加version字段更新時帶上WHERE version #{version}判斷影響行數如果為零說明被別人改過了提示用戶稍后重試。MyBatis-Plus自帶Version插件開啟樂觀鎖只是幾行配置的事強烈推薦加上。4. 核心功能實現的幾個關鍵點這一部分我講一下開發(fā)過程中值得反復斟酌的幾個技術點每個都涉及到系統(tǒng)的穩(wěn)定性和用戶體驗也是答辯時老師容易追問的地方。4.1 工單狀態(tài)機與流轉控制狀態(tài)機是整個業(yè)務最核心的部分。我建議不要在每個接口里都寫一遍if判斷而是把狀態(tài)流轉抽出來統(tǒng)一管理。實現方式有輕量和重量兩種輕量方式是用枚舉加一個變更校驗方法重量方式是引入狀態(tài)機框架比如Spring StateMachine。對報修平臺這個規(guī)模用輕量方式就夠了。我自己寫了一個RepairOrderState枚舉里面定義狀態(tài)和允許的流轉目標然后提供一個transition方法進入新狀態(tài)前先校驗當前狀態(tài)是否允許流轉到目標狀態(tài)不允許就拋業(yè)務異常。這樣所有狀態(tài)更新都走同一個入口不會出現在A接口改了狀態(tài)但沒記錄日志的情況。我把日志寫入也放在transition方法里每流轉一次就自動往t_repair_log插一條記錄省得每個接口手動去寫日志邏輯統(tǒng)一且不容易漏。4.2 前后端分離下的權限控制系統(tǒng)采用前后端分離架構后端接口用JWT做無狀態(tài)認證。登錄成功后簽發(fā)token前端存到localStorage每次請求在header里帶上Authorization。后端用一個攔截器統(tǒng)一解析token解析出userId和roleCode放到ThreadLocal里Controller直接取。權限校驗我是在攔截器里根據角色碼做簡單判斷哪些接口管理員才能訪問哪些是維修工專屬。比如/admin/**開頭的接口只能管理員訪問/worker/**只能維修工訪問/student/**只能學生訪問。如果接口放錯路徑權限就崩了所以不建議用URL前綴做粗粒度權限。更合理的做法是使用RequireRole這樣的注解標注在Controller方法上攔截器通過反射讀取注解做校驗這樣權限和接口寫在了一起可讀性也更高。4.3 圖片上傳與MinIO接入的方式報修必然要上傳故障照片這是整個項目里最容易出問題的一環(huán)。一開始我用的是本地磁盤存儲把上傳的文件寫到服務器的某個目錄然后返回URL看起來簡單但有兩個坑一是服務器重啟后目錄丟失二是前端直接訪問磁盤路徑會有跨域和權限問題。后來我換成了MinIO一個開源的對象存儲服務部署起來就一個docker命令的事本地開發(fā)也可以直接跑。SpringBoot整合MinIO其實不復雜。先在pom.xml引入io.minio:minio依賴然后在application.yml配endpoint、accessKey、secretKey、bucketName寫一個MinioService里面封裝上傳、刪除、獲取訪問地址這幾個方法。上傳時用UUID給文件重命名防止重名覆蓋。有一點需要注意MinIO的bucket要提前創(chuàng)建并設置公共讀策略否則前端拿到的URL預覽會404。這個問題我當時排查了很久最后發(fā)現是bucket的訪問權限沒設置對。4.4 站內信與微信通知的取舍工單狀態(tài)變了學生怎么第一時間知道最開始我只做了站內信就是工單列表里加個未讀紅點后來發(fā)現很多學生根本不會主動刷新網頁于是加了WebSocket推送。實現方式是用Spring的WebSocket握手時從token里解析userId后端維護一個userId到Session的映射工單狀態(tài)變更時主動推送一條消息給對應學生。這里有個細節(jié)WebSocket的Session不是線程安全的多線程并發(fā)推送前要加鎖否則會出現消息丟失或異常。WebSocket推送只是“錦上添花”實際運行時如果學生關了網頁推送還是收不到。所以最終方案是站內信保底WebSocket只做實時提醒。我建議做這類系統(tǒng)時不要過度依賴推送數據庫里的消息表才是數據本體推送只是通知手段。很多同學做這類項目喜歡把推送放得很重結果一重啟連接就全斷反而把系統(tǒng)復雜度拉高了。5. 開發(fā)環(huán)境搭建與調試部署實錄很多人在項目開發(fā)階段很順利一到部署就各種報錯環(huán)境問題占了很大比重。我把自己實際搭建環(huán)境、調試、部署的過程完整記錄下來包括版本選擇、配置項和遇到的重點問題照著走基本能少踩一半坑。5.1 開發(fā)環(huán)境版本與安裝說明我用的開發(fā)環(huán)境就是標題里說的“程序源碼數據庫調試部署開發(fā)環(huán)境”那一套具體版本如下工具推薦版本說明JDK1.8 或 11SpringBoot 2.7.x 對這兩個版本支持最穩(wěn)IDEA2023.x 及以上社區(qū)版完全夠用不用買旗艦版Maven3.8.x不要用3.9.0之后的版本有些倉庫兼容有問題MySQL5.7 或 8.0推薦8.0注意時區(qū)和驅動配置Redis6.x用于token緩存和工單號自增安裝順序我建議先裝JDK再裝Maven然后是MySQL最后是Redis。每次裝完都驗證一下環(huán)境變量JDK驗證命令java -versionMaven驗證mvn -vMySQL驗證mysql --version。很多的坑往往發(fā)生在環(huán)境變量沒配置好導致IDEA里編譯的時候能過但命令行跑jar包就跑不起來。5.2 SpringBoot核心配置與關鍵參數application.yml是SpringBoot啟動的核心我把關鍵的配置項解釋一下特別標注幾個容易出錯的地方server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/repair_platform?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 database: 0 servlet: multipart: max-file-size: 10MB max-request-size: 20MB mybatis-plus: mapper-locations: classpath*:mapper/*.xml configuration: map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl有幾個參數我要特別強調。第一是serverTimezone如果MySQL用的8.0url里必須帶serverTimezoneAsia/Shanghai否則JDBC驅動會報“The server time zone value”的錯這是新手最常見的問題。第二是map-underscore-to-camel-case這個開關默認是開的可以讓數據庫字段create_time自動映射到Java屬性的createTime省去大量TableField注解。第三是multipart上傳大小的限制如果照片原圖比較大默認1MB的限制是不夠的我配置成了10MB實際一張手機拍的照片通常在3-5MB左右。5.3 前端資源打包后放進SpringBoot的整合技巧實際部署時為了省一臺服務器我把前端Vue項目打包后的dist目錄直接放進SpringBoot的靜態(tài)資源目錄這樣整個系統(tǒng)就是一個jar包java -jar啟動后既能訪問后端接口也能訪問前端頁面非常方便。具體步驟是這樣先在前端項目根目錄執(zhí)行npm run build打包后生成一個dist目錄。把dist目錄里的全部文件復制到后端src/main/resources/static目錄下。然后重新用Maven打包后端生成的jar就自帶前端頁面了。前端打包后默認的靜態(tài)資源路徑是/和后端接口的/api前綴不沖突。如果前端用了history路由模式記得要在后端加一個轉發(fā)保證刷新頁面時不會404不然單擊刷新頁面就報404非常影響體驗。我是在SpringBoot里加了個WebMvcConfigurer把非/api的路徑全部轉發(fā)到index.html幾行代碼搞定。5.4 三種部署方式的對比與選擇部署方式我試過三種本地IDEA直接啟動、Linux服務器jar包部署、Docker容器化部署。本地IDEA啟動適合開發(fā)調試按ShiftF10就能跑斷點調試最方便。Linux服務器jar部署適合小規(guī)模正式使用把打包好的jar上傳到服務器執(zhí)行nohup java -jar xxx.jar app.log 21 日志輸出到app.log方便排查。Docker部署適合環(huán)境統(tǒng)一寫一個Dockerfile把JDK和jar打進鏡像再用docker run啟動換服務器的時候一條命令就能拉起環(huán)境。從穩(wěn)定性角度我最推薦Linuxjar的方式原因很簡單Docker雖然好但要額外運維鏡像倉庫對學生項目來說有點重。jar方式只需要一臺能跑Java的服務器就夠了出了問題看日志也比較直觀。6. 常見問題與排查技巧實錄這部分我把實際開發(fā)和部署過程中遇到的高頻問題記錄下來按照現象、原因、解決辦法三個維度整理成速查表方便你遇到同樣問題的時候直接對號入座。6.1 啟動時報數據庫連接錯誤報錯信息一般是“Cannot connect to MySQL server”或“Access denied for user”。大多數原因是數據庫沒有啟動、賬號密碼不對、或者url里的host端口寫錯。排查順序建議先手動用命令行mysql -u root -p試試能不能連上確認數據庫本身沒問題再看SpringBoot配置文件的url、username、password是否一致。還有一個隱蔽原因如果你的MySQL跑在遠程服務器上本地連不上可能是MySQL的bind-address默認綁定了127.0.0.1需要改成0.0.0.0然后授權遠程訪問。這個我在自己的項目里遇到過本地IDEA能連部署到服務器上就連不上最后發(fā)現是MySQL的安全配置問題不是SpringBoot代碼的問題。6.2 端口被占用怎么辦jar部署時最常遇到的報錯是“Port 8080 was already in use”。先用netstat -tlnp | grep 8080找到占用端口的進程確認是不是自己之前啟動的舊進程kill掉之后重新啟動就好。如果你有多個項目要同時跑可以在application.yml里用server.port改成8081、8082等也可以啟動時用--server.port8081覆蓋配置文件里的端口靈活一些。如果服務器上已經有nginx或其他服務占用了80端口我一般會把SpringBoot服務跑在8080然后通過nginx反向代理到80對外提供服務。這樣既不影響現有服務又不用改代碼。6.3 Maven依賴沖突與下載失敗SpringBoot項目依賴多時不時會遇到jar包下載失敗或者依賴沖突。下載失敗大概率是Maven倉庫源的問題國內網絡訪問中央倉庫經常超時我建議在settings.xml里把鏡像源換成阿里云鏡像基本一次解決。依賴沖突的表現是啟動時報NoClassDefFoundError或者bean創(chuàng)建異常原因一般是同一個類有多個版本的jar被加載。排查依賴沖突的命令是mvn dependency:tree看依賴樹里有沒有重復的jar包。比如很多同學同時引入了spring-boot-starter-web和spring-boot-starter-actuator版本不一致時就會出現沖突。解決辦法是使用Maven的依賴管理機制通過dependencyManagement統(tǒng)一版本號或者用exclusion把多余的傳遞依賴去掉。我自己的習慣是在pom.xml的properties里統(tǒng)一聲明版本減少版本沖突的可能性。6.4 文件上傳后無法預覽或丟失圖片上傳后前端拿不到預覽圖這個問題的原因是多樣的。如果是MinIO存儲先確認bucket是否設置了公開讀權限如果是本地存儲檢查上傳文件路徑是否真的有文件以及返回的URL是否能通過瀏覽器直接訪問。還要注意一個細節(jié)SpringBoot默認對靜態(tài)資源的映射不包括磁盤上的其他目錄所以本地存儲時我建議把上傳目錄放到resources/static下的uploads文件夾或者通過自定義資源映射把磁盤路徑映射成/image/**,否則前端訪問不了。文件丟失的問題通常是服務器重啟后磁盤文件沒了所以我一直推薦用MinIO或者OSS把文件數據和服務本身解耦服務器掛了也不怕。這一點在標題里雖然沒有直接體現但“minio加入到springboot”這個點很多人在做報修平臺時都會用到我也就順便講透。6.5 一個容易被忽略的bug事務失效在把多個寫操作放在一起的時候如果方法沒有加Transactional注解或者類沒有被Spring管理就會出現事務失效的情況。報修工單創(chuàng)建、日志插入、通知寫入這三個操作如果不在一個事務里日志插入失敗時工單已經提交了數據就亂了。排查事務失效有個技巧加Transactional的方法不能是private的不能被this調用還要把異常拋出到事務邊界之外否則異常被捕獲了事務不會回滾。我實際開發(fā)時有一次工單創(chuàng)建成功后報錯檢查發(fā)現日志插入方法沒有加Transactional導致創(chuàng)建和日志不一致加上注解并在Service入口統(tǒng)一管理事務后就好了。這個經驗值得記下來很多反復出現的“靈異bug”其實都是事務邊界的問題。7. 常用調試技巧與個人體會最后分享幾個自己總結的調試技巧和心得。第一日志要善用但不濫用。開發(fā)時MyBatis-Plus控制臺輸出SQL日志可以看到每次執(zhí)行的完整SQL排查問題直接看日志不要靠猜。線上部署時把日志級別調成INFO避免刷屏影響性能。第二前后端聯調時先抓包看請求和響應體很多問題一看就是參數名不對或缺失字段不用急著改代碼。第三接口測試用Postman或Apifox把常用的接口做成集合改完代碼跑一遍回歸測試比手工點前端頁面高效很多。我個人在實際開發(fā)后最深的感受是這類多角色系統(tǒng)的難點不在CRUD而在業(yè)務的完整性和數據的準確性。狀態(tài)流轉約束、權限校驗、事務邊界、字段設計的規(guī)范性這些才是真正拉開代碼質量差距的地方。另外給正在做畢業(yè)論文/畢設的同學一個建議不要只滿足于“能跑”把狀態(tài)機設計、權限方案、文件存儲方案、事務控制這幾個點講明白答辯的時候這就是亮點。這個系統(tǒng)后續(xù)如果要擴展方向也挺明確的一是把微信小程序端補上學生更習慣用手機報修二是增加工單超時提醒用定時任務掃描超時未接單的工單自動提醒管理員三是數據統(tǒng)計做可視化大屏按樓棟、按類型展示維修頻次和平均響應時長后勤部門會很需要。我這邊也打算把小程序端和定時提醒做出來后面攢夠經驗再寫一篇分享。如果你正在調這個項目遇到問題歡迎把報錯信息發(fā)在交流區(qū)我看到都會回復。