聶力 杜丹蕾 韋美雁 文昕 唐俊杰
關(guān)鍵詞:微信小程序;C/S;回調(diào)地獄
中圖分類(lèi)號(hào):TP311 文獻(xiàn)標(biāo)識(shí)碼:A
文章編號(hào):1009-3044(2023)02-0029-04
1 前言
隨著科技的高速發(fā)展,我國(guó)的城市化不斷推進(jìn),越來(lái)越多的大自然環(huán)境被建設(shè)為高樓大廈和水泥公路,這使得那些原本生活在大自然環(huán)境中的貓咪的生存空間越來(lái)越小,它們被迫離開(kāi)了自然環(huán)境,被人為或非人為地帶入城市中[1],經(jīng)常吃不飽,到處流浪,受到諸方面的傷害,流浪貓的問(wèn)題越來(lái)越嚴(yán)重[2];有些人可能會(huì)對(duì)這一現(xiàn)象表示同情,想收養(yǎng)流浪貓,但卻不知道通過(guò)怎樣的途徑[3];隨著時(shí)代的變化,人們?cè)絹?lái)越會(huì)享受生活,開(kāi)始養(yǎng)寵物貓,但養(yǎng)貓的人家卻不一定懂得貓咪的生活習(xí)慣。所以關(guān)于這些問(wèn)題項(xiàng)目團(tuán)隊(duì)基于微信公眾平臺(tái)設(shè)計(jì)了一款方便、簡(jiǎn)潔、智能、功能健全的流浪貓領(lǐng)養(yǎng)求助系統(tǒng)[4-5]。
2 相關(guān)技術(shù)介紹
系統(tǒng)采用C/S(Client/Server)架構(gòu),這種架構(gòu)更便于以后的更新與維護(hù),也是目前主流的設(shè)計(jì)模式之一。C/S架構(gòu)安全性高、交互性強(qiáng)、網(wǎng)絡(luò)通信量低、響應(yīng)速度快。分為小程序客戶(hù)端、后臺(tái)服務(wù)端和數(shù)據(jù)庫(kù)端的開(kāi)發(fā)[6-7]。
小程序是一種基于微信平臺(tái)的應(yīng)用,相對(duì)于其他C/S架構(gòu)的系統(tǒng),其不需要下載,更加方便。內(nèi)有許多的內(nèi)置接口,大大方便了開(kāi)發(fā)人員,節(jié)約了開(kāi)發(fā)的時(shí)間,提高了效率[8-9]。小程序使用WXML、WXSS、JS和JSON語(yǔ)言進(jìn)行開(kāi)發(fā)。WXML功能更加強(qiáng)大,新增了數(shù)據(jù)綁定、列表渲染、條件渲染和模板引用等功能,能夠構(gòu)建更加復(fù)雜的頁(yè)面;WXSS增加了尺寸單位——rpx,這種尺寸單位可以為開(kāi)發(fā)者免除不同屏幕之間換算的煩惱。這些語(yǔ)言上手快,開(kāi)發(fā)周期短,開(kāi)發(fā)完后通常能夠在各系統(tǒng)和平臺(tái)上運(yùn)行。
服務(wù)器后端是采用Java語(yǔ)言用IntelliJ IDEA工具進(jìn)行編寫(xiě)。Java語(yǔ)言是一種跨平臺(tái)應(yīng)用程序的面向?qū)ο蟮某绦蛟O(shè)計(jì)語(yǔ)言,其使用廣泛,簡(jiǎn)單。服務(wù)器采用了目前市面上較流行的Spring框架,該框架遵守低耦合、高內(nèi)聚原則,增加了系統(tǒng)的可讀性和可維護(hù)性,降低了對(duì)環(huán)境的要求,無(wú)須配置文件,使得開(kāi)發(fā)更加簡(jiǎn)化,方便和加速了開(kāi)發(fā)人員的代碼編寫(xiě)。
采用關(guān)系型數(shù)據(jù)庫(kù)MySQL管理數(shù)據(jù),MySQL體積較小、速度快、成本低而且還是開(kāi)源軟件,獲得大多人的喜愛(ài)與優(yōu)先選擇,前端向后端請(qǐng)求更新數(shù)據(jù)后,后端通過(guò)MyBaits與數(shù)據(jù)庫(kù)進(jìn)行通信,對(duì)數(shù)據(jù)進(jìn)行增、刪、改、查等各種操作。
3 系統(tǒng)設(shè)計(jì)分析
3.1 功能設(shè)計(jì)
“送它回家”系統(tǒng)包括基礎(chǔ)功能模塊、主要功能模塊以及特色功能模塊。由貓咪領(lǐng)養(yǎng)模塊、貓咪送養(yǎng)模塊、為它治病模塊、貓圈模塊、用品購(gòu)買(mǎi)模塊、消息推送模塊、登錄注冊(cè)模塊和個(gè)人信息模塊組成。各模塊之間相互獨(dú)立,便于管理和維護(hù),用戶(hù)能通過(guò)這些功能模塊能對(duì)貓咪進(jìn)行全方位照顧。這些模塊都實(shí)現(xiàn)了前后端互聯(lián),頁(yè)面的加載與跳轉(zhuǎn)。程序界面清爽,操作簡(jiǎn)單,幫助用戶(hù)從沒(méi)有貓咪到學(xué)會(huì)照顧貓咪與享受貓咪生活的一條龍服務(wù)。
3.2 數(shù)據(jù)庫(kù)設(shè)計(jì)
對(duì)照幾大功能模塊,數(shù)據(jù)庫(kù)一共設(shè)計(jì)了7張數(shù)據(jù)表,分別是cat表(存儲(chǔ)貓咪信息),news表(存儲(chǔ)貓咪小貼士信息),per表(存儲(chǔ)用戶(hù)信息),ship表(存儲(chǔ)貓用品信息),shuo表(存儲(chǔ)說(shuō)說(shuō)信息),shuodis表(存儲(chǔ)說(shuō)說(shuō)的評(píng)論信息),user表(存儲(chǔ)用戶(hù)賬號(hào)信息),每個(gè)表都有唯一ID,表示每條數(shù)據(jù)的唯一性。
4 系統(tǒng)實(shí)現(xiàn)
4.1 登錄與注冊(cè)模塊
界面里input組件綁定了輸入事件(bindinput="in?putWatch"),每當(dāng)input組件被輸入了數(shù)據(jù),JS就能通過(guò)inputWatch(e)函數(shù)的形參e進(jìn)行數(shù)據(jù)的獲取。form組件綁定了提交事件(bindsubmit="submit"),點(diǎn)擊提交按鈕,JS對(duì)填寫(xiě)數(shù)據(jù)進(jìn)行校驗(yàn)。首先用trim()函數(shù)判斷要提交給后端的參數(shù)是否為空,為空便通過(guò)wx.showToast()接口提示“輸入內(nèi)容為空”,不為空便繼續(xù)進(jìn)行數(shù)據(jù)格式的判斷,校驗(yàn)通過(guò)便使用wx.request()請(qǐng)求把數(shù)據(jù)傳給后端,后端進(jìn)行相應(yīng)的處理。
系統(tǒng)能夠以游客的身份進(jìn)入,如果要進(jìn)行領(lǐng)養(yǎng)貓咪、購(gòu)買(mǎi)貓用品等功能時(shí)會(huì)跳轉(zhuǎn)到登錄界面。登錄成功后,系統(tǒng)把用戶(hù)基本信息存入本地緩存中(通過(guò)wx.setStorageSync("userinfo", userInfo) )。當(dāng)程序運(yùn)行到那些需要登錄才能進(jìn)行下去的功能時(shí),系統(tǒng)首先嘗試從本地緩存調(diào)取數(shù)據(jù)(通過(guò)wx.getStorageSync("userIn?fo") ),然后把獲取的數(shù)據(jù)用if 進(jìn)行判斷,如果為NULL,以便提醒用戶(hù)登錄,否則就進(jìn)行下一步操作。
4.2 個(gè)人信息模塊(“我的”模塊)
該界面顯示和管理用戶(hù)個(gè)人消息,用戶(hù)在平臺(tái)上注冊(cè)了一個(gè)賬號(hào),那么用戶(hù)所填寫(xiě)的個(gè)人消息就綁定在這個(gè)賬號(hào)上。
界面中間部分是領(lǐng)養(yǎng)記錄、送養(yǎng)記錄與購(gòu)買(mǎi)記錄的按鈕,當(dāng)用戶(hù)做了相應(yīng)的動(dòng)作后,后臺(tái)會(huì)進(jìn)行更新數(shù)據(jù),點(diǎn)擊進(jìn)入相應(yīng)的界面就能看到用戶(hù)做過(guò)的相關(guān)記錄(比如,當(dāng)用戶(hù)領(lǐng)養(yǎng)過(guò)一次貓咪后,那么領(lǐng)養(yǎng)記錄里會(huì)有這次領(lǐng)養(yǎng)的情況)。界面的上半部分,當(dāng)用戶(hù)登錄了就會(huì)顯示用戶(hù)的頭像與昵稱(chēng),如果未登錄便顯示一個(gè)登錄按鈕,此效果是通過(guò)view組件中的wx-if實(shí)現(xiàn),小程序先從本地緩存嘗試獲取用戶(hù)信息,如果能獲取到便顯示頭像與昵稱(chēng),否則就顯示按鈕。
4.3 用品購(gòu)買(mǎi)模塊
此模塊是一個(gè)電商模塊。通過(guò)線(xiàn)下團(tuán)隊(duì)對(duì)周?chē)堄闷返赀M(jìn)行篩選,最后挑選出一些質(zhì)量靠譜的商家進(jìn)行合作,在這里用戶(hù)能夠買(mǎi)到通過(guò)團(tuán)隊(duì)認(rèn)證的貓用品與貓糧。
界面中的所有商品,通過(guò)request請(qǐng)求向后端獲取,通過(guò)view組件中的屬性wx:for一次性渲染,點(diǎn)擊物品進(jìn)入物品詳情界面。因?yàn)槊總€(gè)物品有一個(gè)唯一的ID號(hào),在這過(guò)程中小程序把用戶(hù)所點(diǎn)擊物品的那個(gè)ID 號(hào)通過(guò)request請(qǐng)求傳給后端,后端通過(guò)物品ID 號(hào)向數(shù)據(jù)庫(kù)查找數(shù)據(jù),再返回相應(yīng)ID號(hào)物品的詳細(xì)信息,前端接收后端返回的數(shù)據(jù),就能通過(guò)一個(gè)固定的模板把不同的商品的詳情給渲染出來(lái)。
4.4 消息推送模塊
針對(duì)用戶(hù)群體對(duì)養(yǎng)貓知識(shí)的興趣,系統(tǒng)開(kāi)辟消息推送模塊,推送一些貓咪冷知識(shí)和生活習(xí)慣。消息推送顯示在首頁(yè)的底部,每當(dāng)用戶(hù)進(jìn)入系統(tǒng)時(shí),便能看到系統(tǒng)發(fā)布的每日小貼士,方便用戶(hù)了解貓咪的相關(guān)消息。
4.5 貓圈模塊
此模塊類(lèi)似于朋友圈,用戶(hù)能夠在這樣分享自己與貓咪一起生活的趣事,發(fā)布后所有系統(tǒng)用戶(hù)都可見(jiàn),能夠評(píng)論與點(diǎn)贊。
每次進(jìn)入貓圈都進(jìn)行一次request請(qǐng)求,獲得所有的說(shuō)說(shuō),通過(guò)view組件渲染;點(diǎn)擊說(shuō)說(shuō)下的愛(ài)心給說(shuō)說(shuō)點(diǎn)贊,此過(guò)程前端是通過(guò)request請(qǐng)求把說(shuō)說(shuō)的ID發(fā)給后臺(tái),后臺(tái)進(jìn)行處理,頁(yè)面刷新,完成點(diǎn)贊;點(diǎn)擊說(shuō)說(shuō)下的評(píng)論按鈕,輸入要評(píng)論的話(huà)后點(diǎn)提交完成評(píng)論,此過(guò)程前端是通過(guò)request請(qǐng)求把評(píng)論人的ID、說(shuō)說(shuō)的ID、評(píng)論內(nèi)容發(fā)送給后臺(tái),后臺(tái)進(jìn)行相應(yīng)處理后,刷新頁(yè)面,完成評(píng)論。點(diǎn)擊右上角的+號(hào)跳轉(zhuǎn)到發(fā)表說(shuō)說(shuō)界面,發(fā)表說(shuō)說(shuō)界面由頂部的評(píng)論欄、中部的+號(hào)(增加圖片按鈕)和發(fā)表按鈕組成。點(diǎn)擊+號(hào)可以從手機(jī)中選取圖片(wx.chooseImage()),增加的圖片會(huì)在+號(hào)右邊顯示,圖片右上方會(huì)有一個(gè)叉號(hào),點(diǎn)擊圖片會(huì)消失,這是一個(gè)自定義組件的功能。在上邊評(píng)論欄寫(xiě)上要分享的話(huà)并進(jìn)行發(fā)表。
4.6 貓咪領(lǐng)養(yǎng)模塊
此模塊是解決流浪貓問(wèn)題的主要模塊。團(tuán)隊(duì)的線(xiàn)下貓舍會(huì)對(duì)周邊的流浪貓進(jìn)行收養(yǎng),管理員把所有線(xiàn)下貓舍的貓錄入數(shù)據(jù)庫(kù),通過(guò)前端渲染出來(lái)。每個(gè)貓有唯一的標(biāo)識(shí)、不同的分類(lèi),用戶(hù)能在這對(duì)流浪貓進(jìn)行領(lǐng)養(yǎng)。
第一次進(jìn)入此界面時(shí),系統(tǒng)通過(guò)request請(qǐng)求向后端獲取所有貓咪信息的一個(gè)列表,然后將貓咪信息列表和發(fā)起request請(qǐng)求時(shí)的系統(tǒng)時(shí)間保存在緩存中(wx. setStorageSync("cates", {time: Date. now(), data: this.Cates}))。之后每次進(jìn)入該模塊,系統(tǒng)先調(diào)取本地緩存中的貓咪列表信息,通過(guò)貓咪列表保存的時(shí)間和當(dāng)前request請(qǐng)求的時(shí)間相減(設(shè)置如果時(shí)間差大于1小時(shí)數(shù)據(jù)便過(guò)期),如果數(shù)據(jù)過(guò)期,便重新向后臺(tái)請(qǐng)求新的數(shù)據(jù)再把數(shù)據(jù)與時(shí)間存入緩存,如果沒(méi)有過(guò)期,便取出本地緩存中的數(shù)據(jù)。這樣當(dāng)貓咪信息過(guò)多時(shí)能極大地增加系統(tǒng)運(yùn)行速度,提升用戶(hù)體驗(yàn)。界面中通過(guò)scroll-view組件形成滾動(dòng)條;點(diǎn)擊貓咪會(huì)進(jìn)入貓咪詳情界面(此部分與用品購(gòu)買(mǎi)模塊功能相似)。
4.7 貓咪送養(yǎng)模塊
一些人可能會(huì)有養(yǎng)寵物的經(jīng)歷,如果出現(xiàn)了一些自己無(wú)能為力的情況,必須要對(duì)寵物進(jìn)行放養(yǎng),那大家可能會(huì)很難過(guò)。但通過(guò)此模塊,大家可以把自己不能照顧的貓咪送給他人領(lǐng)養(yǎng),能夠很好地解決這件事情。
需要填寫(xiě)一些基本信息,再點(diǎn)擊確認(rèn)。在發(fā)送給后端之前,前端會(huì)用JS進(jìn)行一些簡(jiǎn)單的驗(yàn)證。后端又會(huì)進(jìn)行一次驗(yàn)證,如果成功,后端把這只貓咪的信息錄入數(shù)據(jù)庫(kù),返回送養(yǎng)成功的信息給前端,前端渲染在界面上。過(guò)后線(xiàn)下工作人員便會(huì)到相應(yīng)地點(diǎn)帶走貓咪。
4.8 為它治病模塊
在養(yǎng)貓咪的時(shí)候,總會(huì)遇到要打疫苗的時(shí)候,有時(shí)貓咪也會(huì)生病,但一些小的診所可能水平不夠,大的醫(yī)院又感覺(jué)沒(méi)必要。這時(shí)候,便能通過(guò)該模塊聯(lián)系醫(yī)生,向醫(yī)生請(qǐng)求幫助,醫(yī)生會(huì)給你一些更好的意見(jiàn)。
5 技術(shù)難點(diǎn)
5.1 回調(diào)地獄
在開(kāi)發(fā)初期,遇到一個(gè)難點(diǎn):回調(diào)地獄。說(shuō)到回調(diào)地獄首先要先解釋一下什么是回調(diào)函數(shù),當(dāng)一個(gè)函數(shù)作為參數(shù)傳入另一個(gè)參數(shù)中,但它不會(huì)立即執(zhí)行,只有當(dāng)滿(mǎn)足一定條件后該函數(shù)才執(zhí)行,這種函數(shù)就稱(chēng)為回調(diào)函數(shù)。而回調(diào)函數(shù)嵌套回調(diào)函數(shù)的情況就叫作回調(diào)地獄。
微信小程序內(nèi)置接口wx.request()是一個(gè)異步請(qǐng)求,JS不會(huì)等待wx.request執(zhí)行完畢,會(huì)直接往下繼續(xù)執(zhí)行代碼。所以如果想要獲取wx.request接口向后端請(qǐng)求的數(shù)據(jù),就必須在它的回調(diào)函數(shù)里編碼。但一兩個(gè)異步函數(shù)的嵌套感覺(jué)還不是很亂,當(dāng)嵌套層數(shù)達(dá)到4個(gè)及以上,代碼的可讀性會(huì)出現(xiàn)極大問(wèn)題。
但是使用promise對(duì)象解決回調(diào)地獄問(wèn)題后,同步過(guò)程屏蔽了異步優(yōu)勢(shì)。為了解決這一問(wèn)題,引入了es7 的async、await 語(yǔ)法,在函數(shù)前加上async,在re?quest前加上await,表明當(dāng)前函數(shù)是異步函數(shù),不會(huì)阻塞線(xiàn)程導(dǎo)致后續(xù)代碼運(yùn)行停止。這樣解決了promise的一些小缺陷,在請(qǐng)求時(shí),主線(xiàn)程也能一起執(zhí)行,使代碼更加簡(jiǎn)潔,徹底解決了回調(diào)地獄的問(wèn)題。
5.2 其他
“送它回家”微信小程序由微信開(kāi)發(fā)者工具開(kāi)發(fā),由于小程序的大小被限制在2MB之內(nèi),所以小程序本地不能保存太大的文件,系統(tǒng)界面中的圖標(biāo)是引用阿里云矢量圖標(biāo)庫(kù)里的圖標(biāo)樣式,圖標(biāo)樣式單獨(dú)形成一個(gè)樣式文件(iconfont.wxss),被全局樣式文件所引用(通過(guò)@import "./styles/iconfont.wxss" 實(shí)現(xiàn))。
系統(tǒng)中前端與后端間的數(shù)據(jù)傳輸采用了PUT和POST兩種方式,當(dāng)不是重要數(shù)據(jù)時(shí)使用PUT方法,當(dāng)敏感數(shù)據(jù)的傳輸時(shí)便采用POST方式傳輸;前后端圖片的傳輸都以Base64格式進(jìn)行,前后端在發(fā)送圖片之前都要先轉(zhuǎn)換為base64格式才能進(jìn)行傳輸[10]("data:image/png;base64, " +wx. getFileSystemManager().readFileSync(xxx, "base64"))。
6 結(jié)束語(yǔ)
針對(duì)當(dāng)前社會(huì)的流浪貓問(wèn)題,項(xiàng)目團(tuán)隊(duì)認(rèn)真調(diào)研分析研究,實(shí)現(xiàn)了貓用品購(gòu)買(mǎi)、送/領(lǐng)養(yǎng)貓咪、了解貓咪的習(xí)性學(xué)習(xí),為它治病、貓圈等功能,搭建了一個(gè)線(xiàn)上線(xiàn)下一體化小程序流浪貓撫養(yǎng)救助平臺(tái)。
平臺(tái)很好地解決了一般系統(tǒng)異步請(qǐng)求中出現(xiàn)的回調(diào)地獄問(wèn)題,并通過(guò)不同數(shù)據(jù)分端口傳輸,確保了系統(tǒng)數(shù)據(jù)的安全性。通過(guò)線(xiàn)上多次實(shí)測(cè),平臺(tái)穩(wěn)定性與實(shí)用價(jià)值收到了用戶(hù)認(rèn)可。