的校園勤工儉學(xué)微信小程序設(shè)計實(shí)踐)
簡介面向高校畢業(yè)設(shè)計場景這是一份基于微信小程序云開發(fā)的校園勤工儉學(xué)完整源碼覆蓋了崗位發(fā)布、在線申請、后臺審核、個人中心等核心業(yè)務(wù)場景。項目已通過答辯并獲得高分適合計算機(jī)相關(guān)專業(yè)學(xué)生作為畢設(shè)參考也適合初學(xué)者理解云函數(shù)與小程序聯(lián)動的基本原理。壓縮包共1506個文件主要包括js/ts邏輯代碼、json數(shù)據(jù)配置、wxss樣式、wxml結(jié)構(gòu)以及wxs處理腳本另含上傳云函數(shù)的bat工具包體大小僅929KB更加便于下載后直接導(dǎo)入開發(fā)工具。已有1754人學(xué)習(xí)使用具備一定的參考熱度。內(nèi)容提供了完整前端頁面與后端云函數(shù)源碼目錄結(jié)構(gòu)清晰可快速綁定云環(huán)境運(yùn)行并支持按需修改崗位分類、報名流程等模塊是畢業(yè)設(shè)計與項目實(shí)訓(xùn)的實(shí)用素材。1. 基于云開發(fā)的校園勤工儉學(xué)微信小程序這個畢設(shè)到底在做什么基于云開發(fā)的校園勤工儉學(xué)微信小程序本質(zhì)上是一套把「崗位發(fā)布、學(xué)生報名、老師審核、工時統(tǒng)計、工資結(jié)算」全部搬進(jìn)微信里的輕量管理系統(tǒng)。它和傳統(tǒng)勤工儉學(xué)流程的區(qū)別很好懂以前靠群公告發(fā)崗位、接龍報名、月底人工對賬現(xiàn)在學(xué)生打開小程序就能看到所有開放的崗位報名后狀態(tài)實(shí)時可見管理員也不用再拿 Excel 反復(fù)核對工時。選云開發(fā)而不是自建后端是因?yàn)楫呍O(shè)周期內(nèi)你不需要處理服務(wù)器部署、接口文檔、鑒權(quán)中間件數(shù)據(jù)庫、云函數(shù)、云存儲都是現(xiàn)成能力在開發(fā)者工具里初始化一下就能用。想靠低成本把業(yè)務(wù)閉環(huán)完整跑通、同時能應(yīng)付系統(tǒng)設(shè)計答辯的在校生這個方向非常合適。2. 云開發(fā)為什么適合當(dāng)這個項目的后端集合、云函數(shù)、存儲三件套先立住一個觀點(diǎn)這個項目題目的技術(shù)含量不在前端頁面而在數(shù)據(jù)模型和權(quán)限設(shè)計是否合理。云開發(fā)提供了小程序端直連數(shù)據(jù)庫、云函數(shù)、云存儲三類能力對應(yīng)的正是傳統(tǒng)項目中的數(shù)據(jù)庫讀寫、后端邏輯、文件存儲。把這三件套各自承擔(dān)什么角色搞清楚后面寫業(yè)務(wù)就是拼積木。2.1 數(shù)據(jù)模型先把集合關(guān)系畫出來我一般會先按角色拆業(yè)務(wù)。這個系統(tǒng)里至少有三種角色學(xué)生申請崗位、打卡、看工資管理員發(fā)布崗位、審核報名、結(jié)算工資可能還有老師或部門負(fù)責(zé)人做中間審批。角色確定后集合設(shè)計如下。集合名核心字段作用users_openid、name、studentId、role、phone用戶表role 區(qū)分學(xué)生/管理員jobstitle、location、salaryType、salaryAmount、totalSlots、appliedCount、status崗位表status 控制開/停applicationsjobId、_openid、status、applyTime報名表狀態(tài)機(jī)流轉(zhuǎn)checkinsjobId、_openid、checkInTime、checkOutTime、duration考勤表按次打卡salary_records_openid、jobId、amount、status工資記錄按月結(jié)算生成這套設(shè)計的核心原則一個學(xué)生可以報多個崗位一個崗位可以被多人申請所以報名必須是獨(dú)立集合工資如果只存在 user 集合里歷史賬單和月度核對無從談起所以要單獨(dú)建 salary_records。下面是崗位集合的字段 JSON 示例方便你建庫時直接抄{ _id: job_001, title: 圖書館整理助理, department: 圖書館, location: 東區(qū)圖書館二樓, salaryType: hourly, salaryAmount: 18, totalSlots: 3, appliedCount: 2, workTime: 周一至周五 18:00-21:00, status: open, createBy: openid_admin, createTime: 2025-01-10 10:00:00 }salaryType 用 hourly 和 fixed 兩種hourly 按小時計薪fixed 按單次固定金額。這個字段會直接決定工資結(jié)算云函數(shù)的分支邏輯建議一開始就留好不要后面再加。數(shù)據(jù)庫里加字段雖然控制臺能直接操作但歷史數(shù)據(jù)不會自動補(bǔ)默認(rèn)值前端所有查詢條件都要跟著改非常痛苦。所以建集合時字段寧多勿少像 status、createBy、createTime 這類幾乎每個集合都要用到的字段統(tǒng)一從一開始就寫上。2.2 云函數(shù)哪些邏輯必須收進(jìn)后端小程序端可以直接讀寫云數(shù)據(jù)庫這會帶來一個錯覺所有邏輯都放前端不就行了不行。云開發(fā)數(shù)據(jù)庫默認(rèn)權(quán)限就是“僅創(chuàng)建者可讀寫”崗位是管理員創(chuàng)建的學(xué)生端直接讀會失敗審核、結(jié)算這類操作更不能只靠前端因?yàn)榍岸舜a可以被任意用戶看到把管理員判斷寫在頁面里等于形同虛設(shè)。另外多人同時搶最后一個崗位名額這類并發(fā)場景前端完全沒有處理能力。所以我習(xí)慣把敏感操作全部收進(jìn)云函數(shù)目錄結(jié)構(gòu)如下cloudfunctions/ login/ // 登錄返回 openid 和角色 publishJob/ // 管理員發(fā)布崗位 applyJob/ // 學(xué)生報名含并發(fā)控制 reviewApply/ // 管理員審核報名 checkIn/ // 學(xué)生簽到/簽退 settleSalary/ // 定時結(jié)算工資每個云函數(shù)內(nèi)部都先cloud.init再操作數(shù)據(jù)庫wx-server-sdk 是云函數(shù)里唯一的依賴不要亂引其他包。云函數(shù)端操作數(shù)據(jù)庫不受小程序端集合權(quán)限限制所以關(guān)鍵校驗(yàn)條件必須在云函數(shù)里再寫一遍管理員身份要在云函數(shù)里查 users 表確認(rèn)不能只靠前端按鈕隱藏來保護(hù)。小程序端的權(quán)限規(guī)則只是第一道門云函數(shù)里的身份校驗(yàn)是第二道門兩道門都要有。2.3 云存儲圖片和附件必須走這里崗位可能需要配實(shí)拍照片學(xué)生簡歷也可能要傳文件。圖片如果轉(zhuǎn) base64 塞進(jìn)數(shù)據(jù)庫幾 MB 就能把集合讀寫拖慢云存儲的 fileID 是替代方案。前端調(diào)cloud.uploadFile上傳后拿到 fileID把這個字符串存進(jìn)對應(yīng)記錄即可渲染時用image src{{item.coverFileID}}直接顯示不用自己拼臨時鏈接。上傳時建議按業(yè)務(wù)分目錄比如jobs/{jobId}/cover-{timestamp}.jpg方便后續(xù)清理。文件刪除走cloud.deleteFile替換圖片時記得先刪舊 fileID 再傳新圖否則云存儲會一直累積。畢設(shè)階段空間基本用不完但這是良好工程習(xí)慣答辯時提一句“存儲按業(yè)務(wù)目錄隔離、附件可回收”老師印象分會好很多。3. 從零跑通初始化云環(huán)境、配置權(quán)限、打通登錄這個項目最關(guān)鍵的第一次成功是小程序能通過云開發(fā)拿到自己的 openid。后面所有業(yè)務(wù)都建立在這個基礎(chǔ)之上先把這一步跑通剩下的都是數(shù)據(jù)操作。這里按我實(shí)際操作的順序?qū)懻罩c(diǎn)就行。3.1 初始化小程序項目和云環(huán)境項目在微信開發(fā)者工具里創(chuàng)建時選“小程序”模板不要選帶第三方框架的模板。創(chuàng)建完成后點(diǎn)擊開發(fā)者工具頂部“云開發(fā)”按鈕開通環(huán)境會得到一個環(huán)境 ID形如cloud1-xxxx這個 ID 后面所有代碼都要用到。然后在 app.js 里加初始化代碼App({ onLaunch() { if (!wx.cloud) { console.error(當(dāng)前基礎(chǔ)庫過低請使用 2.2.3 以上基礎(chǔ)庫); return; } wx.cloud.init({ env: cloud1-xxxx, // 替換成你自己的環(huán)境 ID traceUser: true }); } })env可以省略省略時默認(rèn)使用第一個創(chuàng)建的環(huán)境但多個環(huán)境存在時省略容易連錯畢設(shè)建議寫死。traceUser的作用是讓小程序端寫入數(shù)據(jù)時自動帶上_openid字段這是很多權(quán)限規(guī)則生效的前提保持開啟。云環(huán)境開通后開發(fā)者工具左側(cè)會出現(xiàn)云開發(fā)控制臺入口數(shù)據(jù)庫、云函數(shù)、存儲三個面板都在里面不需要安裝額外 CLI。3.2 數(shù)據(jù)庫權(quán)限先設(shè)置再寫業(yè)務(wù)新建集合后默認(rèn)權(quán)限是“僅創(chuàng)建者可讀寫”這個權(quán)限對管理員可見所有數(shù)據(jù)的需求不夠。打開集合的權(quán)限設(shè)置我一般把集合分成兩類。集合權(quán)限規(guī)則原因users所有用戶可讀僅創(chuàng)建者可寫學(xué)生能看基本信息只能改自己的資料jobs所有用戶可讀崗位列表是公開數(shù)據(jù)applications僅創(chuàng)建者可讀寫學(xué)生只能看到自己的報名記錄checkins僅創(chuàng)建者可讀寫考勤數(shù)據(jù)屬于個人隱私salary_records僅創(chuàng)建者可讀寫工資只能自己看這里有一個關(guān)鍵矛盾管理員和學(xué)生都在 users 集合里管理員創(chuàng)建的崗位學(xué)生要讀學(xué)生的申請記錄又是云函數(shù)創(chuàng)建的。云函數(shù)端不受集合權(quán)限限制所以跨用戶讀寫的場景全部交給云函數(shù)小程序端只讀公開的 jobs 集合和自己名下的記錄。小程序端“不能讀什么”由權(quán)限規(guī)則攔云函數(shù)“必須讀什么”放開權(quán)限做。把這句話記住權(quán)限設(shè)計就不會亂。提示權(quán)限規(guī)則是安全的第一道門云函數(shù)里的角色校驗(yàn)是第二道門。兩道門都要有缺一道答辯都會被問住。3.3 登錄與身份識別一個 login 云函數(shù)搞定云開發(fā)里不需要自己實(shí)現(xiàn)微信登錄換取 openid云函數(shù)上下文里直接攜帶調(diào)用者的 openid。建一個 login 云函數(shù)作用有兩個初始化用戶記錄和返回角色。const cloud require(wx-server-sdk); cloud.init({ env: cloud.DEFAULT_ENV }); const db cloud.database(); const users db.collection(users); exports.main async (event, context) { const { OPENID } cloud.getWXContext(); const userRes await users.where({ _openid: OPENID }).limit(1).get(); if (userRes.data.length 0) { return { code: 0, data: { openid: OPENID, role: userRes.data[0].role } }; } // 首次登錄自動建檔默認(rèn)角色 student const addRes await users.add({ data: { // 云函數(shù)端不會自動注入 _openid手動寫入保證權(quán)限規(guī)則能匹配 _openid: OPENID, role: student, name: , studentId: } }); return { code: 0, data: { openid: OPENID, role: student, userId: addRes._id } }; };注意云函數(shù) add 出來的記錄不會像小程序端那樣自動帶_openid所以這里必須手動寫入 OPENID否則“僅創(chuàng)建者可讀寫”規(guī)則下學(xué)生端會查不到自己這條用戶記錄。前端在小程序啟動后調(diào)用wx.cloud.callFunction({ name: login })就能拿到當(dāng)前用戶的 openid 和角色。管理員身份怎么來最直白的做法是在云開發(fā)控制臺里找到你自己的那條 users 記錄把 role 字段改成admin。做演示前就設(shè)好之后所有管理員判斷都以這條記錄為準(zhǔn)。不要在頁面里寫死 openid 比較那樣一旦換微信號演示就翻車。4. 核心業(yè)務(wù)落地崗位發(fā)布、申請審核、考勤與工資結(jié)算業(yè)務(wù)打通階段的原則是先跑通一條最完整的鏈路再補(bǔ)分支。完整鏈路是「管理員發(fā)崗位 → 學(xué)生看到崗位 → 學(xué)生報名 → 管理員審核通過 → 學(xué)生打卡 → 月底結(jié)算工資」。鏈路走通后加分功能再慢慢加哪怕最終沒時間做復(fù)雜報表答辯也站得住。4.1 崗位發(fā)布與列表管理員建崗學(xué)生分頁查管理員發(fā)崗位就是一個表單提交調(diào) publishJob 云函數(shù)。這里核驗(yàn)不能只在前端做頁面按鈕只能做非空校驗(yàn)云函數(shù)里必須確認(rèn)調(diào)用者是管理員。exports.main async (event, context) { const { OPENID } cloud.getWXContext(); const userRes await users.where({ _openid: OPENID }).limit(1).get(); if (userRes.data[0]?.role ! admin) { return { code: -1, msg: 無權(quán)限 }; } const { title, location, salaryType, salaryAmount, totalSlots, workTime, coverFileID } event; if (!title || !totalSlots || !salaryAmount) { return { code: -1, msg: 必填字段缺失 }; } const addRes await jobs.add({ data: { title, location, salaryType, salaryAmount, totalSlots, appliedCount: 0, workTime, coverFileID, status: open, createBy: OPENID, createTime: new Date() } }); return { code: 0, data: { jobId: addRes._id } }; };totalSlots是崗位總名額appliedCount初始化為 0后面報名時會用到。createBy存管理員 openid需要統(tǒng)計崗位來源時直接查這個字段。學(xué)生端崗位列表用小程序端直查即可因?yàn)?jobs 集合對所有用戶可讀。分頁上有個云開發(fā)的硬限制小程序端單次最多返回 20 條云函數(shù)端最多 100 條。崗位數(shù)量可能不大但分頁邏輯建議從一開始就寫上const db wx.cloud.database(); db.collection(jobs) .where({ status: open }) .skip(this.data.page * 20) .limit(20) .get() .then(res { /* 追加到列表 */ });.skip(this.data.page * 20)是頁碼乘每頁條數(shù).limit(20)是頁大小。where 里用了 status 作為篩選條件建議在云開發(fā)控制臺的集合索引管理里給 status 建單字段索引。數(shù)據(jù)量小的時候無所謂超過幾千條不加索引的查詢會明顯變慢這是答辯可能被追問的點(diǎn)。4.2 申請與審核用狀態(tài)機(jī)管理用原子操作防超發(fā)報名和審核是聯(lián)動操作共用一張 applications 集合。狀態(tài)流轉(zhuǎn)是pending已申請→ approved已通過→ finished已結(jié)束 └→ rejected已拒絕狀態(tài)遷移只在云函數(shù)里發(fā)生不要在頁面直接 update。原因很簡單如果學(xué)生能在前端把自己的 application 狀態(tài)改成 approved等于自己給自己發(fā)工資。審核云函數(shù)要校驗(yàn)調(diào)用者的 role 是 admin然后按記錄 id 更新目標(biāo)申請的狀態(tài)。并發(fā)搶最后一個名額是經(jīng)典坑。我采用的方案是在崗位集合上做原子扣減先扣名額再寫申請而不是先插入申請再更新崗位數(shù)。const _ db.command; const updateRes await jobs .where({ _id: jobId, appliedCount: _.lt(totalSlots) }) .update({ data: { appliedCount: _.inc(1) } }); if (updateRes.stats.updated 0) { return { code: -1, msg: 崗位名額已滿 }; } // 名額扣成功后再寫 applications 記錄 await applications.add({ data: { jobId, _openid: OPENID, // 云函數(shù)寫入必須手動帶 openid status: pending, applyTime: new Date() } });這里的技巧是 where 條件里帶appliedCount totalSlots云數(shù)據(jù)庫會原子檢查并更新更新成功才算搶到名額。先插申請再更新崗位數(shù)的寫法在并發(fā)下會把名額超發(fā)我在模擬項目X里就翻過這個車后來改成先扣名額。管理員審核拒絕時記得把名額還回去appliedCount: _.inc(-1)。否則會出現(xiàn)“學(xué)生申請失敗但名額消失”的幽靈滿員問題。另外為了防止同一學(xué)生重復(fù)申請同一崗位給 applications 集合的jobId _openid建聯(lián)合唯一索引。重復(fù)插入時云函數(shù)捕獲報錯轉(zhuǎn)換成“你已申請過該崗位”的提示即可。4.3 考勤打卡與工資結(jié)算云函數(shù)加定時觸發(fā)器打卡拆成簽到和簽退兩條操作放在同一條記錄里。打卡前必須校驗(yàn)該學(xué)生是否已通過了該崗位的審核否則沒被錄用的人也能打卡。exports.main async (event, context) { const { jobId, type } event; // type in | out const { OPENID } cloud.getWXContext(); const appRes await applications .where({ jobId, _openid: OPENID, status: approved }) .limit(1).get(); if (appRes.data.length 0) return { code: -1, msg: 未通過審核不能打卡 }; if (type in) { return await checkins.add({ data: { jobId, _openid: OPENID, checkInTime: Date.now(), checkOutTime: 0 } }); } // type out找到當(dāng)天未簽退的記錄更新時間和時長 };簽到記錄里checkOutTime初始為 0簽退時按 openid 和當(dāng)天的 checkInTime 匹配到那條記錄更新checkOutTime并把duration算成小時數(shù)。簽退邏輯里注意只更新當(dāng)天未簽退的記錄否則會把歷史記錄二次覆蓋。工資結(jié)算是重頭戲。常見做法是定期跑 settleSalary 云函數(shù)遍歷已完成的 checkin 記錄按 hourly 單價算錢寫入 salary_records同時累加到用戶余額。為了演示方便我建議把它設(shè)計成支持手動觸發(fā)云開發(fā)控制臺里的“云端測試”按鈕可以直接運(yùn)行不用干等定時器。定時觸發(fā)器在云函數(shù)的 config.json 里配置和代碼一起部署上傳{ permissions: { openapi: [] }, triggers: [ { name: settleDaily, type: timer, config: 0 0 2 * * * * } ] }這個 cron 是 7 段式依次是秒、分、時、日、月、星期、年例子表示每天凌晨 2 點(diǎn)觸發(fā)。第一次用建議先設(shè)成 5 分鐘后觸發(fā)確認(rèn)云函數(shù)日志里有輸出再改回正式時間不要配好就干等時間格式錯了它不會報錯只會沉默。金額計算有個容易忽略的細(xì)節(jié)JavaScript 里 0.1 乘 3 可能是 0.30000000000000004。工資結(jié)算要以“分”為單位計算所有金額字段存整數(shù)分展示時才除以 100。頁面輸入按元入?yún)r先乘 100 再入庫。注意定時觸發(fā)器部署后一定要在云開發(fā)控制臺的云函數(shù)“觸發(fā)器”標(biāo)簽頁里確認(rèn)列表中有這條記錄。沒有就說明觸發(fā)器配置沒隨代碼部署成功。5. 避坑指南云開發(fā)小程序最常見的 5 個翻車點(diǎn)這一章不寫文檔里有的正常操作只寫我親眼見過或者自己踩過的坑。每一條都是現(xiàn)象、原因、解決三段式項目做到哪一步卡住了都可以回來看。5.1 云函數(shù)執(zhí)行一半超時提示 Task timed out after 3 seconds現(xiàn)象發(fā)布崗位或批量導(dǎo)入數(shù)據(jù)的云函數(shù)本地測試沒問題部署后偶爾報超時尤其是第一次冷啟動時。原因云開發(fā)云函數(shù)默認(rèn)超時時間是 3 秒。數(shù)據(jù)庫批量操作、網(wǎng)絡(luò)波動、冷啟動都會把時間吃滿3 秒很容易不夠用。解決在云開發(fā)控制臺進(jìn)入云函數(shù)詳情把超時時間從 3 秒改成 20 秒或 60 秒。改完記得重新部署一次否則不生效。我當(dāng)年就是改完忘了部署又白白排查了半天最后才發(fā)現(xiàn)配置沒生效。5.2 學(xué)生端崗位列表一片空白數(shù)據(jù)庫里明明有數(shù)據(jù)現(xiàn)象jobs 集合里數(shù)據(jù)完整控制臺能看到小程序頁面 get 出來卻是空數(shù)組也不報錯。原因集合權(quán)限問題。jobs 集合如果保持默認(rèn)的“僅創(chuàng)建者可讀寫”崗位是管理員創(chuàng)建的學(xué)生端查詢時在權(quán)限層就被攔掉了get 返回空數(shù)組。解決把 jobs 集合權(quán)限改成“所有用戶可讀”。如果是自定義安全規(guī)則至少要有read: true。反過來applications 這類包含隱私信息的集合不要放開保持僅創(chuàng)建者可讀寫。隱私問題在答辯時很敏感放開讀權(quán)限等于給自己挖坑。5.3 云函數(shù)里查不到任何用戶數(shù)據(jù)現(xiàn)象在云函數(shù)中執(zhí)行db.collection(users).where({...}).get()返回 data 是空數(shù)組但控制臺里明明有記錄。原因最常見有兩種。一是云函數(shù)代碼里忘了cloud.init二是初始化用了cloud.DEFAULT_ENV但云函數(shù)部署到了另一個環(huán)境。開了多個環(huán)境時云函數(shù)可能連到第一個環(huán)境就會查錯庫。解決云函數(shù)第一行確保cloud.init({ env: cloud.DEFAULT_ENV })在開發(fā)者工具里右鍵云函數(shù)目錄選擇“上傳并部署云端安裝依賴”。部署前看下開發(fā)者工具左下角當(dāng)前環(huán)境是不是目標(biāo)環(huán)境。這個坑很隱蔽因?yàn)樗粓箦e只是返回空數(shù)組排查時先看云函數(shù)日志里的環(huán)境 ID。5.4 模擬器一切正常真機(jī)預(yù)覽卻拿不到數(shù)據(jù)現(xiàn)象開發(fā)者工具模擬器里所有頁面正常用真機(jī)掃碼預(yù)覽時部分頁面空白或提示無權(quán)限。原因模擬器默認(rèn)使用開發(fā)者工具登錄的微信身份真機(jī)使用手機(jī)微信身份openid 不一樣。如果代碼里有按 openid 匹配的記錄或者某個集合只有模擬器身份創(chuàng)建的數(shù)據(jù)真機(jī)上就會因?yàn)?openid 對不上而查不到。解決換一種思路排查。先在真機(jī)上跑一次 login 云函數(shù)把返回的 openid 記下來再到 users 集合確認(rèn)這條記錄是否已創(chuàng)建、role 是否設(shè)對。演示時最容易犯的錯是只把開發(fā)者工具里的賬號設(shè)成了管理員真機(jī)上那個微信號從來不是管理員動態(tài)一演示就露餡。這種問題排查起來總有點(diǎn)玄學(xué)味道但本質(zhì)就是 openid 環(huán)境差異。5.5 定時觸發(fā)器配了到點(diǎn)卻不執(zhí)行現(xiàn)象config.json 里寫了 triggers部署成功但到了設(shè)定時間云函數(shù)沒有任何調(diào)用日志。原因cron 表達(dá)式寫錯或者觸發(fā)器配置沒隨代碼一起部署。云開發(fā)的 cron 是 7 段格式少寫一位、順序?qū)戝e都不執(zhí)行而且不報錯。解決第一次驗(yàn)證用最短間隔設(shè)置 2 分鐘后觸發(fā)然后盯云函數(shù)日志。確認(rèn)觸發(fā)正常后再改正式時間。還要注意定時觸發(fā)器按服務(wù)器時間執(zhí)行不要拿本地時間做比較??刂婆_云函數(shù)詳情頁的“觸發(fā)器”標(biāo)簽里能看到已創(chuàng)建的觸發(fā)器列表那里是空的就說明沒部署成功。6. 驗(yàn)收與答辯用一場流暢的演示把項目講清楚畢業(yè)設(shè)計答辯比的不是功能數(shù)量而是邏輯閉環(huán)。老師最怕聽你說“這個功能能跑但當(dāng)時沒造數(shù)據(jù)”所以演示前一定要把數(shù)據(jù)準(zhǔn)備得像真實(shí)運(yùn)營過一學(xué)期。建議準(zhǔn)備三個角色管理員、學(xué)生 A、學(xué)生 B。管理員用開發(fā)者工具里的身份操作學(xué)生用兩個不同微信真機(jī)掃碼。這里有個繞不開的現(xiàn)實(shí)同一微信號在同一個小程序里的 openid 唯一一個人沒法同時扮演管理員和學(xué)生。常見做法是管理員在開發(fā)者工具里操作學(xué)生在真機(jī)上操作頁面右上角實(shí)時顯示當(dāng)前角色讓老師一眼看清身份切換。演示腳本按主線走不要跳。管理員發(fā)布一個崗位 → 學(xué)生 A 瀏覽并報名 → 管理員審核通過 → 學(xué)生 A 簽到簽退 → 手動觸發(fā)結(jié)算云函數(shù) → 展示工資記錄和余額變化。整個過程控制在十分鐘內(nèi)每一步都讓老師看到數(shù)據(jù)變化而不是只看頁面跳轉(zhuǎn)。我當(dāng)年答辯就吃過虧光講頁面不給他看數(shù)據(jù)老師一句“數(shù)據(jù)存在哪里”就把我問住了。答辯前把幾個必問題提前想清楚為什么用云開發(fā)而不是自建后端回答要落到開發(fā)效率和運(yùn)維成本同時指出它的邊界集合權(quán)限怎么設(shè)計的按公開數(shù)據(jù)與私有數(shù)據(jù)分層講并發(fā)搶?shí)徫蝗绾伪苊獬l(fā)講原子操作和唯一索引金額精度怎么處理講以分為單位存儲。這四問答順了項目可信度會立刻上一個臺階。我自己的習(xí)慣是正式答辯前一天做一次“回滾演練”把數(shù)據(jù)庫全部清空重新按演示腳本完整跑一遍確認(rèn)每一步都不依賴之前人為設(shè)置的歷史數(shù)據(jù)。這個動作看著費(fèi)時間但能救命的場景實(shí)在太多——怕的就是演示時發(fā)現(xiàn)某一頁數(shù)據(jù)是上次調(diào)試遺留的狀態(tài)和腳本對不上一緊張就全亂。最后想說云開發(fā)做畢設(shè)最大的優(yōu)勢是把后端復(fù)雜度降到了一個前端同學(xué)能完全掌控的范圍內(nèi)但劣勢同樣明顯如果只寫了頁面沒把權(quán)限、并發(fā)、定時任務(wù)聊透老師會認(rèn)為你沒有真正理解它。把這套狀態(tài)機(jī)和事務(wù)設(shè)計講清楚項目能過你也會真正明白為什么商業(yè)項目要把邏輯收進(jìn)服務(wù)端。希望這篇筆記幫到你少走一點(diǎn)我當(dāng)年的彎路。本文還有配套的精品資源點(diǎn)擊獲取