畢設方案:SpringBoot+Vue+MySQL全棧實現(xiàn))
簡介基于JAVASpringBootVueMySQL開發(fā)的日常辦公用品直售系統(tǒng)畢業(yè)設計面向計算機專業(yè)學生可用于畢業(yè)設計、課程設計或期末大作業(yè)項目經(jīng)導師指導并通過高分前后端代碼齊備涵蓋商品展示、購物車、訂單處理、用戶管理、支付結算等模塊界面簡潔、操作直觀、后臺管理便捷。資源包共597個文件、16.1MB包括139個Java后端源碼、96個Vue前端頁面、SQL數(shù)據(jù)庫腳本、部署配置及開發(fā)工具說明目錄清晰便于二次開發(fā)部署環(huán)境為IDEA、Maven、MySQL5.7以上及Navicat。項目經(jīng)嚴格調(diào)試確保可穩(wěn)定運行已有39人學習下載適合需要可直接運行的高分畢設源碼或希望參考前后端分離商城系統(tǒng)開發(fā)流程的讀者。1. 日常辦公用品直售系統(tǒng)從畢設選題到可交付運行的完整方案做過辦公用品采購的人都知道真正麻煩的從來不是下單而是線下比價、詢價、匯總、報銷這一連串動作。一套基于 JAVA SpringBoot Vue MySQL 的日常辦公用品直售系統(tǒng)想解決的就是這件事把商品展示、購物車、訂單、支付結算和管理后臺裝進一個完整流程里讓學生能拿它交畢設也能讓中小團隊直接改成日常采購工具。這個項目適合兩類人一是正在做畢業(yè)設計或課程設計、需要一套完整且能講清楚原理的系統(tǒng)來參考的同學二是想快速搭一個直售類業(yè)務后臺、驗證運營流程的從業(yè)者。下文按需求分析、總體設計、核心實現(xiàn)、避坑排查、驗收答辯的順序拆開講。2. 需求分析與技術選型核心場景、功能邊界與 SpringBootVueMySQL 的組合理由2.1 辦公用品直售的真實業(yè)務場景與功能需求清單辦公用品直售系統(tǒng)和普通電商系統(tǒng)在功能上有重疊但它有自己的特殊性。普通電商商品種類繁多、促銷規(guī)則復雜、用戶體量大辦公用品直售的典型場景是行政人員或普通員工購買打印紙、簽字筆、文件夾這類固定品類采購頻次高、單筆金額小、商品標準化程度高所以系統(tǒng)不需要海量促銷引擎反而要把“商品管理、庫存狀態(tài)、訂單流轉、用戶權限”四條線做扎實。按照這個場景推算系統(tǒng)至少需要兩個視角用戶端和管理端。用戶端要完成注冊登錄、瀏覽商品、按分類篩選、加入購物車、修改數(shù)量、生成訂單、支付結算、查看個人訂單管理端要完成商品上下架、分類維護、庫存調(diào)整、訂單狀態(tài)管理、用戶賬戶管理。兩邊加起來就是這個系統(tǒng)的功能全貌也是畢設答辯時展示業(yè)務閉環(huán)的主線。隱藏在產(chǎn)品背后的還有幾個容易被忽略的需求。庫存扣減要在下單時鎖定而不是支付時才扣避免超賣訂單狀態(tài)要能在待支付、已支付、已發(fā)貨、已完成之間流轉并留痕不同角色的接口要有訪問控制不能讓普通用戶調(diào)用管理接口。這些需求都來自辦公用品采購的日常操作邏輯不算額外加戲但恰恰是評審老師喜歡追問的點。2.2 技術選型為什么是 SpringBoot 而不是 SSH為什么前端選 VueSpringBoot 在這套方案里的作用是“把后端工程的復雜度壓到最低”。它內(nèi)嵌了 Tomcat用 java -jar 能直接起服務不需要單獨裝容器自動配置機制免掉了一大堆 XML 配置開發(fā)者只需要在 application.yml 里寫數(shù)據(jù)源和端口配合 Maven 做依賴管理項目結構一眼就能看明白。對畢設來說SpringBoot 的 MVC 分層和注解風格能清楚地展示 Controller、Service、Mapper 的調(diào)用鏈評卷老師容易從代碼里讀出設計意圖。Vue 的作用是讓前端頁面具備組件化開發(fā)的能力。商品列表、購物車、訂單頁拆成獨立組件后數(shù)據(jù)流用 Vuex 或組件 props 傳遞頁面刷新時只有局部數(shù)據(jù)更新而不是整頁跳轉。這個系統(tǒng)不用引入重型狀態(tài)管理庫也能跑因為業(yè)務狀態(tài)集中在下單流程上購物車的數(shù)據(jù)結構足夠簡單。Vue 生態(tài)里最實用的部分是 axios 請求封裝和 Element UI 這類組件庫表格、表單、彈窗都是現(xiàn)成的開發(fā)效率比手寫 DOM 高一個量級。MySQL 在這里負責所有業(yè)務數(shù)據(jù)的持久化支撐商品、分類、購物車、訂單、用戶五類核心數(shù)據(jù)。直售業(yè)務的數(shù)據(jù)量不大單庫單表即可MySQL 5.7 以上版本在事務支持和 UTF-8 字符集方面沒有坑navicat 可視化工具也能快速完成建庫、導數(shù)據(jù)和排查。開發(fā)環(huán)境用 IDEA 寫代碼、Maven 管依賴、navicat 管數(shù)據(jù)庫這套工具鏈是當前學生和工作團隊里最常見的組合出了問題網(wǎng)上案例多好排查。3. 總體架構與數(shù)據(jù)庫設計三層鏈路、三類角色與核心表的字段規(guī)劃3.1 前后端分離架構下一次完整請求的流轉鏈路系統(tǒng)采用前后端分離架構前端 Vue 工程和后端 SpringBoot 工程獨立部署通過 HTTP 接口通信。一次商品查詢請求的鏈路是這樣的用戶瀏覽器打開商品列表頁Vue 組件在 created 生命周期里調(diào)用封裝好的 axios 方法向后端 Controller 發(fā)送 GET 請求Controller 解析參數(shù)后調(diào)用 Service 層業(yè)務方法Service 層通過 Mapper 接口操作 MySQL 數(shù)據(jù)庫查詢結果一層層返回最后在頁面渲染成商品卡片。整個鏈路里需要關注的三個角色是普通用戶、管理員和系統(tǒng)本身。普通用戶通過前端登錄頁獲取 Token后續(xù)請求帶上 Token 訪問自己的購物車和訂單數(shù)據(jù)管理員用戶擁有額外的商品管理和訂單管理接口權限系統(tǒng)本身通過 Spring Security 或攔截器校驗接口訪問權限。前端根據(jù)角色動態(tài)渲染菜單后端對每個接口標注訪問權限兩層約束保證管理接口不會暴露給普通用戶。3.2 功能模塊劃分五塊核心業(yè)務與后臺管理的邊界從模塊角度看系統(tǒng)可以分成五塊核心業(yè)務用戶模塊、商品模塊、購物車模塊、訂單模塊、支付模塊。用戶模塊負責注冊、登錄、個人信息維護商品模塊負責分類、列表、詳情、上下架購物車模塊負責加購、改數(shù)量、刪條目訂單模塊負責生成訂單、訂單狀態(tài)流轉支付模塊負責結算和支付回調(diào)處理。五塊業(yè)務在前端對應五個功能頁面在后端對應五組 Controller 和 Service形成清晰的對應關系。后臺管理模塊與用戶端模塊共用底層數(shù)據(jù)庫表但在接口層進行了邊界劃分。管理員操作商品分類、庫存和訂單發(fā)貨狀態(tài)的接口放在 /admin 路徑下前置攔截器校驗管理員身份普通用戶即使知道接口地址也無法訪問。這個設計既保證了前后端兼顧又體現(xiàn)了權限控制的思路是方案里比較出彩的地方。3.3 數(shù)據(jù)庫設計六張核心業(yè)務表的字段規(guī)劃與關系數(shù)據(jù)庫設計決定了系統(tǒng)能不能支撐完整業(yè)務閉環(huán)。這套系統(tǒng)至少要包含六張核心表用戶表、商品分類表、商品表、購物車表、訂單表、訂單明細表。用戶表存放賬號和角色標識商品分類表和商品表是一對多關系購物車表和訂單表都通過用戶 ID 關聯(lián)用戶訂單表與訂單明細表是典型的主從表結構一個訂單包含多件商品明細。下表是六張核心表的字段規(guī)劃表名核心字段說明userid, username, password, role, create_timerole 區(qū)分普通用戶與管理員categoryid, name, sort商品分類層級不多單級即可productid, category_id, name, price, stock, image, statusstatus 控制上下架cartid, user_id, product_id, quantity每條記錄對應購物車中的一件商品ordersid, order_no, user_id, total_amount, status, create_timestatus 表示訂單狀態(tài)如待支付、已支付、已發(fā)貨等order_itemid, order_id, product_id, product_name, price, quantity下單時快照商品信息避免價格變動影響歷史訂單創(chuàng)建訂單相關表的設計通常是這樣CREATE TABLE orders ( id INT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL UNIQUE COMMENT 訂單編號前端展示用, user_id INT NOT NULL COMMENT 下單用戶ID, total_amount DECIMAL(10,2) NOT NULL COMMENT 訂單總金額, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待支付 1已支付 2已發(fā)貨 3已完成 4已取消, create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT 下單時間, KEY idx_user_id (user_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE order_item ( id INT PRIMARY KEY AUTO_INCREMENT, order_id INT NOT NULL COMMENT 所屬訂單ID, product_id INT NOT NULL COMMENT 商品ID, product_name VARCHAR(100) NOT NULL COMMENT 商品名稱快照, price DECIMAL(10,2) NOT NULL COMMENT 成交單價快照, quantity INT NOT NULL COMMENT 購買數(shù)量 ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;字段注釋里專門標出的“快照”是有講究的。如果 order_item 直接關聯(lián) product 表下單后商品改價或刪除訂單歷史就會被篡改驗收時演示“下單后改商品價格、歷史訂單金額不變”時就會翻車。在 order_item 里冗余商品名稱和價格屬于典型的空間換時間做法代價是每個字段看起來有點重復換來的是訂單數(shù)據(jù)的歷史可追溯性。訂單表里增加 order_no 字段也同理用戶和管理員溝通訂單時用一串唯一單號比用自增 ID 方便得多。4. 核心模塊實現(xiàn)購物車、下單支付與權限控制的落地代碼4.1 后端購物車模塊Controller、Service 與異常處理的配合購物車模塊是前后端最早對接的功能之一邏輯相對簡單但代碼結構必須完整要能體現(xiàn) Controller - Service - Mapper 的分層調(diào)用。先看購物車模塊的 Controller 部分RestController RequestMapping(/api/cart) public class CartController { Autowired private CartService cartService; // 查詢當前用戶的購物車列表 GetMapping(/list) public Result list(RequestAttribute(userId) Integer userId) { return Result.success(cartService.getCartList(userId)); } // 添加商品到購物車 PostMapping(/add) public Result add(RequestBody CartAddDTO dto, RequestAttribute(userId) Integer userId) { cartService.addItem(userId, dto.getProductId(), dto.getQuantity()); return Result.success(); } // 修改購物車中某件商品的數(shù)量 PutMapping(/update) public Result update(RequestBody CartUpdateDTO dto, RequestAttribute(userId) Integer userId) { cartService.updateQuantity(userId, dto.getCartId(), dto.getQuantity()); return Result.success(); } // 刪除購物車中的某條記錄 DeleteMapping(/delete/{cartId}) public Result delete(PathVariable Integer cartId, RequestAttribute(userId) Integer userId) { cartService.removeItem(userId, cartId); return Result.success(); } }CartController 里的 userId 不是前端傳的而是從攔截器解析 Token 后塞進請求屬性里的這樣設計有兩個好處前端永遠不需要手動傳用戶 ID杜絕了越權操作的可能后續(xù)下單、查詢訂單的接口都能復用這套獲取用戶身份的機制。這里需要說明的是DTO 類的字段校驗可以在 add 方法里加 Validated 注解完成比如 quantity 最小值為 1否則捕獲到校驗異常后統(tǒng)一返回錯誤信息不需要各處重復判斷。Service 層的核心邏輯要做兩件事查詢時組裝商品信息和數(shù)量新增時判斷是新增記錄還是更新已有記錄。Service public class CartServiceImpl implements CartService { Autowired private CartMapper cartMapper; Autowired private ProductMapper productMapper; Override public ListCartItemVO getCartList(Integer userId) { ListCart carts cartMapper.selectByUserId(userId); ListCartItemVO result new ArrayList(); for (Cart cart : carts) { Product product productMapper.selectById(cart.getProductId()); if (product null || product.getStatus() 0) { continue; // 已下架商品不出現(xiàn)在購物車列表 } CartItemVO vo new CartItemVO(); vo.setCartId(cart.getId()); vo.setProductName(product.getName()); vo.setPrice(product.getPrice()); vo.setQuantity(cart.getQuantity()); vo.setStock(product.getStock()); result.add(vo); } return result; } Override public void addItem(Integer userId, Integer productId, Integer quantity) { Cart exist cartMapper.selectByUserIdAndProductId(userId, productId); if (exist ! null) { exist.setQuantity(exist.getQuantity() quantity); cartMapper.updateById(exist); return; } Cart cart new Cart(); cart.setUserId(userId); cart.setProductId(productId); cart.setQuantity(quantity); cartMapper.insert(cart); } }這段代碼里的“已下架商品不出現(xiàn)在購物車列表”是一個容易被忽略但很體現(xiàn)細節(jié)的寫法它保證了下架商品不會在用戶購物車里留下一個無法結算的臟數(shù)據(jù)。addItem 里先查再改而不是直接插入避免同一商品在購物車中出現(xiàn)多條記錄用戶體驗會順很多。如果遇到商品庫存不足或商品不存在的情況我一般會在 addItem 里先查一遍商品狀態(tài)并拋出業(yè)務異常由全局異常處理器統(tǒng)一轉成友好提示。4.2 前端 Vue 組件商品列表、購物車與狀態(tài)聯(lián)動前端頁面的價值是把后端接口串成完整操作流。商品列表頁通過 axios 請求 /api/product/list 獲取商品數(shù)據(jù)點擊“加入購物車”按鈕時調(diào)用購物車接口并提示結果購物車頁面根據(jù)接口返回的列表渲染每一行商品數(shù)量修改器綁定 input 事件失焦或點擊加減時觸發(fā)數(shù)量更新。template div classcart-page el-table :datacartList v-loadingloading el-table-column propproductName label商品名稱 / el-table-column label單價 template slot-scopescope{{ scope.row.price }}/template /el-table-column el-table-column label數(shù)量 template slot-scopescope el-input-number :valuescope.row.quantity :min1 change(val) updateQuantity(scope.row.cartId, val) / /template /el-table-column el-table-column label小計 template slot-scopescope{{ (scope.row.price * scope.row.quantity).toFixed(2) }}/template /el-table-column el-table-column label操作 template slot-scopescope el-button typetext clickremoveItem(scope.row.cartId)刪除/el-button /template /el-table-column /el-table el-button typeprimary clickcheckout去結算/el-button /div /template script export default { data() { return { cartList: [] }; }, mounted() { this.loadCart(); }, methods: { async loadCart() { this.loading true; const res await this.$http.get(/api/cart/list); this.cartList res.data; this.loading false; }, async updateQuantity(cartId, quantity) { await this.$http.put(/api/cart/update, { cartId, quantity }); this.loadCart(); // 刷新重新計算小計 }, async removeItem(cartId) { await this.$http.delete(/api/cart/delete/${cartId}); this.loadCart(); }, checkout() { this.$router.push({ path: /order/confirm }); } } }; /script去結算按鈕不是直接調(diào)下單接口而是先跳轉到訂單確認頁讓用戶核對商品清單和總金額后再提交。這個設計更貼近真實電商流程也自然引出了訂單模塊訂單確認頁從購物車數(shù)據(jù)生成訂單預覽點擊提交時請求后端創(chuàng)建訂單接口后端創(chuàng)建訂單和扣減庫存放在同一個事務里保證兩張表的數(shù)據(jù)同步更新。前端用 el-input-number 做數(shù)量修改比手寫 input 少了數(shù)字格式校驗的煩惱這是組件庫帶來的實際收益。4.3 訂單狀態(tài)機與支付結算如何做一個可演示又不出錯的流程訂單模塊是整個系統(tǒng)的核心也是最容易被驗收提問的地方。訂單狀態(tài)用整數(shù)標識0 待支付、1 已支付、2 已發(fā)貨、3 已完成、4 已取消流轉方向是創(chuàng)建訂單后進入 0支付成功后進入 1商家發(fā)貨進入 2用戶確認收貨或系統(tǒng)自動確認后進入 3取消只能發(fā)生在 0 或 1 階段。這種狀態(tài)機設計保證了訂單的每一步都有據(jù)可查。創(chuàng)建訂單的 Service 代碼通常長這樣Override Transactional(rollbackFor Exception.class) public Long createOrder(Integer userId) { ListCart cartList cartMapper.selectByUserId(userId); if (cartList.isEmpty()) { throw new BizException(購物車為空無法下單); } BigDecimal total BigDecimal.ZERO; LocalDateTime now LocalDateTime.now(); for (Cart cart : cartList) { Product product productMapper.selectById(cart.getProductId()); if (product null || product.getStatus() 0) { throw new BizException(商品已下架 cart.getProductId()); } if (product.getStock() cart.getQuantity()) { throw new BizException(庫存不足 product.getName()); } total total.add(product.getPrice().multiply(BigDecimal.valueOf(cart.getQuantity()))); } Orders order new Orders(); order.setOrderNo(generateOrderNo(now)); order.setUserId(userId); order.setTotalAmount(total); order.setStatus(0); orderMapper.insert(order); // 批量插入訂單明細并清空購物車 orderItemMapper.batchInsert(order.getId(), cartList); cartMapper.deleteByUserId(userId); return order.getId(); }Transactional 是這里的關鍵。下單操作至少要經(jīng)歷“查庫存、算總價、插入訂單、插入明細、清空購物車”五步任何一步失敗都可能導致訂單和購物車數(shù)據(jù)不一致事務保證這組操作要么全部成功、要么全部回滾。我把庫存從下單邏輯里拆出來單獨看是因為不同團隊的扣庫存策略不一樣簡單方案是下單時校驗庫存充足即可不預扣庫存發(fā)貨完成后再減庫存嚴格方案是在下單時扣減庫存并鎖定超時未支付再回補。畢設場景用前一種更穩(wěn)妥邏輯簡單且容易演示成功路徑也不會因為支付環(huán)節(jié)卡住導致庫存一直被占用。支付模塊在畢設里通常用模擬支付代替前端點擊“模擬支付”按鈕直接調(diào)用后端的支付回調(diào)接口把訂單狀態(tài)從 0 改為 1。接口會校驗訂單是否屬于當前用戶、狀態(tài)是否為待支付若不是則返回錯誤提示。支付對接第三方平臺時也是從這個模擬接口替換成平臺 SDK 調(diào)用的形式整個業(yè)務流程和回調(diào)處理的骨架不需要變。5. 常見問題與部署避坑從 IDEA 到 MySQL 的調(diào)試排查清單5.1 本地部署最容易翻車的四個點第一個高頻問題是 IDEA 運行 SpringBoot 主類直接報端口被占用?,F(xiàn)象是啟動日志里出現(xiàn) “Port 8080 was already in use”原因多半是本機已有進程占用了默認端口。解決方法是打開命令窗口輸入 netstat -ano | findstr 8080查出占用進程的 PID 后到任務管理器結束進程或者修改 application.yml 里的 server.port。這個問題的本質(zhì)是環(huán)境沖突而不是代碼錯誤先改端口是最快的解法。第二個問題是 Maven 依賴下載速度極慢或直接失敗?,F(xiàn)象是 IDEA 底部進度條長時間卡住控制臺報錯顯示無法從中央倉庫下載某個 jar 包。原因通常是網(wǎng)絡訪問中央倉庫不穩(wěn)定。解決方式是在 Maven 的 settings.xml 里配置國內(nèi)鏡像源這里要注意的是配置完成后必須點擊 IDEA 里的 Maven 刷新按鈕否則依賴還是舊的。排查時如果某個依賴反復下載失敗先檢查是不是鏡像地址寫錯了再檢查倉庫配置優(yōu)先級。第三個問題是前端 npm install 安裝依賴失敗?,F(xiàn)象是命令行報 ERESOLVE 或 node-gyp 相關錯誤原因是 Node.js 版本與項目依賴版本不兼容這在 Vue 項目里很常見不同版本的 npm 處理依賴樹的方式不一樣。解決方法是查看項目說明文件里要求的 Node 版本用 nvm 切到對應版本后刪除 node_modules 重新安裝。不要在不清楚版本要求的情況下盲目升級 Node升級帶來的新報錯比原報錯還難排查。第四個問題是前端調(diào)后端接口報 404。現(xiàn)象是瀏覽器控制臺顯示某個 /api 路徑請求失敗排查思路是先確認后端接口是否正常返回。在瀏覽器地址欄直接訪問后端的接口路徑如果返回 JSON 說明接口沒問題問題出在前端如果 404 則檢查后端 Controller 的 RequestMapping 路徑是否多寫或少寫了一層。前后端分離項目里這類路徑不一致屬于低級但高頻問題我在聯(lián)調(diào)階段都會先用瀏覽器的直接訪問或者 Postman 驗證一遍后端接口再開始寫前端對接代碼。5.2 數(shù)據(jù)庫相關的三個注意點數(shù)據(jù)庫環(huán)節(jié)第一個問題是 navicat 導入 SQL 腳本時報語法錯誤?,F(xiàn)象是腳本執(zhí)行到一半中斷原因是本機 MySQL 版本與腳本使用的語法不兼容比如用了 5.7 不支持的新特性。解決方法是核對項目要求的環(huán)境版本優(yōu)先使用 MySQL 5.7 版本建庫導入前先用文本編輯器檢查腳本里的 CREATE TABLE 語句是否包含版本敏感語法。第二個問題是 SpringBoot 連接數(shù)據(jù)庫后控制臺報時區(qū)錯誤?,F(xiàn)象是啟動時提示 “The server time zone value is unrecognized”原因是 MySQL 連接串里沒有指定時區(qū)。解決方法是在 application.yml 的 JDBC 連接串末尾加上 serverTimezoneAsia/Shanghai 和 useSSLfalse 參數(shù)這個問題在 MySQL 8.0 版本尤其明顯5.7 相對少一點但對初學者來說第一次見到時容易慌。第三個問題是插入數(shù)據(jù)后中文變問號。這個問題的根因幾乎都出在字符集上解決方法是數(shù)據(jù)庫連接串里顯式加上 characterEncodingutf8建表語句統(tǒng)一使用 utf8mb4 編碼navicat 連接時在連接屬性里設置編碼為 UTF-8。三層都統(tǒng)一后中文亂碼基本就消失了。排查時不要只看一個層面先看數(shù)據(jù)庫連接串再看表編碼最后看頁面 HTML 的 charset 聲明從鏈路兩頭往中間檢查通常能快速定位。6. 驗收標準與答辯技巧功能用例、演示腳本與評分視角6.1 功能驗收清單從登錄到下單的全流程用例驗收不是“打開頁面看一眼沒問題就行”而是按照用戶操作路徑逐條走一遍并記錄結果。我一般會準備一張功能驗收清單覆蓋系統(tǒng)全部核心鏈路。下面這張表可以照抄使用每條用例對應一個預期的操作結果。編號驗收用例預期結果對應模塊01用戶注冊、登錄、退出注冊成功后可用賬號登錄退出后訪問受限接口跳轉登錄頁用戶模塊02管理員登錄后臺管理員可見商品管理與訂單管理菜單普通用戶無該入口權限控制03商品列表頁按分類篩選點擊分類后列表數(shù)據(jù)刷新為對應分類商品商品模塊04添加商品到購物車購物車數(shù)量增加相同商品不重復新增購物車模塊05修改購物車商品數(shù)量小計金額實時更新數(shù)量最小為 1購物車模塊06從購物車生成訂單生成待支付訂單訂單總金額與購物車合計一致購物車被清空訂單模塊07模擬支付訂單訂單狀態(tài)從待支付變?yōu)橐阎Ц俄撁鏍顟B(tài)同步更新支付模塊08后臺修改訂單狀態(tài)為已發(fā)貨前端訂單頁可見已發(fā)貨狀態(tài)訂單模塊09后臺下架商品前臺商品列表不再展示該商品購物車不可見該商品商品模塊10下單后修改商品價格歷史訂單金額不變訂單明細中金額保持下單時快照訂單模塊6.2 答辯時怎么講設計亮點答辯環(huán)節(jié)的提問基本圍繞“這個系統(tǒng)的設計為什么是這樣”展開與其被問到再臨時解釋不如在講 PPT 或演示時主動拋亮點。第一個值得講的是“業(yè)務閉環(huán)”注冊登錄、逛商品、加購物車、下單、支付、發(fā)貨、收貨整條流程全部打通展現(xiàn)的不只是幾個 CRUD 頁面而是完整業(yè)務系統(tǒng)。第二個是“權限控制”前端動態(tài)渲染菜單后端接口攔截兩個層面說明系統(tǒng)不是僅僅能跑而是考慮了安全性。第三個是“訂單狀態(tài)機加事務保證”用狀態(tài)字段驅動訂單流轉下單過程用事務保證數(shù)據(jù)一致性這兩個點是后端設計能力的直接證據(jù)。演示順序需要提前設計。先以普通用戶身份登錄完整走一遍加購、下單、支付流程讓評審看到前端交互和界面再切換到管理員身份展示商品上下架和訂單發(fā)貨的操作讓評審看到管理端能力。演示過程中如果碰到網(wǎng)絡請求卡頓或者某個頁面渲染慢不要慌先看是不是數(shù)據(jù)庫連接串配置問題這類問題通常不影響最終結果重點是讓流程走通讓功能被看到。6.3 演示腳本與準備工作在正式答辯或驗收前我會強制自己把演示腳本完整跑一遍順序是這樣的第一步啟動 MySQL 服務用 navicat 確認數(shù)據(jù)庫導入成功、商品數(shù)據(jù)存在第二步啟動后端 SpringBoot觀察控制臺日志確認數(shù)據(jù)庫連接成功、項目監(jiān)聽端口正常第三步啟動前端 Vue 工程瀏覽器打開登錄頁第四步登錄管理員賬號檢查商品庫存、訂單列表數(shù)據(jù)齊全第五步切換普通用戶賬號走一遍從瀏覽到支付的全流程確認每個頁面數(shù)據(jù)能正常展示。這五步里最容易出問題的是第一步和第二步因為環(huán)境變量、數(shù)據(jù)庫連接、依賴版本這些影響大且容易被忽略。建議提前一天做一次全流程演練把發(fā)現(xiàn)的問題在正式驗收前修復完。從那以后我每次交付項目前都強制自己走一遍這份清單寧可多花十分鐘也不要在演示中途面對一個意外報錯。希望幫到你。本文還有配套的精品資源點擊獲取