朱勇,伏海旭
(南京工程學(xué)院計(jì)算機(jī)工程學(xué)院,南京 211167)
當(dāng)前受移動(dòng)互聯(lián)網(wǎng)發(fā)展的影響,越來越多的學(xué)生事務(wù)處理開始通過電子化的手段實(shí)現(xiàn),但是通過對(duì)高校的調(diào)查以及筆者自身的體會(huì)發(fā)現(xiàn),依然有許多高校采用傳統(tǒng)手段,一般流程為學(xué)生打印紙質(zhì)假條,前往輔導(dǎo)員處簽字蓋章,將假條交給任課教師。該流程存在效率低,浪費(fèi)時(shí)間等問題,對(duì)學(xué)生生活影響很大。
針對(duì)上述問題,開發(fā)App或Web應(yīng)用也是一種解決手段,但此方案存在終端適應(yīng)復(fù)雜,開發(fā)周期長(zhǎng),用戶使用成本高,擴(kuò)展性差等問題。對(duì)此,本文討論并設(shè)計(jì)了一種基于RESTful的在線請(qǐng)假系統(tǒng),旨在解決目前高校存在的“請(qǐng)假難”痛點(diǎn)問題,基于借助微信小程序易用入口解決多終端適配和擴(kuò)展性等問題,令用戶獲得良好體驗(yàn)。
REST(Representational State Transfer),中文意思是表述性狀態(tài)轉(zhuǎn)移,它將任何有被引用必要的事物定義為資源,包含實(shí)體和抽象概念,資源在網(wǎng)絡(luò)中以某種表現(xiàn)形式進(jìn)行狀態(tài)轉(zhuǎn)移。Resource:資源,即數(shù)據(jù),例如newsfeed、friends等;Representational:某種表現(xiàn)形式,例如用 JSON、XML、JPEG 等;State Transfer:狀態(tài)變化。通過HTTP動(dòng)詞實(shí)現(xiàn)。每一個(gè)URI代表一種資源;客戶端和服務(wù)器之間,傳遞這種資源的某種表現(xiàn)層;客戶端通過四個(gè)HTTP方法(GET/POST/PUT/DELETE)對(duì)服務(wù)器端資源進(jìn)行操作,其目標(biāo)是創(chuàng)建具有良好擴(kuò)展性的分布式系統(tǒng)。RESTful是一種針對(duì)網(wǎng)絡(luò)應(yīng)用的設(shè)計(jì)和開發(fā)方式,可以降低開發(fā)的復(fù)雜性,提高系統(tǒng)的可伸縮性。
REST是設(shè)計(jì)風(fēng)格而不是標(biāo)準(zhǔn)。REST通常基于使用HTTP、URI和XML(標(biāo)準(zhǔn)通用標(biāo)記語言下的一個(gè)子集),以及HTML(標(biāo)準(zhǔn)通用標(biāo)記語言下的一個(gè)應(yīng)用)這些現(xiàn)有的廣泛流行的協(xié)議和標(biāo)準(zhǔn)。作為一種架構(gòu),其提出了以下架構(gòu)級(jí)約束:
(1)使用客戶/服務(wù)器模型??蛻艉头?wù)器之間通過一個(gè)統(tǒng)一的接口來互相通訊。
(2)層次化的系統(tǒng)。在一個(gè)REST系統(tǒng)中,客戶端并不會(huì)固定地與一個(gè)服務(wù)器打交道。
(3)無狀態(tài)。在一個(gè)REST系統(tǒng)中,服務(wù)端并不會(huì)保存有關(guān)客戶的任何狀態(tài),客戶端自身負(fù)責(zé)用戶狀態(tài)的維持,并在每次發(fā)送請(qǐng)求時(shí)提供足夠的信息。
(4)統(tǒng)一的接口。一個(gè)REST系統(tǒng)需要使用一個(gè)統(tǒng)一的接口來完成子系統(tǒng)之間以及服務(wù)與用戶之間的交互,這使得REST系統(tǒng)中的各個(gè)子系統(tǒng)可以獨(dú)自完成演化。
基于RESTful在線請(qǐng)假管理系統(tǒng)架構(gòu)包含前端、后端和數(shù)據(jù)庫。前端分為三種角色(學(xué)生、輔導(dǎo)員、任課教師)三個(gè)模塊(主頁面、歷史記錄、個(gè)人信息及設(shè)置);后端使用Flask外暴露API響應(yīng)前端HTTP請(qǐng)求并完成與數(shù)據(jù)庫交互和ORM(對(duì)象關(guān)系映射),通過使用描述對(duì)象和數(shù)據(jù)庫之間映射的元數(shù)據(jù),將程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫中;數(shù)據(jù)庫中設(shè)三張表(請(qǐng)假表、學(xué)生表、教師表)。
用戶通過前端進(jìn)行操作,前端JavaScript通過AJAX向后端發(fā)起請(qǐng)求,后端根據(jù)請(qǐng)求內(nèi)容與數(shù)據(jù)庫交互,完成邏輯操作、ORM和數(shù)據(jù)持久化,返回JSON數(shù)據(jù),前端解析JSON,異步刷新,呈現(xiàn)結(jié)果。
基于RESTful在線請(qǐng)假管理系統(tǒng)架構(gòu)設(shè)計(jì)見圖1。
圖1 架構(gòu)設(shè)計(jì)
根據(jù)請(qǐng)假系統(tǒng)需求和特點(diǎn),基于RESTful的在線請(qǐng)假系統(tǒng)數(shù)據(jù)庫(leaveDB)設(shè)計(jì)有三張表,分別為請(qǐng)假表(leave)、教師表(teacher)、學(xué)生表(student)。通過登錄號(hào)碼長(zhǎng)度來區(qū)分用戶角色,學(xué)生學(xué)號(hào)為9位,教師工號(hào)為6位。教師表通過Boolean類型的role字段來區(qū)分輔導(dǎo)員和任課教師角色。密碼通過Varchar類型passwd字段存儲(chǔ)經(jīng)SHA256加密后的密碼。
基于RESTful的在線請(qǐng)假系統(tǒng)數(shù)據(jù)庫設(shè)計(jì)見圖2。
圖2 數(shù)據(jù)庫設(shè)計(jì)
根據(jù)前后端交互過程中數(shù)據(jù)的情況特點(diǎn),基于RESTful的在線請(qǐng)假系統(tǒng)API設(shè)計(jì)主要如下:
(1)資源標(biāo)識(shí)
REST中使用資源的特定名詞作為資源的URI,并設(shè)計(jì)相應(yīng)的控制器和模型類??刂破饔糜谔幚磉壿?,模型類用于和數(shù)據(jù)庫交互。根據(jù)交互過程中涉及的資源。
(2)參數(shù)設(shè)計(jì)
為了增加前后端交互的便攜性,對(duì)于不同功能返回不同的JSON鍵值對(duì),前后端事先約定JSON格式,便于解析。參數(shù)設(shè)計(jì)詳見圖3。
圖3 參數(shù)設(shè)計(jì)
基于RESTful的在線請(qǐng)假系統(tǒng)前端采用微信小程序?qū)崿F(xiàn),相對(duì)于傳統(tǒng)的App應(yīng)用,小程序可以在線熱更新,方便版本迭代和敏捷開發(fā),同時(shí)降低了用戶使用成本?!坝猛昙醋摺碧峁┝藘?yōu)質(zhì)的用戶體驗(yàn)。
微信小程序分登錄功能、學(xué)生用戶功能和教師用戶功能,根據(jù)功能點(diǎn)包含不同數(shù)量的page,page由WXML、WXSS、JS和JSON構(gòu)建。WXML構(gòu)建頁面DOM,WXSS構(gòu)建頁面樣式,JS負(fù)責(zé)獲取全局應(yīng)用程序?qū)嵗龑?duì)象并創(chuàng)建頁面實(shí)例對(duì)象,同時(shí)內(nèi)含生命周期函數(shù)用于監(jiān)聽頁面加載、頁面初次渲染完成、頁面顯示、頁面隱藏、頁面卸載及頁面相關(guān)事件處理函數(shù),包含用戶下拉動(dòng)作和自定義點(diǎn)擊事件。程序啟動(dòng)后,login頁面與用戶交互,將數(shù)據(jù)使用AJAX與后端并根據(jù)后端返回JSON解析提取后的結(jié)果跳轉(zhuǎn)用戶對(duì)應(yīng)的page,異步刷新、渲染頁面,不需要整頁面重新刷新,減少了資源占用和用戶等待時(shí)間,提高了用戶體驗(yàn)。
在圖片憑證保存的功能點(diǎn)上,目前業(yè)界通用做法一是使用存入后端文件系統(tǒng)并保存路徑至數(shù)據(jù)庫對(duì)應(yīng)字段,加載時(shí)根據(jù)文件路徑下載;二是直接將圖片Base64轉(zhuǎn)碼后以JSON數(shù)據(jù)包格式傳入數(shù)據(jù)庫longtext或binary類型字段中。做法一需要單獨(dú)構(gòu)建文件系統(tǒng)或使用在線圖床并從外鏈加載,提高了成本且降低了安全性;做法二占用資源過多且上傳時(shí)間過長(zhǎng),用戶體驗(yàn)非常差。在這里本文使用微信官方提供的小程序云開發(fā)功能,在微信官方服務(wù)器上構(gòu)建相互隔離的云環(huán)境,每個(gè)環(huán)境都包含獨(dú)立的數(shù)據(jù)庫實(shí)例、存儲(chǔ)空間等資源。通過對(duì)將環(huán)境構(gòu)建單獨(dú)的內(nèi)置云函數(shù),處理上傳邏輯。上傳圖片時(shí),調(diào)用該內(nèi)置函數(shù)將圖片上傳至云環(huán)境儲(chǔ)存空間中,獲得唯一文件ID并將該ID存入數(shù)據(jù)庫leave表中ensure字段,讀取時(shí)根據(jù)RESTful后端返回JSON中ensure字段通過內(nèi)置函數(shù)直接調(diào)用圖片,對(duì)上傳、下載文件明顯起到簡(jiǎn)化加速作用,使用微信官方云開發(fā)環(huán)境,穩(wěn)定性高,文件加載速度快,與小程序耦合程度高,調(diào)用簡(jiǎn)單,開發(fā)迅速。
(1)學(xué)生請(qǐng)假功能
學(xué)生登錄后在“請(qǐng)假”界面選擇請(qǐng)假類別、時(shí)間等,提交請(qǐng)假請(qǐng)求,在“消息”界面查看請(qǐng)假歷史記錄,在“我”界面查看個(gè)人信息和修改密碼。學(xué)生請(qǐng)假功能見圖4。
(2)輔導(dǎo)員審批功能
輔導(dǎo)員登錄系統(tǒng)后,在“消息”界面查看今日待審批假條,選擇通過或不通過,在“批假”界面可查看已批假歷史記錄并可按學(xué)生姓名查找假條。輔導(dǎo)員審批功能見圖5。
圖4 請(qǐng)假功能
圖5 審批功能
(3)任課教師查看假條功能
任課教師在“消息”查看自己班級(jí)內(nèi)學(xué)生的假條和狀態(tài)(待批準(zhǔn)/已批準(zhǔn)/不通過);在“我”界面查看個(gè)人信息和修改密碼。
基于RESTful的在線請(qǐng)假系統(tǒng)功能流程見圖6。
本系統(tǒng)后端操作數(shù)據(jù)庫時(shí),使SQLAlchemy作為ORM框架[3],創(chuàng)建 SQLAlchemy對(duì)象并定義 student、teacher、leave 對(duì)象,分別對(duì)應(yīng)數(shù)據(jù)庫中 student、teacher、leave表。使用sessionmaker定義會(huì)話類,操作該會(huì)話類實(shí)例對(duì)象的操作方法進(jìn)行數(shù)據(jù)庫操作,操作方法為add()、delete()、update()、query()。
圖6 功能流程
以“修改密碼”功能為例,部分代碼如下:
class teacher(db.Model):
#定義Model,用于ORM綁定數(shù)據(jù)
__tablename__='teacher'
teacher_id=db.Column(db.DECIMAL(65),primary_key=True)
#數(shù)據(jù)類型與數(shù)據(jù)庫中類型對(duì)應(yīng)
name=db.Column(db.VARCHAR(255))
passwd=db.Column(db.VARCHAR(255))
role=db.Column(db.VARCHAR(2))
school=db.Column(db.VARCHAR(255))
def to_dict(self):
#轉(zhuǎn)字典方法用于方便與json交互
return{c.name:getattr(self,c.name,None)for c in self.__table__.columns}
@app.route("/change_pwd",methods=['GET','POST'])
#Flask對(duì)外暴露URL供前端JS調(diào)用
def change_pwd():
#處理json并與Controller交互
if(request.method=='POST'):
if not(request.json):
return jsonify('not json')
else:
data=request.get_json()
rec_id=data['userId']
rec_pwd=data['userPwd']
if(change_passwd(rec_id,rec_pwd)==True):
#調(diào)用Controller修改密碼
return jsonify("True")
else:
return jsonify("Flase")
else:
return jsonify('not POST method')
def change_pwd(userId,userPwd):
#Controller用于與數(shù)據(jù)庫和Model交互
print("用戶"+userId+"修改密碼")
data=db.session.query(teacher).filter_by(
teacher_id=userId).first()
#新建ORM實(shí)例查詢數(shù)據(jù)庫中對(duì)應(yīng)的行
data.passwd=generate_password_hash(str(userPwd))
#對(duì)明文SHA256加密
db.session.commit()
#提交數(shù)據(jù)庫
db.session.close()
#關(guān)閉實(shí)例
print("用戶"+userId+"密碼修改成功")
return(True)
使用ORM技術(shù)可以節(jié)約與數(shù)據(jù)庫交互的步驟,有效提高開發(fā)效率,并解決面向?qū)ο笈c關(guān)系數(shù)據(jù)庫存在的互不匹配的問題。
根據(jù)高校學(xué)生事務(wù)中“請(qǐng)假難”的痛點(diǎn)問題,主要表現(xiàn)在學(xué)生請(qǐng)假流程繁瑣,學(xué)校仍采用紙質(zhì)假條不便于管理等方面。提出了基于RESTful的在線請(qǐng)假系統(tǒng),旨在取代目前高校中采用傳統(tǒng)紙質(zhì)假條請(qǐng)假的方式。本文對(duì)基于RESTful的在線請(qǐng)假系統(tǒng)進(jìn)行了總體架構(gòu)設(shè)計(jì)、數(shù)據(jù)庫設(shè)計(jì)、RESTful API設(shè)計(jì),運(yùn)用Python語言、ORM技術(shù)、Flask框架并以微信小程序的前端為例實(shí)現(xiàn)了該系統(tǒng)的主要功能。實(shí)際測(cè)試表明基于RESTful的在線請(qǐng)假系統(tǒng)速度快、功能完善、兼容性好、擴(kuò)展性好、易于維護(hù),達(dá)到了預(yù)期的效果。顯著提高了請(qǐng)假的效率,節(jié)約了教師和學(xué)生的時(shí)間,解決了“請(qǐng)假難”的問題。