這篇是微信小程序前后端快速入門完結篇了,今天利用之前學習過的所有知識做一個新的項目「群登記助手v1.0」小程序。
整體技術架構:小程序原生前端+小程序云開發。
經歷了前面教程的學習,大家有了一定的基礎,所以本次分享重心主要是帶著大家理清楚邏輯相關的云開發處理方案和之前未講解過的重要組件,之前已經講解過的重復知識就不會重新再講解,需要大家利用之前已經學習過的知識來組合今天學習的新知識對接龍小程序進行整體的完善。
業務分析
流程分析
接龍小程序使用者角色上會有兩種,分別是發起者和參與者。這個接龍是由發起者來讓參與者接龍,所以他們兩之間的使用邏輯是:
一共有以下七步,來完成整個接龍行為的閉環。
- 發起者 - 創建接龍活動
- 發起者 - 進入接龍列表
- 發起者 - 轉發到微信群
- 參與者 - 點擊程序卡片
- 參與者 - 進入活動詳情
- 參與者 - 接龍信息填寫
- 參與者 - 進入活動詳情
界面如下:
數據庫設計
首先數據庫設計來看,我們需要三張表:
- 用戶表(users),用于用戶體系的基礎搭建
2. 接龍活動表(solitaire),用于存放發起者接龍活動
3. 接龍信息表(solitaire_info),用于存放參與者接龍信息
實現路線圖
難點部分會進行分析講解,簡單部分需自行實現(之前教過的知識點)
- 創建活動 -> 獲取用戶信息 -> 用戶表插入用戶數據 -> 活動表插入活動信息
- 轉發活動 -> 通過聯合查詢出活動列表 -> 將接龍活動轉發到群里
- 查詢信息 -> 通過分享的活動ID查詢詳情 -> 跳轉到填寫信息
- 填寫信息 -> 獲取用戶信息(同上)-> 信息表插入接龍信息 -> 更新活動參與人數 -> 發送訂閱消息
- 回到詳情 -> 刷新接龍信息列表(使用聚合查詢)
- 其他功能 -> 導出表格
復雜查詢
由于接龍信息和用戶信息分別在兩張表中實現,所以這里需要用到聯表查詢。這個時候就需用到小程序的聚合查詢能力。
聯表查詢
如我們現在已經有一條活動數據了,那么現在數據庫的數據結構應該是這樣的:
用戶表 users:
接龍表 solitaire:
然后使用 lookup 函數進行關聯起來。
以下為屬性含義
lookup({from: <要連接的集合名>,localField: <輸入記錄的要進行相等匹配的字段>,foreignField: <被連接集合的要進行相等匹配的字段>,as: <輸出的數組字段名>
})
結合以上使用方式,我們使用下lookup連接查詢
async queryLookupList(context, params) {let res = await db.collection('solitaire').aggregate().match({openid: context.OPENID}).lookup({from: 'users',localField: 'openid',foreignField: '_openid',as: 'users',}).sort({date: -1}).end()return res}
最后查詢出來的結果是:
[{"_id": "cd045e756110ed09047443683dd70ecf","content": "312312","date": "2021-08-09 16:53","title": "12312","type": 1,"openid": "oyfiv5Z90bqbQ6BJ6A273eP68j-w","number": 0,"users": [{"_id": "8937eaa96110ea39039e900278a1529e","_openid": "oyfiv5Z90bqbQ6BJ6A273eP68j-w","date": "2021-08-09T08:41:29.878Z","userInfo": {"avatarUrl": "https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJ9VBHPzRxk4M7bc4xxwXOaw6DpciahEjzeZ4GP0UoSmiaqBMFQznROZlVG5ukvpv8dSXNzl34oaP7g/132","city": "Changsha","country": "China","gender": 1,"language": "zh_CN","nickName": "111陳宇明","province": "Hunan"}}]}]
由于在實際復雜業務中,聚合查詢使用的比較多的,所以再次我們帶大家來對聚合查詢進行更深入的了解。
聚合查詢
聚合是非常強大的數據分析工具,主要用于對記錄進行批量處理,可以對記錄進行按條件分組、跨集合聯表等一系列批量而又復雜操作。類似于Excel整列整列跨字段的運算(如加、減、合并、比較等)、對內嵌的字段可以進行整列拆分、類型變換、組合等。
聚合查詢 VS 普通查詢
聚合aggregate和普通數據查詢get是兩套不同的體系,聚合更偏向于數據的復雜查詢。聚合查詢和普通數據查詢都能對數據庫進行查詢,兩個的很多方法都特別類似,我們可以通過對之前普通查詢的理解來理解聚合查詢的部分功能,具體查看以下表格對比。
在這里需要注意的是使用聚合查詢之前需要先 aggregate() 發起一個聚合操作。以上是普通查詢可以做到的,聚合查詢也可以做到,接下來是普通查詢做不到的。
聚合階段
聚合階段是聚合管理流水線作業的組成單元,是一個個功能節點,有的可以聯表lookup、有的可以組合group、有的可以拆分unwind等等。每個聚合階段可以使用表達式、操作符對輸入文檔進行計算綜合、均值、拼接、分割、轉換格式等操作,操作完成之后會輸出給下一個階段,直到end返回結果。
小技巧
在這里告訴大家一個小技巧,其實寫查詢的時候可以在數據庫的高級操作區間先寫好測試然后再放到函數中去使用,這樣可以提高效率。
在這里不需要獲取數據庫對象,直接通過db就能使用,數據也不需要打印出來,只要使用了結束函數就可以了。
訂閱消息
當發起者轉發到群里之后,參與者就可以填寫接龍信息,當接龍信息填寫完成之后,可以在這里給到參與者發送一個訂閱消息,告知參與者接龍成功。
這樣設計有兩個好處:
- 便于再次激活用戶,多一個入口就多一些用戶打開的概率。
- 更快捷的打開方式(提升1倍的效率)
- 正常打開路徑:
- 下拉聊天界面進入小程序列表
- 點擊接龍小程序
- 找到參與的接龍活動
- 找到具體接龍點擊查看詳情
- 訂閱模版
- 進入服務通知列表
- 找到具體模版點擊查看詳情
那么如何給用戶發送訂閱消息呢?請接著往下看:
申請消息模版
第一步,先登錄到后臺,找到訂閱消息菜單->申請訂閱消息模版
第二步,進入訂閱消息列表頁面,點擊選用按鈕
第三步,進入選用模版庫,通過關鍵詞搜索進行查找,消息模版和小程序的類目有關,以“接龍”為例,小程序類目是「預約/報名,筆記」所以搜索到了這兩個類目下的消息模版。
第四步,選擇自己需要的模版,點擊「選用」進入詳情頁面。模版有很多關鍵詞,只需要勾選自己需要的關鍵詞即可,然后填寫下場景說明即可點擊提交
第五步,填寫完成后,會在我的模版看到剛才申請好的消息模版,復制模版ID即可,到時候然后切換到小程序端進行使用
獲取訂閱授權
第六步,找到小程序需要讓用戶授權的觸發方法。如:需求是當用戶填寫完成接龍資料,讓用戶授權報名成功提醒,然后發一條報名成功的訂閱消息,那么這個時候就需要找到填寫信息的方法。如果只是單獨先對這個功能進行學習,那么就可以在一個頁面寫個按鈕,然后按鈕綁定一個點擊事件觸發即可。
寫在任意測試頁面wxml
<button bindtap="onMsg" >測試訂閱消息</button>
當前測試頁面對應的js
wx.requestSubscribeMessage({tmplIds: ['模版ID'], success(res) {console.log(res)}})
第七步,用真機調試,模擬器不支持。點擊之后界面會出現授權頁面。
以下為我分別點擊取消和允許的日志輸出。用戶可以支持一次調用最多可訂閱3條消息。
然后我們再來看下 requestSubscribeMessage 文檔中對返回體的解釋
對于開發者來說,需要關心的就是是否用戶允許來,所以我們需要通過以下方式獲取結果,當結果是允許的時候我們插入就發送成功通知給到用戶即可。當然我這里指的是用戶添加完后發送添加成功通知的業務路徑,如果不是需要當前動作完成后發送的話,那么就需要存儲一條記錄到數據庫,等需要用到的時候再去做發送消息模版的動作。
onMsg() {wx.requestSubscribeMessage({tmplIds: ['模版ID'],success(res) {if(res.模版ID=='accept'){// 發送消息給到用戶}}})}
發送模版消息
第七步,發送模版消息,新建一個發送模版消息的云函數 sendMessage ,然后打開 subscribeMessage. send 文檔,可以看到這個方法支持云調用,也就是說官方已經幫開發者封裝好了方法使用起來非常簡單。
云調用是云開發提供的基于云函數使用小程序開放接口的能力
那么我們就用云調用方法來試試,首先在 sendMessage 的config.json文件配置權限
{"permissions": {"openapi": ["subscribeMessage.send"]}
}
然后在js中編寫調用發送模版消息的方法,方法參數如下:
我把重要的參數用紅色框框標記起來了,看下代碼。
// 云函數入口文件
const cloud = require('wx-server-sdk')cloud.init()// 云函數入口函數
exports.main = async (event, context) => {const wxContext = cloud.getWXContext()const result = await cloud.openapi.subscribeMessage.send({"touser": wxContext.OPENID, // 發給自己直接從 getWXContext 獲取"templateId":'模版ID',"page": '目標頁面路徑',"lang": 'zh_CN',"data": {"thing2": {"value": '報名接龍2021'},"phrase8": {"value": '報名成功'},"thing19": {"value": '詳細點擊查看=>'}},"miniprogramState": 'developer'})return result}
注意 data 這個參數需要回到小程序管理后臺的消息訂閱列表查看訂閱模版的詳情
這里需要注意每個不同的數據類型都有些限制條件詳細可見文檔,然后data參數需要和上面的模版內容一對一對應上,方法寫完上傳并部署即可。
第八步,調用模版消息。
onMsg() {wx.requestSubscribeMessage({tmplIds: ['模版ID'],success(res) {if (res.XXXXID == 'accept') {wx.cloud.callFunction({name: 'sendMessage'}).then(res => {console.log(res)})}}})}
調用成功后會在微信聊天頁面的服務通知中收到模版消息提醒,點擊即可進入小程序,效果如下:
導出表格
使用云函數使用Node.js的node-xlsx模塊
安裝模塊
- 新建云函數 excel
- 右鍵云函數選擇在外部終端窗口開打
- 輸入命令
npm install node-xlsx
- 安裝成功
- 文件結構
使用模塊
- 導入模塊
const xlsx = require('node-xlsx')
- 準備數據
let row = ['姓名', '電話', '備注']; //表格的屬性let allData = [] //表格內容// 添加表頭allData.push(row)// 假數據,真實數據需要從小程序端傳遞過來或在云函數中云數據庫查詢出來allData.push(['陳宇明', '13148123123', ''])allData.push(['陳X明', '13148123123', '不知道'])
- 生成表格
// 生成表格var buffer = await xlsx.build([{name: 'mySheetName',data: allData}]);
- 最后生成完成之后還需要用到我們之前學習過的上傳文件 uploadFile 上傳到云存儲中
let cloudPath = `xlsx/${Math.floor(Math.random()*1000000000)}.xlsx`
//上傳文件返回結果return await cloud.uploadFile({cloudPath: cloudPath,fileContent: buffer, //excel二進制文件})
- 調試一下
- 查看文件
- 通過復制下載鏈接,打開查看表格內容
在線查看文檔
當獲取到文件ID,在使用 getTempFileURL 用云文件 ID 換取真實鏈接,然后 downloadFile 下載文件資源到本地,通過 openDocument 新開頁面打開文檔。
openExcel(){wx.cloud.callFunction({name: "excel",data: {infos: {} //表格數據},complete: res => {wx.cloud.getTempFileURL({fileList: [res.result.fileID],success: res => {this.setData({tempFileURL: res.fileList[0].tempFileURL})console.log(this.data.tempFileURL)wx.downloadFile({url: this.data.tempFileURL,success: (res) => {const filePath = res.tempFilePathconsole.log(filePath)wx.openDocument({filePath: filePath,showMenu: true,success: res => {console.log(res)}})}})}})}})},
復制下載鏈接
當獲取到文件ID,在使用 getTempFileURL 用云文件 ID 換取真實鏈接,然后 setClipboardData 設置系統剪貼板的內容。
getExcelUrl() {wx.cloud.callFunction({name: "excel",data: {infos: {} //表格數據},complete: res => {wx.cloud.getTempFileURL({fileList: [res.result.fileID],success: res => {this.setData({tempFileURL: res.fileList[0].tempFileURL})wx.setClipboardData({ //復制到粘貼板data: this.data.tempFileURL,success(res) {wx.getClipboardData({success(res) {}})}})}})}})},
最后
這篇教程相比之前的備忘錄教程更像是一道填空題,需要大家利用之前教程學習到的知識進行融合才能實現這個小程序,獨立完成這個項目才是檢驗學習效果的最佳方式。
學習更多小程序云開發知識請關注CRMEB開源項目