Jimmychoo商城系統總結


一、需求

1.游戲模塊

①在進入H5之前,首先有一個動態的探照燈的動效,然后由“淡出”效果到H5首頁。

②在點擊“開始游戲”之后會有一段動畫演示游戲內容,然后滑動開啟游戲,開始計時。

③成功找到目標短語之后,進入下一關。總共5關,難度遞增。

④滑錯之后,會提示滑錯懲罰,第一次計時加2秒,后面每次遞增1秒。

⑤有“提示”按鈕,有兩次提示的機會,點擊確定使用后會將正確的短語亮起熒光,兩次機會用完提示按鈕消失。

⑥5關全部成功之后,顯示游戲成績以及擊敗對手的百分數。可以查看排行榜,會顯示前10名+個人成績。

2.商城模塊

I、打開首頁,會有一段文字描述商城以及銷售條款。點擊“即刻擁有”開始購物流程。

II、點擊“即刻擁有”之后,跳轉到商品列表頁面,會顯示商品的品名,類型,圖片。商品列表是下滑類型的頁面。

III、點擊每個商品可以查看商品詳情,可以左右滑動查看3個視角的產品圖片。鞋類的商品有選擇尺碼和尺碼參考這兩個功能,包類的沒有。點擊查看產品詳情可以查看商品介紹,可以加入購物袋。

IV、選擇尺碼的時候列出所有的尺碼,並且當這個碼數只有一雙的時候提示,僅剩一雙。

V、點擊“加入購物袋”,如果商品售罄會跳轉至售罄頁面,如果沒有跳轉至購物袋。

VI、購物袋頁面,以列表的形式把購物袋內容顯示出來,並且可以刪除。如果其中某款商品無貨,則該商品的背景成為灰色。可以點擊“結算”按鈕,如果結算成功跳轉至支付頁面。

VII、結算的過程中要實時的計算商品的庫存,如果庫存不足則不能結算成功,有多人同時結算同款產品的壓力。

VIII、支付頁面  分為配送方式、發票信息、支付方式三部分,配送方式是必填,支付方式固定是微信支付,發票信息選填。點擊“支付”按鈕,調起微信支付,支付成功跳轉至訂單頁面。

IX、支付失敗  會檢測支付訂單是否超時,如果超時跳轉至首頁。

X、訂單頁面,按照每個訂單的商品分開顯示,未支付的訂單會有“付款”、“取消”兩個按鈕,支付的訂單會有“收貨地址”、“查看物流”、“申請售后”三個按鈕。

XI、“取消”或者訂單超時訂單都會顯示交易關閉,“付款”會跳轉至付款頁面,“收貨地址”會顯示用戶的收貨地址,“查看物流”會顯示用戶訂單的真實物流信息,“申請售后”會顯示售后電話。

 二、設計

1.游戲模塊

 動畫、效果方面主要由前端來實現,這里不做解釋。后端在游戲部分主要包括三個方面:

①玩家在通關游戲之后的分數記錄

②排行榜的計算

③游戲通關之后的分享和分享頁面的顯示

2.商城模塊

 商城模塊除了一些頁面的排版、顯示需要前端來實現,其他的功能全部交由后端。主要功能包括:

①商品列表的顯示,以及從個kol進來之后各產品和導航的隱藏與顯示

②商品單品頁商品的各項屬性顯示,如價格、圖片、模特圖、產品介紹等

③購物袋頁面,要顯示客戶購買的東西 ,可以刪除商品,添加商品,結算購物袋

④結算頁面,要顯示與修改客戶的收貨地址、發票信息、以及折扣信息(后來加的)、微信H5內公眾號支付

⑤結算成功后,跳到成功頁面;結算失敗后,跳到訂單頁面。

⑥訂單頁面,顯示客戶的所有訂單號、訂單狀態,以及訂單內的各個單品信息、收貨地址、物流信息等

三、實現以及問題

1.游戲模塊

  游戲部分是一個類似圖案滑動解鎖的游戲,在你觸摸那些單詞划過“I want choo”這幾個單詞的時候,就會過關。連續闖過5關,游戲結束。每一關的難度會有提升,每關游戲的圖案是隨機生成的,其中用到的技術(我知道的,因為我不是前端,只負責后端以及交互的 部分)有下面這些:

①圖案解鎖

  圖案解鎖用的是一個patternlock.js的插件,在已有插件的情況要考慮的就是這個游戲難度的事情。一開始應客戶要求,最少要有50個以上的圖案供玩家玩,結果一開始客戶代表還准備傻傻的去畫50種圖案放上去。后來考慮到這個圖案可能真的會畫死人,最后決定用隨機生成一個圖案里面所有需要的字母,然后用canvas畫在頁面上。最后用patternlock.js這個js觸摸解鎖這個答案。效果如下:

在觸摸滑動這些單詞錯誤的時候會有錯誤的音效提示,在點擊“提示”后會在正確的“i want choo”上面呈現粉色。

 ②計時器

  問題:

  1.香港客戶反應,計時器走的很慢,不是正常的一個秒數轉換,而且越走越慢。

  2.會出現完了00:00.00的用戶

  原因:

  計時器的話,一開始用的是setinterval,讓他1000毫秒的時候,秒數位置上加1;60秒的時候分鍾上面+1;聽起來是不是很合理沒有一點毛病,然后只要計算出開始時間和結束時間,獲得他們的差值就是這個人游戲時間。其實這是錯誤的。

  1.setinterval和settimeout的機制是把你要執行的代碼在你設定的那個時間點插入js引擎維護的一個代碼隊列中,但是插入隊列代碼並不意味着馬上執行,因為js解釋引擎是單線程運行的。他會等到前面的代碼先執行完之后才會來執行這個隊列中的代碼,因為平時頁面代碼很少,js執行很快,所以平時我們感覺到定時器在你設置的那一刻他就開始運行了,運行的很平穩,這是一種錯覺。在你設置定時器的時候獲取開始時間只是代碼設置的時間,並不是定時器任務開始的時間。並且setInterval的回調函數並不是到時后立即執行,而是等系統計算資源空閑下來后才會執行.而下一次觸發時間則是在setInterval回調函數執行完畢之后才開始計時,所以如果setInterval內執行的計算過於耗時,或者有其他耗時任務在執行,setInterval的計時會越來越不准,延遲很厲害.

  2.獲取時間這里也是有漏洞的,我們平時用的Date.now()獲取到的是從1970年1月1日00:00:00 UTC開始經過的毫秒數,他會根據系統時間來檢索當前的時間戳。非常不幸的是,這個函數會因為用戶代理不同而不一樣,精度非常不可靠,在同一時間不同地方獲取到的時間戳是不同的。

  3.說起來第一次看到出現00:00.00秒的用戶,我的第一反應是我提交游戲數據的接口被攻擊了,別人肯定是利用了其他的非法手段給我提交數據,我一點都沒懷疑前端。我檢查了后端的代碼,有微信授權不太可能在微信之外的瀏覽器打開,但是微信授權是可以使用模擬器模擬出來的,我當時想的是他肯定是用模擬器抓包,然后提交到了我的接口導致了00:00.00的記錄。后來去查看了當時記錄數據的方法,結果真的有一點漏洞,雖然我驗證了cookie和提交方式post,但是還是有漏洞的,cookie可以偽造,post也可以模擬提交。我以為我發現了真正的原因,並向他們保證肯定不會有問題。結果第二天測試的人一玩,又出現了00:00.00,瞬間打臉。我有點不知所措,這個時候才開始認真思考真正的漏洞在哪里,是我一開始想的太多了。出現這種情況無非原因有兩種:①我的接口記錄這一塊出了問題導致記錄成了00:00.00②前端傳過來的時間就是00:00.00接口我仔細檢查了代碼是沒有問題的,那就只有一種可能前端傳過來的值就有問題。后來經過努力好不容易搞到了那台出問題手機的型號,系統版本號和微信版本號,我們拿相同的版本號測試發現,計時器他居然不走,一直是00:00.00所以才導致了這種事情。后面會寫為什么出現這種情況,下面是后端的記錄代碼(tp5)

  解決方案

  1.時間精度不准的情況下,采用了H5的新接口Performance接口。Performance接口提供當前時間在毫秒級的分辨率,使他不受系統時間的偏斜或者調整,在2012年10月23日成為了W3C的推薦。Performance.now()獲取到的是當前時間的毫秒數,他精確到了千分之一毫秒。這個新接口擁有這諸多好處,但是新生事物有一個缺點就是兼容性,支持該API的瀏覽器很少,IE10,firefox15+以及谷歌瀏覽器,ios系統必須在9以上,安卓必須在4.0以上。就是因為低版本系統不支持的原因,所以會有部分手機根本就沒獲取到開始時間導致了00:00.00的發生。后來我們提出建議,做一個補償機制,就是在客戶手機不支持這個最新接口的情況下,才用new Date().getTime()來獲取時間,然后在計算他們之間的時間差,最后統一返回一個計算好的時間差。但是當時項目已經上線,客戶表示這個修改很大怕影響在線的效果,才用了另外一種辦法。如果客戶的手機不支持最新接口,那么提示他升級系統之后再來玩,下面是測試支持情況的代碼。

如果這個接口不被支持,那么就會返回null。

  2.針對setinterval機制的問題,我們采用了requestAnimationFrame。requestAnimationFrame采用系統時間間隔,保持最佳繪制效率,不會因為間隔時間過短,造成過度繪制,增加開銷;也不會因為間隔時間太長,使用動畫卡頓不流暢,讓各種網頁動畫效果能夠有一個統一的刷新機制,從而節省系統資源,提高系統性能,改善視覺效果。他不會去等待其他任務執行完才執行,有效的提高了計時的精度。

2.商城部分

  相信大部分人都做過商城,像商品列表,單品這種是肯定沒有問題的,這里就不做介紹了,只介紹一些可能出問題的功能。

  1.購物袋功能

   問題

  在通過按鈕加入購物袋這個操作,我們一般會用ajax提交到購物袋之后跳轉到購物袋頁面,但是對這個按鈕的點擊沒有做限制,導致有時候客戶感覺只點擊了一次,但是卻是加入了兩件商品到購物車,客戶體驗很差。

  解決方案

  1.在提交到購物車頁面這里,點擊提交到購物車按鈕才用同步提交到后台,等待后台返回的時候在進行下一步跳轉到購物袋頁面。2.就是用一個flag來控制提交,在提交的時候變成false,只有等待提交成功了變成true,才可以再次提交,但是這個只能在正常情況下使用。

  2.結算功能

  問題

  在購物袋頁面,點擊結算跳轉到結算頁面,然后在返回購物袋頁面,這個時候購物袋頁面應該是空的。這個操作在安卓上面是沒有問題的,但是在iphone上面就有問題,在結算頁面的時候,點擊返回到上一頁的時候,他讀取了棧中的緩存,並沒有重新加載那個頁面。結果就成了點擊返回,上一頁被結算的那些商品還擺在那里,但是點擊結算結算的數據也為空,點擊刪除的數據也是空的。

  解決方案

  這個問題就是在於iphone點擊返回的時候,讓他刷新返回的頁面。在這里頁面寫js刷新是沒用的,因為在點擊返回的時候讀取的是緩存,相當於在頁面剛進來的刷新了,這個時候再返回它是不會刷新的。關鍵在於怎么捕捉iphone手機的返回事件。這里我采用的是H5的另外一個新接口history,在頁面跳到下一個頁面的時候在堆棧中replacestate替換掉這個頁面,然后在用戶點擊返回的時候會觸發popstate事件。這個時候因為在堆棧的history中頁面已經被替換了,所以再返回的時候就會刷新這個頁面。代碼如下:

 

  3.支付頁面

  問題

  在支付頁面,用戶填寫了打折的手機號碼的時候,會有一個優惠價給到客戶,然后客戶可以用優惠價來支付,但是支付的那些信息在頁面加載的時候已經生成好了,里面包含了金額,如果有優惠價格的時候修改不了

  解決方案

  微信支付在生成prepay_id的時候,會涉及到商戶訂單號,價錢。這些東西在頁面加載的時候已經生成並且顯示到了頁面上,如果這個人不是優惠客戶,那么使用這個已經生成好的jsapi支付是可以的。如果這個人是優惠客戶的時候,因為要修改價格,如果拿以前的訂單號和價格去生成prepay_id,去調起微信的jsapi支付,就會報錯商戶訂單號重復。這個時候我們可以重新生成一個訂單號,然后用新的訂單號和價格重新生成一個prepay_id來調起微信支付,代碼如下

這里要注意的是返回的json信息要轉換為json對象才可以成功的調起微信支付。

  4.支付回調

  問題

  在支付成功的時候,會觸發微信的回調,這個時候才算真正的完成這個訂單。但是有的時候回調成功,有些時候回調不成功,但是真實存在付款。

  解決方案

  微信支付回調的時候,回調的鏈接一定不能攜帶任何參數,不然就會導致回調失敗。有時候回調成功,有時候回調不成功,可能的原因是你有構造函數或者其他驗證的東西,微信在通過這些東西的時候被攔截了,並且跳到了其他的頁面,我就是因為下面原因導致回調有時不成功:

  

  后來,我在另外一個單獨的控制器中做了回調驗證,這個問題就解決了。

  5.庫存問題

  問題

  在商城中的很多商品是有庫存的,他們不能超賣,因為沒有那么多貨品,要在售賣的時候保證出售的數量不能超過庫存

  解決方案

  一般情況下是不會發生超賣這種事情的,因為在並發不是很高的情況下,mysql這類的關系型數據庫也可以完全支撐。但是在高並發的情況下,數據庫的讀寫速度太快的時候,會導致鎖表。很多操作都在等待前面的執行完畢釋放了之后才能執行,結果可能會導致數據庫掛掉。這個時候就用到了我們的nosql。我在這里使用的是redis,他可以支撐10W的並發,足以應付很多場景。redis有兩種辦法可以控制庫存,string和list,我推薦使用list。因為雖然redis的string也是原子性的操作,比如現在的庫存是5,六個人同時買了之后,他肯定是-1,而不可能是其他數字。redis的string雖然可以當成數字來計算,可以使用incr和decr進行原子性的遞增遞減操作,但是它是可以見到負數的,你可以想象一下你的庫存已經是負數了,它還在減是什么樣的情況。這種情況很有可能發生。

  所以我用了list,在用戶點擊商品的時候,把該商品的對應信息加載到redis緩存list中。每次有人購買了商品,就用lpop彈出一個隊列元素,如果隊列的長度為0了,他就會返回false而不會繼續減下去,很好的避免了在庫存已經為0的情況下超賣出去。

  這里還有一個問題是如果購物車中的商品有很多種,每種商品的庫存是不一樣的,如果在結算的過程中,在沒有結算完畢的情況下,某種商品沒有庫存了,這個結算不成功。這個時候需要告知客戶那樣商品沒有了,並且分別返回他們各自的庫存,因為有的結算了,有的沒結算。這里大家可以使用事務來控制,逐條來結算購物車商品,如果有沒有的商品就回滾,保證了數據庫數據的完整性。但是redis這邊沒有這么完整的事務支持的,如果有某幾件商品已經操作reidis減去庫存了,這個時候怎么辦呢?

  我在循環開始前,定義了一個數組$command。在循環操作redis的時候,每操作成功一條就把操作的這個key加入到$command這個數組中。一旦某件商品沒有庫存了,我就循環這個數組,把減去的庫存全部加回來,比用數據庫事務要方便點。

 

  

 

 

  小弟才疏學淺,文筆不精,哪里有寫的不對的或者不好的地方,歡迎大家指正!

  

  

需求->設計->實現->測試->交付


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM