:從需求到上線踩坑復(fù)盤)
“舊時光”這三個字聽起來就很適合做項目背景——一家主打懷舊復(fù)古風(fēng)的咖啡廳既有堂食、外帶也有會員儲值、積分兌換這些餐飲老玩法。技術(shù)棧選了Java Spring Boot做后端前端用Vue這套組合在學(xué)校畢設(shè)、個人全棧作品、甚至小型創(chuàng)業(yè)項目里都非常成熟資料多、社區(qū)活躍遇到問題基本搜得到答案。這篇文章我不會給你貼一層皮式的“項目展示”而是按我實際做這類點餐收銀系統(tǒng)的思路從需求分析、表結(jié)構(gòu)、后端接口、前端頁面、懷舊主題落地到上線前容易踩的坑完整走一遍。適合正準備做類似管理系統(tǒng)的同學(xué)參考也適合已經(jīng)寫完業(yè)務(wù)、想優(yōu)化代碼細節(jié)的朋友當(dāng)個檢查清單。1. 動手之前先給咖啡廳管理系統(tǒng)“畫像”很多人做管理系統(tǒng)有個通病拿到需求就建表表建完就寫增刪改查結(jié)果做到一半發(fā)現(xiàn)業(yè)務(wù)流程對不上返工成本極高?!芭f時光咖啡廳”這種項目核心是運營閉環(huán)第一步應(yīng)該先把角色、場景和流程定死。1.1 角色與使用場景咖啡廳管理系統(tǒng)絕不是只有管理員一個角色的“單機軟件”我按照現(xiàn)場動線設(shè)計了四類使用者分別對應(yīng)不同的終端和界面角色主要終端職責(zé)核心操作管理員PC后臺門店全局管理商品上下架、訂單查詢、數(shù)據(jù)報表、員工賬號管理收銀員PC收銀臺/平板堂食點單、結(jié)賬、退款快速開單、折扣、接單、打印小票吧臺/后廚后廚顯示屏制作出品查看待制作訂單、標記完成顧客手機瀏覽器掃碼自助點餐掃碼看菜單、下單、查看訂單進度這里有個特別容易忽略的點顧客端必須移動端優(yōu)先收銀臺要適應(yīng)平板觸屏操作而后廚屏是大屏展示。一套 Vue 響應(yīng)式布局在桌面上做“寬度斷點 觸控按鈕加大”就能覆蓋沒必要像有些項目一樣拆好幾個獨立前端工程。1.2 核心業(yè)務(wù)流程梳理我從“顧客進店到離店”這條主線倒推系統(tǒng)功能顧客到店掃描桌臺二維碼手機端瀏覽菜單、加購、提交訂單訂單進入后臺待支付狀態(tài)顧客在線支付或到收銀臺結(jié)賬后廚屏顯示新訂單按順序制作點擊完成收銀臺打印小票顧客取餐或服務(wù)員送餐結(jié)賬后會員積分自動累計餐后顧客可查看歷史訂單。這一套流程對應(yīng)到后端就是桌臺模塊、菜品模塊、購物車模塊、訂單模塊、支付模塊、后廚狀態(tài)流轉(zhuǎn)模塊、會員模塊。你的“管理后臺”其實只服務(wù)其中三分之一的需求另外三分之二都在給顧客和后廚做工具。當(dāng)時我畫完流程有個很關(guān)鍵的體會不要把一個需求的每一步都做成頁面。比如“后廚屏”根本沒有復(fù)雜表單就是一張輪詢更新的列表加一個完成按鈕真正重的邏輯都在訂單狀態(tài)的流轉(zhuǎn)和并發(fā)控制上。2. 數(shù)據(jù)庫設(shè)計“舊時光”的家底怎么盤表結(jié)構(gòu)設(shè)計是這類系統(tǒng)的地基。地基歪了后端的業(yè)務(wù)代碼寫得再漂亮也是空中樓閣。2.1 核心表清單我按業(yè)務(wù)域拆成六大模塊自認為這是咖啡廳管理系統(tǒng)性價比最高的建模方式用戶與權(quán)限user員工/管理員、role、permission或者直接用更簡單的 user role 兩張表 前端按鈕級權(quán)限判斷。多數(shù)校園項目用 JWT 攔截器判斷角色就夠不需要引入復(fù)雜的權(quán)限框架。菜品域category菜品分類、product菜品、product_spec規(guī)格比如大杯/中杯、常溫/加冰還有 product_image 處理多圖切換。桌臺域table包含桌號、座位數(shù)、當(dāng)前狀態(tài)空閑/占用/待清理、綁定的二維碼。訂單域orders主表、order_item明細表、order_status_log狀態(tài)流轉(zhuǎn)記錄。會員域member會員檔案、member_balance_log儲值流水、member_points_log積分流水、coupon優(yōu)惠券和 user_coupon領(lǐng)券記錄。倉儲域material原材料、purchase進貨單、stock_record庫存流水??Х葟d也是要算物料成本的這一塊做好了管報表時才有東西可看。有些同學(xué)對“狀態(tài)機日志表”不重視覺得多寫一張表很麻煩。真上線后你會發(fā)現(xiàn)顧客說“我明明支付了但顯示未支付”或者后廚說“這單怎么重復(fù)出現(xiàn)了”查訂單狀態(tài)歷史時沒有日志你只能跟用戶來回拉扯。加一張 status_log每次狀態(tài)變更記一下誰改的、從哪改到哪、為什么改排查問題效率翻倍。2.2 建表時的幾個細節(jié)訂單主表我建議長這樣省略部分字段CREATE TABLE orders ( id BIGINT PRIMARY KEY AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL COMMENT 訂單號, table_id BIGINT COMMENT 桌臺ID自取可空, member_id BIGINT COMMENT 會員ID非會員可空, total_amount DECIMAL(10,2) NOT NULL COMMENT 應(yīng)收金額, discount_amount DECIMAL(10,2) DEFAULT 0.00 COMMENT 優(yōu)惠金額, pay_amount DECIMAL(10,2) NOT NULL COMMENT 實付金額, pay_type TINYINT COMMENT 1微信 2支付寶 3現(xiàn)金 4儲值卡, status TINYINT NOT NULL COMMENT 訂單狀態(tài), remark VARCHAR(255) COMMENT 顧客備注, create_time DATETIME NOT NULL, update_time DATETIME NOT NULL, KEY idx_order_no (order_no), KEY idx_table_status (table_id, status), KEY idx_create_time (create_time) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT訂單主表;幾個容易踩的點金額一律DECIMAL(10,2)Java 里對應(yīng)BigDecimal絕不用double。咖啡單價看似是 18 元、28 元這種整數(shù)但折扣、滿減、積分抵扣算下來浮點數(shù)誤差積累幾萬單之后會很惡心。訂單號order_no我習(xí)慣由后端生成用時間戳 隨機序列 門店前綴比如2025031215301001。不要用自增 ID 當(dāng)訂單號漏給顧客既不安全也難辨識。所有跟“狀態(tài)”有關(guān)的字段建議用TINYINT數(shù)字而不是字符串表里注釋寫明每個數(shù)字的含義。Java 側(cè)用枚舉類映射前后端統(tǒng)一狀態(tài)碼字典。凡是需要列表查詢的表都給 create_time 和狀態(tài)字段建索引。管理端“查今天的訂單”“查某桌待支付訂單”是最常見的高頻查詢沒索引的話數(shù)據(jù)量過萬就會開始卡。2.3 索引與查詢優(yōu)化后臺報表頁經(jīng)常出現(xiàn)“時間范圍 狀態(tài) 門店”組合查詢這種場景別想著一個復(fù)合索引通吃。我當(dāng)時的做法是訂單主表給(status, create_time)建聯(lián)合索引因為最常出現(xiàn)的篩選是“某狀態(tài) 最近時間”桌臺表按(store_id, status)走訂單明細表則完全靠order_id查詢只建單列索引。運行時如果發(fā)現(xiàn)某個報表接口慢用EXPLAIN看一下是否走了索引別盲目加索引——咖啡廳系統(tǒng)寫入頻率遠高于讀取索引過多會導(dǎo)致插入和更新變慢得不償失。3. Spring Boot 后端把“重復(fù)勞動”砍到最低后端我用的版本組合是 Spring Boot 3.2.x JDK 17 MyBatis-Plus MySQL 8。選這個組合的理由很簡單Spring Boot 3 已經(jīng)非常穩(wěn)定JDK 17 是長期支持版MyBatis-Plus 做單表 CRUD 幾乎不用寫 SQL可以把精力集中在真正復(fù)雜的訂單流轉(zhuǎn)和報表聚合上。3.1 工程結(jié)構(gòu)不要過度設(shè)計現(xiàn)在網(wǎng)上很多項目一上來就拆 Maven 多模塊common、system、order、member……對于一個單體就能扛住的咖啡廳管理系統(tǒng)我強烈建議用單模塊按包名分域目錄長這樣com.oldtime.cafe ├── config # 全局配置CORS、MyBatisPlus、Jackson ├── common # 統(tǒng)一返回體、異常、工具類 ├── security # JWT 認證與攔截器 ├── controller # 接口層 ├── service # 業(yè)務(wù)層 ├── mapper # MyBatis-Plus Mapper ├── entity # 數(shù)據(jù)庫實體 ├── dto # 請求/響應(yīng)對象 └── vo # 前端視圖對象只要你的代碼不是爛到完全不可維護這種包結(jié)構(gòu)足夠支撐到幾千家門店的規(guī)模。多模塊真正的收益是在團隊協(xié)作和強制依賴邊界上一個人開發(fā)的項目用多模塊純屬給自己找編譯麻煩。3.2 認證方案JWT 攔截器咖啡廳的角色不多用 Spring Security 也綽綽有余但我實際用的是輕量方案登錄接口發(fā)放 JWT前端每次請求帶上 Token后端寫一個攔截器解析 Token、校驗角色、放行請求。JWT 的“無狀態(tài)”特性在這個場景很合適顧客手機端、收銀臺 PC、后廚屏三個終端共享同一套認證不需要服務(wù)端維護 Session。但要注意 JWT 過期時間的設(shè)置——顧客點餐可能長時間不退出我設(shè)置的是 7 天員工后臺則設(shè)置 2 小時過期后重新登錄。登錄接口的核心邏輯大致如下Override public LoginResult login(String username, String password) { User user userMapper.selectOne( new LambdaQueryWrapperUser() .eq(User::getUsername, username) ); if (user null) { throw new BusinessException(用戶名或密碼錯誤); } if (!passwordEncoder.matches(password, user.getPassword())) { throw new BusinessException(用戶名或密碼錯誤); } if (user.getStatus() ! 1) { throw new BusinessException(賬號已被禁用); } String token jwtUtil.generateToken(user.getId(), user.getRole(), user.getNickname()); return new LoginResult(token, user.getRole(), user.getNickname()); }有一件事必須單獨提醒顧客掃碼點餐本質(zhì)上也是登錄。不要讓顧客去注冊賬號注冊門檻會把手機點餐轉(zhuǎn)化率砍掉一半。顧客端用“微信授權(quán) 手機號”方式或者干脆生成一個臨時游客身份結(jié)賬時才引導(dǎo)綁定會員。我在表設(shè)計里的 member 就是可空字段原因就在這里。3.3 訂單提交接口與并發(fā)思考點餐系統(tǒng)最容易出事故的就是“提交訂單”這個動作。顧客瞬間提交、多次點擊、庫存修改、余額扣減任何一個環(huán)節(jié)不加控制都會出問題。我的訂單提交流程分四步冪等校驗前端生成“請求唯一標識”比如 UUID提交時帶上。后端用 Redis 的 SETNX 緩存這個標識如果 3 秒內(nèi)重復(fù)提交直接返回“訂單處理中”。這一步能擋住 90% 的重復(fù)點擊問題。庫存預(yù)扣讀取商品庫存預(yù)扣除購買數(shù)量而不是等到支付完成才扣。如果顧客 15 分鐘未支付庫存自動回補。計算金額加購項單價 × 數(shù)量減去優(yōu)惠券金額再算會員折扣全程用BigDecimal。事務(wù)落庫在事務(wù)里寫入訂單主表、明細表、庫存流水、優(yōu)惠券核銷記錄。用Transactional(rollbackFor Exception.class)明確指定回滾條件。我當(dāng)時踩過一個大坑訂單超時未支付回補庫存用的是定時任務(wù)掃表結(jié)果高峰期定時任務(wù) 3 分鐘跑一次顧客看到“還有 5 件”點進去卻發(fā)現(xiàn)沒有了。后來改成 Redis 延遲隊列 訂單狀態(tài)掃描雙保險體驗才真正達標。3.4 后端基建統(tǒng)一返回、全局異常、日志接口返回格式一定要統(tǒng)一這是前后端協(xié)作的底線{ code: 200, message: success, data: {} }為了少寫重復(fù)代碼我做了一個ApiResponseT泛型工具類配合全局異常處理器RestControllerAdvice這樣業(yè)務(wù)里想報錯時直接throw new BusinessException(庫存不足)前端拿到的永遠是同一個結(jié)構(gòu)。日志方面用 Slf4j 在關(guān)鍵節(jié)點打日志登錄、下單、支付回調(diào)、退款、庫存變更。上線后顧客來反饋問題你只需要搜訂單號就能串起整個過程。4. Vue 前端從路由守衛(wèi)到掃碼點餐前端我用的是 Vue 3 Vite Element Plus Pinia Axios這套組合是目前 Vue 生態(tài)的主流答案。Vite 比 Webpack 快的不是一點點開發(fā)體驗舒服太多了。4.1 工程目錄與 API 封裝Vue 前端單倉庫多頁面即可按“后臺管理”和“顧客端 H5”拆成兩個路由空間但共用一套請求封裝和組件src ├── api # 所有接口定義按模塊拆分 ├── assets # 靜態(tài)資源、懷舊主題圖片 ├── components # 通用組件 ├── layout # 后臺布局 ├── router # 路由配置 ├── store # Pinia 狀態(tài) ├── views │ ├── admin # 管理后臺頁面 │ └── mobile # 顧客掃碼點餐頁面 └── utils # axios、工具函數(shù)Axios 封裝里最核心的是攔截器。請求攔截器從 Pinia 的 token 狀態(tài)里取 JWT 塞進 Header響應(yīng)攔截器統(tǒng)一處理業(yè)務(wù)錯誤碼401 跳登錄500 彈出錯誤提示。這段代碼每個項目都得寫一遍但寫好之后所有頁面調(diào)用接口就是一行await api.order.submit(params)干凈利落。4.2 路由守衛(wèi)與角色控制管理后臺的訪問控制說復(fù)雜也復(fù)雜說簡單也簡單。我用的是“路由 meta 全局前置守衛(wèi)”router.beforeEach((to, from, next) { const store useUserStore(); if (to.meta.public) { next(); return; } if (!store.token) { next(/login); return; } if (to.meta.roles !to.meta.roles.includes(store.role)) { next(/403); return; } next(); });把“哪些頁面哪些角色能進”寫在路由表的 meta 里加頁面時順手聲明權(quán)限維護成本非常低。管理員能看到報表和員工管理收銀員看不到這些入口后廚屏甚至不需要登錄——它是獨立路由走的是店內(nèi)局域網(wǎng)接口。4.3 掃碼點餐的實現(xiàn)思路顧客端最核心的交互是“掃碼 → 看菜單 → 加購 → 下單”。二維碼不是技術(shù)難點但有幾個體驗細節(jié)值得說二維碼內(nèi)容用一個短標識符比如cafe://table/12而不是完整 URL。這樣換個域名二維碼不用重新生成。掃碼后先調(diào)接口查詢桌臺狀態(tài)如果已占用則提示“本桌已開臺”避免重復(fù)開臺。加購按鈕要大觸控區(qū)域不小于 44px菜單分類左右布局右側(cè)菜品列表可滾動。購物車做成懸浮底部欄點擊展開明細整個交互參考外賣 App 但比外賣更簡單——不需要配送地址省掉一大塊表單。購物車狀態(tài)我用 Pinia 管理刷新頁面會丟失所以下單前用戶看到的購物車是前端本地狀態(tài)。這里有個小優(yōu)化把未提交的購物車持久化到 localStorage顧客手滑刷新頁面購物車還在體驗會好很多。4.4 后廚屏最簡單的界面最需要注意的刷新策略后廚屏不是一個 CRUD 頁面而是一個“實時看板”。我用了兩種刷新方式組合頁面加載時拉一次全量待制作訂單之后通過 WebSocket 推送新訂單事件收到事件后再拉增量列表。用原生 WebSocket 就行不需要引入 Socket.IO。這里有個小坑如果咖啡館網(wǎng)絡(luò)不穩(wěn)定WebSocket 掉線期間新訂單會堆積。解決方案是前端加一個 30 秒的輪詢兜底發(fā)現(xiàn) WebSocket 狀態(tài)異常就自動切換到輪詢模式頁面頂部顯示“連接已降級每 30 秒自動刷新”。5. “舊時光”視覺主題懷舊不是放幾張老照片這個項目的名字本身就是最大賣點界面風(fēng)格如果做成默認藍白后臺那“舊時光”三個字就白起了。5.1 設(shè)計關(guān)鍵詞拆解我把“舊時光”拆成三個視覺關(guān)鍵詞暖木色、紙張質(zhì)感、復(fù)古字體。主色調(diào)不用多定一個深咖色#4A3426作為品牌主色輔以奶油底色#F5EFE0和點綴的懷舊紅#A65B3C。Element Plus 的主題變量可以自定義把這個幾個顏色替換進去整個后臺的按鈕、輸入框、卡片會自動全部換膚比手工改 CSS 劃算得多。5.2 幾個低成本高質(zhì)感的落地技巧菜單卡片模擬老菜單紙張背景用奶油色漸變加極淡的噪點紋理字體用手寫風(fēng)格的標題字體中文可以找免費商用字庫價格用等寬數(shù)字字體。收銀臺界面做“膠片感”頁面切換用平滑淡入而不是生硬的跳轉(zhuǎn)小圖標統(tǒng)一使用線性風(fēng)格整體降低飽和度和對比度。首頁放“記憶墻”顧客端 H5 的首頁不是上來就逼你下單而是先放一組品牌故事照片和新品海報往下滑才是菜單。這個設(shè)計讓顧客愿意在頁面上多停留一會兒間接提升點單概率。小票樣式復(fù)古化訂單完成后的“電子小票”做成帶鋸齒邊緣的卡片字體用像素感和圓角感兼顧的中文字體顧客截圖分享本身就是免費宣傳。懷舊不等于放棄現(xiàn)代體驗。所有按鈕至少 44px 高字號不小于 14px關(guān)鍵操作有明確的按下反饋。視覺風(fēng)格再舊交互邏輯必須新。5.3 響應(yīng)式打印適配收銀小票是 Java Vue 項目里容易被忽略的環(huán)節(jié)。小票打印一般走瀏覽器打印但頁面寬度、字體大小要單獨適配 58mm/80mm 熱敏紙。我的方案是專門做一個打印組件生成純表格樣式的小票頁面再用media print隱藏導(dǎo)航和按鈕只保留小票區(qū)域。這里有個實用技巧小票寬度設(shè)成 58mmpage { size: 58mm auto; margin: 0; }打印時選擇“實際大小”不要“適應(yīng)頁面”否則字體會被壓縮到看不清。6. 從開發(fā)到上線實測中我反復(fù)踩的坑功能寫完只是第一步能穩(wěn)定跑起來才是真本事。整理幾個我在這個項目里反復(fù)踩、也幫別人排查過的問題。6.1 金額和時間兩個“差之毫厘謬以千里”的細節(jié)金額精度問題前面提過這里再說一個隱蔽場景訂單金額在數(shù)據(jù)庫是DECIMAL(10,2)MyBatis-Plus 映射到 Java 會給你BigDecimal沒問題。但前端 JavaScript 計算金額時0.1 0.2 這種浮點誤差會直接爆出來。前端只負責(zé)展示金額計算一律以后端返回為準前端不要做任何加減乘除。購物車頁面的“合計”必須是后端在加購時就算好返回的而不是前端把單價相加。時間問題則是時區(qū)加格式的組合拳。后端用LocalDateTime統(tǒng)一存數(shù)據(jù)庫接口返回格式統(tǒng)一成yyyy-MM-dd HH:mm:ss。Jackson 配置里要顯式設(shè)置日期格式spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8不然前端拿到的是數(shù)組或者帶 T 的 ISO 格式解析起來一臉懵。另外數(shù)據(jù)庫連接串記得加serverTimezoneAsia/Shanghai這個坑在部署到云服務(wù)器后最容易出現(xiàn)——本地好好的服務(wù)器一跑時間全錯。6.2 商品圖片上傳本地存儲還是對象存儲如果只是校園項目或者單店部署最穩(wěn)妥的方案是本機磁盤存儲 Nginx 映射靜態(tài)資源。圖片上傳接口把文件存到服務(wù)器某個目錄返回給前端一個/images/products/xxx.jpg路徑由 Nginx 直接服務(wù)后端完全不用管讀取。但如果你打算做成可商用、支持多門店的系統(tǒng)就得上 MinIO——它是一種兼容 S3 協(xié)議的開源對象存儲。商品圖片、品牌素材全部打到 MinIO 桶里加個桶權(quán)限策略圖片鏈接走 Nginx 代理緩存會比自己管理磁盤干凈很多。不管是本機存儲還是 MinIO上傳接口統(tǒng)一返回相對路徑不要返回完整 URL這樣以后換域名、換 HTTPS 都不用改數(shù)據(jù)庫里的舊數(shù)據(jù)。6.3 商品上下架與緩存一致性菜單是高頻讀取、低頻修改的數(shù)據(jù)。顧客端每次打開都查 MySQL 顯然不劃算我在 Redis 里存了一份“在售商品列表”key 為menu:store:{storeId}30 分鐘過期。這里真正要注意的是緩存更新時機商品上架/下架、改價格、改庫存這些操作發(fā)生時必須主動刪除緩存而不是依賴過期。因為我用的是“被動失效 主動刪除”策略管理員修改商品后立刻刪緩存下一次查詢重新從數(shù)據(jù)庫加載。極端情況下緩存和數(shù)據(jù)庫最多有幾秒不一致這點延遲對咖啡廳場景完全可接受。6.4 報表導(dǎo)出Java POI 的真實邊際管理后臺通常會有“營業(yè)報表導(dǎo)出”需求常見實現(xiàn)是 Apache POI 生成 Excel。很多同學(xué)一聽說 POI 就頭疼其實餐廳報表用最基本的XSSFWorkbook就夠了做一個訂單匯總表try (XSSFWorkbook workbook new XSSFWorkbook()) { Sheet sheet workbook.createSheet(營業(yè)報表); Row header sheet.createRow(0); header.createCell(0).setCellValue(日期); header.createCell(1).setCellValue(訂單數(shù)); header.createCell(2).setCellValue(營業(yè)額); // 遍歷訂單數(shù)據(jù)填充... ByteArrayOutputStream out new ByteArrayOutputStream(); workbook.write(out); return out.toByteArray(); }POI 完全支持在 Excel 里生成圖表比如月度營業(yè)額柱狀圖。如果你只是導(dǎo)出報表不需要整那些花活老老實實把數(shù)據(jù)鋪出來就行圖表展示交給前端用 ECharts 渲染性能和美觀度都遠超 Excel 自帶圖。6.5 Spring Boot 版本與依賴沖突用 Spring Boot 3 記得 JDK 必須是 17 及以上MyBatis-Plus 也要用適配 Spring Boot 3 的版本mybatis-plus-spring-boot3-starter。很多同學(xué)項目啟動報一堆錯十有八九是 Spring Boot 2 的依賴習(xí)慣性復(fù)制到了 3 里。還有 Lombok 插件版本也要同步升級舊版 Lombok 和 JDK 17 組合經(jīng)常出現(xiàn)java.lang.ClassFormatError。我的建議是新項目直接 Spring Boot 3 JDK 17不要猶豫。網(wǎng)上雖然 Spring Boot 2 教程多但類名和方法基本一致遇到差異時翻官方文檔比查舊博客靠譜得多。7. 我想額外說給“做畢設(shè)”的人聽的幾句話這套系統(tǒng)作為畢業(yè)設(shè)計技術(shù)棧非常合適因為它的技術(shù)覆蓋面廣Spring Boot 的接口開發(fā)、MyBatis-Plus 的數(shù)據(jù)操作、JWT 認證、Vue 的組件化和路由權(quán)限、數(shù)據(jù)庫設(shè)計、甚至桌臺二維碼這種 IoT 邊緣場景都能講出東西來。但切記——不要堆砌沒有業(yè)務(wù)邏輯的 CRUD 頁面。提升項目含金量的方向不是增加頁面數(shù)量而是把幾個核心場景做深訂單并發(fā)控制做了沒有金額計算是否全程可靠狀態(tài)機流轉(zhuǎn)是否清晰可追蹤前端交互是否有思考過真實用戶的使用感受有沒有報表分析、緩存優(yōu)化這些“非必選但加分”的能力答辯時能把這幾個問題說到位比列十個“增刪改查模塊”管用得多。咖啡廳管理系統(tǒng)這類項目最迷人的地方在于它離真實生活很近。你把代碼寫完、部署上線看著顧客用手機掃碼下單、收銀臺打出復(fù)古小票、后廚屏彈出新訂單那種“技術(shù)真的在服務(wù)具體的人”的感覺會讓人覺得這段代碼寫得值。如果這個項目能幫到你哪怕只是其中一個建表思路、一個排查方向我就覺得這篇分享沒白寫。祝你開發(fā)順利記得給自己留一杯咖啡的時間。