管理系統(tǒng):Java Web畢設項目全流程實戰(zhàn))
畢業(yè)設計選題這件事每年都有一大批人被卡在“做什么”和“怎么做”之間。做太簡單的系統(tǒng)答辯時拿不出手做太復雜的架構開發(fā)周期又撐不住。如果你正在找 Java Web 方向的畢設項目又希望它既有完整業(yè)務閉環(huán)、又有拿得出手的技術棧那 SpringBootVue 的就業(yè)管理系統(tǒng)是一個比較穩(wěn)妥的選擇。這篇文章我把這個項目的源碼結構、SQL 腳本設計、接口文檔編寫、前后端聯(lián)調(diào)和部署上線全流程拆開講一遍順便把我自己開發(fā)時踩過的坑一并說清楚希望能讓你的畢設少走點彎路。1. 為什么 SpringBootVue 是 Java Web 畢設的穩(wěn)妥選擇先聊點實在的。每年春季學期開始也就是 3 月到 4 月這個時間窗口是畢設選題的高峰期。如果你在這個節(jié)點打開招聘網(wǎng)站或者逛技術社區(qū)會發(fā)現(xiàn)大量 Java 方向的崗位要求里同時出現(xiàn) SpringBoot 和 Vue 這兩個關鍵詞這背后是有強烈行業(yè)原因的——企業(yè)里真實的 web 項目絕大多數(shù)就是這種前后端分離的形態(tài)。1.1 技術棧的選型邏輯后端選 SpringBoot 而不是更老的 SSM 或者 Struts核心原因是開發(fā)效率。SpringBoot 的自動配置機制幫我們省掉了大量 XML 配置內(nèi)嵌 Tomcat 也讓部署變得極其簡單。我見過不少同學還在手動配置 web.xml 和數(shù)據(jù)源光這些環(huán)境問題就能耗掉一個禮拜。而 SpringBoot 項目的起步只需要一個啟動類加幾個注解連版本兼容性問題大部分都被 Spring Initializr 處理掉了。前端選 Vue 而不是 jQuery 或者純模板渲染核心邏輯在于組件化開發(fā)。Vue 的單文件組件模式把 HTML、CSS、JS 寫在一個文件里業(yè)務邏輯清晰團隊協(xié)作時不會互相覆蓋文件。更重要的是Vue 生態(tài)里的 Element UI 組件庫提供了現(xiàn)成的表格、表單、彈窗、分頁這些管理端高頻組件畢設里增刪改查列表搜索這四大金剛基本可以直接拼裝。如果你是第一次做完整的前后端分離項目這個組合的學習曲線也相對友好。SpringBoot 側你只需要掌握 Controller 層怎么接收請求、Service 層怎么寫業(yè)務邏輯、Mapper 層怎么操作數(shù)據(jù)庫Vue 側只需要理解組件通信、生命周期、路由跳轉(zhuǎn)三個概念就能把頁面搭起來。對于需要在一學期內(nèi)完成設計編碼測試論文的畢設場景來說這套技術棧足夠把時間用在業(yè)務上而不是浪費在環(huán)境配置上。1.2 就業(yè)管理系統(tǒng)為什么適合作為畢設題目就業(yè)管理系統(tǒng)這個題目之所以在每年的畢設選題庫里都能看到甚至很多學校會把它單獨列為一個方向是因為它的業(yè)務邊界足夠清晰同時又覆蓋了完整的用戶角色體系。這個系統(tǒng)天然需要三類角色學生、企業(yè)、管理員。學生可以錄入個人信息、瀏覽招聘崗位、投遞簡歷、查看投遞進度企業(yè)可以注冊入駐、發(fā)布職位、篩選簡歷、發(fā)出面試邀請管理員負責審核企業(yè)資質(zhì)、管理公告、統(tǒng)計就業(yè)數(shù)據(jù)。這樣的角色劃分直接決定了系統(tǒng)的權限控制模型而權限控制恰恰是答辯時最容易展開講深度的點。業(yè)務上還有一個隱藏價值——它屬于典型的信息管理流程流轉(zhuǎn)型系統(tǒng)。前半部分本質(zhì)上還是各類信息表的 CRUD這是保底線無論開發(fā)到什么程度系統(tǒng)都能跑起來后半部分的投遞流程、審核流程、統(tǒng)計分析是可以在論文里單獨開一章講業(yè)務流程設計與優(yōu)化的進階點。這種基礎功能保底模塊化擴展的特征讓這個題目幾乎不可能出現(xiàn)做不出來的極端情況。2. 項目整體架構設計與數(shù)據(jù)庫表拆分思路架構設計這件事很多畢設選手容易走進兩個極端要么完全不做設計直接打開 IDE 開始寫代碼結果寫到一半發(fā)現(xiàn)實體類之間關系混亂、代碼互相依賴要么過度設計把微服務、消息隊列、分布式緩存這些不該出現(xiàn)在畢設里的東西全塞進來給自己挖了個大坑。2.1 單體應用 前后端分離的架構模式就業(yè)管理系統(tǒng)這類校園業(yè)務系統(tǒng)最合理的架構就是單體應用 前后端分離。后端用 SpringBoot 打包成獨立服務前端用 Vue 開發(fā)后用 npm 構建成靜態(tài)資源部署時可以直接放在 Nginx 下托管并反向代理到后端接口。為什么不建議上微服務原因很直接微服務的核心價值在于獨立部署和彈性伸縮一個就業(yè)管理系統(tǒng)即便在校園環(huán)境里跑用戶量也遠遠達不到需要拆分的程度。引入微服務反而會引入服務注冊、配置中心、分布式事務等問題每一個都能讓畢設進度停滯兩周以上。記住一句話畢業(yè)設計的架構復雜度應該剛好覆蓋題目需求多一分是負擔少一分是缺憾。這個項目的后端模塊劃分我建議這樣組織controller接收前端請求參數(shù)校驗返回統(tǒng)一響應體service業(yè)務邏輯事務控制mapper數(shù)據(jù)庫持久層操作entity與數(shù)據(jù)表對應的實體類dto前端傳輸對象避免直接暴露實體類內(nèi)部結構config配置類包括跨域配置、攔截器注冊util通用工具類如 Token 生成與校驗、日期處理前端方面Vue 項目的標準目錄結構是src/api接口請求封裝、src/views頁面組件、src/router路由配置、src/store狀態(tài)管理、src/components通用組件。管理端頁面基本就是布局組件嵌套路由頁面頂部是系統(tǒng)標題左側是菜單欄右側是內(nèi)容區(qū)。2.2 數(shù)據(jù)庫表設計與字段規(guī)劃數(shù)據(jù)庫是整系統(tǒng)的地基。我見過太多畢設的庫表設計要么是字段命名混亂有駝峰有下劃線要么是缺少外鍵邏輯關聯(lián)要么是沒加時間戳字段導致做統(tǒng)計分析時無從下手。就業(yè)系統(tǒng)的表結構設計要從真實業(yè)務流程倒推來理解為什么這樣設計。核心數(shù)據(jù)表至少有這些表名用途關鍵字段說明sys_user系統(tǒng)用戶表賬號、密碼MD5 加密存儲、角色標識sys_role角色表角色編碼、角色名稱student_profile學生信息表姓名、學號、專業(yè)、畢業(yè)年份、簡歷附件路徑company_info企業(yè)信息表企業(yè)名稱、統(tǒng)一社會信用代碼、行業(yè)類別、規(guī)模job_position職位表職位名稱、薪資范圍、工作城市、崗位要求job_resume簡歷表基本資料、教育經(jīng)歷、項目經(jīng)歷、技能標簽delivery_record投遞記錄表學生ID、職位ID、投遞時間、狀態(tài)interview_record面試記錄表關聯(lián)投遞ID、面試時間、面試結果sys_notice公告表標題、內(nèi)容、發(fā)布時間、發(fā)布人collect_record收藏記錄表用戶ID、職位ID、收藏時間舉例說明為什么要這樣設計。student_profile和sys_user分開是有講究的賬號登錄信息和業(yè)務個人信息本身就是兩個維度的數(shù)據(jù)合并到一張表雖然能省一次聯(lián)表查詢但會導致表字段膨脹、職責混亂后續(xù)如果要做管理員給用戶重置密碼功能時業(yè)務表的信息就不該被無辜翻出來。再來看delivery_record這個表的設計。它除了簡單的外鍵關聯(lián)外狀態(tài)字段待查看、已查看、已邀請、不合適、已通過是整個投遞流程的核心狀態(tài)機。你在寫后端 Service 時要有意識地用常量或者枚舉來管理這些狀態(tài)而不是在業(yè)務代碼里直接寫魔法字符串。畢竟狀態(tài)一旦寫錯后續(xù)統(tǒng)計就業(yè)率、分析投遞轉(zhuǎn)化率都會出錯。建表腳本的規(guī)范問題也值得注意所有表的主鍵建議使用bigint自增避免使用 UUID 字符串主鍵因為自增主鍵在插入時性能更好索引空間占用也更小所有業(yè)務表都建議加create_time和update_time兩個字段這個習慣會為后續(xù)調(diào)試、排查數(shù)據(jù)問題帶來極大的便利外鍵約束在畢設中可以直接使用邏輯關聯(lián)而不是物理外鍵即僅保留 ID 字段作為關聯(lián)字段不在數(shù)據(jù)庫層面強制 FOREIGN KEY這樣既保持數(shù)據(jù)關系的可讀性又避免在刪除數(shù)據(jù)時被外鍵約束卡住。初始化數(shù)據(jù)也很有講究。學生用戶、測試企業(yè)、示例職位、公告信息建議全都在 SQL 腳本里預置好。這樣數(shù)據(jù)庫一旦導入導入完成頁面登錄進去就會有現(xiàn)成的數(shù)據(jù)展示不用為了跑通流程去一條條手動錄入。3. 后端 SpringBoot 核心功能實現(xiàn)與接口設計后端開發(fā)的核心目標是讓前端頁面能夠通過 HTTP 請求拿到數(shù)據(jù)并完成業(yè)務操作。這里涉及三個核心問題接口怎么定義、數(shù)據(jù)怎么傳輸、登錄怎么鑒權。3.1 統(tǒng)一響應體的設計接口返回的數(shù)據(jù)結構如果不統(tǒng)一前后端聯(lián)調(diào)時會產(chǎn)生非常多的低級溝通成本。這里建議從第一個接口開始就使用一個統(tǒng)一的響應體類public class Result { private Integer code; // 200 成功400 業(yè)務異常401 未認證500 系統(tǒng)錯誤 private String message; private Object data; public static Result success(Object data) { Result result new Result(); result.setCode(200); result.setMessage(操作成功); result.setData(data); return result; } public static Result error(Integer code, String message) { Result result new Result(); result.setCode(code); result.setMessage(message); return result; } }前端 axios 攔截器拿到響應后統(tǒng)一判斷code字段如果等于 200 就進入正常業(yè)務處理否則彈出錯誤提示并終止流程。這套模式寫起來很簡單但它讓前后端之間的契約非常清晰尤其是答辯演示的時候柵欄一眼就能看到系統(tǒng)的邏輯脈絡。3.2 登錄鑒權鏈路登錄鑒權是就業(yè)管理系統(tǒng)重中之重因為系統(tǒng)有三個角色不同角色能訪問的功能菜單和操作按鈕是不同的。這里介紹一種在畢設中同時兼顧安全性和實現(xiàn)難度的方案——JWTJSON Web Token 攔截器。登錄流程拆解如下前端將用戶名和密碼發(fā)送到/api/auth/login。后端從sys_user表查詢用戶用MD5(密碼 鹽)來驗證密碼。校驗通過后生成 JWT Token把用戶ID和角色編碼放入 token 的 claims 中。前端把 token 存儲在 localStorage并在 axios 請求攔截器里統(tǒng)一加上Authorization: Bearer token。后端定義一個攔截器在請求進入 Controller 之前校驗 token 的合法性和有效期并在請求上下文中解析出用戶ID和角色。攔截器核心邏輯大致如下public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String authHeader request.getHeader(Authorization); if (authHeader null || !authHeader.startsWith(Bearer )) { response.setStatus(401); return false; } String token authHeader.substring(7); try { Claims claims JwtUtil.parseToken(token); request.setAttribute(userId, claims.get(userId)); request.setAttribute(role, claims.get(role)); return true; } catch (Exception e) { response.setStatus(401); return false; } } }這個方案比傳統(tǒng)的 Session 方案好在哪Session 依賴服務端保存狀態(tài)在部署時如果開了多實例還需要額外的 Session 共享方案而 JWT 本身就是無狀態(tài)的服務端不需要保存任何會話信息校驗的是簽名的正確性天然適合前后端分離的場景。畢設里能把這個邏輯講明白答辯時你怎么處理登錄態(tài)這個問題基本就穩(wěn)了。3.3 核心業(yè)務接口的設計思路就業(yè)系統(tǒng)的核心業(yè)務接口圍繞職位和投遞鏈路展開列舉幾個典型接口及其設計理由POST /api/job發(fā)布職位。請求參數(shù)是職位表單數(shù)據(jù)后端需要校驗當前用戶角色是否為企業(yè)端并且企業(yè)信息已通過管理員審核。這里最關鍵的是校驗的是角色和資格而不是誰都能發(fā)表職位。GET /api/job/list職位分頁列表。前端傳當前頁碼、每頁條數(shù)、篩選條件城市、行業(yè)、薪資范圍、關鍵詞后端使用 MyBatis-Plus 的Page對象做分頁查詢。不要把排序和篩選邏輯寫死在 SQL 里通過前端傳參控制會更靈活。POST /api/delivery投遞簡歷。需要校驗當前登錄學生是否已填完整簡歷資料若沒填完整就返回業(yè)務異常并提示先去完善簡歷。同時需要做一個冪等校驗——同一個職位同一個學生不能重復投遞。GET /api/delivery/student學生查看自己的投遞記錄。這是一個多表聯(lián)查需要把投遞記錄和職位信息、企業(yè)信息關聯(lián)起來返回給前端展示完整的投遞卡片。注意設計好 VO 而不是直接把三層表字段全塞到一個 Map 里不然前端拿到的數(shù)據(jù)雜亂無章。GET /api/admin/stats管理員統(tǒng)計分析。統(tǒng)計學校整體就業(yè)率、各專業(yè)就業(yè)人數(shù)分布、熱門崗位 TOP10。這類接口不需要返回分頁結構直接返回一個統(tǒng)計對象即可。SQL 上要善用GROUP BY和COUNT必要時可以把復雜統(tǒng)計查詢拆成多個 SQL 在 Service 層匯總。3.4 數(shù)據(jù)庫訪問層的選型理由數(shù)據(jù)庫訪問層有的人用原生 MyBatis有的人用 MyBatis-Plus有的人用 Spring Data JPA。我的建議是選 MyBatis-Plus理由有三點它沒改變 MyBatis 的核心使用方式SQL 能力沒有縮水BaseMapper提供了常用 CRUD 方法幾乎不用寫 SQLLambdaQueryWrapper讓復雜條件查詢在 Java 代碼里直接表達比拼接 XML SQL 更安全也更體面。比如投遞去重的判斷用 LambdaQueryWrapper 只需這樣寫LambdaQueryWrapperDeliveryRecord wrapper new LambdaQueryWrapper(); wrapper.eq(DeliveryRecord::getStudentId, studentId) .eq(DeliveryRecord::getJobId, jobId); if (deliveryMapper.selectCount(wrapper) 0) { throw new BusinessException(您已投遞過該職位請勿重復投遞); }沒有繁瑣的 XML 配置、沒有格式不齊的 SQL 映射對趕進度的畢設來說是實實在在的省心方案。4. 前端 Vue 工程搭建與聯(lián)調(diào)實踐后端接口定義好了前端才是真正讓系統(tǒng)可見、可用、可演示的部分。Vue 工程從初始化到跑通整套業(yè)務核心環(huán)節(jié)包括環(huán)境搭建、路由組織、請求封裝和跨域處理。4.1 環(huán)境搭建與項目初始化前端環(huán)境主要涉及 Node.js 和 npm版本選擇上建議使用 Node 16 或 18 的 LTS 版本。Vue CLI 可以按需選擇 Vue 2 加 Element UI或者 Vue 3 加 Element Plus。畢設項目我傾向 Vue 2 Element UI 組合因為網(wǎng)上資料最多踩坑時更容易查到解決方案。項目初始化命令就是一個npm install -g vue/cli vue create job-web cd job-web npm install element-ui axios vue-router vuex創(chuàng)建完成后對src目錄做一次重組router下寫路由配置、api下按模塊封裝接口請求、views下按角色建立頁面文件夾。這個結構從一開始就清晰后面寫頁面時不會到處亂放文件。4.2 路由組織與權限控制前端的路由分為公開路由和認證路由兩類。公開路由例如登錄頁、注冊頁。認證路由又按角色細分學生端路由/student企業(yè)端路由/company管理端路由/admin。核心是路由守衛(wèi)。在router/index.js里通過beforeEach攔截跳轉(zhuǎn)router.beforeEach((to, from, next) { const token localStorage.getItem(token); if (to.path /login) { next(); return; } if (!token) { next({ path: /login }); return; } const role localStorage.getItem(role); if (to.meta.roles !to.meta.roles.includes(role)) { next({ path: /403 }); return; } next(); });這個邏輯非常簡單清晰沒有 token 就別想進任何業(yè)務頁面角色不符的跳轉(zhuǎn)到 403 頁。安全要放在兩條腿走路——后端鑒權是最后一道關卡前端守衛(wèi)只是給正常用戶提供友好體驗不能指望前端攔攔截就能防住惡意請求。4.3 axios 封裝與跨域問題axios 封裝的核心是兩件事統(tǒng)一注入 token、統(tǒng)一處理錯誤。import axios from axios; const request axios.create({ baseURL: /api, // 由代理轉(zhuǎn)發(fā)到后端真實地址 timeout: 10000 }); request.interceptors.request.use(config { const token localStorage.getItem(token); if (token) { config.headers[Authorization] Bearer token; } return config; }); request.interceptors.response.use( response { const res response.data; if (res.code 200) { return res.data; } if (res.code 401) { localStorage.clear(); window.location.href /login; } return Promise.reject(new Error(res.message)); }, error Promise.reject(error) ); export default request;跨域問題在開發(fā)聯(lián)調(diào)階段一定會遇到前端跑在 8080 端口后端跑在 8082 端口直接從瀏覽器發(fā)請求會被瀏覽器的同源策略攔下。標準解決方案是前端開發(fā)服務器配置代理在vue.config.js里寫module.exports { devServer: { port: 8080, proxy: { /api: { target: http://localhost:8082, changeOrigin: true, pathRewrite: { ^/api: } } } } };這樣前端代碼里請求路徑都寫/api/...開發(fā)時由 webpack-dev-server 代理轉(zhuǎn)發(fā)到后端完全繞開跨域限制。前端部署時再由 Nginx 做同樣的反向代理生產(chǎn)環(huán)境的路徑邏輯和開發(fā)環(huán)境保持一致避免環(huán)境切換帶來的額外坑。5. 從零跑通項目的完整流程與部署踩坑記錄很多同學拿到別人的項目源碼第一步就卡在建環(huán)境上。這里我把從零到瀏覽器跑起來的標準流程列一遍以及每個環(huán)節(jié)會踩到什么坑。5.1 環(huán)境準備清單后端側需要安裝 JDK 1.8 或 11、Maven 3.6、MySQL 5.7 或 8.0 。前端側需要 Node 16、npm。開發(fā)工具推薦 IDEA社區(qū)版就行 VSCodeIDEA 專門寫后端VSCode 專門寫前端兩邊互不干擾。有個容易忽略的坑是 JDK 和 SpringBoot 版本兼容問題。如果你用 JDK 17 或者更高版本而后端項目是基于 SpringBoot 2.x 搭建的啟動時大概率會遇到模塊訪問權限報錯需要額外添加 JVM 參數(shù)不了解的人直接卡死。穩(wěn)妥方案是安裝 JDK 1.8 或 11與 SpringBoot 2.x 完美匹配。5.2 數(shù)據(jù)庫導入 SQL 腳本拿到項目的 SQL 腳本后導入操作不要直接在命令行粘貼整個文件尤其當腳本有幾十 KB 時容易中間斷開。推薦用可視化工具執(zhí)行整個腳本比如 Navicat 的運行 SQL 文件功能。腳本文件導入后檢查sys_user表里是否有初始化好的管理員賬號確保密碼字段是加密后的值而不是明文。如果 SQL 腳本執(zhí)行報錯優(yōu)先排查是不是版本問題——比如用了 MySQL 8.0 新增的語法卻在 5.7 上跑或者排序規(guī)則和默認字符集不匹配。順手把數(shù)據(jù)庫字符集統(tǒng)一設為utf8mb4避免插入中文出現(xiàn)亂碼。5.3 啟動后端服務的實操用 IDEA 導入 Maven 項目后等待依賴下載完成然后修改application.yml里的數(shù)據(jù)庫連接配置server: port: 8082 spring: datasource: url: jdbc:mysql://localhost:3306/job_db?useUnicodetruecharacterEncodingutf8mb4useSSLfalseserverTimezoneAsia/Shanghai username: root password: 123456 mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl第一次啟動時建議開啟log-impl這樣控制臺會打印每條 SQL方便觀察后端實際執(zhí)行了什么 SQL排查問題時作用極大。等系統(tǒng)穩(wěn)定后再關掉日志避免輸出刷屏。啟動類直接運行main方法看到控制臺輸出 Started Application in x seconds 就代表后端起來了。5.4 啟動前端與打包部署前端依賴安裝運行npm install這一步在國內(nèi)網(wǎng)絡環(huán)境下可能很慢可以把 npm 鏡像源換成淘寶源速度會顯著提升。啟動開發(fā)服務運行npm run serve瀏覽器訪問http://localhost:8080登錄即可看到系統(tǒng)界面。開發(fā)完成后的部署環(huán)節(jié)我提供一個固定的流程模板后端執(zhí)行 Maven 打包mvn clean package -DskipTests在 target 目錄生成job-system.jar。前端執(zhí)行npm run build生成dist目錄。把dist里的靜態(tài)文件上傳到服務器把 jar 包也傳上去。用 Nginx 托管前端靜態(tài)文件并配置/api反向代理到后端端口。用java -jar job-system.jar啟動后端服務。Nginx 的配置核心如下server { listen 80; server_name your-domain.com; location / { root /opt/job-web/dist; index index.html; try_files $uri $uri/ /index.html; # 解決 Vue 路由刷新 404 的問題 } location /api/ { proxy_pass http://127.0.0.1:8082/; # 注意斜杠會去掉 /api 前綴 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }這個try_files指令是 Vue 路由的關鍵如果不寫瀏覽器直接刷新子頁面比如/student/job-list就會報 404。很多人部署完發(fā)現(xiàn)頁面打不開十有八九是這里漏配了。5.5 部署時遇到的典型錯誤部署環(huán)節(jié)我整理了一個高頻問題排查表報錯現(xiàn)象根本原因解決方案前端請求接口 502Nginx 沒有啟動后端或后端端口不對確認 jar 包進程存在curl http://127.0.0.1:8082/api/auth/login測試前端請求接口 404代理路徑 rewrite 配置錯誤檢查proxy_pass是否處理了/api前綴刷新子頁面 404Nginx 缺少 try_files 配置補上try_files $uri $uri/ /index.html;頁面能開但登錄失敗后端數(shù)據(jù)庫連接失敗查看后端日志確認 MySQL 賬戶密碼和遠程訪問權限插入數(shù)據(jù)中文亂碼數(shù)據(jù)庫字符集不是 utf8mb4執(zhí)行ALTER DATABASE job_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;MySQL 連接報 SSL 錯誤連接串未加 useSSLfalse在 url 后追加useSSLfalseserverTimezoneAsia/Shanghai每個錯誤排查時先看日志后端日志是 Locate 的第一利器不要憑感覺亂改配置。6. 接口文檔編寫規(guī)范與給答辯準備的經(jīng)驗接口文檔在畢設里的定位經(jīng)常被忽視但它在兩個場景下非常重要一是你自己寫前端時需要回頭查接口的定義二是答辯時老師翻開你的項目文檔接口設計規(guī)范程度直接反映你的工程素養(yǎng)。6.1 接口文檔該記錄哪些內(nèi)容每個接口建議包含五部分信息接口地址、請求方式、請求參數(shù)名稱、類型、是否必填、說明、返回示例、錯誤碼說明。這套格式寫清楚后后端每個接口相當于一個契約前端照著調(diào)用即可。截取一個登錄接口的文檔示例接口路徑POST /api/auth/login 接口描述用戶登錄校驗賬號密碼后返回 JWT Token 請求參數(shù) - username string 必填 用戶名 - password string 必填 密碼明文后端負責加密校驗 返回示例 { code: 200, message: 登錄成功, data: { token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..., userId: 1, role: admin } } 錯誤碼 400 用戶名或密碼錯誤 401 賬號已被禁用文檔可以采用 Swagger 自動生成也可以手寫 Markdown。我個人建議手寫因為強迫自己重新審視一遍每個字段發(fā)現(xiàn)潛在問題時能及時修正審閱起來也更有成就感。6.2 答辯前值得深入準備的題目畢設答辯的核心邏輯是你做的系統(tǒng)經(jīng)得起問推薦提前準備以下問題為什么做前后端分離答前后端獨立開發(fā)部署、接口解耦、職責清晰。前端專注交互后端專注業(yè)務處理和數(shù)據(jù)安全團隊協(xié)作效率更高也符合當前企業(yè)主流開發(fā)模式。登錄態(tài)的 token 過期時間是怎么設的過期了怎么辦答畢業(yè)設計里設置短期過期容易讓用戶頻繁被迫重新登錄可以設置 24 小時。過期后前端通過 axios 響應攔截器統(tǒng)一跳轉(zhuǎn)登錄頁。如果需要更完善的方案可以引入 Refresh Token 雙令牌機制重登錄體驗幾乎不受影響。數(shù)據(jù)庫表為什么不加物理外鍵答邏輯外鍵在刪除和更新時更靈活也更容易在大數(shù)據(jù)量下保持性能。對畢設系統(tǒng)來說邏輯關聯(lián)完全足夠表達數(shù)據(jù)關系代碼層通過事務來保證一致性。系統(tǒng)可以支撐多少并發(fā)答單體應用加 MySQL 支撐幾百并發(fā)沒有問題畢設場景在學校局域網(wǎng)內(nèi)演示足夠。如果真要談擴展可以在數(shù)據(jù)庫連接池調(diào)優(yōu)和中間件緩存層面展開但承認不引入復雜架構是合理的設計選擇。你用什么校驗用戶提交的數(shù)據(jù)答前端做輸入格式的基本校驗是否為空、長度、正則規(guī)則后端用 Spring Validation 注解或手動校驗做二次校驗。后端校驗永遠是不可動搖的防線前端校驗只是為了更友好的用戶體驗。統(tǒng)計功能怎么保證準確答通過 SQL 聚合函數(shù)實現(xiàn)關鍵統(tǒng)計數(shù)據(jù)都基于固定的條件比如已就業(yè)狀態(tài)必須嚴格等于某個狀態(tài)碼避免語義不清。同時在代碼里做了多條件防重復統(tǒng)計。6.3 如何把這個項目變成你自己的源碼可能來自下載或參考但答辯時老師其實很在意你是否真正理解項目。這里分享幾個讓別人一眼看不出是純搬運的做法把項目里的包名、類名改成你自己命名的規(guī)范比如把com.example改成com.yourname.jobs。改動包名后不僅 IDE 項目結構更符合你的書寫習慣也讓代碼確實過了一遍你的手。換一套系統(tǒng)名和 UI 配色。前端有個配置文件統(tǒng)管主題色把原生藍色改成深綠、深紅或者其他任意你喜歡的色系再改掉導航欄的系統(tǒng)標題比如XX大學就業(yè)信息服務平臺。這個成本很低但效果極佳。增加一個原項目沒有的小功能。比如學生端增加導出個人簡歷 PDF企業(yè)端增加查看本校各專業(yè)畢業(yè)生人數(shù)圖表這類小型功能。實現(xiàn)方案在網(wǎng)上都有現(xiàn)成參考工作量兩三天足夠但答辯說起來是你獨立設計實現(xiàn)的亮點。把論文的核心論點與系統(tǒng)功能對應起來。比如論文里的系統(tǒng)安全性設計這一章就講 JWT 鑒權鏈路和角色權限控制數(shù)據(jù)可視化設計這一章就講管理員統(tǒng)計圖表。讓論文和系統(tǒng)互相印證評審老師一眼看到你的工作量和思考深度。最后再提醒一件容易被忽略的事把系統(tǒng)的測試數(shù)據(jù)跑得活一點每個列表頁面都有數(shù)據(jù)顯示、每個按鈕都能點出效果投遞流程能完整走通比答辯時口若懸河講解設計理念重要得多。我見過很多系統(tǒng)功能本身做得不錯但演示時裸奔的同學就是栽在演示前沒有完整跑一遍正常流程、忘了處理邊界情況上。