产品表每次更新商品都会变动的,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}
- {$item['name']}
- {set:$specVal=explode(',',trim($item['value'],','))}
{foreach:items=$specVal item=$spec_value}
{if:$item['type'] == 1}
- {$spec_value}
{else:}
{/if}
{/foreach}
{/foreach}
{/if}
~~~
* * * * *
### 扩展讨论:标类与非标
当商品比较容易标准化,规范化时使用类型来决定规格这种形式比较好(根据商品类型定义规格模型),但是有一些场景这样就不太灵活了,比如当商品很难标准化,规范化时,比如外卖的餐品,不是每一个餐品都有规格,都有辣度规格,大份小份等规格,所以此时应该寻找另外一种解决方案了,比如使用自定义的规格,这样就灵活很多了,这里就有个很好的实例:[这是商品不依赖类型,自定义规格的完美解决方案!](https://coding.net/u/xiasf/p/gcb/git/commit/6d4116b91cc05e4db483e9eb49bd58611510f0e5#commit-comment-91257) ,当然如果情况复杂特殊,使用两种方式结合也是我们愿意看到的,不过设计起来可能比较复杂,以后有实际案例再讨论。
* * * * *
update:2017-3-16 11:18:03