:從數(shù)據(jù)庫設計到論文答辯全流程)
這幾年帶畢業(yè)設計SpringBoot加Vue的博物館信息管理系統(tǒng)幾乎是我見過最多人選的題目之一。光一個方向我前后看過幾十個版本有的偏重藏品管理有的著重預約流程還有的把展廳和志愿者都塞進去。題目年年類似但做得好的和做得一般的拿出來的完成度會有天壤之別。這篇文章我想把這套系統(tǒng)從選題邏輯、數(shù)據(jù)庫設計、前后端實現(xiàn)到怎么轉(zhuǎn)化成畢業(yè)論文再到搭建過程中的高頻坑位整體捋一遍。如果你正在準備這類畢業(yè)設計或者想用這個項目作為全棧入門練手順著這條線走下去能少走不少彎路。我先說一個判斷博物館信息管理系統(tǒng)不是簡單的“增刪改查”堆砌它是一個非常適合用來展示工程能力的綜合型業(yè)務系統(tǒng)。無論從業(yè)務復雜度、表結(jié)構設計、權限控制、預約邏輯還是從Vue端界面呈現(xiàn)的角度它都能裝下足夠的干貨。對畢業(yè)生來說它既不會難到無法落地也不會簡單到答辯時無話可說。1. 這個選題為什么年年火——畢業(yè)設計題型的真實分析1.1 “信息系統(tǒng)類畢業(yè)設計”的底層邏輯先把這個題目的本質(zhì)拆開。任何信息管理系統(tǒng)無論前面掛的是“博物館”“圖書館”“健身房”還是“寵物店”它的底層骨架都差不太多用戶管理、內(nèi)容管理、預約或訂單處理、統(tǒng)計展示。選這類題目的學生本質(zhì)上是在用一套全棧技術棧解決一個中等復雜度的業(yè)務數(shù)據(jù)管理問題。為什么博物館場景特別受歡迎原因是它兼顧了兩頭。一端是普通用戶也就是參觀者他們要瀏覽展覽、查看藏品、在線預約另一端是后臺管理員要維護藏品檔案、發(fā)布展覽信息、審核預約、管理展廳數(shù)據(jù)。這種“兩端都有事干”的設計讓前端頁面顯得豐富后端接口也不至于只是幾個空殼子。我在跟學生聊選題時經(jīng)常說一句話畢業(yè)設計最怕的不是功能多而是功能少到?jīng)]法支撐論文的章節(jié)結(jié)構。博物館管理系統(tǒng)天然有至少五個功能域——藏品信息管理、展廳與展覽管理、參觀預約管理、用戶與權限管理、公告與數(shù)據(jù)統(tǒng)計。這五個域一個個寫進論文里需求分析、系統(tǒng)設計、功能實現(xiàn)、系統(tǒng)測試四章就都有實打?qū)嵉膬?nèi)容可以寫。1.2 相比其他信息系統(tǒng)博物館場景的特殊優(yōu)勢有學生問我那跟“圖書管理系統(tǒng)”“二手交易平臺”比選博物館有什么差別差別在業(yè)務語義。圖書管理基本就是圖書增刪改查加借還流程業(yè)務邏輯相對線性二手交易平臺雖然業(yè)務豐富但涉及到支付、訂單狀態(tài)扭轉(zhuǎn)、買家賣家糾紛處理對畢業(yè)設計來說容易“收不住”。博物館系統(tǒng)的業(yè)務量級恰好卡在中間藏品有朝代、材質(zhì)、年代、分類、狀態(tài)這些有專業(yè)感的屬性展覽有策劃周期和關聯(lián)關系預約有一整套狀態(tài)流轉(zhuǎn)。它比純CRUD多了一層“業(yè)務味道”但又不會像電商平臺那樣復雜到讓你陷進分布式事務的泥潭。更要緊的是博物館系統(tǒng)在答辯時非?!昂弥v”。評委老師不用懂技術也能理解場景。你說“參觀者在線預約參觀管理員后臺審核”一句話就能講清系統(tǒng)價值。反過來如果你做一個算法類的題目可能光解釋問題定義就得花五分鐘。信息管理系統(tǒng)的優(yōu)勢就在這里業(yè)務模型是透明的技術實現(xiàn)的討論門檻自然就低了。1.3 動工之前先確認自己的基線技能選這個題目之前我建議你先做一次誠實的現(xiàn)狀評估。需要具備的硬指標有這么幾項Java基礎語法和面向?qū)ο笏枷氩荒苌柚辽倌芸炊甋ervice、Controller這些注解的含義會寫最簡單的SQL知道主鍵、外鍵、索引大概是怎么回事前端方面能看懂Vue單文件組件的基本結(jié)構知道data、methods、mounted是干什么用的。如果這些條件離你還有點遠那第一步不是急著敲代碼而是先花兩周把基礎補齊。我見過一些學生Java還停留在“照著抄能跑”的階段就直接開項目結(jié)果被Maven依賴、MyBatis映射、前端跨域三連擊勸退最后只能花錢請人代做這對于畢業(yè)設計來說就失去意義了。反過來如果你已經(jīng)具備這些基礎那博物館管理系統(tǒng)是一個很好的放大器——你可以在一個可控的復雜度內(nèi)把后端分層、接口設計、前端組件化、權限控制整套工程實踐都過一遍做完之后簡歷上也能多一個拿得出手的項目。2. 數(shù)據(jù)模型先行博物館信息系統(tǒng)的功能邊界與表單設計2.1 從需求分析到功能清單哪些模塊該保留哪些沒必要做很多學生拿到題目第一反應是打開IDE新建項目開始寫代碼。這是順序錯了。做信息系統(tǒng)第一步永遠是畫功能清單。我習慣讓學生先拿一張紙把系統(tǒng)角色和功能列出來再決定表結(jié)構。博物館信息管理系統(tǒng)通常保留兩大角色普通用戶參觀者和管理員。管理員內(nèi)部還可以再拆超級管理員負責賬號和數(shù)據(jù)維護普通管理員負責展覽和預約審核。這里的核心功能模塊我建議鎖定為五個藏品管理藏品的錄入、編輯、下架、詳情查看支持按名稱、朝代、分類檢索。展廳與展覽管理維護展廳基礎信息創(chuàng)建展覽并將展品關聯(lián)到展覽。預約管理參觀者提交預約、查看預約狀態(tài)管理員后臺審核或者自動審核。用戶管理注冊、登錄、角色分配、賬號啟停用。系統(tǒng)管理公告發(fā)布、數(shù)據(jù)統(tǒng)計、操作日志。至于要不要做展廳VR、語音導覽、線上文創(chuàng)商城我一律建議慎重。這些功能聽起來好看但每一個都會顯著拉長開發(fā)周期。畢業(yè)設計的核心是“完整”不是“酷炫”。做一個邏輯閉環(huán)的小系統(tǒng)遠比做一個半成品的“大平臺”更有說服力。2.2 核心表的字段設計與關系約定功能清單定了之后表結(jié)構就是整個項目的承重墻。我建議至少設計這六張核心表用戶表user主鍵、用戶名、密碼密文存儲、昵稱、聯(lián)系電話、角色標識、創(chuàng)建時間、狀態(tài)。角色標識可以用一個字段區(qū)分也可以引入角色表做標準RBAC。小系統(tǒng)里我傾向于直接用字段區(qū)分省事且夠用。藏品表collection主鍵、藏品編號業(yè)務唯一、名稱、類別、朝代、材質(zhì)、尺寸、圖片地址、藏品狀態(tài)在庫/展出/修復/下架、簡介、錄入人、錄入時間。這張表的字段是后面檢索功能和列表展示的數(shù)據(jù)來源字段命名要規(guī)范別一會兒用create_time一會兒用created_at。展廳表hall主鍵、展廳名稱、位置、容納人數(shù)上限、開放時間、簡介。展覽表exhibition主鍵、標題、封面圖、展覽介紹、舉辦時間起止、關聯(lián)展廳ID、狀態(tài)籌備中/進行中/已結(jié)束。預約表reservation主鍵、預約編號、用戶ID、展覽ID、預約日期、到館時間、預約人數(shù)、聯(lián)系電話、狀態(tài)待確認/已確認/已取消/已完成、提交時間。這張表是整個系統(tǒng)業(yè)務邏輯最密的地方后面會詳細說。公告表notice主鍵、標題、內(nèi)容、發(fā)布人、發(fā)布時間。這張表用來撐起首頁信息和論文里的“信息發(fā)布”功能點。字段層面有幾個細節(jié)要提醒。第一個是密碼必須加密存儲這是安全底線。第二個是含有狀態(tài)語義的字段建議用Integer而不是String方便做狀態(tài)機的邏輯判斷。第三個是大量用于聯(lián)表查詢的字段比如exhibition_id、user_id一定要建索引。別小看這種細節(jié)答辯時老師問到數(shù)據(jù)庫設計你能說出索引和唯一約束的設置理由印象分會明顯不一樣。2.3 角色權限體系如何劃分超級管理員為什么不可或缺權限設計是信息系統(tǒng)類畢業(yè)設計的必考點。最簡單好用的做法是用一張用戶表加一個role字段區(qū)分USER和ADMIN兩種角色。查詢功能通過登錄狀態(tài)控制管理功能通過角色控制。超級管理員往往是學生容易漏掉的點。很多人覺得系統(tǒng)里有管理員賬號就夠了為什么還要分超級管理員和普通管理員實際場景是這樣的。普通管理員可以管理藏品和展覽但不應該能刪除其他管理員賬號也不應能修改系統(tǒng)參數(shù)。系統(tǒng)則需要有一個最高權限賬號來兜底。這種“分級授權”的思想寫進論文里是對權限管理的合理展開也讓你后端的權限校驗邏輯有了層次。3. SpringBoot后端接口設計順序與實現(xiàn)要點3.1 地基先打好統(tǒng)一返回體、異常處理和JWT后端工程搭建的時候我強烈建議第一件事不是寫業(yè)務接口而是把三樣基礎設施先做好。第一個是統(tǒng)一返回體。所有接口都返回一個統(tǒng)一包裝對象比如Result 里面包含code、message、data三個字段。這樣前端可以用統(tǒng)一的邏輯處理成功和失敗而不是每個接口各寫各的返回格式。public class ResultT { private Integer code; private String message; private T data; public static T ResultT success(T data) { ResultT result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static T ResultT error(String message) { ResultT result new Result(); result.setCode(500); result.setMessage(message); return result; } }第二個是全局異常處理。用RestControllerAdvice統(tǒng)一捕獲業(yè)務異常和系統(tǒng)異常。這一寫在排錯時會救你很多命。否則一旦代碼里某個查詢報空指針前端只會看到一個格式亂七八糟的報錯排查起來效率極低。第三個是登錄認證。我推薦用JWT而不是簡單的Session。JWT的核心思路是用戶登錄成功后后端簽發(fā)一個帶有效期的token前端后續(xù)請求都在header里帶上這個token后端通過攔截器解析并校驗。這個方案的好處是無狀態(tài)、易于前后端分離部署而且“Token認證機制”本身也是論文里一個很漂亮的章節(jié)素材。jwt: secret: your-secret-key expire: 86400 # 24小時3.2 藏品管理接口CRUD中容易被忽視的細節(jié)藏品管理模塊對應的是一組標準CRUD接口。但這里有兩個細節(jié)值得展開。第一個是分頁條件查詢。接口需要支持同時按照名稱模糊查詢、按朝代篩選、按分類篩選并返回分頁數(shù)據(jù)。使用MyBatis-Plus時可以這樣組織查詢條件Override public PageResultCollection pageCollections(CollectionQuery query) { LambdaQueryWrapperCollection wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.hasText(query.getName()), Collection::getName, query.getName()); wrapper.eq(StringUtils.hasText(query.getDynasty()), Collection::getDynasty, query.getDynasty()); wrapper.eq(query.getCategory() ! null, Collection::getCategory, query.getCategory()); wrapper.orderByDesc(Collection::getCreateTime); PageCollection page new Page(query.getPageNum(), query.getPageSize()); PageCollection result collectionMapper.selectPage(page, wrapper); return new PageResult(result.getRecords(), result.getTotal()); }這里有個經(jīng)驗查詢條件對象和實體類分開定義不要直接用實體類接收前端參數(shù)。原因很簡單實體類字段會被MyBatis-Plus用于自動填充和邏輯刪除混用容易出問題而且在論文里你可以把“DTO與實體分離”作為接口設計的一項規(guī)范寫出來。第二個是圖片處理。藏品圖片的上傳建議上傳到服務器本地目錄數(shù)據(jù)庫里只存訪問路徑。這個方案對畢業(yè)設計來說夠用也不需要額外花錢開通云存儲。但要注意配置虛擬路徑映射否則圖片文件寫到了本地磁盤前端卻訪問不到。Configuration public class WebConfig implements WebMvcConfigurer { Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/upload/**) .addResourceHandler(file: uploadPath /); } }3.3 預約模塊整個系統(tǒng)最容易出錯的地方預約管理是博物館系統(tǒng)區(qū)別于普通CRUD系統(tǒng)的核心點也是答辯時老師最喜歡深挖的地方。預約這里有三層邏輯。第一層是預約創(chuàng)建的合法性校驗。用戶提交預約時后端不能只往表里插一條記錄要先校驗預約的展覽是否存在并處于“進行中”狀態(tài)預約日期是否在展覽舉辦時間范圍內(nèi)當前預約人數(shù)是否超過展廳人數(shù)上限。這些校驗邏輯全部通過才允許落庫。第二層是預約人數(shù)的控制。這里有兩種做法簡單做法是預約時只校驗單次預約人數(shù)不超過上限完整做法是統(tǒng)計該日期的累計預約人次與上限比較。做完整版的難度并不高一條SQL聚合查詢就搞定但避免超限的效果和論文里的說辭會漂亮很多。SELECT COALESCE(SUM(visit_count), 0) FROM reservation WHERE exhibition_id #{exhibitionId} AND visit_date #{visitDate} AND status CONFIRMED第三層是狀態(tài)流轉(zhuǎn)。預約狀態(tài)我建議設置為PENDING待確認、CONFIRMED已確認、CANCELLED已取消、COMPLETED已完成。最簡單的流轉(zhuǎn)是用戶在待確認狀態(tài)下可以取消管理員可以將待確認轉(zhuǎn)為已確認系統(tǒng)在預約日期過后可以定時或手動將已確認變更為已完成。這個狀態(tài)機寫清楚后后端代碼結(jié)構會清晰很多論文里也能畫一張狀態(tài)流轉(zhuǎn)圖。3.4 接口設計順序建議后端接口不要零散地亂寫我建議按依賴順序推進先寫登錄注冊因為沒有token就無法調(diào)試其他接口再寫用戶管理和公告這些表結(jié)構簡單能幫你把統(tǒng)一返回體和異常處理的代碼跑通接著寫藏品和展廳吃透分頁條件和實體類分離最后寫預約模塊因為它要依賴展覽和展廳的數(shù)據(jù)屬于業(yè)務集成層。每寫完一個模塊就用Postman或Apifox把接口跑一遍再往前推進。不要等全部寫完了再統(tǒng)調(diào)那時代碼里積累的錯誤會讓你調(diào)試到崩潰。4. Vue前端管理端與參觀端的頁面結(jié)構拆解4.1 后臺管理界面怎么組織導航與表格前端部分我建議使用Vue3加Element Plus這也是目前最主流的中后臺前端組合。管理端頁面結(jié)構通常是標準的左側(cè)菜單加右側(cè)內(nèi)容區(qū)左側(cè)菜單按照后端模塊一一對應首頁儀表盤、藏品管理、展廳管理、展覽管理、預約審核、用戶管理、公告管理。右側(cè)內(nèi)容區(qū)用Router來控制頁面切換每個模塊配一個獨立的視圖組件。注意菜單別做得太花哨Element Plus的el-menu組件能滿足需求而且這套結(jié)構在論文里的“前端架構設計”章節(jié)非常好寫。列表頁的設計有固定的套路頂部是篩選條件區(qū)域關鍵詞輸入框、下拉選擇、搜索重置按鈕中間是表格區(qū)域底部是分頁器。這個結(jié)構幾乎適用于所有管理模塊。format一下用el-table綁定數(shù)據(jù)用el-pagination綁定分頁參數(shù)。template div classcollection-page el-form :inlinetrue el-form-item label藏品名稱 el-input v-modelquery.name placeholder請輸入 clearable / /el-form-item el-form-item label朝代 el-select v-modelquery.dynasty clearable el-option label唐代 value唐代 / el-option label宋代 value宋代 / /el-select /el-form-item el-form-item el-button typeprimary clickhandleSearch搜索/el-button /el-form-item /el-form el-table :datatableData v-loadingloading !-- 列定義省略 -- /el-table el-pagination v-model:current-pagequery.pageNum v-model:page-sizequery.pageSize :totaltotal current-changefetchData / /div /template當你把第一個列表頁完整做出來后后面所有模塊的列表頁都是復制、改字段、調(diào)接口三個動作。這也是為什么我不建議一上來就搞復雜封裝先做一個標準的讓你理解套路。先做一套最樸素的頁面跑通之后再考慮封裝一個BaseTable組件。按照做中學的順序來對新手更友好。如果一開始就搞很多抽象組件很容易因為過度設計把自己繞暈。4.2 參觀端頁面觀眾視角的動線設計參觀端是面對普通用戶的頁面主要包括首頁展示、展覽列表、藏品瀏覽、預約提交、個人中心。首頁我建議簡單直接輪播圖展示重點展覽下面放最新公告和推薦展品。不要試圖塞太多東西信息層級越清晰越好。展覽列表頁展示所有正在進行的展覽點擊進入詳情頁在詳情頁預留“立即預約”按鈕。預約流程前端要設計得盡量少出岔子用戶選擇預約日期系統(tǒng)需要在頁面顯示該日期的剩余可預約情況。這個“剩余量”數(shù)據(jù)需要前端調(diào)一個接口去后端查詢。查詢到之后再讓用戶選擇參觀人數(shù)校驗不超過剩余限額最后提交預約。整個流程可以做成一個步驟條組件引導用戶一步步完成操作。個人中心要展示我提交的預約列表每條記錄顯示狀態(tài)。注意待確認狀態(tài)下的預約需要顯示“取消預約”按鈕已確認狀態(tài)的預約可以展示二維碼或者取票碼。哪怕這個取票碼只是系統(tǒng)自動生成的一串編號沒有真正的對接閘機它也能讓系統(tǒng)看起來有完整業(yè)務閉環(huán)。在論文里你可以寫“為已確認預約生成唯一預約憑證”功能描述上完全說得通。4.3 聯(lián)調(diào)時的關鍵約定API路徑、數(shù)據(jù)格式、Token注入前后端聯(lián)調(diào)是很多學生卡殼的地方其實大部分問題都出在沒有提前約定接口規(guī)范。我這里分享一個我慣用的約定體系。接口路徑統(tǒng)一以/api開頭比如/api/user/login、/api/collection/page。前端所有請求走axios實例baseURL指向這個前綴開發(fā)環(huán)境通過Vite的proxy把請求轉(zhuǎn)發(fā)到后端地址// vite.config.js export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })這個配置的原理是開發(fā)環(huán)境前端跑在5173端口后端跑在8080端口兩者不同源瀏覽器會攔截跨域請求。通過代理讓前端的請求先到達自己的5173端口再由Vite去請求后端從而繞過瀏覽器同源策略限制。axios請求攔截器統(tǒng)一注入token響應攔截器統(tǒng)一處理code不等于200的情況service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] Bearer ${token} } return config }) service.interceptors.response.use( response { const res response.data if (res.code ! 200) { ElMessage.error(res.message) return Promise.reject(new Error(res.message)) } return res }, error { ElMessage.error(網(wǎng)絡請求異常) return Promise.reject(error) } )這套約定跑通之后聯(lián)調(diào)基本不會出現(xiàn)“前端拿不到數(shù)據(jù)”“后端說前端沒傳參”這類互相甩鍋的局面。5. 畢業(yè)論文如何把系統(tǒng)實現(xiàn)寫成有邏輯的論文5.1 論文結(jié)構如何映射到系統(tǒng)模塊很多學生做完系統(tǒng)之后開始寫論文發(fā)現(xiàn)寫不出來或者寫出來像“系統(tǒng)說明書”原因是沒有建立“論文結(jié)構”和“系統(tǒng)結(jié)構”的對應關系。我建議按這個框架來走緒論這一章內(nèi)容包括研究的背景和意義博物館數(shù)字化管理的需求、國內(nèi)外研究現(xiàn)狀這里要寫文獻梳理不能只羅列網(wǎng)址、主要工作與論文組織結(jié)構。相關技術介紹這一章把SpringBoot、Vue、MyBatis-Plus、JWT、Element Plus各用一個小節(jié)來介紹。注意不要寫成百科詞條要寫“為什么在本次系統(tǒng)中選用這項技術”比如“選用MyBatis-Plus是為了借助其內(nèi)置分頁插件簡化數(shù)據(jù)訪問層的開發(fā)”之類。需求分析這一章從系統(tǒng)角色出發(fā)畫用例圖寫各角色的功能需求。非功能需求也要寫比如安全性密碼加密、Token鑒權、性能分頁查詢控制數(shù)據(jù)量、易用性前端操作流程清晰。系統(tǒng)設計這一章總體架構圖、功能模塊設計、數(shù)據(jù)庫設計ER圖和表結(jié)構說明表、接口設計列出主要接口的路徑、請求方式、參數(shù)、返回值。系統(tǒng)實現(xiàn)這一章分模塊描述每個功能的實現(xiàn)配合核心代碼片段和頁面截圖。系統(tǒng)測試這一章測試環(huán)境說明、功能測試用例表、測試結(jié)果分析。結(jié)論與展望這一章總結(jié)完成的工作指出不足和未來改進方向。5.2 摘要、需求分析、系統(tǒng)設計這三章的寫作技巧摘要別看它放在最前面通常是最后寫的。摘要是全文的微縮版核心邏輯是四句話系統(tǒng)解決什么問題系統(tǒng)采用什么技術系統(tǒng)實現(xiàn)了哪些功能模塊經(jīng)過測試達到什么效果。第一次不會寫可以先寫一個粗糙版本放那兒等正文全部完成之后回頭精煉。需求分析這一章的得分點在于用例圖和數(shù)據(jù)流描述。用例如能用UML工具畫出來最好畫不出來的話畫一個功能結(jié)構圖也比純文字強。功能需求描述要寫成“用戶能夠做什么”而不要寫“系統(tǒng)提供了什么按鈕”前者是需求語言后者是說明書語言。系統(tǒng)設計這一章注意兩點。一是數(shù)據(jù)庫設計不能只貼建表SQL要給字段說明表列名、類型、允許為空、說明一列列列清楚。二是接口設計建議給出一個接口清單表格把每個模塊的接口統(tǒng)一列出包括請求類型和功能簡述。這份表格不需要太細節(jié)但能直接證明你的系統(tǒng)設計是有規(guī)劃的。圖是論文中非常能提升觀感的部分。架構圖、ER圖、功能結(jié)構圖、預約流程圖建議多用圖說話。畫圖工具不必糾結(jié)能用清楚的就行。5.3 測試章節(jié)避免流水賬測試章節(jié)是學生最容易寫砸的地方。很多人寫“打開系統(tǒng)輸入用戶名密碼點擊登錄成功進入首頁”這種寫法既無技術含量也無法體現(xiàn)測試的嚴謹性。測試應當以用例為單位每個用例包含用例編號、測試名稱、前置條件、操作步驟、預期結(jié)果、實際結(jié)果、是否通過。比如預約功能可以設計這樣的用例前置條件是后臺已存在一個正在進行的展覽當前預約人數(shù)未滿上限操作是用戶選擇展覽、日期、填寫人數(shù)后提交預期結(jié)果是預約成功并生成待確認狀態(tài)的預約記錄。這個用例可以驗證并發(fā)的邏輯。測試結(jié)論不要只寫“全部通過”寫上缺陷修復的過程更能體現(xiàn)工作量。5.4 截圖素材的收集心得寫論文時你會需要大量系統(tǒng)截圖。建議在開發(fā)完成之后按照論文的章節(jié)順序統(tǒng)一把所有功能頁面截圖一遍歸檔到文件夾里。我見過一些學生代碼寫完了結(jié)果頁面上的測試數(shù)據(jù)亂糟糟截圖也臨時補效果慘不忍睹。提前準備一套排版整潔、數(shù)據(jù)合理的截圖數(shù)據(jù)會讓整個論文質(zhì)量上一個臺階。我在搭建演示環(huán)境時通常會在數(shù)據(jù)庫腳本里預置一批樣例數(shù)據(jù)包括幾個朝代分明的藏品、兩個狀態(tài)不同的展覽以及一條待審核的預約。演示和截圖都能直接展示出系統(tǒng)的多狀態(tài)效果。6. 搭建過程中的高頻坑位與排查思路6.1 前端代理跨域時報錯怎么查搭建時最常見的現(xiàn)象前端頁面能打開但請求接口就報錯。報錯信息通常是CORS相關或者404。排查路徑是分層的。第一步先用瀏覽器直接訪問后端接口地址比如直接打開http://localhost:8080/api/collection/page看能不能返回數(shù)據(jù)。如果后端本身報錯那是代碼問題如果后端正常而前端代理失敗那就是代理配置問題。第二步檢查前端proxy的target端口是不是后端實際端口。第三步檢查請求路徑是否被正確拼接比如代理配置的是/api前綴請求寫成了http://localhost:8080/api那就會被拼成http://localhost:8080/api/api自然404。記住一個原則前端請求不要寫完整后端地址寫相對路徑由代理或部署后的網(wǎng)關來轉(zhuǎn)發(fā)。6.2 登錄認證的死循環(huán)token過期與攔截器放行JWT相關的常見坑是登錄接口請求抵達后端時JWT攔截器先攔截了它發(fā)現(xiàn)沒有token返回“未登錄”錯誤前端跳轉(zhuǎn)登錄頁但這就是登錄頁形成死循環(huán)。解決方案是在攔截器配置里放行登錄接口、注冊接口和靜態(tài)資源。同時在前后端約定好凡是接口返回401狀態(tài)碼一律做清空token并跳轉(zhuǎn)登錄頁處理。這里我還要提示一個小細節(jié)響應攔截器里要先優(yōu)先處理401再處理code邏輯順序放反了也會出問題。6.3 MyBatis-Plus時間字段、邏輯刪除和事務的隱藏坑如果你用了MyBatis-Plus有幾個細節(jié)容易踩坑。第一個是時間字段的自動填充。創(chuàng)建時間、更新時間如果每次插入、更新都手動set會非常痛苦。用TableField(fill FieldFill.INSERT)配合MetaObjectHandler實現(xiàn)自動填充代碼會清爽很多。第二個是邏輯刪除。配置了TableLogic之后查詢語句會自動拼接deleted0條件這是好事。但如果你在同一張表里用了唯一約束邏輯刪除的用戶再注冊同一個用戶名會報唯一鍵沖突因為邏輯刪除并沒有物理刪除記錄。解決辦法通常是把唯一鍵改成包含deleted字段的聯(lián)合唯一索引或者注冊時先查詢包含已刪除的記錄。這個坑很少有人提前意識到但一旦踩到排查時間會很久。第三個是事務。預約創(chuàng)建時要查詢、校驗、插入三步如果其中一步失敗之前的操作也應該回滾。在方法上加上Transactional注解能在異常時自動回滾數(shù)據(jù)庫操作。這個注解的使用在論文測試章節(jié)也可以作為事務一致性驗證的一個點來寫。6.4 演示環(huán)境的數(shù)據(jù)初始化臨近答辯時你需要一個可以直接演示的環(huán)境。建議準備一個演示數(shù)據(jù)庫腳本里面包含可用的管理員賬號、測試用戶賬號、若干條規(guī)格完整的藏品數(shù)據(jù)、進行中和已結(jié)束的展覽各一個。開啟服務后打開前端登錄、瀏覽、預約、審核一路點下來不出錯。還要注意靜態(tài)資源的路徑問題。如果服務器換了操作系統(tǒng)上傳目錄的絕對路徑會失效盡量把上傳路徑做成可配置項寫在配置文件里。部署時只需改配置不需要改代碼。涉及文件上傳的演示環(huán)節(jié)最好在答辯前用同樣路徑試一次不然圖片顯示不出來的尷尬真會讓人撓頭。7. 寫在最后的實操體會如果讓我總結(jié)這套系統(tǒng)的搭建心得排第一位的是順序。先數(shù)據(jù)庫再后端再前端最后論文這個順序不是隨便定的每一步都是在為下一步鋪路。數(shù)據(jù)庫設計得不清楚后端代碼就混亂后端接口不定好前端聯(lián)調(diào)就返工系統(tǒng)功能不穩(wěn)定論文截圖就得一直重截。排第二位的是留痕。開發(fā)過程中每一步遇到的問題和解決方式建議記錄下來。畢業(yè)設計的論文里測試章節(jié)和總結(jié)章節(jié)非常需要這些素材。平時記錄的三言兩語寫論文時可能就是一段寶貴的內(nèi)容。排第三位的是控制欲望。別覺得功能越多越好。把核心模塊做扎實把異常情況處理好比掛一堆用不到的邊緣功能強得多。答辯時老師最看重的是你對系統(tǒng)的理解——為什么這么設計、遇到問題怎么排查、系統(tǒng)有哪些可優(yōu)化之處。這些理解只有自己一行行敲出來才能真正說得明白。最后分享一個小技巧在預置樣例數(shù)據(jù)時把藏品的朝代、材質(zhì)、來源、尺寸這些字段都填滿、填細致。一來頁面表格顯得專業(yè)二來論文截圖時不用手忙腳亂去補數(shù)據(jù)。細節(jié)上多花十分鐘現(xiàn)場演示觀感完全不同。祝每一個準備做這套系統(tǒng)的同學都能順利走完全程。