微信小程序開(kāi)發(fā)實(shí)戰(zhàn):云開(kāi)發(fā)與預(yù)約報(bào)名系統(tǒng)設(shè)計(jì))
簡(jiǎn)介面向計(jì)算機(jī)相關(guān)專業(yè)畢設(shè)與課程設(shè)計(jì)場(chǎng)景這套基于微信小程序的非物質(zhì)文化遺產(chǎn)傳播平臺(tái)提供可直接運(yùn)行的完整項(xiàng)目。資源共2000個(gè)文件主要由Vue前端組件450個(gè)、JavaScript邏輯318個(gè)、JSON配置288個(gè)、Java后端代碼104個(gè)、WXML/WXSS小程序頁(yè)面與樣式43/44個(gè)構(gòu)成同時(shí)包含SQL數(shù)據(jù)庫(kù)腳本、bat一鍵式啟動(dòng)腳本、mp4演示視頻與Markdown說(shuō)明文檔整體約88.14MB。項(xiàng)目經(jīng)過(guò)嚴(yán)格調(diào)試源碼、運(yùn)行說(shuō)明、數(shù)據(jù)庫(kù)資料一應(yīng)俱全可支撐快速部署、功能二次開(kāi)發(fā)或畢業(yè)設(shè)計(jì)答辯展示幫助Java學(xué)習(xí)者理解小程序前端與后端數(shù)據(jù)交互的實(shí)現(xiàn)方式。已有74人瀏覽學(xué)習(xí)適合需要現(xiàn)成項(xiàng)目案例、模塊化代碼拆解及完整畢設(shè)方案的人群。1. 非遺傳播平臺(tái)為什么值得放進(jìn)微信小程序某非遺工作室的負(fù)責(zé)人A同學(xué)找我的時(shí)候資料已經(jīng)整理得很完整但網(wǎng)站訪問(wèn)量慘淡公眾號(hào)文章只有幾十閱讀量。我建議他把重心轉(zhuǎn)移到“基于微信小程序的非物質(zhì)文化遺產(chǎn)傳播平臺(tái)”上。原因很簡(jiǎn)單非遺內(nèi)容屬于低頻瀏覽、強(qiáng)分享、重現(xiàn)場(chǎng)體驗(yàn)的內(nèi)容用戶沒(méi)有每天打開(kāi)網(wǎng)站的動(dòng)機(jī)卻會(huì)因一場(chǎng)活動(dòng)或一段視頻被轉(zhuǎn)發(fā)進(jìn)群聊。小程序不要求安裝點(diǎn)開(kāi)即用分享卡片直接觸達(dá)微信好友恰好匹配這種傳播路徑。這篇文章我不打算照搬官方文檔就按自己做這類平臺(tái)的習(xí)慣講一遍先選技術(shù)路線再拆頁(yè)面和數(shù)據(jù)給出核心代碼最后講上線前后最容易踩的坑。準(zhǔn)備接手類似項(xiàng)目的開(kāi)發(fā)者、想給工作室做線上展示的運(yùn)營(yíng)者都可以按這套思路走一遍不用一開(kāi)始就把系統(tǒng)做得很大等跑通“了解—預(yù)約—參與—分享”的閉環(huán)再逐步加功能。2. 技術(shù)路線怎么定小程序原生還是跨端云開(kāi)發(fā)還是自建后端決定做非遺傳播平臺(tái)之前我會(huì)先評(píng)估平臺(tái)規(guī)模。如果主要做內(nèi)容展示、活動(dòng)預(yù)約、用戶反饋初期用戶量大概率在幾千到幾萬(wàn)這個(gè)量級(jí)并發(fā)很低。這類輕量平臺(tái)最優(yōu)先要解決的不是性能而是開(kāi)發(fā)速度、迭代成本和運(yùn)維負(fù)擔(dān)。我現(xiàn)在的做法是原生小程序加云開(kāi)發(fā)少數(shù)情況用自建后端下面細(xì)說(shuō)判斷依據(jù)。2.1 為什么不在Web/H5上做傳播閉環(huán)非遺平臺(tái)的用戶來(lái)源很大比例來(lái)自微信群、公眾號(hào)、線下掃碼和熟人轉(zhuǎn)發(fā)。Web/H5在微信里也能打開(kāi)但轉(zhuǎn)發(fā)要靠帶參鏈接用戶進(jìn)入時(shí)瀏覽器環(huán)境不一致支付、訂閱消息、獲取用戶信息這些能力都要額外做JSSDK封裝體驗(yàn)和穩(wěn)定性都不如小程序。尤其是訂閱消息H5端現(xiàn)在基本沒(méi)法直接給用戶發(fā)服務(wù)通知而活動(dòng)預(yù)約后的開(kāi)課提醒恰恰是這類平臺(tái)的運(yùn)營(yíng)剛需。小程序也有自己的約束比如類目審核、內(nèi)容安全要求。對(duì)非遺這類偏內(nèi)容展示的平臺(tái)這些約束反而是好事它逼你提前把用戶生成內(nèi)容和來(lái)源審核處理好避免后面被投訴或者被平臺(tái)提醒。另外別把舊Web站直接包進(jìn)web-view當(dāng)作小程序非遺項(xiàng)目的視頻、互動(dòng)、預(yù)約流程在web-view里體驗(yàn)割裂用戶一旦覺(jué)得不方便就會(huì)流失。我一般建議首頁(yè)和核心活動(dòng)流程全部用原生頁(yè)面長(zhǎng)文章這類靜態(tài)內(nèi)容再考慮web-view承載。2.2 原生、uni-app、Taro怎么選方案適合團(tuán)隊(duì)優(yōu)勢(shì)主要代價(jià)原生小程序沒(méi)有框架偏好、以微信為主調(diào)試直接、基礎(chǔ)庫(kù)能力更新最快代碼只能跑微信端uni-app會(huì)Vue的團(tuán)隊(duì)一套代碼可編譯到多端需要處理各端差異原生組件交互要額外適配Taro會(huì)React的團(tuán)隊(duì)適合多端、React生態(tài)打包后部分API需要做環(huán)境兼容對(duì)非遺傳播平臺(tái)這類以內(nèi)容展示、視頻播放、報(bào)名表單為主的項(xiàng)目原生小程序完全夠用。我見(jiàn)過(guò)一些項(xiàng)目用跨端框架做為了兼容H5和App在路由和組件適配花掉大量時(shí)間最后實(shí)際只上線了微信小程序一個(gè)端等于白付了遷移成本。如果團(tuán)隊(duì)已經(jīng)熟練使用Vue或React且未來(lái)明確要做App再考慮跨端框架也不遲。2.3 云開(kāi)發(fā)還是自建后端決策清單非遺平臺(tái)要不要自己買服務(wù)器搭后端我的判斷是沒(méi)有現(xiàn)成運(yùn)維體系就別搭。自建后端意味著要處理服務(wù)器安全、HTTPS證書(shū)、數(shù)據(jù)庫(kù)備份、接口限流、日志采集這些事在小團(tuán)隊(duì)里沒(méi)人長(zhǎng)期維護(hù)就會(huì)變成一直欠著的技術(shù)債。小程序云開(kāi)發(fā)提供數(shù)據(jù)庫(kù)、存儲(chǔ)、云函數(shù)和鑒權(quán)對(duì)這類業(yè)務(wù)量級(jí)支撐很夠而且免運(yùn)維。// app.js 云開(kāi)發(fā)初始化 App({ onLaunch() { if (!wx.cloud) { console.error(當(dāng)前基礎(chǔ)庫(kù)版本過(guò)低請(qǐng)升級(jí)后使用); } else { wx.cloud.init({ env: cloud1-xxxxxxxx, // 換成你自己的云環(huán)境ID在云開(kāi)發(fā)控制臺(tái)查看 traceUser: true, // 記錄用戶訪問(wèn)來(lái)源方便排查 }); } }, });env決定了云函數(shù)和數(shù)據(jù)庫(kù)所在環(huán)境填錯(cuò)會(huì)導(dǎo)致線上查不到數(shù)據(jù)這是最常見(jiàn)的配置翻車點(diǎn)。traceUser開(kāi)啟后會(huì)在用戶訪問(wèn)時(shí)留下記錄方便后續(xù)排查用戶來(lái)源生產(chǎn)環(huán)境建議保持開(kāi)啟。什么情況才需要自建后端當(dāng)平臺(tái)要對(duì)接外部文旅系統(tǒng)、需要定時(shí)任務(wù)處理大量數(shù)據(jù)、或者要自定義復(fù)雜權(quán)限模型時(shí)云開(kāi)發(fā)的邊界就會(huì)出現(xiàn)。不過(guò)這些需求在傳播平臺(tái)早期很少發(fā)生先別為不存在的復(fù)雜度買單。3. 頁(yè)面與數(shù)據(jù)怎么拆非遺平臺(tái)的模塊邊界和信息架構(gòu)平臺(tái)頁(yè)面不用追求大而全我常用一版“夠用”的頁(yè)面清單首頁(yè)、項(xiàng)目列表頁(yè)、項(xiàng)目詳情頁(yè)、傳承人頁(yè)、活動(dòng)預(yù)約頁(yè)、個(gè)人中心。留言反饋?zhàn)龀稍斍轫?yè)里的一個(gè)組件不必單獨(dú)開(kāi)頁(yè)面。這樣既能跑通核心流程又不會(huì)把開(kāi)發(fā)周期拉得過(guò)長(zhǎng)。3.1 信息架構(gòu)一版能跑通的頁(yè)面清單頁(yè)面職責(zé)主要數(shù)據(jù)來(lái)源首頁(yè)推薦內(nèi)容、分類入口、近期活動(dòng)projects 推薦位、activities項(xiàng)目列表頁(yè)按分類篩選、關(guān)鍵詞搜索projects項(xiàng)目詳情頁(yè)項(xiàng)目介紹、視頻、傳承人、預(yù)約入口projects、artisans、activities傳承人頁(yè)人物故事、代表作品artisans、projects活動(dòng)預(yù)約頁(yè)場(chǎng)次、名額、報(bào)名表單activities、signups個(gè)人中心收藏項(xiàng)目、我的預(yù)約favorites、signups信息架構(gòu)不是一次到位先按這些頁(yè)面把流程打通。非遺內(nèi)容復(fù)用性很高同一個(gè)項(xiàng)目會(huì)出現(xiàn)在推薦位、分類列表、傳承人作品集、活動(dòng)關(guān)聯(lián)等多個(gè)位置因此數(shù)據(jù)庫(kù)里的項(xiàng)目文檔不要嵌套太多內(nèi)容而是通過(guò)字段關(guān)聯(lián)復(fù)用避免一處修改需要同步多個(gè)文檔。3.2 首頁(yè)別把輪播圖當(dāng)門面內(nèi)容入口才是核心很多非遺小程序首頁(yè)放一個(gè)全屏輪播點(diǎn)擊后跳到詳情。實(shí)際上用戶在一個(gè)非高頻平臺(tái)上的停留時(shí)間很短輪播運(yùn)營(yíng)成本高點(diǎn)擊率還不一定好。我習(xí)慣把首頁(yè)重點(diǎn)放在“分類標(biāo)簽”“熱門推薦”“近期可預(yù)約活動(dòng)”三塊。分類標(biāo)簽要在首屏露出讓用戶知道這里有哪些非遺門類推薦位每?jī)芍苁謩?dòng)維護(hù)一次數(shù)據(jù)來(lái)自運(yùn)營(yíng)字段而不是隨機(jī)排序。如果首頁(yè)硬要放輪播就堅(jiān)持放一張圖對(duì)應(yīng)一個(gè)具體活動(dòng)或故事配上“預(yù)約”“查看”按鈕不要只放一張風(fēng)景圖。用戶進(jìn)入首頁(yè)第一眼需要知道“這里能做什么”而不是“這里很漂亮”。把預(yù)約入口放在首屏內(nèi)對(duì)轉(zhuǎn)化率的拉動(dòng)比單獨(dú)做一個(gè)大按鈕更明顯。3.3 項(xiàng)目詳情頁(yè)字段數(shù)據(jù)結(jié)構(gòu)決定后面好不好改// projects 集合文檔示例 { title: 古法手工造紙?bào)w驗(yàn), category: 傳統(tǒng)技藝, cover: cloud://env-id.xxx/cover.jpg, intro: 從選料、浸泡到抄紙全程體驗(yàn)傳統(tǒng)造紙流程, content: 富文本內(nèi)容..., videoUrl: https://..., artisanId: artisan_001, location: 某非遺體驗(yàn)館, tags: [造紙, 親子, 可預(yù)約], status: online, viewCount: 0, createdAt: 2024-01-01 10:00:00 }字段設(shè)計(jì)遵循一個(gè)原則列表能讀到的字段詳情頁(yè)不要再查一遍。列表頁(yè)需要展示title、category、cover、tags、status詳情頁(yè)加上content、videoUrl、artisanId。viewCount用于推薦排序和熱門列表后期做數(shù)據(jù)看板不用再改表結(jié)構(gòu)。status控制上下線避免刪除數(shù)據(jù)影響歷史預(yù)約記錄。3.4 預(yù)約與留言把“看過(guò)”變成“去過(guò)”非遺傳播平臺(tái)真正的轉(zhuǎn)化點(diǎn)是預(yù)約線下體驗(yàn)或參觀。預(yù)約我用兩張表activities是活動(dòng)模板signups是報(bào)名記錄。活動(dòng)表里放場(chǎng)次時(shí)間、名額、地點(diǎn)和報(bào)名截止時(shí)間報(bào)名記錄里冗余活動(dòng)標(biāo)題、場(chǎng)次時(shí)間這樣即使運(yùn)營(yíng)后續(xù)修改活動(dòng)內(nèi)容歷史報(bào)名信息仍然可以追溯。留言反饋模塊收集的是用戶對(duì)項(xiàng)目的感想和建議這直接關(guān)系到內(nèi)容安全審核。我建議留言不要立即上墻先進(jìn)入后臺(tái)審核審核通過(guò)后再展示不要給自己后續(xù)埋雷。這個(gè)機(jī)制在前面信息架構(gòu)里已經(jīng)預(yù)留后面避坑章節(jié)會(huì)再展開(kāi)。4. 核心代碼落地云開(kāi)發(fā)初始化、動(dòng)態(tài)列表和預(yù)約報(bào)名的實(shí)現(xiàn)這一章把最小可運(yùn)行的代碼串起來(lái)。假設(shè)已經(jīng)在開(kāi)發(fā)者工具里開(kāi)通云開(kāi)發(fā)并創(chuàng)建了projects、activities、signups、artisans、favorites、feedback這幾個(gè)集合。集合權(quán)限先說(shuō)清楚projects、activities、artisans設(shè)置“所有用戶可讀僅管理端可寫(xiě)”signups和favorites設(shè)置“僅創(chuàng)建者可讀寫(xiě)”feedback默認(rèn)“僅創(chuàng)建者可讀寫(xiě)”后續(xù)審核通過(guò)后再?gòu)?fù)制一份到公開(kāi)集合。4.1 云函數(shù)基礎(chǔ)模板動(dòng)態(tài)環(huán)境ID與分頁(yè)查詢// 云函數(shù) getIndexData / index.js const cloud require(wx-server-sdk); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); const db cloud.database(); exports.main async (event, context) { const { category , page 1, pageSize 10 } event; const where { status: online }; if (category) where.category category; const res await db.collection(projects) .where(where) .orderBy(viewCount, desc) .skip((page - 1) * pageSize) .limit(pageSize) .get(); return { list: res.data }; };DYNAMIC_CURRENT_ENV會(huì)自動(dòng)使用當(dāng)前環(huán)境避免把環(huán)境ID硬編碼進(jìn)云函數(shù)。category是前端傳入的過(guò)濾條件為空時(shí)返回全部線上項(xiàng)目。orderBy、skip、limit組合做分頁(yè)云函數(shù)內(nèi)單次get最多返回100條所以這里按頁(yè)取數(shù)據(jù)是合理做法。注意skip在小數(shù)據(jù)量下沒(méi)問(wèn)題如果數(shù)據(jù)量變大要改用基于游標(biāo)或_id的翻頁(yè)方式。前端調(diào)用云函數(shù)的方式如下// pages/list/list.js Page({ data: { category: , page: 1, list: [], finished: false }, onLoad() { this.loadMore(); }, async loadMore() { if (this.data.finished) return; wx.showLoading({ title: 加載中 }); try { const res await wx.cloud.callFunction({ name: getIndexData, data: { category: this.data.category, page: this.data.page, pageSize: 10 }, }); const list this.data.list.concat(res.result.list); this.setData({ list, page: this.data.page 1, finished: res.result.list.length 10, }); } finally { wx.hideLoading(); } }, });finished標(biāo)志用來(lái)避免重復(fù)觸發(fā)加載。res.result.list是云函數(shù)返回的數(shù)據(jù)微信會(huì)自動(dòng)完成序列化前端不需要再做額外解包。這里把加載狀態(tài)放在finally里無(wú)論成功還是失敗都能關(guān)掉loading避免用戶等半天看不到結(jié)果。4.2 為什么用云函數(shù)而不是前端直接讀庫(kù)前端直接讀云數(shù)據(jù)庫(kù)不是不行但有三個(gè)問(wèn)題。第一集合權(quán)限設(shè)為所有用戶可讀后任何人都能通過(guò)開(kāi)發(fā)者工具直接調(diào)數(shù)據(jù)庫(kù)API讀取數(shù)據(jù)繞過(guò)業(yè)務(wù)邏輯翻出未上線內(nèi)容。第二客戶端數(shù)據(jù)庫(kù)API對(duì)復(fù)雜查詢支持有限按標(biāo)簽過(guò)濾、按熱度排序、關(guān)聯(lián)活動(dòng)這類操作寫(xiě)起來(lái)很別扭。第三邏輯放在云函數(shù)里后續(xù)要加緩存、埋點(diǎn)、內(nèi)容檢測(cè)時(shí)只需要改一處不用動(dòng)小程序端。我一般把查詢、寫(xiě)入、審核類操作全部放到云函數(shù)里前端只負(fù)責(zé)渲染和交互。這樣也方便將來(lái)把云函數(shù)替換成自建HTTP接口前端代碼只改調(diào)用層頁(yè)面邏輯不動(dòng)。4.3 關(guān)鍵詞搜索用正則做中文模糊查詢的邊界// 云函數(shù) searchProjects const keyword String(event.keyword || ).trim(); if (!keyword) return { list: [] }; const reg db.RegExp({ regexp: keyword, options: i }); const res await db.collection(projects) .where({ status: online, title: reg, }) .limit(20) .get();對(duì)中文內(nèi)容來(lái)說(shuō)db.RegExp是最快上手的模糊查詢方案。這里只匹配title真實(shí)項(xiàng)目中可以同時(shí)匹配tags但要注意RegExp會(huì)讓索引失效數(shù)據(jù)量超過(guò)幾千條時(shí)性能會(huì)明顯下降需要換成輕量搜索方案或內(nèi)容服務(wù)。還有一個(gè)容易忽略的點(diǎn)用戶輸入的正則元字符比如[、*、會(huì)讓RegExp出現(xiàn)異常匹配所以我在傳入前會(huì)先過(guò)濾掉這類字符。4.4 預(yù)約報(bào)名用事務(wù)防止超賣和重復(fù)報(bào)名// 云函數(shù) signUpActivity const cloud require(wx-server-sdk); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); const db cloud.database(); const _ db.command; exports.main async (event, context) { const { activityId } event; const { OPENID } cloud.getWXContext(); const result await db.runTransaction(async transaction { const act await transaction.collection(activities).doc(activityId).get(); if (!act.data || act.data.status ! open) { throw new Error(活動(dòng)未開(kāi)放); } if (act.data.signUpCount act.data.maxPeople) { throw new Error(名額已滿); } const dup await transaction.collection(signups) .where({ activityId, openid: OPENID }) .count(); if (dup.total 0) { throw new Error(請(qǐng)勿重復(fù)報(bào)名); } await transaction.collection(activities).doc(activityId).update({ data: { signUpCount: _.inc(1) }, }); await transaction.collection(signups).add({ data: { activityId, openid: OPENID, createdAt: db.serverDate() }, }); return { ok: true }; }); return result; };runTransaction保證讀到的活動(dòng)狀態(tài)、名額、重復(fù)報(bào)名檢查、名額增加、報(bào)名寫(xiě)入這五個(gè)操作在同一個(gè)事務(wù)里執(zhí)行避免多人同時(shí)報(bào)名時(shí)超賣。關(guān)鍵點(diǎn)是OPENID從云函數(shù)上下文獲取而不是讓前端把openid作為參數(shù)傳進(jìn)來(lái)否則用戶可以偽造別人的報(bào)名記錄。db.command.inc(1)是原子自增比先讀后寫(xiě)更可靠這條路徑也是預(yù)約系統(tǒng)最容易翻車的地方。提示活動(dòng)名額字段一定要用signUpCount加maxPeople配合判斷不要只在前端寫(xiě)死剩余名額。5. 避坑指南非遺小程序開(kāi)發(fā)里最容易翻車的五個(gè)問(wèn)題這個(gè)方向踩過(guò)的坑不少。下面這五條是我在開(kāi)發(fā)非遺類小程序時(shí)最常遇到的每一條都按“現(xiàn)象—原因—解決”來(lái)寫(xiě)方便你直接對(duì)照排錯(cuò)。5.1 上線后首頁(yè)空白模擬器卻一切正?,F(xiàn)象開(kāi)發(fā)者工具預(yù)覽正常體驗(yàn)版或線上版首頁(yè)列表加載不出來(lái)控制臺(tái)報(bào)數(shù)據(jù)庫(kù)權(quán)限錯(cuò)誤。原因最常見(jiàn)的是集合權(quán)限設(shè)置成了“僅創(chuàng)建者可讀寫(xiě)”前端直接讀庫(kù)時(shí)非創(chuàng)建者自然讀不到數(shù)據(jù)。第二種可能是云函數(shù)初始化時(shí)把env寫(xiě)成了另一個(gè)環(huán)境ID和實(shí)際部署環(huán)境不一致。解決先檢查集合權(quán)限projects、activities這類公開(kāi)內(nèi)容至少設(shè)為“所有用戶可讀”。再檢查云函數(shù)初始化代碼統(tǒng)一用cloud.DYNAMIC_CURRENT_ENV避免環(huán)境ID手滑寫(xiě)錯(cuò)。最后在云函數(shù)里加一行日志輸出當(dāng)前環(huán)境用云開(kāi)發(fā)控制臺(tái)查看請(qǐng)求日志能快速定位是權(quán)限還是環(huán)境問(wèn)題。5.2 圖片加載不出來(lái)一會(huì)兒行一會(huì)兒不行現(xiàn)象本地開(kāi)發(fā)時(shí)圖片正常線上圖片一直轉(zhuǎn)圈有的機(jī)型能顯示有的機(jī)型加載失敗。原因小程序?qū)D片資源有合法域名限制圖片域名沒(méi)有配置到downloadFile合法域名里或者直接把云存儲(chǔ)fileID當(dāng)普通URL使用在部分組件和基礎(chǔ)庫(kù)組合下不穩(wěn)定。解決在小程序后臺(tái)配置圖片所在域名為合法域名如果是云存儲(chǔ)文件建議用wx.cloud.getTempFileURL換取臨時(shí)鏈接再交給image組件或者在image的src里直接使用cloud://開(kāi)頭的fileID組件會(huì)自動(dòng)處理。不要在data里存拼接后的完整URL容易把域名寫(xiě)死。5.3 預(yù)約活動(dòng)名額被搶超或者出現(xiàn)重復(fù)報(bào)名現(xiàn)象后臺(tái)看到同一用戶有兩條報(bào)名記錄或者報(bào)名人數(shù)超過(guò)活動(dòng)名額。原因先查庫(kù)存再寫(xiě)入是典型的并發(fā)競(jìng)態(tài)兩個(gè)請(qǐng)求同時(shí)讀到剩余名額為1各自執(zhí)行寫(xiě)入最后超賣。前端按鈕置灰只能防手抖防不了并發(fā)。解決把報(bào)名邏輯整體放進(jìn)db.runTransaction讀取活動(dòng)、校驗(yàn)名額、檢查重復(fù)、更新計(jì)數(shù)、寫(xiě)入記錄五步在一個(gè)事務(wù)里完成。對(duì)同一用戶重復(fù)報(bào)名用where({ activityId, openid })配合count()檢測(cè)事務(wù)內(nèi)能保證一致性。5.4 留言反饋功能提交后被審核提醒現(xiàn)象提交版本審核時(shí)平臺(tái)提示“涉及用戶自生成內(nèi)容”或者上線后收到內(nèi)容安全警告。原因平臺(tái)對(duì)用戶可以生成內(nèi)容的場(chǎng)景有專門要求留言、評(píng)論、上傳圖片都需要接入內(nèi)容安全能力不能只把內(nèi)容存進(jìn)數(shù)據(jù)庫(kù)就完事。解決云函數(shù)里接入文本和圖片安全檢測(cè)文本內(nèi)容在寫(xiě)入前先調(diào)用檢測(cè)接口圖片上傳到云存儲(chǔ)前也做一輪檢測(cè)。常見(jiàn)做法是先審后發(fā)用戶提交的內(nèi)容進(jìn)入feedback_pending集合管理員審核通過(guò)后再?gòu)?fù)制到公開(kāi)的feedback集合。這樣既滿足要求也避免臟數(shù)據(jù)直接出現(xiàn)在前端。5.5 分享卡片打開(kāi)后頁(yè)面空白或跳錯(cuò)頁(yè)現(xiàn)象用戶點(diǎn)分享卡片進(jìn)入小程序頁(yè)面沒(méi)有數(shù)據(jù)或者直接跳到首頁(yè)和分享時(shí)看到的內(nèi)容對(duì)不上。原因onShareAppMessage返回的 path 里沒(méi)有帶項(xiàng)目ID或者項(xiàng)目ID包含特殊字符沒(méi)做編碼導(dǎo)致onLoad解析參數(shù)失敗。解決分享路徑顯式帶上ID比如path: /pages/detail/detail?id projectId在onLoad(options)里讀取options.id并做decodeURIComponent同時(shí)兼容未傳ID的場(chǎng)景直接跳回首頁(yè)。分享后的落地頁(yè)一定要保證有數(shù)據(jù)兜底不能只依賴網(wǎng)絡(luò)請(qǐng)求成功才顯示內(nèi)容。6. 進(jìn)階運(yùn)營(yíng)讓非遺小程序形成分享與預(yù)約的傳播閉環(huán)平臺(tái)上線只是第一步真正要做的是讓用戶愿意轉(zhuǎn)發(fā)。我常用的三個(gè)做法是分享海報(bào)、活動(dòng)前提醒、數(shù)據(jù)復(fù)盤。分享海報(bào)比普通鏈接卡片的轉(zhuǎn)化率高很多。用canvas生成一張包含非遺項(xiàng)目封面、名稱、時(shí)間地點(diǎn)的海報(bào)用戶保存到相冊(cè)后轉(zhuǎn)發(fā)到群聊或朋友圈掃碼進(jìn)入小程序時(shí)帶上邀請(qǐng)參數(shù)。這個(gè)功能建議放在項(xiàng)目詳情頁(yè)的“分享”按鈕里按鈕文案寫(xiě)“生成海報(bào)”而不是“分享”用戶更愿意點(diǎn)。生成海報(bào)時(shí)注意圖片域名的限制背景圖盡量用云存儲(chǔ)的臨時(shí)鏈接用wx.getImageInfo下載后再畫(huà)進(jìn) canvas?;顒?dòng)前提醒依賴訂閱消息。用戶在報(bào)名時(shí)通過(guò)wx.requestSubscribeMessage申請(qǐng)一次訂閱授權(quán)活動(dòng)開(kāi)始前一天由定時(shí)觸發(fā)器調(diào)用云函數(shù)給已報(bào)名用戶發(fā)送服務(wù)通知。這里要記住一個(gè)硬性限制一次授權(quán)只能發(fā)送一條消息所以報(bào)名頁(yè)要把訂閱請(qǐng)求放在用戶主動(dòng)點(diǎn)擊的動(dòng)線里比如點(diǎn)“提交報(bào)名”后再?gòu)棾鍪跈?quán)授權(quán)體驗(yàn)更自然用戶同意率也更高。數(shù)據(jù)復(fù)盤方面云開(kāi)發(fā)控制臺(tái)的請(qǐng)求統(tǒng)計(jì)能看到每個(gè)云函數(shù)的調(diào)用量我一般按“首頁(yè)瀏覽→詳情頁(yè)瀏覽→報(bào)名提交”三步漏斗去查。如果詳情頁(yè)到報(bào)名頁(yè)的轉(zhuǎn)化率很低優(yōu)先檢查報(bào)名頁(yè)的字段數(shù)量最好只保留姓名、手機(jī)號(hào)、人數(shù)三個(gè)必填項(xiàng)多余字段都放到后臺(tái)補(bǔ)充。如果首頁(yè)到詳情頁(yè)的點(diǎn)擊率低問(wèn)題多數(shù)出在推薦位內(nèi)容不夠吸引人這時(shí)候換掉標(biāo)題頭圖比改代碼更有效。我吃過(guò)一次虧平臺(tái)做完就丟上線結(jié)果一個(gè)月沒(méi)幾個(gè)自然訪問(wèn)。后來(lái)把分享路徑打通、配合線下活動(dòng)掃碼、運(yùn)營(yíng)每周更新推薦位數(shù)據(jù)才慢慢起來(lái)。這個(gè)方向不是一次性開(kāi)發(fā)交付而是需要持續(xù)運(yùn)營(yíng)的傳播工具。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取