李 涵 葉 子
基于Android系統(tǒng)的指尖訂餐軟件
李 涵 葉 子
本系統(tǒng)借助移動(dòng)互聯(lián)網(wǎng),構(gòu)建一個(gè)C/S結(jié)構(gòu)的訂餐系統(tǒng),為學(xué)生訂餐提供便利,同時(shí)也方便學(xué)校食堂的經(jīng)營(yíng)管理工作。服務(wù)器端由Node.js實(shí)現(xiàn),具有數(shù)據(jù)查詢操作、Web管理界面、向Android客戶端提供JSON API的功能;Android客戶端通過(guò)此API與服務(wù)器進(jìn)行數(shù)據(jù)交換,提供登錄、查看菜單、購(gòu)物車、下單、查看訂單的功能。用戶可在Android設(shè)備上通過(guò)客戶端遠(yuǎn)程訂餐,食堂可通過(guò)網(wǎng)頁(yè)對(duì)后臺(tái)訂單信息進(jìn)行管理,以在一定程度上緩解食堂在就餐高峰期的混亂問(wèn)題,提升學(xué)生的食堂訂餐體驗(yàn)。
在當(dāng)今社會(huì),蓬勃發(fā)展的移動(dòng)互聯(lián)網(wǎng)已滲透到人們?nèi)粘I畹姆椒矫婷妫诓粩酁榇蠹規(guī)?lái)便利的同時(shí)也在漸漸地改變著人們的生活方式。餐飲業(yè)是有著悠久歷史的傳統(tǒng)行業(yè),對(duì)于大學(xué)校園中的學(xué)生而言,一日三餐自然必不可少。本系統(tǒng)旨在借助移動(dòng)互聯(lián)網(wǎng),為學(xué)生訂餐提供便利,同時(shí)也方便學(xué)校食堂的經(jīng)營(yíng)管理工作。
本系統(tǒng)主要針對(duì)大學(xué)校園中的食堂點(diǎn)餐問(wèn)題而設(shè)計(jì),其目的在于構(gòu)建一個(gè)軟件系統(tǒng),使學(xué)生可在Android設(shè)備上通過(guò)客戶端遠(yuǎn)程訂餐,而食堂可通過(guò)網(wǎng)頁(yè)對(duì)后臺(tái)訂單信息進(jìn)行管理,以在一定程度上緩解食堂在就餐高峰期的混亂問(wèn)題,提升學(xué)生的食堂訂餐體驗(yàn)。
本系統(tǒng)具備以下功能:
服務(wù)器端:
1)通過(guò)數(shù)據(jù)庫(kù)管理用戶信息、訂單信息。
2)提供與客戶端交互的應(yīng)用程序接口。包括用戶管理操作(注冊(cè)、登錄、個(gè)人信息管理),菜品查詢操作,訂單操作(提交、取消、修改、查看)。
3)提供后臺(tái)管理功能,實(shí)現(xiàn)對(duì)菜品信息、用戶信息、訂單信息的相關(guān)操作。
客戶端:
1)實(shí)現(xiàn)用戶的注冊(cè)、登錄、個(gè)人信息管理。
2)實(shí)現(xiàn)校園餐廳餐點(diǎn)信息查詢。
3)實(shí)現(xiàn)訂餐訂單的提交、修改、取消等管理工作。
Node.js
Node.js致力于簡(jiǎn)化高速、可擴(kuò)展網(wǎng)絡(luò)應(yīng)用的開發(fā)。Node.js的一大特色是使用事件驅(qū)動(dòng)的非阻塞I/O模式,使運(yùn)行在不同設(shè)備上的數(shù)據(jù)密集型實(shí)時(shí)應(yīng)用更加輕量、高效。Node.js是運(yùn)行在服務(wù)器端的JavaScript。要在服務(wù)器端運(yùn)行JavaScript代碼,需要編譯、執(zhí)行。而Node.js利用谷歌的V8虛擬機(jī)完成了這些工作。Node. js提供大量的實(shí)用模塊,開發(fā)人員不必從最底層開始編寫程序。因此,Node.js實(shí)際上由運(yùn)行時(shí)和庫(kù)這兩部分組成。
后端框架Sails
Sails是使用Node.js技術(shù)的Web后端開發(fā)框架。為使開發(fā)過(guò)程更高效、更具可控性,Sails與其它 MVC Web應(yīng)用程序框架有著相同的設(shè)計(jì)理念,并提供清晰合理的應(yīng)用程序模板。
Waterline是預(yù)裝在Sails中的功能強(qiáng)大的對(duì)象關(guān)系映射層,它與數(shù)據(jù)的存儲(chǔ)方式無(wú)關(guān),在很大程度上簡(jiǎn)化了對(duì)一個(gè)或多個(gè)數(shù)據(jù)庫(kù)的操作。在底層的數(shù)據(jù)庫(kù)之上,Waterline提供了一個(gè)抽象層,允許開發(fā)者統(tǒng)一地查詢和操作數(shù)據(jù),而無(wú)需對(duì)特定的數(shù)據(jù)庫(kù)特定的代碼。
為充分利用Waterline的抽象性,本系統(tǒng)在設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí),不通過(guò)底層接口通過(guò)原生SQL語(yǔ)句手動(dòng)實(shí)現(xiàn)外鍵與多表連接查詢,而使用Waterline提供的關(guān)聯(lián)(Association)來(lái)實(shí)現(xiàn)類似于外鍵的結(jié)構(gòu),使用populate( )實(shí)現(xiàn)類似于多表連接查詢的查詢操作。
模板引擎EJS
EJS是一個(gè)JavaScript模板庫(kù),常用于從JSON數(shù)據(jù)中構(gòu)建HTML字符串。它致力于解決JavaScript動(dòng)態(tài)生成HTML代碼時(shí)的代碼可讀性與可維護(hù)性問(wèn)題。傳統(tǒng)的做法是在JavaScript中將HTML標(biāo)簽及動(dòng)態(tài)數(shù)據(jù)連接成字符串后再處理,HTML代碼與JavaScript代碼混雜在一起,程序的編寫及維護(hù)有所不便。而EJS通過(guò)使用運(yùn)行于客戶端的模板,能避免HTML標(biāo)簽夾雜在JavaScript代碼中,使程序代碼更簡(jiǎn)潔。同時(shí),EJS封裝了許多視圖輔助函數(shù),這些視圖輔助函數(shù)使諸如創(chuàng)建鏈接、創(chuàng)建表格等視圖展示代碼更加便捷。
在本系統(tǒng)中,Sails在服務(wù)器端將標(biāo)記語(yǔ)言模板編譯成HTML頁(yè)面,此即是Sails中的視圖(View)。在多數(shù)情況下,它用于對(duì)傳入的HTTP請(qǐng)求的響應(yīng)。用戶可通過(guò)Android客戶端查看食品、下單、查看訂單列表,食堂方可通過(guò)瀏覽器對(duì)用戶、食品、訂單進(jìn)行管理。

圖1 系統(tǒng)模塊示意圖
本系統(tǒng)分前后臺(tái)兩部分,前臺(tái)是Android客戶端,后臺(tái)利用Web頁(yè)面進(jìn)行管理。
Web管理模塊:實(shí)現(xiàn)對(duì)管理員的身份認(rèn)證,以及對(duì)用戶信息、食品信息、訂單信息的查看與修改。
客戶端模塊:實(shí)現(xiàn)新用戶注冊(cè)、用戶登錄、食品信息查看、訂單的下達(dá)及查看操作。
本系統(tǒng)各模塊的示意如圖1所示。
后端設(shè)計(jì)
后端的主要作用是為其它的模塊提供數(shù)據(jù)存儲(chǔ)、執(zhí)行訪問(wèn)權(quán)限控制策略、提供API。
數(shù)據(jù)存儲(chǔ):使用Waterline ORM對(duì)數(shù)據(jù)庫(kù)的抽象,建立模型及模型間的關(guān)聯(lián),以實(shí)現(xiàn)不同表之間的聯(lián)合查詢操作。使用數(shù)據(jù)模型的生命周期回調(diào)自動(dòng)完成數(shù)據(jù)維護(hù)操作。例如創(chuàng)建用戶時(shí),在寫入數(shù)據(jù)庫(kù)存前對(duì)明文密碼進(jìn)行散列;添加訂單時(shí),計(jì)算訂單的金額并更新數(shù)據(jù)庫(kù)存中相應(yīng)的字段等。
控制器:完成對(duì)請(qǐng)求的接收、整理,根據(jù)請(qǐng)求對(duì)數(shù)據(jù)庫(kù)進(jìn)行相應(yīng)操作,整理并返回操作結(jié)果。
訪問(wèn)權(quán)限控制:對(duì)Web管理界面及API執(zhí)行訪問(wèn)權(quán)限控制。對(duì)于Web管理界面采用會(huì)話認(rèn)證,在用戶登錄后,將該用戶的身份信息存儲(chǔ)在會(huì)話中,在請(qǐng)求頁(yè)面時(shí)檢查會(huì)話中的用戶身份信息,實(shí)現(xiàn)對(duì)不同權(quán)限用戶的訪問(wèn)控制。對(duì)于API的訪問(wèn)采用Token認(rèn)證,每當(dāng)API被訪問(wèn)時(shí),將請(qǐng)求中的Token信息與數(shù)據(jù)庫(kù)中的用戶Token進(jìn)行比對(duì),若某次請(qǐng)求中的Token與某用戶的Token對(duì)應(yīng),則服務(wù)器視該請(qǐng)求為該用戶所發(fā)出,并使得該用戶可以且僅能訪問(wèn)與自己相關(guān)的操作,如下單、查詢歷史訂單等。
(1)用戶表
本系統(tǒng)使用Passport.js實(shí)現(xiàn)基于本地用戶名/密碼的身份驗(yàn)證,需要一個(gè)額外的模型來(lái)在存儲(chǔ)用戶的身份認(rèn)證信息,故用戶信息實(shí)際上存儲(chǔ)在兩個(gè)相關(guān)聯(lián)的模型中,即User模型和Passport模型。它們的定義分別位于api/models/User.js和api/models/Passport.js中。
User模型只保存了用戶名、訂單等基本系統(tǒng)。
Passport模型用于處理用戶的身份驗(yàn)證,預(yù)留了本地驗(yàn)證或第三方平臺(tái)驗(yàn)證的方法。本系統(tǒng)中只使用了本地驗(yàn)證。由于在每一次會(huì)話中,應(yīng)用程序只需要驗(yàn)證一個(gè)用戶,故把身份驗(yàn)證相關(guān)的數(shù)據(jù)封裝到一個(gè)模型中,程序就只用對(duì)會(huì)話中的不包含用戶身份驗(yàn)證信息的基本信息進(jìn)行處理,由此使會(huì)話本身盡可能地輕量。
(2)食品表
食品表中存有各種食品的基本信息。api/models/ Food.js中的內(nèi)容如下:

(3)訂單表
訂單模型Order中只包含了訂單的編號(hào)、下單的用戶編號(hào),并與存儲(chǔ)有訂單明細(xì)的OrderItem建立關(guān)聯(lián),來(lái)描述一份訂單的完整信息。api/models/Order.js中對(duì)數(shù)據(jù)的定義如下:

(4)訂單明細(xì)表
一個(gè)訂單對(duì)應(yīng)的商品種類、數(shù)量是靈活的,使得在一個(gè)模型中存儲(chǔ)訂單中的所有物品比較困難。于是單獨(dú)設(shè)立一個(gè)訂單明細(xì)模型OrderItem,記錄訂單中的商品種類、數(shù)量信息,并使每個(gè)Order模型與OrderItem模型建立一對(duì)多的關(guān)系,便于訂單明細(xì)的查詢。
api/models/OrderItem.js中對(duì)數(shù)據(jù)的定義如下

Web管理
管理員可通過(guò)Web瀏覽器訪問(wèn)管理界面,對(duì)系統(tǒng)中的用戶數(shù)據(jù)、食品數(shù)據(jù)、訂單數(shù)據(jù)進(jìn)行操作。界面頂部的導(dǎo)航條可在不同管理項(xiàng)目之前切換。主要包括登錄界面、用戶管理界面、食品管理界面,以及訂單管理界面的設(shè)計(jì)。
Sails應(yīng)用程序的目錄結(jié)構(gòu)如圖2所示。
下對(duì)其中重要的目錄、文件作簡(jiǎn)要說(shuō)明。

圖2 Sails應(yīng)用程序的目錄結(jié)構(gòu)
api/controllers目錄:此目錄中含有應(yīng)用程序的控制器。在Sails中,控制器是包含用于與模型交互、向客戶端渲染對(duì)應(yīng)的視圖的邏輯的JavaScript文件。
api/models目錄:此目錄中含有應(yīng)用程序使用的模型。在Sails中,模型是對(duì)應(yīng)用程序中數(shù)據(jù)的存儲(chǔ)結(jié)構(gòu)的定義。在此可配置記錄在數(shù)據(jù)庫(kù)中如何定義。
api/policies目錄:這是保存認(rèn)證策略文件的目錄。認(rèn)證策略實(shí)質(zhì)上是用于對(duì)應(yīng)用訪問(wèn)進(jìn)行身份驗(yàn)證的Express中間件。
api/services目錄:此目錄中包含有服務(wù)。服務(wù)的作用類似于控制器,但服務(wù)與請(qǐng)求和響應(yīng)無(wú)關(guān)。為了保持控制器的簡(jiǎn)潔,任何與請(qǐng)求、響應(yīng)無(wú)關(guān)的邏輯都可以寫成服務(wù)。
assets目錄:此目錄用于存儲(chǔ)靜態(tài)資源文件。例如,在assets/someFolder/ someFile.txt創(chuàng)建一個(gè)文件,當(dāng)Sails應(yīng)用程序啟動(dòng)后,可通過(guò)http://localhost:1337/someFolder/ someFile.txt來(lái)訪問(wèn)到它。
config/env/development.js:運(yùn)行于開發(fā)模式時(shí),Sails會(huì)加載此文件。本系統(tǒng)在此文件中指定數(shù)據(jù)模型默認(rèn)的數(shù)據(jù)庫(kù)連接。不指定運(yùn)行模式相關(guān)的配置時(shí),Sails默認(rèn)運(yùn)行于開發(fā)模式。
config/local.js:本文件用于Sails應(yīng)用程序的本地環(huán)境配置,可指定監(jiān)聽的端口號(hào)以及Sails的運(yùn)行模式。
config/http.js:本文件常用于配置Sails的HTTP服務(wù)器所使用的中間件,以及中間件的順序。
config/connections.js:配置數(shù)據(jù)庫(kù)適配器。如連接數(shù)據(jù)庫(kù)的參數(shù)、使用的數(shù)據(jù)庫(kù)名稱等。
config/policies.js:配置默認(rèn)的認(rèn)證策略。
config/routes.js:此文件配置用戶的URL與控制器的映射關(guān)系。
views目錄:此目錄中含有所有自定義的視圖。要?jiǎng)?chuàng)建新的自定義視圖,可在此文件夾中建立一個(gè)新的文件夾,并在這個(gè)新文件夾中建立新的.ejs文件。若要向客戶端渲染這個(gè)視圖 ,可在config/routes.js中為它配置一個(gè)路由,或在控制器的動(dòng)作中使用res.view()方法。
Android客戶端設(shè)計(jì)
Android客戶端包括如下模塊:
(1)注冊(cè)/登錄模塊:實(shí)現(xiàn)用戶的登錄過(guò)程,登錄后取得用戶的Token用于身份認(rèn)證。
(2)食品查看模塊:實(shí)現(xiàn)食品列表的展示,并能將食品添加進(jìn)購(gòu)物車。
(3)訂單操作模塊:實(shí)現(xiàn)購(gòu)物車查看、訂單提交、歷史訂單查看功能。

圖3 登錄界面

圖4 食品管理界面

圖5 訂單管理界面

圖6 查看訂單詳情
Web管理
在本機(jī)啟動(dòng)服務(wù)器:進(jìn)入服務(wù)器項(xiàng)目所在目錄,在命令行中執(zhí)行sails lift即可開啟服務(wù)器。在默認(rèn)配置下,服務(wù)器將監(jiān)聽本機(jī)的1337端口。
可進(jìn)入管理系統(tǒng)的登錄頁(yè)面。登錄界面如圖3所示。
在Web界面,管理員成功登陸后可以管理用戶信息。在食品管理界面,顯示了食品ID、名稱、單價(jià)、圖片等信息,并可對(duì)食品信息進(jìn)行添加、編輯、刪除操作。在訂單管理中,訂單詳情界面顯示了訂單的下單用戶、下單時(shí)間,訂單中食品的圖片、名稱、數(shù)量、價(jià)格,以及訂單的總價(jià)格。圖4至圖6顯示了Web頁(yè)面的管理信息。

圖7 登錄界面

圖8 登錄頁(yè)面加載動(dòng)畫

圖9 食品列表界面

圖10 加入購(gòu)物車提示

圖11 添加購(gòu)物車成功

圖12 刪除購(gòu)物車中的項(xiàng)目

圖13 購(gòu)物車下單

圖14 歷史訂單
Android客戶端測(cè)試
Android客戶端的登錄界面如圖7和圖8所示。登錄成功后,將會(huì)顯示食品列表界面。
食品列表界面如圖9和圖10所示所示。
點(diǎn)擊界面右下方的“訂單”標(biāo)簽將進(jìn)入圖11所示的購(gòu)物車頁(yè)面,此頁(yè)面可進(jìn)行下訂單前的確認(rèn),并可以刪除不想要的項(xiàng)目。長(zhǎng)按購(gòu)物車中的某一項(xiàng),會(huì)提示用戶是否要?jiǎng)h除,如圖12所示。確認(rèn)無(wú)誤后可點(diǎn)擊“立即下單”按鈕,向服務(wù)器提交訂單,如圖13所示。
從訂單界面左滑,或點(diǎn)擊上方的“訂單”可進(jìn)入歷史訂單界面。下拉會(huì)向服務(wù)器請(qǐng)求登錄用戶的訂單信息。訂單按照時(shí)間升序,如圖14所示。
本系統(tǒng)主要針對(duì)大學(xué)校園中的食堂點(diǎn)餐問(wèn)題而設(shè)計(jì),其目的在于構(gòu)建一個(gè)系統(tǒng),使學(xué)生可在Android設(shè)備上通過(guò)客戶端遠(yuǎn)程訂餐,而食堂可通過(guò)網(wǎng)頁(yè)對(duì)后臺(tái)訂單信息進(jìn)行管理。服務(wù)器端由Node.js實(shí)現(xiàn),具有數(shù)據(jù)查詢操作、Web管理界面、向Android客戶端提供JSON API的功能;Android客戶端通過(guò)此API與服務(wù)器進(jìn)行數(shù)據(jù)交換,提供登錄、查看菜單、購(gòu)物車、下單、查看訂單的功能。用戶可在Android設(shè)備上通過(guò)客戶端遠(yuǎn)程訂餐,食堂可通過(guò)網(wǎng)頁(yè)對(duì)后臺(tái)訂單信息進(jìn)行管理,以在一定程度上緩解食堂在就餐高峰期的混亂問(wèn)題,提升學(xué)生的食堂訂餐體驗(yàn)。
10.3969/j.issn.1001-8972.2015.21.016