畢設(shè)全流程:從數(shù)據(jù)庫到部署聯(lián)調(diào))
很多做Java Web方向畢業(yè)設(shè)計(jì)的同學(xué)第一反應(yīng)都會糾結(jié)選題管理系統(tǒng)太沒亮點(diǎn)電商類又太龐大做的過程中很容易被各種業(yè)務(wù)細(xì)節(jié)拖垮。像“SpringBootVue web電影院購票系統(tǒng)平臺”這類項(xiàng)目正好卡在一個非常舒服的位置——業(yè)務(wù)復(fù)雜度適中、技術(shù)棧主流、前后端分離的流程能完整走通又能在答辯時講清楚自己的設(shè)計(jì)思路。這篇文章就結(jié)合我實(shí)際帶過學(xué)生做這套系統(tǒng)的經(jīng)驗(yàn)把從數(shù)據(jù)庫設(shè)計(jì)、后端接口、前端頁面到部署聯(lián)調(diào)的完整路徑梳理一遍同時也把源碼里最容易踩的坑提前指出來。如果你手上正好有這個項(xiàng)目的源碼、SQL腳本和接口文檔但還是不知道怎么串起來用或者想順利跑通之后往里面加一點(diǎn)自己的功能這篇文章應(yīng)該能幫你省下不少折騰時間。1. 項(xiàng)目定位與整體設(shè)計(jì)1.1 畢業(yè)設(shè)計(jì)選題的核心思路電影院購票系統(tǒng)能成為Java Web畢設(shè)里的常青樹不是因?yàn)槊致犉饋頍狒[而是它的業(yè)務(wù)模型覆蓋了教學(xué)大綱里幾乎所有要求掌握的知識點(diǎn)。先看用戶端涉及注冊登錄、電影列表瀏覽、場次排片展示、選座、下單購票、訂單查詢再到后臺的影片管理、場次管理、訂單統(tǒng)計(jì)。這一條線下來增刪改查、事務(wù)處理、狀態(tài)流轉(zhuǎn)、權(quán)限控制全都有對應(yīng)的落點(diǎn)不是那種為了湊頁面而硬寫的功能。和純管理系統(tǒng)相比它多了一個“票務(wù)”的業(yè)務(wù)約束比如同一個座位不能重復(fù)被賣出、場次開始后不能退票、會員購買有折扣價這些規(guī)則湊在一起代碼量適中但邏輯層次比CRUD豐富得多在答辯時可以展開講業(yè)務(wù)建模的思路。另外從視覺呈現(xiàn)上說電影院系統(tǒng)天生帶一點(diǎn)“逼格”。電影海報、場次時間軸、座位圖這種元素比管理系統(tǒng)里那種干巴巴的表格更容易把前端做得像樣對UI基礎(chǔ)薄弱的同學(xué)來說反而友好因?yàn)楹每吹捻撁婺茏龀霾实珜?shí)現(xiàn)難度并不高。1.2 技術(shù)選型的取舍邏輯SpringBoot加Vue這套組合基本是當(dāng)前Java Web畢設(shè)的默認(rèn)配置選它最大的原因在于分工清晰、生態(tài)成熟。后端用SpringBoot主要看中它簡化配置的能力。傳統(tǒng)Servlet加SSH那套光是XML配置文件就能勸退一批人SpringBoot用自動裝配把大多數(shù)樣板配置吃掉了你只需要專注寫Controller、Service、Mapper三層。配合MyBatis或MyBatis-Plus操作數(shù)據(jù)庫SQL可控性好對于需要定制查詢的報表類功能也靈活。Maven管理依賴打包成jar直接能跑部署環(huán)節(jié)簡單。前端Vue則是組件化開發(fā)的代表。頁面拆成組件后復(fù)用性很高比如電影卡片組件在首頁、搜索結(jié)果頁、后臺列表頁都能用。配合Vue Router做頁面路由Axios做HTTP請求狀態(tài)管理在購票流程里用不上復(fù)雜的Vuex場景純展示加簡單的狀態(tài)傳遞就夠了學(xué)習(xí)成本可控。UI庫用Element UI或Element Plus頁面整體風(fēng)格統(tǒng)一表格、表單、彈窗這些組件開箱即用效率是非常高的。前后端分離帶來的好處是調(diào)試方便。開發(fā)階段起一個Vue的devServer代理到后端接口改前端代碼熱更新秒級生效不用像JSP時代一樣反復(fù)重啟Tomcat。接口聯(lián)調(diào)是以后工作中必然要面對的場景通過這個項(xiàng)目把RESTful接口規(guī)范、跨域處理、聯(lián)調(diào)工具的使用都練一遍本身就是很實(shí)際的經(jīng)驗(yàn)積累。有一點(diǎn)要提醒這套系統(tǒng)的核心價值不在于技術(shù)有多么前沿而在于它讓一個學(xué)習(xí)者完整走過了“數(shù)據(jù)庫設(shè)計(jì) → 接口設(shè)計(jì) → 前端實(shí)現(xiàn) → 聯(lián)調(diào)測試”的全流程。答辯的時候能把這套方法論講清楚就是最大的得分點(diǎn)。2. 數(shù)據(jù)庫設(shè)計(jì)與SQL腳本詳解2.1 核心表結(jié)構(gòu)與ER設(shè)計(jì)拿到SQL腳本之后第一步不是急著運(yùn)行而是先打開文本看表結(jié)構(gòu)把數(shù)據(jù)表之間的關(guān)系在腦子里過一遍。電影院購票系統(tǒng)的表不算多但表間關(guān)系是典型的“一對多”鏈?zhǔn)浇Y(jié)構(gòu)常見核心表大概有這幾張表名職責(zé)關(guān)鍵字段用戶表注冊登錄用戶信息id, username, password, nickname, phone, member_level電影表影片基礎(chǔ)信息和海報id, title, cover, duration, director, actors, description, status場次表某部電影在某時間某影廳的排片id, movie_id, hall_name, start_time, end_time, price, stock訂單表用戶購票生成的訂單id, order_no, user_id, session_id, total_price, status, create_time訂單明細(xì)表訂單對應(yīng)的具體座位id, order_id, session_id, seat_row, seat_col, price這五張表基本就是系統(tǒng)的骨架。用戶表和電影表之間通過訂單表產(chǎn)生關(guān)聯(lián)場次表掛在電影表下面訂單表同時關(guān)聯(lián)用戶表和場次表明細(xì)表則記錄每個座位的落點(diǎn)??茨_本的時候重點(diǎn)關(guān)注外鍵和索引。比如場次表的movie_id字段一般會建一個普通索引因?yàn)榍岸肆斜眄撔枰措娪安樵儓龃胃哳l查詢字段必須有索引支持。訂單表在畢設(shè)級項(xiàng)目里數(shù)據(jù)量不算大但order_no這種業(yè)務(wù)唯一標(biāo)識建議建唯一索引避免重復(fù)訂單號。2.2 字段設(shè)計(jì)與關(guān)鍵約束有經(jīng)驗(yàn)的老師評審數(shù)據(jù)庫設(shè)計(jì)時不會只看ER圖畫得對不對還會關(guān)注一些細(xì)節(jié)一是訂單狀態(tài)的設(shè)計(jì)。不要用字符串直接存放建議用int類型約定比如0表示待支付1表示已支付2表示已取消3表示已退票。這樣在統(tǒng)計(jì)和篩選時只要一條where語句就能搞定代碼里的狀態(tài)流轉(zhuǎn)也清楚。SQL腳本里一般會帶注釋說明每個枚舉值含義導(dǎo)入數(shù)據(jù)庫后用Navicat或DataGrip把注釋內(nèi)容整理到自己的文檔里寫設(shè)計(jì)說明書時直接能用。二是座位關(guān)聯(lián)方式的取舍。有的設(shè)計(jì)把座位存成字段直接放在場次表里做成“5排8座”這種字符串這種方式簡則簡矣但做鎖定座位的時候非常痛苦因?yàn)橐鹱址ケ葘?。?guī)范一點(diǎn)的方案是給場次建立一個“可用座位”的標(biāo)記機(jī)制下單時落一張訂單明細(xì)表明細(xì)里的座位就是已占用的座位查詢可售座位時用笛卡爾積排除明細(xì)里已有的行和列。這樣數(shù)據(jù)庫層面的邏輯非常干凈也不存在并發(fā)寫同一個字符串的問題。三是金額字段類型選擇。價格雖然只有小數(shù)點(diǎn)后一位或兩位仍然建議用decimal(10,2)不要用float或double。浮點(diǎn)數(shù)在電商、金融、票務(wù)這類涉及錢的計(jì)算中會累積精度誤差出現(xiàn)1.9999999這種值對賬的時候非常頭疼。項(xiàng)目里折扣計(jì)算、訂單總額統(tǒng)計(jì)都以分為最小單位的整數(shù)運(yùn)算是另一套思路但畢設(shè)里直接存decimal配合BigDecimal做運(yùn)算就是穩(wěn)妥方案。2.3 SQL腳本使用注意事項(xiàng)把腳本導(dǎo)入數(shù)據(jù)庫的時候有幾句提醒導(dǎo)入之前手工建一個專門的數(shù)據(jù)庫比如db_cinema設(shè)置utf8mb4編碼。有的同學(xué)直接拿腳本默認(rèn)的庫名和本地其他項(xiàng)目的庫沖突或者編碼沒配對導(dǎo)致中文亂碼這些屬于完全沒必要浪費(fèi)的時間。MySQL的版本差異也要注意。腳本如果是5.7寫的默認(rèn)排序規(guī)則是utf8mb4_general_ci8.0默認(rèn)也不會有大問題但有一類腳本里寫的是utf8mb4_0900_ai_ci導(dǎo)入到5.7就會出現(xiàn)字符集排序錯誤。只要在建立數(shù)據(jù)庫時顯式指定編碼這些版本差異基本都能規(guī)避。另外SQL腳本中通常會有一段初始化數(shù)據(jù)包括幾部測試電影、幾個場次、以及一個管理員賬號。千萬別把這些測試數(shù)據(jù)刪了再啟動項(xiàng)目因?yàn)榍岸隧撁嫠姓故径家蕾囘@些數(shù)據(jù)。運(yùn)行起來看到電影列表是空的第一反應(yīng)應(yīng)該是去數(shù)據(jù)庫檢查初始化數(shù)據(jù)是否成功而不是改代碼。注意在導(dǎo)入SQL腳本前建議給數(shù)據(jù)庫做一次完整備份。萬一在聯(lián)調(diào)測試時誤刪了數(shù)據(jù)或改了表結(jié)構(gòu)恢復(fù)腳本一鍵救回比手動補(bǔ)數(shù)據(jù)高效得多。3. 后端接口設(shè)計(jì)與實(shí)現(xiàn)3.1 接口規(guī)范與統(tǒng)一返回格式接口文檔里通常會把所有接口列出來并標(biāo)注請求方式、請求參數(shù)、返回參數(shù)。一個值得學(xué)習(xí)的地方是統(tǒng)一返回格式的設(shè)計(jì)。大部分正規(guī)項(xiàng)目會定義一個全局響應(yīng)類比如Result 包含code、message、data三個字段。前端拿到響應(yīng)后先判斷code如果等于200就是成功否則在頁面上提示message。這個規(guī)范看起來簡單但很多人寫畢設(shè)時還是各自為政有的接口直接返回業(yè)務(wù)對象有的返回Map有的成功時把數(shù)據(jù)塞進(jìn)data里失敗時把error堆在data里前端聯(lián)調(diào)時面對各種形狀的響應(yīng)體只能到處寫if判斷。統(tǒng)一返回格式的核心價值就在于此——把接口語義收斂到固定結(jié)構(gòu)里任何異常情況都能在入口處攔截并封裝好。接口文檔里一般還會包含一個全局異常處理器。比如查詢一個不存在的場次后端不應(yīng)該直接返回null而應(yīng)該拋一個業(yè)務(wù)異常然后由全局異常處理器轉(zhuǎn)換為統(tǒng)一格式的響應(yīng)。這樣前端拿到code為404或500的響應(yīng)可以直接在攔截器里做統(tǒng)一提示業(yè)務(wù)代碼里不用挨個try catch。3.2 核心接口邏輯拆解后端代碼量大頭在Controller和Service層但真正能體現(xiàn)水平的是Service層的業(yè)務(wù)邏輯。手把手拆幾個核心接口一、用戶登錄接口。這里的邏輯不是簡單的查一下用戶名密碼就完事。密碼正常情況應(yīng)該加鹽之后用BCrypt或MD5鹽去加密存儲表里的password字段存的是密文而不是明文。登錄成功后后端生成一個Token返回給前端前端存在sessionStorage里后續(xù)請求帶上Token做身份標(biāo)識配合Spring Security或攔截器做校驗(yàn)。有的項(xiàng)目用了JWT那是加分項(xiàng)答辯時能講清楚JWT的構(gòu)造和解碼過程很容易引導(dǎo)老師去問安全問題準(zhǔn)備充分了反而是展示亮點(diǎn)。二、電影列表接口。這個接口看似只是select *但實(shí)際上要考慮分頁、條件篩選、排序。比如你希望首頁既支持按熱門程度排序也支持按時長篩選后端接口就需要支持pageNum、pageSize、keyword、category這些可選參數(shù)。用MyBatis-Plus的分頁插件一條Page對象接Param寫起來干凈利落。三、選座與鎖定狀態(tài)。這是整個系統(tǒng)里最有業(yè)務(wù)含金量的接口之一。實(shí)際開發(fā)時不是前端點(diǎn)一下“選座”就結(jié)束了而是前端拿到場次ID后端實(shí)時計(jì)算哪些座位已售、哪些可售。查詢時用“總座位-已售座位”得到可用座位集合返回給前端一個二維數(shù)組或者座位狀態(tài)列表。前端根據(jù)后端返回的結(jié)果渲染座位圖已經(jīng)售出的座位置灰不可點(diǎn)擊。四、下單購票接口。這里必須把“扣庫存”和“生成訂單”放到一個事務(wù)里。選一個競態(tài)條件最典型的場景說明兩個用戶同時搶最后一個座位如果代碼是先查詢再插入兩人同時查詢都能看到座位可售同時插入時數(shù)據(jù)庫沒有唯一約束限制就會出現(xiàn)超賣。解決辦法有兩種直接在座位的明細(xì)表上建唯一索引session_id seat_row seat_col組合唯一或者在下單前用樂觀鎖、SELECT FOR UPDATE鎖住場次行。對畢設(shè)來說把精細(xì)處理的方案選一種能講明白為什么需要事務(wù)和鎖水平評級立刻不一樣。3.3 接口文檔的編寫與維護(hù)很多人有一個誤區(qū)覺得接口文檔是參考資料不是項(xiàng)目的一部分寫完代碼再補(bǔ)就行。我建議如果你還沒交文檔從項(xiàng)目中后期開始就同步維護(hù)用Apifox或Swagger都能做到。用Swagger注解每個接口標(biāo)注說明、參數(shù)含義、響應(yīng)示例啟動項(xiàng)目后訪問/swagger-ui.html就能看到可視化的接口列表答辯現(xiàn)場演示一下接口自測很有說服力。Apifox則更偏向團(tuán)隊(duì)協(xié)作先設(shè)計(jì)接口再生成代碼骨架對于從零開始寫這個項(xiàng)目的同學(xué)也會很有幫助。文檔里除了接口說明建議還要有環(huán)境說明和部署步驟。比如JDK版本要求、Node版本要求、MySQL版本要求這些信息自己在實(shí)戰(zhàn)中碰到問題時都是一步步踩出來、驗(yàn)證出來的寫進(jìn)文檔里對閱讀者更友好也體現(xiàn)你的工程素養(yǎng)。4. 前端頁面與交互實(shí)現(xiàn)4.1 Vue項(xiàng)目結(jié)構(gòu)與路由設(shè)計(jì)拿到前端源碼之后第一步應(yīng)該是看目錄結(jié)構(gòu)。一個清晰的前端工程通常會把視圖、組件、路由、請求封裝分開放置比如src下常見的有views、components、router、api幾個目錄。views目錄下是頁面級組件一個頁面一個文件夾比如Home、FilmDetail、Order、Login、Admin。components目錄是復(fù)用組件比如電影卡片F(xiàn)ilmCard、分頁組件Pagination、座位圖SeatMap。router目錄是路由配置文件把URL路徑和頁面組件關(guān)聯(lián)起來。路由設(shè)計(jì)上要注意是否需要路由守衛(wèi)。項(xiàng)目里常有一種情況未登錄用戶點(diǎn)了去購票被強(qiáng)制跳轉(zhuǎn)到登錄頁已登錄用戶訪問后臺管理頁如果不是管理員則被攔截。這些邏輯用Vue Router的前置守衛(wèi)就能實(shí)現(xiàn)在router.beforeEach鉤子函數(shù)中判斷用戶身份和權(quán)限比對要訪問的路由meta信息決定是放行還是重定向。這個機(jī)制理解透了在你后續(xù)做任何帶權(quán)限的角色系統(tǒng)時都能用上。4.2 核心頁面功能實(shí)現(xiàn)首頁邏輯相對簡單重點(diǎn)是列表數(shù)據(jù)的加載與展示。頁面用axios請求電影列表接口把返回?cái)?shù)據(jù)存到data屬性渲染時通過電影卡片組件展示海報和標(biāo)簽信息。如果接口分頁需要用一個加載更多或者分頁欄。這里可以加loading動畫、骨架屏效果做成交互體驗(yàn)好一點(diǎn)的小細(xì)節(jié)。選座頁面是整個前端的核心。拿到場次信息后根據(jù)后端返回的座位狀態(tài)矩陣把座位圖渲染出來可用座位用綠色、已選座位用橙色、已售座位用灰色。點(diǎn)擊可售座位時將座位置入已選列表底部實(shí)時顯示總價。提交訂單后跳轉(zhuǎn)到訂單確認(rèn)頁或支付頁。這個流程看似簡單但做的時候需要處理用戶中途點(diǎn)擊退出、重新選座的場景要把已選座位恢復(fù)為可售狀態(tài)并清除數(shù)據(jù)和本地緩存。后臺管理頁面主要包括影片管理、場次管理、訂單管理。這部分一般借助Element的表格組件配合表單彈窗做增刪改。關(guān)鍵點(diǎn)在于先摸清楚增刪改對應(yīng)的接口和數(shù)據(jù)字段開發(fā)展示的時候不出錯比較重要。4.3 前后端聯(lián)調(diào)與跨域處理聯(lián)調(diào)階段遇到最多的就是跨域問題。前端運(yùn)行在localhost:8081后端在localhost:8080瀏覽器的同源策略會攔截跨域請求。解決方式通常有兩種第一種是后端起一個CORS過濾器在響應(yīng)頭里加上Access-Control-Allow-Origin*簡單粗暴前端不用做任何特殊處理。第二種是前端利用devServer的proxy代理在vue.config.js里配置/api前綴的請求都轉(zhuǎn)發(fā)到localhost:8080Nginx部署時也用類似的proxy_pass配置。開發(fā)階段更建議用devServer代理的方式因?yàn)樯暇€后也可以直接用Nginx把前后端通過同一個域名暴露出去避免暴露后端端口的另一層含義。生產(chǎn)上把后端直接暴露公網(wǎng)會被掃描到各種安全漏洞從這層意義上來講即使畢設(shè)項(xiàng)目提前掌握正確的部署方式也很有價值。聯(lián)調(diào)時還有一類問題是請求參數(shù)和響應(yīng)結(jié)構(gòu)的匹配。前端要求接口返回list字段后端返回的是rows前端傳的是date字符串后端期望的格式是時間戳。這種問題只能靠接口文檔約束來避免。遇到504、401、400這類錯誤優(yōu)先去瀏覽器F12看網(wǎng)絡(luò)請求的響應(yīng)體基本都在里面這是排查聯(lián)調(diào)問題的第一選擇。5. 部署運(yùn)行與實(shí)操記錄5.1 本地環(huán)境準(zhǔn)備先確認(rèn)環(huán)境這是跑通項(xiàng)目的第一步。后端需要JDK 1.8或以上、Maven 3.6、MySQL 5.7或8.0。前端需要Node.js 14以上的版本npm或pnpm任意一個包管理器都可以。推薦用IDEA開發(fā)后端、VS Code或WebStorm開發(fā)前端如果機(jī)器內(nèi)存富裕兩個IDE同時開沒有問題。然后按順序來看先把SQL腳本導(dǎo)入數(shù)據(jù)庫用Navicat或命令行工具執(zhí)行再用IDEA導(dǎo)入后端的Maven項(xiàng)目等待依賴下載完成接著修改數(shù)據(jù)庫連接配置一般是application.yml里的數(shù)據(jù)庫地址、用戶名、密碼注意改成你自己本機(jī)的配置最后在VS Code里打開前端項(xiàng)目npm install安裝依賴。三步做完環(huán)境就位。npm install經(jīng)常是卡住的重災(zāi)區(qū)如果你在國內(nèi)的鏡像源下不動把npm的registry切換到國內(nèi)鏡像站比如執(zhí)行npm config set registry https://registry.npmmirror.com速度會明顯改善。5.2 從零啟動完整項(xiàng)目跑通整個項(xiàng)目的步驟其實(shí)非常規(guī)律我先以常規(guī)方式走一遍先啟動后端。在IDEA里找到啟動類即標(biāo)注了SpringBootApplication的類直接右鍵運(yùn)行。看到控制臺輸出Spring Boot的啟動日志和Tomcat started on port(s): 8080就表示成功。如果端口被占用在application.yml里改端口即可但前提是先把之前占用的進(jìn)程殺掉Windows上可以用netstat -ano找PID再結(jié)束進(jìn)程。這里要注意你改動端口之后前端的代理配置也要同步改否則聯(lián)調(diào)時依然請求不到數(shù)據(jù)。再啟動前端。在終端進(jìn)入前端項(xiàng)目目錄執(zhí)行npm run serve命令默認(rèn)端口一般是8081??吹紺ompiled successfully就可以訪問http://localhost:8081打開首頁。用賬號登錄測試。普通用戶登錄會進(jìn)入正常的購票流程頁面。管理員登錄會進(jìn)入后臺管理頁面可以對電影、場次等數(shù)據(jù)進(jìn)行增刪改查。測試完記得看看控制臺有沒有報錯有問題及時解決別帶著錯誤狀態(tài)交文檔。啟動步驟本身不難但很多人第一次跑時會在配置上出問題其中最典型的就是數(shù)據(jù)庫密碼不對、端口沖突、前端包沒裝完、admin賬號密碼找錯。我建議按順序排查先看后端啟動日志再看前端頁面請求返回看具體是404、500還是其他錯誤。5.3 演示數(shù)據(jù)與測試用例答辯或演示的時候準(zhǔn)備好測試用例是很有必要的。我會在演示前規(guī)劃好這樣幾條路徑第一條是正常購票路徑用戶注冊登錄、瀏覽電影、選場次、選座位、下單、支付成功、查看訂單。這條路走下來功能完整。第二條是異常購票路徑比如座位已被別人購買前端立即置灰不可點(diǎn)擊或者余額不足下單失敗并顯示提示。第三條是管理員路徑新增影片、新增場次、查看訂單列表、對某個訂單做退款操作。這幾條路徑走完基本能把系統(tǒng)的核心功能全覆蓋。測試的時候要注意清理測試產(chǎn)生的臟數(shù)據(jù)不然在管理員訂單列表里留一堆半成品狀態(tài)看起來不夠整潔老師看到會很減分。建議用新的用戶賬號跑測試結(jié)束后在數(shù)據(jù)庫里把測試訂單清理掉。6. 常見問題與排查技巧實(shí)錄6.1 環(huán)境與依賴問題問npm install裝半天還是失敗怎么辦最常見的是網(wǎng)絡(luò)問題和Node版本問題。網(wǎng)絡(luò)問題用鏡像源解決版本問題則要看控制臺的報錯如果提示ERR_OSSL_EVP_UNSUPPORTED說明舊項(xiàng)目用了較新版本的工具鏈而你本機(jī)的Node版本過新比如17以上很多原生模塊編譯不過解決方案是換用項(xiàng)目配套的Node LTS版本。問后端啟動時MySQL連接超時先看數(shù)據(jù)庫服務(wù)有沒有啟動再看連接配置的用戶名密碼是否正確最后檢查IP是不是localhost。有個小坑是localhost默認(rèn)解析成IPv6的::1而MySQL服務(wù)只監(jiān)聽了IPv4這時把localhost改成127.0.0.1就好。6.2 數(shù)據(jù)庫與數(shù)據(jù)問題問導(dǎo)入SQL腳本報錯提示語法錯誤大概率是MySQL版本差異導(dǎo)致。5.7的腳本有時會用utf8mb4_0900_ai_ci或者_(dá)_current_timestamp(6)這種高級功能低版本不兼容。要么在8.0環(huán)境中跑要么手動替換有問題的字段類型看清報錯行做對應(yīng)修改。問前端頁面顯示電影列表是空的但數(shù)據(jù)庫有數(shù)據(jù)先確認(rèn)前端訪問的后端接口地址正確再看接口返回結(jié)構(gòu)是否和前端約定一致。如果接口返回了數(shù)據(jù)但頁面沒渲染優(yōu)先看瀏覽器控制臺的報錯字段名對不上會是undefined字段類型不一致可能渲染為NaN。6.3 業(yè)務(wù)邏輯細(xì)節(jié)問題問選座時兩個用戶同時選同一個座位怎么處理前端層面解決不了并發(fā)問題必須靠后端約束。如果訂單明細(xì)表上已經(jīng)有了唯一索引插入時會被數(shù)據(jù)庫攔截為Duplicate entry此時后端統(tǒng)一捕獲這個異常并返回“座位已被購買”前端刷新座位圖即可。如果沒有索引就先改表加上組合唯一約束再談其他。問訂單支付狀態(tài)沒有變化確認(rèn)后端的支付接口是否真實(shí)調(diào)用了第三方支付模擬還是僅做了偽支付。畢設(shè)項(xiàng)目往往只是本地模擬支付即點(diǎn)擊“支付成功后”直接把訂單從待支付改成已支付。如果你的項(xiàng)目里實(shí)現(xiàn)了微信或支付寶沙箱支付那在答辯中是絕對的亮點(diǎn)一定要多準(zhǔn)備些細(xì)節(jié)比如回調(diào)邏輯、簽名校驗(yàn)流程。寫在最后的實(shí)操心得我在帶學(xué)生跑這套項(xiàng)目的時候最深的一個感觸是源碼和SQL腳本本身只是起點(diǎn)真正的成長在于“跑通之后的二次加工”。你完全可以動手把某個模塊改一改比如把訂單狀態(tài)機(jī)從簡單的兩三個狀態(tài)升級為完整的待支付、已支付、已出票、已檢票、已退票流轉(zhuǎn)也可以給電影列表加上按類型篩選的標(biāo)簽或者把后臺的數(shù)據(jù)報表用圖表展示成折線圖、柱狀圖。每加一個小功能都要走一遍數(shù)據(jù)庫設(shè)計(jì)、接口設(shè)計(jì)、前端聯(lián)調(diào)的全流程這才是畢設(shè)帶給你最核心的訓(xùn)練價值。這系統(tǒng)后期如果還想擴(kuò)展實(shí)用性最強(qiáng)的方向是接真實(shí)或模擬的第三方支付以及加入管理員對影廳座位數(shù)量的可配置管理改成可配置化的座位圖影廳分為大中小三種規(guī)格。另外多終端適配把移動端H5做出來也是一個在展示時非常實(shí)用的加分項(xiàng)。做這步擴(kuò)產(chǎn)之前注意先評估現(xiàn)有表結(jié)構(gòu)的擴(kuò)展性。最后跑項(xiàng)目和寫論文不要分開進(jìn)行。項(xiàng)目做早了報告里很多細(xì)節(jié)忘干凈項(xiàng)目做晚了時間來不及沖刺。我的習(xí)慣是先寫出報告大綱把數(shù)據(jù)庫設(shè)計(jì)、接口列表、技術(shù)棧說明這些框架填好再在開發(fā)過程中持續(xù)補(bǔ)充實(shí)際截圖和測試記錄。這樣答辯PPT做起來也有素材驗(yàn)收時老師問什么你都有內(nèi)容可以講不會臨場卡殼。