貿(mào)市場管理系統(tǒng)畢業(yè)設(shè)計(jì)全流程解析)
又到了畢業(yè)設(shè)計(jì)選題的時候我最近被問到最多的問題就是SpringBoot農(nóng)貿(mào)市場管理系統(tǒng)這種題目是不是太簡單了做出來會不會顯得沒有技術(shù)含量說實(shí)話兩年前我自己接觸這個方向時也有同樣的疑慮但真正把一個基于SpringBoot的農(nóng)產(chǎn)品在線交易平臺從零搭起來之后才發(fā)現(xiàn)這個題目的水很深——它表面是個“管理系統(tǒng)”實(shí)際上要求你在一套B/S架構(gòu)里跑通生鮮電商的完整鏈路商品管理、購物車、訂單、庫存、支付、統(tǒng)計(jì)分析全都要有。它的業(yè)務(wù)復(fù)雜度介于“圖書管理”和“電商秒殺”之間既不會讓你無從下手又能把SpringBoot生態(tài)里的核心知識點(diǎn)全部串起來是非常典型的畢業(yè)設(shè)計(jì)優(yōu)質(zhì)選題。這篇文章我會把整個項(xiàng)目的落地過程拆開來講內(nèi)容包括需求邊界怎么圈定、技術(shù)棧怎么選型、數(shù)據(jù)庫表怎么設(shè)計(jì)、核心交易鏈路怎么實(shí)現(xiàn)、開發(fā)過程中最容易被扣分的幾個坑以及最后論文和答辯怎么準(zhǔn)備。不管你是想直接參考這個題目還是打算在它基礎(chǔ)上換個場景比如社區(qū)團(tuán)購、校園二手交易這套思路都能復(fù)用。1. 三個關(guān)鍵詞幫我圈定了需求邊界1.1 系統(tǒng)里到底有哪幾類角色剛開始拿到這個題目時最容易犯的錯誤是上來就寫代碼。我見過一位同學(xué)第一版把系統(tǒng)做成了“商戶后臺管理后臺”兩個界面消費(fèi)者端的瀏覽和下單功能完全沒有答辯時被導(dǎo)師問了一句“你的農(nóng)產(chǎn)品賣給誰”當(dāng)場就沒接上話。這里要先把標(biāo)題里的三個關(guān)鍵詞拆開理解“農(nóng)貿(mào)市場管理系統(tǒng)”強(qiáng)調(diào)的是線下市場管理側(cè)比如攤位商戶管理、市場公告、投訴建議、交易數(shù)據(jù)匯總。“農(nóng)產(chǎn)品在線交易平臺”強(qiáng)調(diào)線上交易側(cè)消費(fèi)者可以逛、加購物車、下單。“生鮮電商服務(wù)系統(tǒng)”強(qiáng)調(diào)業(yè)務(wù)的電商屬性訂單狀態(tài)流轉(zhuǎn)、庫存扣減、支付流程要設(shè)計(jì)得像樣。把這三個維度合并后系統(tǒng)的角色應(yīng)該是四類角色核心訴求對應(yīng)功能消費(fèi)者在線買菜、查詢訂單商品瀏覽、購物車、下單、模擬支付、訂單跟蹤商戶/攤主上架商品、管理庫存商品管理、庫存修改、訂單發(fā)貨市場運(yùn)營管理員維護(hù)市場秩序、發(fā)布公告商戶入駐審核、商品審核、公告管理、數(shù)據(jù)統(tǒng)計(jì)系統(tǒng)管理員平臺運(yùn)維用戶管理、角色權(quán)限、系統(tǒng)配置我在項(xiàng)目里最終實(shí)現(xiàn)的版本中消費(fèi)者走C端頁面商戶和管理員共用一套后臺管理界面通過角色權(quán)限來控制菜單和數(shù)據(jù)范圍。這樣做的好處是頁面數(shù)量不會失控同時又能體現(xiàn)“不同角色看到不同內(nèi)容”的權(quán)限設(shè)計(jì)思路。1.2 哪些功能必須做哪些可以直接砍掉畢業(yè)設(shè)計(jì)不是商業(yè)項(xiàng)目最忌諱“功能堆砌”。我在需求階段列了一個優(yōu)先級清單原則是先保證主鏈路完整再考慮錦上添花。必須做的主鏈路功能用戶注冊登錄手機(jī)號密碼JWT鑒權(quán)商品分類瀏覽和關(guān)鍵字搜索購物車增刪改查下單生成訂單、扣庫存模擬支付回調(diào)支付結(jié)果、更新訂單狀態(tài)商戶端商品上下架、庫存維護(hù)后臺用戶管理、公告管理基礎(chǔ)數(shù)據(jù)統(tǒng)計(jì)訂單量、銷售額、商品銷量Top10可以后期擴(kuò)展的功能論文里寫成“未來展望”即可優(yōu)惠券和滿減活動菜品推薦算法配送路線規(guī)劃用戶評價和投訴秒殺活動這里有個很重要的經(jīng)驗(yàn)如果時間只有兩到三個月主鏈路能跑通、能講清楚就已經(jīng)超過大部分人了。把4個模塊做深遠(yuǎn)比把10個模塊都做出來但每個都是“增刪改查”更有說服力。1.3 把需求翻譯成頁面清單我習(xí)慣用“用戶故事”來梳理頁面。比如“消費(fèi)者小明在首頁看到今日推薦點(diǎn)擊商品詳情加入購物車結(jié)算支付然后在訂單列表里看到物流狀態(tài)”。每個用戶故事對應(yīng)一組頁面列出來后需求邊界就非常清晰。最終頁面清單大致是消費(fèi)者端首頁、商品列表、商品詳情、購物車、結(jié)算頁、訂單列表、訂單詳情、個人中心商戶端Dashboard、商品管理、訂單處理發(fā)貨/缺貨、銷售統(tǒng)計(jì)管理端用戶管理、商戶入駐審核、公告管理、分類管理、系統(tǒng)統(tǒng)計(jì)2. 技術(shù)選型不是越新越好夠用且能講清原理才重要2.1 選型清單和背后的理由我做這套系統(tǒng)時用的技術(shù)棧如下層面選擇說明后端框架SpringBoot 2.7.x穩(wěn)定資料多舊版本的坑基本都被踩過了ORM框架MyBatis-Plus單表CRUD直接內(nèi)置復(fù)雜查詢手寫SQL兼顧效率與靈活數(shù)據(jù)庫MySQL 8.0用5.7也行8.0對窗口函數(shù)支持更好統(tǒng)計(jì)數(shù)據(jù)方便緩存Redis僅用于首頁緩存和購物車優(yōu)化非必須但加上了可以顯著提升論文深度鑒權(quán)方式JWT Spring攔截器比Spring Security輕量很多也更容易解釋清楚前端Vue 3 Element Plus Axios前后端分離體現(xiàn)B/S架構(gòu)下的現(xiàn)代開發(fā)模式構(gòu)建工具M(jìn)aven依賴管理方便團(tuán)隊(duì)配合還是單人開發(fā)都適合當(dāng)初沒有選Spring Security是因?yàn)樗倪^濾器鏈、UserDetailsService、權(quán)限表達(dá)式這套體系對新手來說學(xué)習(xí)曲線比較陡很容易把時間耗在配置上而不是業(yè)務(wù)上。而JWT方案的核心邏輯就三件事登錄后簽發(fā)token攔截器校驗(yàn)token從token中解析用戶身份。這個鏈路自己寫一遍之后對“無狀態(tài)鑒權(quán)”的理解會比直接用框架深得多。2.2 B/S架構(gòu)分層的直觀理解面向B/S架構(gòu)意味著用戶在瀏覽器里訪問系統(tǒng)不需要安裝客戶端。代碼層面上一次請求的完整鏈路是瀏覽器Vue頁面或HTML - 發(fā)起HTTP請求 - Controller層接收參數(shù)、校驗(yàn)請求 - Service層處理業(yè)務(wù)邏輯、管理事務(wù) - Mapper層與MySQL交互 - 返回?cái)?shù)據(jù)封裝成統(tǒng)一格式 - 瀏覽器渲染展示我在實(shí)際開發(fā)中嚴(yán)格要求自己遵守“Controller里不寫業(yè)務(wù)代碼”的原則。很多同學(xué)最終代碼的Service層很薄所有邏輯都堆在Controller里雖然功能能跑但答辯時一問“你的業(yè)務(wù)邏輯在哪一層”就會露怯。2.3 開發(fā)環(huán)境上兩個容易卡住的地方Maven和MySQL的版本搭配是第一個坑。Maven 3.6.3配合JDK 8是安全的組合SpringBoot 2.7.x原生支持JDK 8不需要額外配置。如果你用的是JDK 17則要注意SpringBoot必須使用2.7.0以上版本否則會報Caused by: java.lang.IllegalArgumentException之類的兼容性錯誤。第二個坑是MySQL 8.0的驅(qū)動變化。SpringBoot 2.7.x默認(rèn)用的是com.mysql.cj.jdbc.Driver如果你在配置文件里寫了老版的com.mysql.jdbc.Driver啟動時會告警。最保險的配置是spring.datasource.urljdbc:mysql://localhost:3306/market_db?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/Shanghai spring.datasource.usernameroot spring.datasource.password你的密碼 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver注意serverTimezoneAsia/Shanghai不能省略否則時間字段的查詢結(jié)果會和本地時間差8個小時。3. 數(shù)據(jù)庫設(shè)計(jì)錢和庫存是兩個最容易出錯的地方3.1 核心表清單與關(guān)系數(shù)據(jù)庫設(shè)計(jì)是整個項(xiàng)目的根后面的代碼都是圍繞表結(jié)構(gòu)展開的。我把核心表整理成下面這個清單表名用途重要字段user用戶表消費(fèi)者/商戶/管理員共用username、password、phone、rolemerchant商戶信息表user_id、market_name、address、audit_statuscategory商品分類表name、parent_id、sortproduct商品表name、category_id、merchant_id、price、stock、unit、image、statuscart購物車表user_id、product_id、quantityorders訂單主表order_no、user_id、merchant_id、total_amount、status、create_timeorder_item訂單明細(xì)表order_id、product_id、product_name、price、quantity、subtotalpayment支付流水表order_id、payment_no、amount、status、pay_timeannouncement公告表title、content、create_time為什么訂單要拆成主表和明細(xì)表因?yàn)橛唵魏蜕唐肥嵌鄬Χ嗟年P(guān)系。一個訂單里可能有胡蘿卜和白菜兩樣商品如果把商品名和價格直接放在訂單表里那訂單表里的字段就會冗余且難以擴(kuò)展。拆成orders order_item之后訂單主表只管總金額、狀態(tài)、下單人等核心信息明細(xì)表記錄每個商品的快照。3.2 金額為什么必須用Decimal生鮮商品的價格涉及小數(shù)點(diǎn)比如土豆2.58元/斤很多初學(xué)者喜歡用double或float來存價格這是一個非常經(jīng)典的錯誤??纯催@段代碼double a 0.58; double b 0.01; System.out.println(a b); // 輸出 0.5899999999999999原因在于浮點(diǎn)數(shù)在計(jì)算機(jī)中是以二進(jìn)制存儲的很多十進(jìn)制小數(shù)無法精確表示。涉及金額的場景必須使用BigDecimal數(shù)據(jù)庫字段類型用DECIMAL(10, 2)。下單計(jì)算總價時也要用BigDecimal而不是先轉(zhuǎn)成double再乘。[[注意]]在JSON序列化時BigDecimal默認(rèn)會輸出成數(shù)字前端展示沒有問題。但如果你在計(jì)算時把BigDecimal除以100之類的操作記得用divide方法時必須指定小數(shù)位數(shù)比如price.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)否則會報ArithmeticException: Non-terminating decimal expansion。3.3 庫存字段設(shè)計(jì)預(yù)留擴(kuò)展余地生鮮商品的庫存單位可能不是“件”而是“斤”“份”所以product表里我加了unit字段。庫存字段名不要用count這是SQL關(guān)鍵字最好用stock。另外哪怕你現(xiàn)在不做并發(fā)控制也要提前在表里留一個version字段后面做樂觀鎖扣庫存時可以派上大用場。商品表的建表SQL核心部分大致是這樣CREATE TABLE product ( id BIGINT AUTO_INCREMENT PRIMARY KEY, category_id BIGINT NOT NULL COMMENT 分類ID, merchant_id BIGINT NOT NULL COMMENT 商戶ID, name VARCHAR(100) NOT NULL COMMENT 商品名稱, price DECIMAL(10,2) NOT NULL COMMENT 單價, stock INT NOT NULL DEFAULT 0 COMMENT 庫存, unit VARCHAR(20) DEFAULT 斤 COMMENT 單位, image VARCHAR(255) COMMENT 商品圖片, status TINYINT DEFAULT 1 COMMENT 1上架 0下架, version INT DEFAULT 0 COMMENT 樂觀鎖版本號, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );3.4 訂單狀態(tài)機(jī)的設(shè)計(jì)訂單狀態(tài)是整個系統(tǒng)里最容易講出彩的地方。我設(shè)計(jì)的狀態(tài)流轉(zhuǎn)是待支付(0) - 已支付(1) - 備貨中(2) - 配送中(3) - 已完成(4) 待支付(0) - 已取消(5) 已支付(1) - 申請退款(6) - 已退款(7)狀態(tài)用整數(shù)存并單獨(dú)建一個常量類或者枚舉類來定義千萬不能直接在Controller里寫魔法數(shù)字。比如public class OrderStatus { public static final int PENDING_PAYMENT 0; public static final int PAID 1; public static final int PREPARING 2; public static final int DELIVERING 3; public static final int COMPLETED 4; public static final int CANCELLED 5; }這里說一個經(jīng)驗(yàn)訂單狀態(tài)更新時SQL里一定要帶上“當(dāng)前狀態(tài)”條件。比如用戶點(diǎn)擊“取消訂單”時更新語句是UPDATE orders SET status 5 WHERE id #{orderId} AND status 0如果返回的影響行數(shù)是0說明訂單已經(jīng)不是待支付狀態(tài)了這時候要提示用戶“當(dāng)前狀態(tài)不可取消”。這種寫法叫樂觀鎖在狀態(tài)流轉(zhuǎn)上的應(yīng)用能防止兩個操作同時把訂單狀態(tài)覆蓋掉。4. 核心交易鏈路代碼落地4.1 注冊登錄與JWT鑒權(quán)登錄模塊我采用的是JWT方案。用戶在登錄成功后后端用用戶的id、角色和過期時間生成一個token返回給前端。前端把它存在localStorage里之后每次請求在Header里帶上Authorization: Bearer xxx。JWT工具類的核心方法如下public class JwtUtil { private static final String SECRET your-secret-key-change-me; public static String generateToken(Long userId, String role) { return Jwts.builder() .setSubject(String.valueOf(userId)) .claim(role, role) .setExpiration(new Date(System.currentTimeMillis() 7 * 24 * 3600 * 1000L)) .signWith(SignatureAlgorithm.HS256, SECRET) .compact(); } public static Claims parseToken(String token) { return Jwts.parser() .setSigningKey(SECRET) .parseClaimsJws(token) .getBody(); } }攔截器里校驗(yàn)token并放行public class JwtInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (OPTIONS.equalsIgnoreCase(request.getMethod())) { return true; } String authHeader request.getHeader(Authorization); if (authHeader ! null authHeader.startsWith(Bearer )) { try { Claims claims JwtUtil.parseToken(authHeader.substring(7)); request.setAttribute(userId, Long.parseLong(claims.getSubject())); request.setAttribute(role, claims.get(role)); return true; } catch (Exception e) { response.setStatus(401); return false; } } response.setStatus(401); return false; } }注冊時密碼一定要加密存儲至少使用BCryptPasswordEncoder。千萬不要明文存密碼這在論文里體現(xiàn)“安全性設(shè)計(jì)”時也是一個得分點(diǎn)。4.2 下單事務(wù)的邊界哪些操作要放在同一個事務(wù)里下單看起來簡單但它的原子性邊界需要想清楚。我最終把以下四個操作放在一個事務(wù)方法里校驗(yàn)商品狀態(tài)和庫存是否充足生成訂單主表和訂單明細(xì)扣減商品庫存生成支付流水狀態(tài)為待支付對應(yīng)的Service方法上加Transactional注解Transactional(rollbackFor Exception.class) public OrderVO createOrder(OrderCreateDTO dto, Long userId) { // 1. 從購物車或前端傳來的商品列表獲取items // 2. 遍歷items校驗(yàn)庫存 // 3. 計(jì)算總金額 // 4. 批量扣庫存 // 5. 插入orders和order_item // 6. 插入payment記錄 return orderVO; }rollbackFor Exception.class這一行值得專門解釋一下。默認(rèn)情況下Spring只能對RuntimeException進(jìn)行事務(wù)回滾如果你在方法里拋出了一個受檢異常比如自定義的BizException extends Exception事務(wù)是不會自動回滾的。很多同學(xué)在這個細(xì)節(jié)上栽過跟頭我比較推薦自定義異常時直接繼承RuntimeException。4.3 扣庫存時用樂觀鎖防止超賣這是整個項(xiàng)目里最有技術(shù)含金量的點(diǎn)。在第一次測試時我用兩個賬號對同一件只剩1份的商品同時下單結(jié)果兩個訂單都成功了庫存變成了-1。原因很簡單代碼里的“先查庫存再更新庫存”不是原子操作。修復(fù)方法是把庫存校驗(yàn)和扣減合并成一條SQL同時判斷庫存數(shù)量int updated productMapper.updateStock(productId, quantity);對應(yīng)的XMLupdate idupdateStock UPDATE product SET stock stock - #{quantity}, version version 1 WHERE id #{productId} AND stock #{quantity} /update如果updated 0說明庫存不足或商品已被修改此時直接拋出“庫存不足”異常讓整個事務(wù)回滾。這里沒有用數(shù)據(jù)庫悲觀鎖SELECT ... FOR UPDATE是因?yàn)樯r商品高頻短小的查詢場景更多樂觀鎖在讀多寫少的畢業(yè)設(shè)計(jì)流量下完全夠用而且更容易在答辯時解釋清楚。4.4 模擬支付把接口設(shè)計(jì)成可以替換的樣子真實(shí)對接第三方支付需要商戶號、證書和回調(diào)驗(yàn)簽這在畢業(yè)設(shè)計(jì)中不太現(xiàn)實(shí)。但我采用了一種“接口隔離”的方案讓模擬支付和真實(shí)支付能夠無縫切換public interface PaymentService { PaymentResult pay(Long orderId, BigDecimal amount); } Service public class MockPaymentServiceImpl implements PaymentService { Override public PaymentResult pay(Long orderId, BigDecimal amount) { // 模擬支付固定延遲1~2秒后返回成功 // 更新訂單狀態(tài)為已支付 // 更新支付流水狀態(tài)為已支付 return PaymentResult.success(模擬支付成功); } }前端在支付頁調(diào)/api/payment/pay后端直接執(zhí)行模擬邏輯。答辯時如果你說“這里做了一個支付接口抽象層如果接真實(shí)支付只需要新寫一個實(shí)現(xiàn)類替換即可”這個回答是很加分的。5. 真實(shí)開發(fā)中踩過的坑5.1 前端跨域和統(tǒng)一返回格式前后端分離之后本地開發(fā)時Vue在8080端口后端在8081端口瀏覽器默認(rèn)會攔截跨域請求。最初我在Controller里一個一個寫CrossOrigin非常丑陋也不規(guī)范。后來配置了一個WebMvcConfigurer全局跨域Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOriginPatterns(*) .allowedMethods(GET, POST, PUT, DELETE, OPTIONS) .allowedHeaders(*) .allowCredentials(true) .maxAge(3600); } }同時我封裝了一個統(tǒng)一返回格式ResultT包含code、message、data三個字段。成功返回Result.success(data)失敗返回Result.error(參數(shù)錯誤)。這樣前端只需要攔截一次響應(yīng)根據(jù)code做統(tǒng)一處理而不是每個接口各自為政。5.2 MyBatis-Plus的分頁插件沒配置就會導(dǎo)致分頁失效使用MyBatis-Plus分頁時selectPage()方法如果不配置分頁插件你會發(fā)現(xiàn)它對傳入的Page參數(shù)無動于衷直接查出全表。這是因?yàn)榉猪摴δ芤蕾嘙ybatisPlusInterceptor里注冊的PaginationInnerInterceptorConfiguration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }這個坑的癥狀非常隱蔽頁面能出數(shù)據(jù)但數(shù)據(jù)庫里明明有50條記錄第一頁卻顯示了全部。排查辦法是看控制臺打出的SQL有沒有LIMIT關(guān)鍵字。5.3 前端時間字段顯示差8小時訂單創(chuàng)建時間傳給前端后頁面上顯示的時間比實(shí)際時間少了8個小時。原因有兩個一是MySQL連接串沒有加serverTimezoneAsia/Shanghai前面提過二是Jackson序列化LocalDateTime時默認(rèn)采用UTC時區(qū)。解決方式是在application.yml里明確序列化格式spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8實(shí)體類里時間字段習(xí)慣上用LocalDateTime而不是Date配合上面的配置后前后端顯示時間就一致了。5.4 文件上傳圖片路徑到底存什么商品圖片上傳時我犯過一個錯誤直接把上傳后的文件完整路徑比如D:/upload/xxx.jpg存進(jìn)了數(shù)據(jù)庫。這個路徑在本地能用但換一臺機(jī)器部署就失效而且前端瀏覽器也不會允許直接訪問本地的D盤路徑。正確的做法是把文件上傳到項(xiàng)目的靜態(tài)資源目錄下比如/resources/upload/然后用http://localhost:8081/upload/xxx.jpg這樣的相對URL風(fēng)格訪問。配置一個靜態(tài)資源映射registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadDir /);數(shù)據(jù)庫里只存/upload/xxx.jpg前端通過后端域名拼接出完整的圖片地址。這樣項(xiàng)目換服務(wù)器后只要上傳目錄路徑改一下配置圖片就能繼續(xù)訪問。5.5 統(tǒng)計(jì)報表里的小數(shù)計(jì)算管理端的數(shù)據(jù)統(tǒng)計(jì)功能里銷售額需要按月匯總。如果在SQL里用SUM(order_item.subtotal)直接計(jì)算由于subtotal是Decimal類型結(jié)果沒問題。但如果你把Decimal轉(zhuǎn)成Float去計(jì)算匯總就會碰到浮點(diǎn)數(shù)精度問題。我最終在SQL層面全部使用ROUND(SUM(amount), 2)來處理Java代碼中統(tǒng)計(jì)結(jié)果的DTO字段類型也用String或BigDecimal來承接避免JSON序列化帶來的精度丟失。6. 答辯準(zhǔn)備和論文結(jié)構(gòu)怎么搭6.1 做一份演示腳本答辯時最尷尬的事不是bug崩潰而是演示到一半不知道下一步要操作什么。我建議提前準(zhǔn)備一份演示腳本按正常用戶操作路徑走一遍注冊一個新用戶登錄在首頁搜索“土豆”加入購物車購物車?yán)镎{(diào)整數(shù)量結(jié)算下單訂單列表看到待支付訂單執(zhí)行模擬支付切換商戶賬號在訂單管理里看到新訂單執(zhí)行發(fā)貨切回消費(fèi)者賬號看到訂單狀態(tài)變?yōu)榕渌椭星械焦芾韱T賬號查看銷售統(tǒng)計(jì)確認(rèn)金額正確演示時不要點(diǎn)開那種需要輸入復(fù)雜數(shù)據(jù)的表單盡量用提前構(gòu)造好的演示賬號和數(shù)據(jù)。也可以準(zhǔn)備一個小號專門用來演示登錄注冊流程。6.2 論文的核心章節(jié)怎么寫雖然每個學(xué)校的論文模板不同但大體邏輯是一樣的。我的論文目錄大致如下第一章 引言背景、目的與意義、國內(nèi)外現(xiàn)狀第二章 相關(guān)技術(shù)介紹SpringBoot、MyBatis-Plus、Vue、Redis、JWT第三章 系統(tǒng)分析可行性分析、需求分析、用例分析第四章 系統(tǒng)設(shè)計(jì)總體架構(gòu)、功能模塊設(shè)計(jì)、數(shù)據(jù)庫設(shè)計(jì)第五章 系統(tǒng)實(shí)現(xiàn)每個功能模塊的實(shí)現(xiàn)和核心代碼第六章 系統(tǒng)測試測試用例、測試結(jié)果、性能分析第七章 總結(jié)與展望關(guān)于“國內(nèi)外現(xiàn)狀”這一章很多同學(xué)寫不好大段抄別人的話。我的建議是聚焦“農(nóng)產(chǎn)品電商在國內(nèi)的生鮮配送模式演進(jìn)”比如從傳統(tǒng)B2C到前置倉到社區(qū)團(tuán)購然后落腳在“如何在校園/農(nóng)貿(mào)市場場景設(shè)計(jì)輕量級交易系統(tǒng)”這個定位就很自然順暢。6.3 常見答辯問題清單根據(jù)我的經(jīng)驗(yàn)導(dǎo)師最喜歡問的問題集中在以下幾個方向?yàn)槭裁催x擇SpringBoot而不是SSM——回答框架演進(jìn)、約定優(yōu)于配置、生態(tài)整合訂單超賣問題是怎么解決的——樂觀鎖SQL更新庫存、事務(wù)回滾用戶密碼是怎么存儲的——BCrypt加密不存明文如果樓上說的模擬支付換成真實(shí)微信支付需要改動哪些地方——增加微信支付實(shí)現(xiàn)類配置回調(diào)接口驗(yàn)簽等系統(tǒng)安全性怎么體現(xiàn)——JWT身份認(rèn)證、權(quán)限攔截器、統(tǒng)一異常處理、密碼加密這些問題要提前用自己的語言組織好答案特別是“樂觀鎖”那段需要能把SQL和事務(wù)講清楚最好配合代碼示意。6.4 時間安排建議我做這個項(xiàng)目整體用時大約兩個月主要時間分配是階段時間內(nèi)容需求分析技術(shù)預(yù)演第一周確定功能列表、搭建項(xiàng)目骨架、跑通HelloWorld數(shù)據(jù)庫設(shè)計(jì)與后端基礎(chǔ)CRUD第二周至第三周表結(jié)構(gòu)、用戶模塊、商品模塊核心交易鏈路第四周至第五周購物車、下單、支付、訂單狀態(tài)流轉(zhuǎn)管理端功能第六周商品審核、數(shù)據(jù)統(tǒng)計(jì)、公告管理前端整合與聯(lián)調(diào)第七周Vue頁面完善、接口聯(lián)調(diào)、修bug論文撰寫與答辯準(zhǔn)備第八周按學(xué)校模板整理內(nèi)容、測試、答辯PPT如果你的基礎(chǔ)比較薄弱我建議把技術(shù)預(yù)演的時間拉長一點(diǎn)先單獨(dú)做一個涉及“兩個表聯(lián)合查詢新增數(shù)據(jù)”的小Demo確認(rèn)自己對SpringBoot的請求流轉(zhuǎn)和MyBatis-Plus操作熟練后再開始正式開發(fā)否則很容易在項(xiàng)目初期就陷入“到處搜報錯”的泥潭。最后再說幾個我親測有效的小建議第一一定要用Git從第一天就開始管理代碼哪怕只有你一個人開發(fā)。每完成一個模塊就提交一次版本寫論文時按提交記錄來回憶開發(fā)過程比翻聊天記錄和桌面文件高效得多。第二開發(fā)過程中把遇到的異常和解決方案記錄在一個筆記文件里這部分內(nèi)容可以直接轉(zhuǎn)化成論文中的“系統(tǒng)調(diào)試與問題分析”小節(jié)也是答辯時展示你真實(shí)做過項(xiàng)目的證據(jù)。第三系統(tǒng)的命名和注釋盡量規(guī)范類名用ProductController而不是productController注釋寫清楚業(yè)務(wù)意圖因?yàn)檎撐睦飼苯臃藕诵拇a截圖代碼質(zhì)量會直接影響老師對論文的印象。農(nóng)貿(mào)市場管理系統(tǒng)和農(nóng)產(chǎn)品在線交易平臺這個題目看似樸素但它把B/S架構(gòu)下最典型的業(yè)務(wù)場景完整覆蓋了一遍。做扎實(shí)之后你收獲的不僅僅是一份能通過答辯的項(xiàng)目而是對SpringBoot開發(fā)流程和電商業(yè)務(wù)邏輯的整體感知。如果你正在考慮類似的題目希望這篇復(fù)盤能幫你減少一些摸索的時間。