完善購物車系統(tǒng)

目錄:

  1. 完善加入購物車的提示頁
  2. 完善購物車的刪除
  3. 細節(jié)說明

之前有寫了一個購物車,將會員和游客,分開.會員加車存數(shù)據(jù)庫,游客加車存cookie.但是這個系統(tǒng),加入購物車就會跳轉(zhuǎn)至購物車頁面.但是在京東等電商當中,我發(fā)現(xiàn)他們并不是這樣處理的

圖片來自京東

京東會先跳往一個加入購物車成功的一個頁面.這樣做有什么好處呢

  • 可以誘導(dǎo)用戶繼續(xù)購物
  • 可以讓cookie寫入成功(這個在后面會有詳細說明)
  • 可以不用將某件商品加入購物車,而直接進入購物車(這算是個bug的修復(fù))

首先我們需要明白,做這樣的購物車優(yōu)化,我們需要些什么.

  • 首先我們需要一個前端頁面代碼,這個不是今天的重點,我就不說了

我們直接來看看流程圖


購物車優(yōu)化.png

我們按照這個思路,寫了一個加入購物車提示頁方法

    /**
     * 提示加車成功頁面
     */
    public function actionCarttips()
    {
        //接收前臺數(shù)據(jù)
        $data = Yii::$app->request->get();
        //判斷用戶是否登陸
        if (Yii::$app->user->isGuest) {
            //如果沒有登陸,調(diào)用未登陸加車方法
            if (!$this->guestAddCart($data)) {
                echo '數(shù)據(jù)出錯,稍后再試游客';
                exit;
            }
        } else {
            //如果登陸,調(diào)用登陸加車方法
            if (!$this->memberAddCart($data)) {
                echo '數(shù)據(jù)出錯,稍后再試';
                exit;
            }
        }
        //渲染加車提示頁面,傳入id,繼續(xù)購物使用
        return $this->render('CartTips', ['goods_id' => $data['goods_id']]);
    }

在這段代碼中,我在這個控制器里之前就已經(jīng)封裝好了,游客和會員兩個不同的加入購物車方法.
由于商品詳情頁,我使用的是頁面靜態(tài)化,所有只能使用get傳值來避免csrf驗證
get接收到值過后,傳給相應(yīng)的方法,完成加車,渲染加車提示頁面.
這里有個小細節(jié),我們傳遞了一個goods_id到前端頁面,這里是為了讓用戶點擊繼續(xù)購物的時候能夠直接跳回之前的那個商品頁面.讓用戶體驗更完善.


下面我們來看看購物車里商品的刪除,一個購物車,必須得有刪除功能,我們不能規(guī)定用戶加入購物車后就不能刪除,也許是用戶手滑或則別的什么原因,購物車里必須有刪除.

這里我們選擇的是異步請求刪除
之所以要選擇異步是因為,異步刪除不刷新頁面感覺比較高級.還有就是異步請求,只會傳遞數(shù)據(jù),并不會重新加載靜態(tài)資源.這樣反應(yīng)也會比較快

下面我們來看看刪除購物車的流程


購物車刪除.png

我們先來看前端jquery代碼

<script type="text/javascript" src="<?= Yii::$app->params['jquery'] ?>"></script>
<script type="text/javascript" src="/statics/plug/layer/layer/layer.js"></script>
<script type="text/javascript" src="/statics/js/cart1.js"></script>
<script type="text/javascript">
    $(function () {
        //使用事件委派,委派到刪除的a標簽上.a標簽有兩個屬性,一個是class="del",一個是goods_id="對應(yīng)的商品id"
        $("#cart_content").on('click', ".del", function (event) {
            //獲取到id
            var goods_id = $(event.target).attr('goods_id');
            //通過尋找父級對象.找到點擊刪除的那一行tr
            var dom = $(event.target).parents('.num_tr');
            if (confirm('您真的要刪除這個商品嗎')) {
                //將id發(fā)送到后臺接口,獲取json結(jié)果
                $.getJSON(
                    '<?=\yii\helpers\Url::to(['goods/delcart'])?>',
                    {'goods_id': goods_id},
                    function (data) {
                        if (data.status) {
                            //成功
                            layer.msg(data.message, {icon: 1});
                            //刪除dom節(jié)點
                            dom.remove();
                           //重新計算總價
                            var price = 0;
                            if ($(".onePrice") !== undefined) {
                                $('.onePrice').each(function (i, v) {
                                    price += Number($(v).text());
                                });
                            }
                            $("#total").text(price);
                        } else {
                            //彈出小標簽提示
                            layer.msg(data.message, {icon: 2});
                        }
                    }
                )
            }
        })
    })
</script>

前段jq代碼,使用了兩個小技術(shù).一個是事件委派,一個是ajax異步請求技術(shù).這里就不細講了.我們重點來看看后臺的接口方法

    /**
     * 刪除購物車中的數(shù)據(jù)接口
     */
    public function actionDelcart()
    {
        $goods_id = Yii::$app->request->get('goods_id');
        if (Yii::$app->user->isGuest) {
            //游客
            //獲取cookie
            $cookieobj = Yii::$app->request->cookies;
            $cookieValue = $cookieobj->getValue('cart_cookie');
            if (empty($cookieValue)) {
                echo json_encode(['status' => 0, 'message' => '購物車中沒有這個商品']);
                exit;
            }
            //反序列化cookie中的數(shù)據(jù)
            $cartArr = unserialize($cookieValue);
            foreach ($cartArr as $key => $value) {
                if ($key == $goods_id) {
                    unset($key);
                }
            }
            //序列化
            $serArr = serialize($cartArr);
            //將cookie寫入
            Yii::$app->response->cookies->add(new Cookie([
                'name' => 'cart_cookie',
                'value' => $serArr
            ]));
            echo json_encode(['status' => 1, 'message' => '刪除成功']);
        }
        else{
            //會員
            //查出數(shù)據(jù)庫中這個商品的對象
            $cartModel=Cart::findOne(['goods_id'=>$goods_id,'user_id'=>Yii::$app->user->identity->getId(),'status'=>2]);
            if (empty($cartModel)) {
                echo json_encode(['status' => 0, 'message' => '購物車中沒有這個商品']);
                exit;
            }
            //修改這條商品的狀態(tài)
            $cartModel->status=0;
            $cartModel->save();
            echo json_encode(['status' => 1, 'message' => '刪除成功']);
        }
    }

這里首先將游客和會員分開,使用Yii::$app->user->isGuset來判斷

  • 游客的話,要復(fù)雜一點,我們將cookie里的數(shù)據(jù)取出,然后找到相應(yīng)的goods_id對應(yīng)的那條數(shù)據(jù),將它刪除,隨后,又將剩下的數(shù)據(jù)再序列化后,再寫入cookie.返回json化的執(zhí)行結(jié)果
  • 會員我們是選擇查出購物車表中的含有當前用戶和含有g(shù)oods_id的一條數(shù)據(jù)對象
    將這一對象的狀態(tài)改為0,這樣完成的刪除,同樣的,返回一條json化的執(zhí)行結(jié)果

之前有提到要在購物車中加上提示頁面,對寫入cookie更友好.

我們都知道,cookie是存儲在瀏覽器中的數(shù)據(jù).當我們的代碼執(zhí)行到寫入一條cookie時,并沒有真正的寫入,原因是我們必須在response,也就是渲染頁面時候才能寫入到cookie,在之前的版本中.我發(fā)現(xiàn),當我渲染頁面,在cookie中取值,并沒有剛加入的cookie數(shù)據(jù).

當時我的解決方案就是,在渲染頁面中把get到的值,合并到之前的cookie中,來解決cookie寫入慢半拍的問題,可是這一解決方案,始終感覺不夠優(yōu)雅,數(shù)據(jù)來源復(fù)雜化了.

所有采用中間加一頁的方法的話,就在渲染提示頁的時候就成功加入cookie,當用戶這是點擊購物車時候,我們直接到cookie中取值,就可與取到完整的數(shù)據(jù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,563評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,694評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,672評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,965評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,690評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,019評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,013評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,188評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,718評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,438評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,667評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,149評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,845評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,252評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,590評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,384評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,635評論 2 380

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,767評論 25 708
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,833評論 18 139
  • 全文鏈接 第一章 創(chuàng)建一個blog應(yīng)用第二章 使用高級特性來增強你的blog第三章 擴展你的blog應(yīng)用第四章上 ...
    夜夜月閱讀 10,080評論 27 36
  • 收拾起行囊 面對陌生的遠方 點一支煙 看自己的雙腳和足跡 為那荒唐的圖案而懊悔 為那誠懇和樸實而羞愧 朋友說 那是...
    一言一語一行閱讀 226評論 0 0
  • 輸出信息含義 執(zhí)行netstat后,其輸出結(jié)果為 Active Internet connections (w/o...
    bailongxian閱讀 1,260評論 0 2