畢設(shè)實戰(zhàn):從業(yè)務(wù)閉環(huán)到技術(shù)落地)
這類畢設(shè)項目最值得關(guān)注的不是功能列表而是如何把一個常見的“增刪改查”系統(tǒng)做出符合高校資助業(yè)務(wù)邏輯的完整流程并且能讓評審老師清晰地看到你的技術(shù)選型、架構(gòu)設(shè)計和前后端聯(lián)調(diào)能力。很多同學做這類系統(tǒng)容易陷入兩個極端要么只堆砌技術(shù)名詞業(yè)務(wù)邏輯空洞要么業(yè)務(wù)邏輯復雜但代碼結(jié)構(gòu)混亂難以部署和演示。我建議你從“業(yè)務(wù)閉環(huán)”和“技術(shù)棧落地”兩個角度來構(gòu)建這個系統(tǒng)。別一上來就寫代碼先想清楚資助業(yè)務(wù)里“學生申請-輔導員審核-學院審批-學校復核-資金發(fā)放-信息歸檔”這條主線以及SSM和Vue分別在這條線上扮演什么角色。下面我會按實際開發(fā)順序拆解從環(huán)境搭建到功能實現(xiàn)再到部署演示的全過程重點講那些容易卡住、容易被忽略但評審時又很關(guān)鍵的細節(jié)。1. 先理清業(yè)務(wù)主線再設(shè)計技術(shù)架構(gòu)高校學生資助信息系統(tǒng)核心是圍繞“資助項目”的生命周期來管理學生、輔導員、學院管理員和學校管理員四類角色的協(xié)作。如果業(yè)務(wù)主線理不清數(shù)據(jù)庫表設(shè)計就會出問題導致后續(xù)功能越寫越別扭。1.1 資助業(yè)務(wù)的典型流程與角色權(quán)限資助業(yè)務(wù)不是簡單的信息登記它有一條清晰的審批鏈。通常的流程是學生端查看可申請的資助項目如助學金、助學貸款、臨時困難補助 - 在線填寫申請表并提交證明材料 - 查看申請狀態(tài)和歷史記錄。輔導員端審核本班級學生的申請材料核實家庭情況、在校表現(xiàn)等 - 填寫初審意見通過/駁回 - 提交至學院。學院管理員端匯總審核本學院各班級提交的申請 - 進行學院級評審與公示 - 填寫學院審批意見 - 提交至學校資助中心。學校管理員端進行最終復核與審批 - 確定資助名單與金額 - 發(fā)布公示 - 記錄資金發(fā)放情況 - 進行數(shù)據(jù)統(tǒng)計與分析。權(quán)限設(shè)計必須緊扣這條流程。例如學生不能審核自己的申請輔導員只能操作自己班級的學生學院管理員只能操作本學院的申請。這需要在后端接口層面進行嚴格的權(quán)限攔截不是光靠前端菜單隱藏就夠的。1.2 基于 SSM Vue 的技術(shù)棧分工明確了業(yè)務(wù)技術(shù)選型才能有的放矢。后端 (SSM框架)Spring負責整個項目的Bean管理、事務(wù)控制例如審核操作必須保證數(shù)據(jù)庫狀態(tài)的一致性和AOP如統(tǒng)一日志記錄、權(quán)限驗證。SpringMVC接收前端Vue發(fā)來的HTTP請求調(diào)用Service層處理業(yè)務(wù)最后將JSON數(shù)據(jù)返回給前端。這里是前后端交互的橋梁。MyBatis負責與MySQL數(shù)據(jù)庫交互將Java對象和數(shù)據(jù)庫表進行映射。你需要編寫清晰的SQL語句特別是多表關(guān)聯(lián)查詢?nèi)绮樵兩暾垥r需要聯(lián)查學生表、項目表、審核記錄表。前端 (Vue框架)Vue 2.x / 3.x構(gòu)建用戶界面的核心。建議使用Vue 3 Composition API但考慮到生態(tài)和資料Vue 2 Options API對于畢設(shè)也完全足夠。Vue Router管理前端路由實現(xiàn)單頁面應(yīng)用SPA效果。不同角色登錄后根據(jù)權(quán)限動態(tài)加載不同的菜單和路由。Vuex / Pinia狀態(tài)管理。用于集中管理用戶登錄信息、權(quán)限令牌等全局狀態(tài)。例如用戶登錄后將token和用戶角色信息存入Vuex其他組件即可共享。Axios用于向后端SpringMVC接口發(fā)送HTTP請求并處理響應(yīng)。數(shù)據(jù)庫 (MySQL)設(shè)計表結(jié)構(gòu)時要體現(xiàn)業(yè)務(wù)關(guān)系。核心表通常包括用戶表、學生信息表、資助項目表、資助申請表、審核記錄表、公示公告表、資金發(fā)放記錄表等。表與表之間通過外鍵關(guān)聯(lián)。一個關(guān)鍵建議在動手編碼前用工具如PDManer、Navicat畫出數(shù)據(jù)庫的ER圖并和你的導師或同學確認。這能避免后期大量返工。2. 搭建可運行、易演示的開發(fā)環(huán)境環(huán)境沒配好一切等于零。畢設(shè)項目最怕在答辯演示時因為環(huán)境問題跑不起來。下面是一套穩(wěn)妥的環(huán)境配置方案。2.1 后端開發(fā)環(huán)境準備JDK安裝JDK 8或JDK 11LTS版本。配置JAVA_HOME環(huán)境變量并在命令行用java -version驗證。Maven用于管理項目依賴Spring、MyBatis、MySQL驅(qū)動等。下載安裝后配置MAVEN_HOME和settings.xml可配置國內(nèi)鏡像源加速下載。IDEIntelliJ IDEA社區(qū)版即可或 Eclipse。IDEA對Maven和Spring的支持更友好。MySQL安裝MySQL 5.7或8.0。記住你設(shè)置的root密碼。建議安裝Navicat或DBeaver等圖形化工具來管理數(shù)據(jù)庫。項目骨架生成最簡單的方式是使用Spring Initializr在IDEA里直接選擇生成一個基礎(chǔ)Spring Boot項目它內(nèi)嵌了Tomcat簡化了SSM的配置。勾選依賴Spring Web(用于SpringMVC)、MyBatis Framework、MySQL Driver。生成后你的pom.xml文件會自動包含這些依賴。2.2 前端開發(fā)環(huán)境準備Node.jsVue的運行和構(gòu)建環(huán)境。安裝LTS版本它會自帶npm包管理器。安裝后在命令行用node -v和npm -v驗證。Vue CLIVue的官方腳手架工具用于快速創(chuàng)建項目結(jié)構(gòu)。通過npm全局安裝npm install -g vue/cli。安裝后用vue --version驗證。創(chuàng)建Vue項目在指定目錄下運行vue create student-funding-frontend。選擇手動配置建議勾選Babel,Router,Vuex,CSS Pre-processors如Sass/ScssLinter / Formatter代碼規(guī)范可選。安裝輔助庫axios用于網(wǎng)絡(luò)請求。npm install axioselement-ui或ant-design-vue推薦使用Element Plus對應(yīng)Vue 3或Element UI對應(yīng)Vue 2作為UI組件庫能極大提升開發(fā)效率。npm install element-plus --save可選echarts用于數(shù)據(jù)統(tǒng)計圖表。npm install echarts2.3 解決第一個聯(lián)調(diào)問題跨域前后端分離開發(fā)前端運行在localhost:8080后端運行在localhost:8081瀏覽器會因同源策略阻止請求。必須在后端解決跨域。在Spring Boot項目中創(chuàng)建一個配置類import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter; Configuration public class CorsConfig { Bean public CorsFilter corsFilter() { CorsConfiguration config new CorsConfiguration(); // 允許所有域名訪問生產(chǎn)環(huán)境應(yīng)指定具體前端地址 config.addAllowedOriginPattern(*); // 允許攜帶cookie config.setAllowCredentials(true); // 允許所有請求方法 config.addAllowedMethod(*); // 允許所有請求頭 config.addAllowedHeader(*); // 暴露哪些響應(yīng)頭給前端 config.addExposedHeader(*); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); } }這樣前端axios就能正常調(diào)用后端接口了。3. 實現(xiàn)核心業(yè)務(wù)功能模塊環(huán)境跑通后按照“數(shù)據(jù)庫 - 后端 - 前端”的順序?qū)崿F(xiàn)功能。這里以“資助申請與審核”這個核心流程為例。3.1 數(shù)據(jù)庫設(shè)計與關(guān)鍵SQL創(chuàng)建fund_application資助申請表和audit_record審核記錄表這是實現(xiàn)審批流的關(guān)鍵。-- 資助申請表 CREATE TABLE fund_application ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 主鍵ID, student_id int(11) NOT NULL COMMENT 學生ID, project_id int(11) NOT NULL COMMENT 資助項目ID, application_reason text COMMENT 申請理由, attachment_path varchar(500) DEFAULT NULL COMMENT 證明材料路徑, status tinyint(4) NOT NULL DEFAULT 1 COMMENT 狀態(tài)1-待輔導員審核2-待學院審核3-待學校審核4-審核通過5-審核駁回, current_auditor_id int(11) DEFAULT NULL COMMENT 當前待審核人ID, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_student_id (student_id), KEY idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT資助申請表; -- 審核記錄表 (每條審核操作都記錄在此) CREATE TABLE audit_record ( id int(11) NOT NULL AUTO_INCREMENT, application_id int(11) NOT NULL COMMENT 申請ID, auditor_id int(11) NOT NULL COMMENT 審核人ID, auditor_role varchar(50) NOT NULL COMMENT 審核人角色, audit_result tinyint(4) NOT NULL COMMENT 審核結(jié)果1-通過2-駁回, audit_opinion varchar(500) DEFAULT NULL COMMENT 審核意見, audit_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_application_id (application_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT審核記錄表;關(guān)鍵點fund_application.status字段記錄了申請單的當前狀態(tài)驅(qū)動著整個流程。audit_record表記錄了所有審核痕跡便于追溯。3.2 后端接口開發(fā)SpringMVC MyBatis實體類Entity創(chuàng)建與數(shù)據(jù)庫表對應(yīng)的Java類如FundApplication、AuditRecord。Mapper接口與XML使用MyBatis在Mapper接口中定義數(shù)據(jù)庫操作方法在對應(yīng)的XML文件中編寫SQL。// FundApplicationMapper.java public interface FundApplicationMapper { ListFundApplication selectByStudentId(Param(studentId) Integer studentId); // 根據(jù)狀態(tài)和審核人ID查詢待辦列表給輔導員、學院管理員用 ListFundApplication selectTodoListByAuditor(Param(status) Integer status, Param(auditorId) Integer auditorId); int updateStatus(Param(id) Integer id, Param(status) Integer status, Param(currentAuditorId) Integer currentAuditorId); }!-- FundApplicationMapper.xml -- select idselectTodoListByAuditor resultTypeFundApplication SELECT a.* FROM fund_application a WHERE a.status #{status} !-- 這里需要根據(jù)業(yè)務(wù)邏輯關(guān)聯(lián)查詢確定當前審核人是否是該學生的輔導員或?qū)W院管理員 -- AND a.current_auditor_id #{auditorId} ORDER BY a.create_time DESC /selectService層實現(xiàn)核心業(yè)務(wù)邏輯如提交申請、執(zhí)行審核。Service public class AuditService { Autowired private FundApplicationMapper applicationMapper; Autowired private AuditRecordMapper auditRecordMapper; Transactional // 重要審核操作要放在事務(wù)里 public void doAudit(AuditRequest request) { // 1. 查詢原申請單 FundApplication application applicationMapper.selectById(request.getApplicationId()); // 2. 校驗權(quán)限當前登錄用戶是否有權(quán)審核此單 // 3. 更新申請單狀態(tài)和當前審核人 Integer newStatus calculateNextStatus(application.getStatus(), request.getAuditResult()); applicationMapper.updateStatus(application.getId(), newStatus, getNextAuditorId(newStatus, application)); // 4. 插入審核記錄 AuditRecord record new AuditRecord(); record.setApplicationId(application.getId()); record.setAuditorId(request.getAuditorId()); record.setAuditorRole(request.getAuditorRole()); record.setAuditResult(request.getAuditResult()); record.setAuditOpinion(request.getOpinion()); auditRecordMapper.insert(record); } private Integer calculateNextStatus(Integer currentStatus, Integer auditResult) { // 根據(jù)當前狀態(tài)和審核結(jié)果通過/駁回計算下一個狀態(tài) // 例如狀態(tài)1輔導員待審 審核通過 - 狀態(tài)2學院待審 // 審核駁回 - 狀態(tài)5已駁回 // ... 具體邏輯 } }Controller層提供RESTful API給前端調(diào)用。RestController RequestMapping(/api/audit) public class AuditController { Autowired private AuditService auditService; PostMapping(/do) public ResponseEntityCommonResult doAudit(RequestBody AuditRequest request, HttpSession session) { // 從session或token中獲取當前登錄用戶信息并設(shè)置到request中 User currentUser (User) session.getAttribute(user); request.setAuditorId(currentUser.getId()); request.setAuditorRole(currentUser.getRole()); auditService.doAudit(request); return ResponseEntity.ok(CommonResult.success(審核完成)); } GetMapping(/todo-list) public ResponseEntityCommonResult getTodoList(RequestParam Integer status, HttpSession session) { User currentUser (User) session.getAttribute(user); ListFundApplication list auditService.getTodoList(status, currentUser.getId()); return ResponseEntity.ok(CommonResult.success(list)); } }3.3 前端頁面與交互Vue Element UI路由與權(quán)限在router/index.js中配置路由并使用路由守衛(wèi)進行權(quán)限控制。// 路由守衛(wèi)示例 router.beforeEach((to, from, next) { const userRole store.state.user.role; // 從Vuex獲取用戶角色 if (to.meta.roles !to.meta.roles.includes(userRole)) { // 如果目標路由需要特定角色而用戶角色不匹配 next(/403); // 跳轉(zhuǎn)到無權(quán)限頁面 } else { next(); } });狀態(tài)管理使用Vuex存儲用戶登錄狀態(tài)。用戶登錄成功后將用戶信息和token存入Vuex并持久化到localStorage。頁面組件開發(fā)學生申請頁面使用Element UI的Form組件構(gòu)建表單Upload組件上傳材料通過axios提交到后端。輔導員/管理員待辦頁面使用Table組件展示待審核的申請列表。關(guān)鍵列包括學生姓名、申請項目、申請時間、當前狀態(tài)。提供“審核”按鈕點擊后彈出Dialog對話框填寫審核意見和結(jié)果。template el-table :datatodoList stylewidth: 100% el-table-column propstudentName label學生姓名/el-table-column el-table-column propprojectName label資助項目/el-table-column el-table-column propstatus label狀態(tài) :formatterformatStatus/el-table-column el-table-column label操作 template #defaultscope el-button sizesmall clickhandleAudit(scope.row)審核/el-button /template /el-table-column /el-table !-- 審核對話框 -- el-dialog v-modelauditDialogVisible title審核申請 el-form :modelauditForm el-form-item label審核結(jié)果 el-radio-group v-modelauditForm.result el-radio :label1通過/el-radio el-radio :label2駁回/el-radio /el-radio-group /el-form-item el-form-item label審核意見 el-input v-modelauditForm.opinion typetextarea/el-input /el-form-item /el-form template #footer el-button clickauditDialogVisible false取消/el-button el-button typeprimary clicksubmitAudit確定/el-button /template /el-dialog /template script import { getTodoList, submitAudit } from /api/audit; export default { data() { return { todoList: [], auditDialogVisible: false, currentApplicationId: null, auditForm: { result: 1, opinion: } }; }, mounted() { this.fetchTodoList(); }, methods: { async fetchTodoList() { const res await getTodoList({ status: 1 }); // 假設(shè)狀態(tài)1是待輔導員審核 this.todoList res.data; }, handleAudit(row) { this.currentApplicationId row.id; this.auditDialogVisible true; }, async submitAudit() { await submitAudit({ applicationId: this.currentApplicationId, ...this.auditForm }); this.$message.success(審核提交成功); this.auditDialogVisible false; this.fetchTodoList(); // 刷新列表 } } }; /scriptAPI封裝在src/api目錄下創(chuàng)建audit.js等文件統(tǒng)一管理所有后端接口請求。// src/api/audit.js import request from /utils/request; // 這是基于axios封裝的請求工具 export function getTodoList(params) { return request({ url: /api/audit/todo-list, method: get, params }); } export function submitAudit(data) { return request({ url: /api/audit/do, method: post, data }); }4. 項目部署、演示與答辯準備代碼寫完只是第一步讓項目能在評審老師的電腦上順利跑起來并且清晰地展示你的工作同樣重要。4.1 后端打包與部署打包在Spring Boot項目的根目錄包含pom.xml的目錄下運行Maven命令mvn clean package -DskipTests。成功后會在target目錄下生成一個*.jar文件如student-funding-0.0.1-SNAPSHOT.jar。準備運行環(huán)境確保演示電腦上安裝了JDK和MySQL。導入數(shù)據(jù)庫將你的數(shù)據(jù)庫SQL腳本包含建表語句和必要的初始數(shù)據(jù)如管理員賬號、資助項目在演示電腦的MySQL中執(zhí)行。配置與運行將打包好的jar文件、application.properties或application.yml配置文件放到演示電腦的同一個文件夾。在配置文件中修改數(shù)據(jù)庫連接信息指向演示電腦的MySQL。在命令行中進入該目錄運行java -jar student-funding-0.0.1-SNAPSHOT.jar。看到Spring Boot的啟動日志沒有報錯說明后端服務(wù)啟動成功。4.2 前端打包與部署打包在前端項目根目錄下運行npm run build。這會在項目下生成一個dist文件夾里面是壓縮優(yōu)化后的靜態(tài)文件HTML, CSS, JS。部署有兩種簡單方式供演示方式一使用Node.js靜態(tài)服務(wù)安裝serve工具npm install -g serve。然后在dist目錄下運行serve -s .它會啟動一個本地HTTP服務(wù)器默認端口3000。你訪問http://localhost:3000就能看到前端頁面。方式二將dist文件夾放入后端靜態(tài)資源目錄更推薦。將前端dist文件夾里的所有文件復制到Spring Boot項目的src/main/resources/static目錄下。然后重新打包后端。這樣訪問后端服務(wù)地址如http://localhost:8080就能直接打開前端頁面實現(xiàn)了前后端一體化部署演示時只需啟動一個Jar包非常方便。4.3 答辯演示要點與避坑指南演示腳本提前寫好一個演示腳本按邏輯順序操作。例如1. 學生登錄 - 申請資助2. 輔導員登錄 - 審核通過3. 學院管理員登錄 - 審核通過4. 學校管理員登錄 - 最終審批并發(fā)布公示。確保每個環(huán)節(jié)的數(shù)據(jù)都能在頁面上看到變化。準備測試數(shù)據(jù)提前在數(shù)據(jù)庫里插入幾條完整的測試數(shù)據(jù)覆蓋不同狀態(tài)待審、通過、駁回避免演示時現(xiàn)場錄入浪費時間。重點展示你的工作權(quán)限控制演示用學生賬號登錄無法訪問審核頁面。業(yè)務(wù)閉環(huán)演示一個申請從提交到最終審批通過的完整流程并在數(shù)據(jù)庫中展示關(guān)聯(lián)的審核記錄。關(guān)鍵技術(shù)點可以簡單提一下你是如何解決跨域的、事務(wù)管理如何保證審核數(shù)據(jù)一致性、Vuex如何管理登錄狀態(tài)等。常見避坑點端口沖突確保演示時后端端口如8080沒有被其他程序占用。數(shù)據(jù)庫連接失敗檢查application.properties中的數(shù)據(jù)庫IP、端口、用戶名、密碼是否正確以及MySQL服務(wù)是否已啟動。前端請求404檢查前端axios請求的baseURL是否配置為后端正確的地址和端口。頁面空白或樣式錯亂檢查前端打包后資源路徑是否正確。如果部署到Spring Boot的static目錄可能需要配置vue.config.js中的publicPath為./。準備一個干凈的備用環(huán)境如果可能在答辯前將整個項目源碼、數(shù)據(jù)庫腳本、運行說明打包并在一臺干凈的電腦上預演一遍。這能發(fā)現(xiàn)所有隱藏的環(huán)境依賴問題。最后記住畢設(shè)的核心是展示你運用技術(shù)解決實際問題的能力。把“高校學生資助”這個業(yè)務(wù)背景吃透用清晰的技術(shù)架構(gòu)把它實現(xiàn)出來并流暢地演示出來你的項目就已經(jīng)成功了一大半。代碼的優(yōu)雅程度可以逐步提升但一個能跑通、邏輯清晰的系統(tǒng)是獲得好評的基礎(chǔ)。