比如说现在一个SPU下对应有三种类型规格,分别为颜色,尺寸,重量
三种类型规格各自拥有三个规格值
颜色: 红色,白色,蓝色
尺寸: XL XXL XXXL
重量: 50kg 100kg 150kg
那么这三种类型的规格值各自组合,笛卡尔积下,就是有9个SKU商品
在发布商品的时候,会为每个SKU配置一个库存
目的是获取基于用户已经选择的规格值获取所有规格值可选的规格值集合
什么样的情况下才算可选?
sku对应的商品的库存不为0
举例来说
红色 XL 50kg对应的sku库存为0
红色 XL 100kg对应的sku库存为0
红色 XL 150kg对应的sku库存为0
则用户在选择红色以后,XL不可选,50kg,100kg,150kg因为存在其他尺寸的搭配,所以未知,可能可选,所以不置灰
用户选择红色以后,再选择XL的话,则50kg,100kg,150kg都不可选
我的思路是:
1. 列出所有的规格值
2. 遍历所有商品,过滤出库存为0的商品列表,从过滤出的商品列表中列出所有的规格值,然后去重,所有不可选的规格值肯定在这范围之内,得到数组A
3. 将用户已选择的规格值进行拆分,可以这样理解:用户目前选择的规格值影响的不可选规格集合都是每次点击一个规格值的时候不可选规格的组合;比如说,用户选择了红色,XL以后,可以拆分为红色,XL,然后进行去重,得到数组B
4. 遍历数组B,然后在数组B中遍历数组A,将数组A中每一个元素与数组B中每一个数组进行合并之后,遍历所有商品,如果商品规格包含合并后的规格数组,则进行下一个判断,是否存在库存不为0的情况,如果存在,则这个数组A中的元素是可选的,如果不存在,则将这个A中的这个规格值丢到不可选的数组内
5. 得到不可选的规格值集合
public function getDisabledSpec($goods_info,$spec_arr){
if(empty($spec_arr)){
$spec_arr = array_keys($goods_info['goods_spec']);//用户已选择的规格值
}else{
$spec_arr = array_values($spec_arr);//用户已选择的规格值
function convertToInt($value){
return intval($value);
}
$spec_arr = array_map("convertToInt",$spec_arr);
}
if(empty($goods_info['goods_spec']) || empty($goods_info['spec_value'])) return array();
$goods_list = Model('goods')->getGoodsList(array('goods_commonid' => $goods_info['goods_commonid']));
$disable_goods = array();
$all_goods = array();
$result = array();
$all_spec_key = array();
foreach($goods_list as $key => $goods_item){
$goods_spec_key = array_keys(unserialize($goods_item['goods_spec']));
$all_goods[] = array('spec_key' => $goods_spec_key,'storage' => $goods_item['goods_storage']);
$all_spec_key = array_merge($all_spec_key,$goods_spec_key);
if(intval($goods_item['goods_storage']) <= 0) {
$disable_goods[] = $goods_spec_key;
}
}
$all_spec_key = array_unique($all_spec_key);
// $all_spec_key = array_diff($all_spec_key,$spec_arr);
//若两者相等,则此spu下所有的sku规格值的库存都为空
if(count($disable_goods) == count($goods_list)){
return $all_spec_key;
}
$intersect_arr = array();
$disable_arr = array();
foreach($disable_goods as $key => $goods_item){
$intersect = array_intersect($spec_arr, $goods_item);
if(empty($intersect)) continue;
$intersect_arr[] = $intersect;
$disable_arr = array_merge($disable_arr,$goods_item);
}
$disable_arr = array_values(array_unique($disable_arr));
$handle_arr = array();
for($i = 0;$i < count($intersect_arr);$i++){
if(empty($intersect_arr[$i])) continue;
if(in_array($intersect_arr[$i],$handle_arr)) continue;
array_push($handle_arr,$intersect_arr[$i]);
for($j=0;$j < count($disable_arr); $j++){
if(!in_array($disable_arr[$j],$intersect_arr[$i])){
$this->_handleSpec($result,$all_goods,$intersect_arr[$i],$disable_arr[$j]);
}
}
}
/**
* 最后两步
*
* 1. 去重
* 2. 去掉勾选的规格值
*/
$result = array_unique($result);
$result = array_diff($all_spec_key,$result);
$result = array_values($result);
unset($handle_arr);
unset($disable_arr);
unset($intersect_arr);
unset($all_spec_key);
unset($all_goods);
unset($goods_list);
unset($disable_goods);
return $result;
}
private function _handleSpec(&$result,$all_goods,$intersect,$disable_key){
$flag = 0;
$intersect = array_values($intersect);
array_push($intersect,$disable_key);
foreach($all_goods as $key => $goods_item){
if(count(array_intersect($intersect,$goods_item['spec_key'])) == count($intersect)){
$flag = 1;
if($goods_item['storage'] != 0){
$flag = 2;break;
}
}
}
//处理
if($flag == 1){
array_push($result,$disable_key);
}
}