產品表每次更新商品都會變動的,ID不能用,可是購物車還是用了,這就導致每次保存商品,哪怕什么都沒有改動,也會導致用戶的購物車失效。
~~~
其實可以考慮不是每次更新商品就除所有的SKU,畢竟有時什么都沒修改呢,只改一個價格呢,或者增加一個SKU呢,其實這個問題做細一點有好的處理方式的。
比如商品增加一個版本號字段,SKU也增加一個版本字段,如果SKU規格值變動了那么刪除,如果發現規格值還在,只是價格或其它的改變了,那么則只需要改變版本號就可以了,但其實這里面的細節很多,考慮得比較麻煩,還是干脆不要用SKU的ID了,如果能不用SKU的ID,那就全部都不要用,購物車里面也只記錄商品的ID和規格字符串就可以了,根據規格字符串查詢SKU,如果找不到那就是沒有。
~~~
規格不是屬于模型,而是模型有個字段可以包含多個規格。多個規格值使用json編碼保存。
屬性是屬于模型的。多個屬性值使用逗號分隔。
商品展示時規格怎么獲取,跟后臺可不一樣,后臺是可以看到模型下面的所有規格,但不一地你給選用該規格,而前臺是要展現所有SKU,請注意這個區別。
iwebshop是將商品的所有規格組(SKU)都放入了goods表,顯示時使用了這兒的數據。而tpshop是從sku表中獲取的。
classes/goods_class.php 119 line
~~~
//是否存在貨品
$goodsUpdateData['spec_array'] = '';
if(isset($postData['_spec_array']))
{
//生成goods中的spec_array字段數據
$goods_spec_array = array();
foreach($postData['_spec_array'] as $key => $val)
{
foreach($val as $v)
{
$tempSpec = JSON::decode($v);
if(!isset($goods_spec_array[$tempSpec['id']]))
{
$goods_spec_array[$tempSpec['id']] = array('id' => $tempSpec['id'],'name' => $tempSpec['name'],'type' => $tempSpec['type'],'value' => array());
}
$goods_spec_array[$tempSpec['id']]['value'][] = $tempSpec['value'];
}
}
foreach($goods_spec_array as $key => $val)
{
$val['value'] = array_unique($val['value']);
$goods_spec_array[$key]['value'] = join(',',$val['value']);
}
$goodsUpdateData['spec_array'] = JSON::encode($goods_spec_array);
}
~~~
products.html 模板
~~~
{if:$spec_array}
{set:$specArray = JSON::decode($spec_array);}
{foreach:items=$specArray}
<div id="mall_detail_type">
<dl name="specCols" class="mall_detail">
<dt>{$item['name']}</dt>
<dd id="specList{$item['id']}"> {set:$specVal=explode(',',trim($item['value'],','))}
{foreach:items=$specVal item=$spec_value}
{if:$item['type'] == 1}
<ul>
<li><a href="javascript:void(0);" onclick="sele_spec(this);" value='{"id":"{$item['id']}","type":"{$item['type']}","value":"{$spec_value}","name":"{$item['name']}"}' >{$spec_value}</a></li>
{else:}
<li><a href="javascript:void(0);" onclick="sele_spec(this);" value='{"id":"{$item['id']}","type":"{$item['type']}","value":"{$spec_value}","name":"{$item['name']}"}' ><img src="{webroot:$spec_value}" width='30px' height='30px' /></a></li>
</ul>
{/if}
{/foreach} </dd>
</dl>
</div>
{/foreach}
{/if}
~~~
* * * * *
### 擴展討論:標類與非標
當商品比較容易標準化,規范化時使用類型來決定規格這種形式比較好(根據商品類型定義規格模型),但是有一些場景這樣就不太靈活了,比如當商品很難標準化,規范化時,比如外賣的餐品,不是每一個餐品都有規格,都有辣度規格,大份小份等規格,所以此時應該尋找另外一種解決方案了,比如使用自定義的規格,這樣就靈活很多了,這里就有個很好的實例:[這是商品不依賴類型,自定義規格的完美解決方案!](https://coding.net/u/xiasf/p/gcb/git/commit/6d4116b91cc05e4db483e9eb49bd58611510f0e5#commit-comment-91257) ,當然如果情況復雜特殊,使用兩種方式結合也是我們愿意看到的,不過設計起來可能比較復雜,以后有實際案例再討論。
* * * * *
update:2017-3-16 11:18:03
- 開始
- 公益
- 更好的使用看云
- 推薦書單
- 優秀資源整理
- 技術文章寫作規范
- SublimeText - 編碼利器
- PSR-0/PSR-4命名標準
- php的多進程實驗分析
- 高級PHP
- 進程
- 信號
- 事件
- IO模型
- 同步、異步
- socket
- Swoole
- PHP擴展
- Composer
- easyswoole
- php多線程
- 守護程序
- 文件鎖
- s-socket
- aphp
- 隊列&并發
- 隊列
- 講個故事
- 如何最大效率的問題
- 訪問式的web服務(一)
- 訪問式的web服務(二)
- 請求
- 瀏覽器訪問阻塞問題
- Swoole
- 你必須理解的計算機核心概念 - 碼農翻身
- CPU阿甘 - 碼農翻身
- 異步通知,那我要怎么通知你啊?
- 實時操作系統
- 深入實時 Linux
- Redis 實現隊列
- redis與隊列
- 定時-時鐘-阻塞
- 計算機的生命
- 多進程/多線程
- 進程通信
- 拜占庭將軍問題深入探討
- JAVA CAS原理深度分析
- 隊列的思考
- 走進并發的世界
- 鎖
- 事務筆記
- 并發問題帶來的后果
- 為什么說樂觀鎖是安全的
- 內存鎖與內存事務 - 劉小兵2014
- 加鎖還是不加鎖,這是一個問題 - 碼農翻身
- 編程世界的那把鎖 - 碼農翻身
- 如何保證萬無一失
- 傳統事務與柔性事務
- 大白話搞懂什么是同步/異步/阻塞/非阻塞
- redis實現鎖
- 淺談mysql事務
- PHP異常
- php錯誤
- 文件加載
- 路由與偽靜態
- URL模式之分析
- 字符串處理
- 正則表達式
- 數組合并與+
- 文件上傳
- 常用驗證與過濾
- 記錄
- 趣圖
- foreach需要注意的問題
- Discuz!筆記
- 程序設計思維
- 抽象與具體
- 配置
- 關于如何學習的思考
- 編程思維
- 談編程
- 如何安全的修改對象
- 臨時
- 臨時筆記
- 透過問題看本質
- 程序后門
- 邊界檢查
- session
- 安全
- 王垠
- 第三方數據接口
- 驗證碼問題
- 還是少不了虛擬機
- 程序員如何談戀愛
- 程序員為什么要一直改BUG,為什么不能一次性把代碼寫好?
- 碎碎念
- 算法
- 實用代碼
- 相對私密與絕對私密
- 學習目標
- 隨記
- 編程小知識
- foo
- 落盤
- URL編碼的思考
- 字符編碼
- Elasticsearch
- TCP-IP協議
- 碎碎念2
- Grafana
- EFK、ELK
- RPC
- 依賴注入
- 開發筆記
- 經緯度格式轉換
- php時區問題
- 解決本地開發時調用遠程AIP跨域問題
- 后期靜態綁定
- 談tp的跳轉提示頁面
- 無限分類問題
- 生成微縮圖
- MVC名詞
- MVC架構
- 也許模塊不是唯一的答案
- 哈希算法
- 開發后臺
- 軟件設計架構
- mysql表字段設計
- 上傳表如何設計
- 二開心得
- awesomes-tables
- 安全的代碼部署
- 微信開發筆記
- 賬戶授權相關
- 小程序獲取是否關注其公眾號
- 支付相關
- 提交訂單
- 微信支付筆記
- 支付接口筆記
- 支付中心開發
- 下單與支付
- 支付流程設計
- 訂單與支付設計
- 敏感操作驗證
- 排序設計
- 代碼的運行環境
- 搜索關鍵字的顯示處理
- 接口異步更新ip信息
- 圖片處理
- 項目搭建
- 閱讀文檔的新方式
- mysql_insert_id并發問題思考
- 行鎖注意事項
- 細節注意
- 如何處理用戶的輸入
- 不可見的字符
- 抽獎
- 時間處理
- 應用開發實戰
- python 學習記錄
- Scrapy 教程
- Playwright 教程
- stealth.min.js
- Selenium 教程
- requests 教程
- pyautogui 教程
- Flask 教程
- PyInstaller 教程
- 蜘蛛
- python 文檔相似度驗證
- thinkphp5.0數據庫與模型的研究
- workerman進程管理
- workerman網絡分析
- java學習記錄
- docker
- 筆記
- kubernetes
- Kubernetes
- PaddlePaddle
- composer
- oneinstack
- 人工智能 AI
- 京東
- pc_detailpage_wareBusiness
- doc
- 電商網站設計
- iwebshop
- 商品規格分析
- 商品屬性分析
- tpshop
- 商品規格分析
- 商品屬性分析
- 電商表設計
- 設計記錄
- 優惠券
- 生成唯一訂單號
- 購物車技術
- 分類與類型
- 微信登錄與綁定
- 京東到家庫存系統架構設計
- crmeb
- 命名規范
- Nginx https配置
- 關于人工智能
- 從人的思考方式到二叉樹
- 架構
- 今日有感
- 文章保存
- 安全背后: 瀏覽器是如何校驗證書的
- 避不開的分布式事務
- devops自動化運維、部署、測試的最后一公里 —— ApiFox 云時代的接口管理工具
- 找到自己今生要做的事
- 自動化生活
- 開源與漿果
- Apifox: API 接口自動化測試指南