

NEWS
將想法與焦點與您一起共享
年會必備,5分鐘學(xué)會制作年會抽獎小程序


免費生成微信小程序
年會年年有,中獎次次無,不知道你們有沒有中獎,反正我是終將絕緣體。好了,想必大家對年會抽獎小程序不了解吧,年會臨近,制作一個年會抽獎小程序是非常必要的,下面我們要用Excel和golang制作一個抽獎小程序。
用Excel制作年會抽獎小程序
現(xiàn)在從A列成員中抽取3名中獎人員,效果如動圖。
下面我借用隨機數(shù):RAND和RANDBETWEEN函數(shù)。
獲取0-1的隨機數(shù)。
=RAND()
獲取某個范圍的隨機數(shù),例如1-12。
=RANDBETWEEN(1,12)
在Excel中更新數(shù)據(jù)或按F9鍵,數(shù)據(jù)就會變動。
Step01在B2輸入公式,并向下填充公式。
=RAND()
Step02在D2輸入公式,并下拉到D4,這樣就剛好是三個名額。
=LOOKUP(1,0/(LARGE($B$2:$B$13,ROW(A1))=$B$2:$B$13),$A$2:$A$13)
LARGE函數(shù)語法說明:
LARGE函數(shù)換成SMALL函數(shù)也可以。
Step03一直按F9鍵,這樣數(shù)據(jù)就有滾動的效果,停下來就是中獎名單。
用golang制作年會抽獎小程序
之前在學(xué)區(qū)塊鏈,然后看到很多區(qū)塊鏈項目都是基于golang在開發(fā),包括以太坊的官方go-ethereum。了解了下go是google出品,很多人說其有c/c++的性能,然后卻有腳本語言的開發(fā)效率。我就被吸引到了,開始學(xué)一下。方便后面搞后臺遇到性能瓶頸的場景,以及區(qū)塊鏈的開發(fā)。
加上最近小程序大熱,這塊技術(shù)棧也要學(xué)習(xí)了解下。我就想著動手做個簡單的抽獎小程序,后臺可以用go來實現(xiàn),又能學(xué)習(xí)小程序開發(fā),一箭雙雕,開搞。動手實踐永遠是學(xué)習(xí)的最好方式。
一、后臺整體架構(gòu)
整體后臺的結(jié)構(gòu)設(shè)計就如上圖:
小程序和后臺間使用https通信,保證安全性,這也是為了滿足小程序官方的硬性規(guī)定。騰訊負載均衡作為后臺入口有幾個好處:幫助處理https的流量,然后解密后再將請求通過http轉(zhuǎn)發(fā)給后端的服務(wù)器,簡化了邏輯,減少了https對后臺服務(wù)的性能影響,同時還能配置進行動態(tài)的伸縮。
負載均衡將請求通過http轉(zhuǎn)發(fā)給cvm進行處理。nginx做了個反向代理,go服務(wù)端跑在本地。
使用騰訊云的redis和mysql數(shù)據(jù)庫。redis用于頻繁的用戶鑒權(quán)等,mysql保存常規(guī)數(shù)據(jù)。
這樣的設(shè)計在抽獎這種情境下,已經(jīng)能保證足夠的并發(fā)和流量了。如果想提高并發(fā)量,可以通過配置負載均衡來進行動態(tài)伸縮,然后增加云數(shù)據(jù)庫的處理能力。有時間再寫下怎么進行性能評測和相應(yīng)的提高并發(fā)量的升級。
二、抽獎流程設(shè)計
因為每天工作挺忙的,沒那么多時間。就準(zhǔn)備先弄最簡單的抽獎邏輯,有時間和精力再迭代。用戶可以進入小程序創(chuàng)建一個抽獎活動,設(shè)置活動主題、開獎時間、獎品和數(shù)量。然后就能分享出去,其它用戶點擊后參加抽獎。到達開獎時間后,則進行隨機的開獎,每個參加抽獎的用戶最多只能中獎1次。開獎后,對所有抽獎用戶發(fā)送消息提醒。
其實可以簡單地利用開獎來進行大致劃分:
開獎前:用戶創(chuàng)建抽獎活動后,所有用戶都能參加抽獎、取消抽獎,創(chuàng)建者能刪除抽獎活動。
開獎中:到達開獎時間,鎖定這個抽獎活動,不允許用戶操作了。然后內(nèi)部進行抽獎,將獎品隨機分給抽獎用戶。
開獎后:獎品分配完畢,結(jié)果公布。向所有用戶展示開獎結(jié)果,需要通知到參加抽獎的用戶。
三、api文檔設(shè)計
接口文檔非常重要,值得用心好好寫,我覺得這是做后臺開發(fā)的基本素養(yǎng)。不管項目小還是大,一份良好的文檔是必需的。文檔寫好了,可以有很多好處。隨著時間和迭代,我們依然能對每個接口有很好的了解。接口文檔可以將后臺開發(fā)同外部依賴脫離開,使得前端和后臺能解耦。同時,寫接口文檔的過程其實就是思考和梳理的過程,通過細致地討論和思考,理清楚一些細節(jié)和避開一些坑。
下面是我維護的文檔,先是基本的描述,域名、基路徑等。
然后就是每個接口的詳細描述,要定義好請求和返回的結(jié)構(gòu),以及每個參數(shù)的含義和格式。
一個接口的信息
我一般會在git上維護一份最新的md格式接口文檔。如果有協(xié)作的話,其他人對接口有疑問,不用在溝通上每次扯皮,按照文檔的說明來調(diào)用即可。
四、實現(xiàn)
4.1web框架選擇
調(diào)研了下go的web框架,目前用得較多的是beego、echo、gin,所以隨便選個就行。我選了echo,感覺文檔稍微全一些。但相對于其他語言的web框架,echo的文檔太少、不全,學(xué)習(xí)和使用成本高些。
使用echo,我先整體過了一遍官方文檔,最好最全的資料還是官方文檔介紹,所以英文要始終堅持學(xué)習(xí)。附上網(wǎng)址:https://echo.labstack.com/guide
這里主要的流程基本差不多,注冊url處理函數(shù),然后就是crud操作,及各種內(nèi)部邏輯了。每個請求附帶了內(nèi)部自定義的session_id,在echo的Middleware中進行驗證。
4.2數(shù)據(jù)庫操作
4.2.1mysql
我用到的是Go-MySQL-Driver這個包,github地址:https://github.com/go-sql-driver/mysql
如何crud的話,我看了遍使用文檔,地址:http://go-database-sql.org/
連接db
import'database/sql'import_'github.com/go-sql-driver/mysql'db,err=sql.Open('mysql','user:password@tcp(127.0.0.1:3306)/lottery?charset=utf8')
獲取數(shù)據(jù)
利用Query()綁定參數(shù),進行查詢。這里比較麻煩的是獲取db里的一行數(shù)據(jù),需要用Scan()逐個賦值。當(dāng)取出來數(shù)據(jù)很多的時候還是有點麻煩的,不過我還是蠻喜歡自己操控sql語句的,一些orm框架用起來很簡單,但對編程思維和寫sql的訓(xùn)練不夠。自己寫sql,就會考慮怎么優(yōu)化。我會經(jīng)常多問自己一些問題:能不能少進行一次sql查詢?查詢的sql語句能不能更高效?設(shè)計的sql表能不能更優(yōu)?
var(
idint
namestring
)rows,err:=db.Query('selectid,namefromuserswhereid=?',1)iferr!=nil{
log.Fatal(err)}deferrows.Close()forrows.Next(){
err:=rows.Scan(&id,&name)
iferr!=nil{
log.Fatal(err)
}
log.Println(id,name)}err=rows.Err()iferr!=nil{
log.Fatal(err)}
更新數(shù)據(jù)
_,err=db.Exec('updateeventssetstatus=?,cancel_time=?whereid=?andstatus=?',util.DBEventStatusCANCELED,time.Now().Unix(),queryEvent.ID,util.DBEventStatusINIT)
上面是我將抽獎活動從初始狀態(tài),設(shè)置為取消狀態(tài)的sql語句,使用db.Exec來執(zhí)行更新、刪除等語句。
事務(wù)
事務(wù)的話,可以具體看文檔:
tx,err:=db.Begin()iferr!=nil{
log.Fatal(err)}defertx.Rollback()stmt,err:=tx.Prepare('INSERTINTOfooVALUES(?)')iferr!=nil{
log.Fatal(err)}deferstmt.Close()fori:=0;i<10;i++{
_,err=stmt.Exec(i)
iferr!=nil{
log.Fatal(err)
}}err=tx.Commit()iferr!=nil{
log.Fatal(err)}
4.2.2redis
每個請求都需要進行鑒權(quán)session,這里使用的是redis。redis操作用的github.com/garyburd/redigo/redis這個庫。
大家的流程都差不多:連接redis,然后進行put、get操作。這里有個簡單封裝的例子,可以借鑒。https://github.com/aiscrm/redisgo/blob/master/redis.go
4.3微信登錄流程
這里可以說一下微信用戶使用小程序,如何進行登錄的流程。
a.用戶進入小程序。小程序使用wx.login()去微信后臺進行登錄,登錄成功會獲得一個code。真實的返回是這樣的:
{errMsg:'login:ok',code:'001nnSQv1QStGa0X1bSv13u7Rv1nnSQA”}
b.小程序?qū)⑦@個code發(fā)送我給我們自己的后臺。
c.后臺收到這個code后,拼接一個url去微信后臺獲取該微信用戶的session_key。
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
各字段的含義:
appid:這里填小程序appId
secret:小程序appSecret
js_code:小程序發(fā)來的code
grant_type:授權(quán)類型,此處只需填寫authorization_code
撈了條日志看下微信返回的數(shù)據(jù)。其中session_key,對應(yīng)該用戶的會話密鑰;expires_in,憑證有效時間,單位:秒;openid,用戶唯一標(biāo)識。
{'time':'2018-10-13T18:19:41.472758451+08:00','level':'DEBUG','prefix':'echo','file':'auth.go','line':'52','message':'result:map[session_key:ig6tsRoILO2cpxCnk0TXVg==expires_in:7200openid:(隱私刪除)]”}
d.自己后臺定義登錄態(tài),返回給小程序自定義登錄態(tài)。這個時候用戶相當(dāng)于成功登錄了,那么我們給這個用戶一個我們自己定義的session_id,然后每個請求都需要攜帶此session_id,用于驗證。
4.4抽獎活動狀態(tài)機設(shè)計
其實整個后臺的業(yè)務(wù)邏輯重點是跟隨抽獎活動的狀態(tài)來變換的。所以每個發(fā)起的抽獎,我定義了幾個狀態(tài),狀態(tài)機如下:
//數(shù)據(jù)庫中抽獎活動的狀態(tài)常量,const(
DBEventStatusINIT=0//抽獎中,活動創(chuàng)建后此狀態(tài),允許參加抽獎
DBEventStatusOPENING=1//開獎中,不允許抽獎了
DBEventStatusOPEND=2//已經(jīng)開獎了,
DBEventStatusCANCELED=9//活動取消)
抽獎活動的狀態(tài)機
活動創(chuàng)建成功即為狀態(tài)0,可以進行抽獎。
創(chuàng)建者在開獎前可以取消,活動由0可轉(zhuǎn)變?yōu)闋顟B(tài)9,不可再抽獎,終態(tài)。
狀態(tài)0的活動開獎前1分鐘,會進入開獎階段,轉(zhuǎn)換為狀態(tài)1,這時候不可抽獎。
抽獎完成后,狀態(tài)為1的活動會轉(zhuǎn)換為狀態(tài)2,終態(tài),進行通知結(jié)果等處理。
五、總結(jié)
做完這個蠻辛苦的,要學(xué)很多東西,看很多文檔。比如小程序的官方文檔需要看,不然登錄等等后臺沒法配合。使用的語言是go,不是很熟悉,邊學(xué)邊干,echo框架的文檔也要看。然后設(shè)計抽獎的整個流程,設(shè)計數(shù)據(jù)庫,設(shè)計接口請求和返回格式,編寫接口文檔。由于大塊的時間不多,打斷后再接上效率很低。不過整個弄完,感覺對go和小程序有了一個比較全面的理解,接下來我還會繼續(xù)搞。
然后如何用docker來快速部署?如何打造完整的自動化編譯、部署、測試的流程?這些后面有時間,我會后面繼續(xù)總結(jié)發(fā)。
標(biāo)簽:
- 微信小程序電商吸粉的7種裂變方法
2019-11-01 08:02
- 微動助力商家快速抓住小程序的紅利
2020-07-15 09:12
- 第三方平臺類小程序策劃、設(shè)計、運營秘籍
2022-01-12 11:28
- 開發(fā)一個微信小程序大約多少錢?
2022-01-25 08:34
- 電商微信小程序勢必成為新零售未來發(fā)展的強大助力
2020-07-18 15:38
- 小程序制作的費用是多少?貴不貴呢?
2022-02-18 08:35
- 小程序制作需要注意什么?這四點十分重要!
2022-01-24 08:45
- 全維度比較APP、小程序以及公眾號
2022-01-17 11:27
- 商家為何要提前進行移動端小程序布局
2020-07-13 15:00