kunlilove521 2022-04-27 23:49
浏览 130
已结题

PHP 商品详情页 sku多选规格时的算法,类似京东,点击任何规格,打开新的商品页

属性名表数据 attr:[id,attr_name]
1: 颜色
2: 尺码
3: 款式

属性值表数据 attr_values:[id, attr_id, attr_value]
1: 1: 红色
2: 1: 蓝色
3: 2: 41码
4: 2: 42码
5: 3: 欧版
6: 3: 美版

spu表 [spu_id, name]
1
sku表 [sku_id, spu_id, name ]
100 1 abc
101 1 xdxx
102 1 xdxdf
103 1 xdxx
104 1 xxgdx
105 1 xaxsafx
106 1 xsdxfx
107 1 xfdxsx

sku属性值关联表 sku_attr:[id, sku_id, attr_value_id]
1: 100: 1
2: 100: 3
3: 100: 5
4: 101: 1
5: 101: 3
6: 101: 6
7: 102: 1
8: 102: 4
9: 102: 5
10: 103: 1
11: 103: 4
12: 103: 6
13: 104: 2
14: 104: 3
15: 104: 5
16: 105: 2
17: 105: 3
18: 105: 6
19: 106: 2
20: 106: 4
21: 106: 5
22: 107: 2
23: 107: 4
24: 107: 6

sku集合 手写数据,非程序组装
sku_id:100 红色+41+欧版 1:3:5
sku_id:101 红色+41+美版 1:3:6
sku_id:102 红色+42+欧版 1:4:5
sku_id:103 红色+42+美版 1:4:6
sku_id:104 蓝色+41+欧版 2:3:5
sku_id:105 蓝色+42+欧版 2:4:5
sku_id:106 蓝色+41+美版 2:3:6
sku_id:107 蓝色+42+美版 2:4:6

商品详情选项:
颜色:红色 蓝色
尺码:41 42
款式:欧版 美版

第一种情况:
当打开sku 100 时,规格选项如下
颜色:红色(已选中) 蓝色(打开104)
尺码:41(已选中) 42(打开102)
款式:欧版(已选中) 美版(打开101)

第二种情况:
当打开sku 101 时,规格选项如下
颜色:红色(已选中) 蓝色(打开106)
尺码:41(已选中) 42(打开107)
款式:欧版(打开100) 美版(已选中)

请问实现这种效果,代码应该怎么写,脑袋有点大,头发都白了,最好是 PHP

  • 写回答

1条回答 默认 最新

  • kunlilove521 2022-05-03 21:42
    关注

    经过2天的研究,将上述代码改良后,终于实现想要的效果,附上代码,希望能帮到有需要的小伙伴:

    <?php
    $attr = [
        [
            'attr_id'        => 1,
            'attr_name'      => '颜色',
            'attr_values'     => [
                ['id' => 1, 'value' => '红色', 'checked' => 0, 'url' => ''],
                ['id' => 2, 'value' => '蓝色', 'checked' => 0, 'url' => ''],
            ]
        ],
        [
            'attr_id'        => 2,
            'attr_name'      => '尺码',
            'attr_values'     => [
                ['id' => 3, 'value' => 41, 'checked' => 0, 'url' => ''],
                ['id' => 4, 'value' => 42, 'checked' => 0, 'url' => ''],
                ['id' => 7, 'value' => 43, 'checked' => 0, 'url' => ''],
                ['id' => 8, 'value' => 44, 'checked' => 0, 'url' => ''],
            ]
        ],
        [
            'attr_id'        => 3,
            'attr_name'      => '款式',
            'attr_values'     => [
                ['id' => 5, 'value' => '欧版', 'checked' => 0, 'url' => ''],
                ['id' => 6, 'value' => '美版', 'checked' => 0, 'url' => ''],
            ]
        ],
        [
            'attr_id'        => 4,
            'attr_name'      => '年龄段',
            'attr_values'     => [
                ['id' => 9, 'value' => '0-10',   'checked' => 0, 'url' => ''],
                ['id' => 10, 'value' => '10-20', 'checked' => 0, 'url' => ''],
            ]
        ],
    ];
    
    $sku_id = 100;  //当前sku
    $curr_sku_attr = [   //当前sku的属性集合 排序后
        0 => '1:1', //红色
        1 => '2:3', //41
        2 => '3:5', //欧版
        3 => '4:9'
    ];
    $sku_list = [//spu下所有sku集合
        100 => ['1:1','2:3','3:5','4:9'],//红色 41 欧版 0-10
        101 => ['1:2','2:3','3:5','4:9'],//蓝色 41 欧版 0-10
        102 => ['1:1','2:4','3:5','4:9'],//红色 42 欧版 0-10
        103 => ['1:2','2:4','3:5','4:9'],//蓝色 42 欧版 0-10
        108 => ['1:1','2:7','3:5','4:9'],//红色 43 欧版 0-10
        109 => ['1:2','2:7','3:5','4:9'],//蓝色 43 欧版 0-10
        110 => ['1:1','2:8','3:5','4:9'],//红色 44 欧版 0-10
        111 => ['1:2','2:8','3:5','4:9'],//蓝色 44 欧版 0-10
        104 => ['1:1','2:3','3:6','4:9'],//红色 41 美版 0-10
        105 => ['1:2','2:3','3:6','4:9'],//蓝色 41 美版 0-10
        106 => ['1:1','2:4','3:6','4:9'],//红色 42 美版 0-10
        107 => ['1:2','2:4','3:6','4:9'],//蓝色 42 美版 0-10
        112 => ['1:1','2:7','3:6','4:9'],//红色 43 美版 0-10
        113 => ['1:2','2:7','3:6','4:9'],//蓝色 43 美版 0-10
        114 => ['1:1','2:8','3:6','4:9'],//红色 44 美版 0-10
        114 => ['1:2','2:8','3:6','4:9'],//蓝色 44 美版 0-10
        115 => ['1:1','2:3','3:5','4:10'],//红色 41 欧版 10-20
        116 => ['1:2','2:3','3:5','4:10'],//蓝色 41 欧版 10-20 
        117 => ['1:1','2:4','3:5','4:10'],//红色 42 欧版 10-20 
        118 => ['1:2','2:4','3:5','4:10'],//蓝色 42 欧版 10-20 
        119 => ['1:1','2:7','3:5','4:10'],//红色 43 欧版 10-20 
        120 => ['1:2','2:7','3:5','4:10'],//蓝色 43 欧版 10-20 
        121 => ['1:1','2:8','3:5','4:10'],//红色 44 欧版 10-20 
        122 => ['1:2','2:8','3:5','4:10'],//蓝色 44 欧版 10-20 
        123 => ['1:1','2:3','3:6','4:10'],//红色 41 美版 10-20 
        124 => ['1:2','2:3','3:6','4:10'],//蓝色 41 美版 10-20 
        125 => ['1:1','2:4','3:6','4:10'],//红色 42 美版 10-20 
        126 => ['1:2','2:4','3:6','4:10'],//蓝色 42 美版 10-20 
        127 => ['1:1','2:7','3:6','4:10'],//红色 43 美版 10-20 
        128 => ['1:2','2:7','3:6','4:10'],//蓝色 43 美版 10-20 
        129 => ['1:1','2:8','3:6','4:10'],//红色 44 美版 10-20 
        130 => ['1:2','2:8','3:6','4:10'],//蓝色 44 美版 10-20
    ];
    
    //剔除当前sku的第一个属性,用剩余属性对比所有sku列表,包含当前剩余属性的sku留下
    //[2:3],[3:5] 100,101
    foreach($curr_sku_attr as $key => $csa){
        $tmp_attrs = $curr_sku_attr;
        unset($tmp_attrs[$key]);//剔除当前属性,用其他剩余属性与sku集合中的所有属性做对比,
        foreach($sku_list as $sku_key => $sku_val){
            $tmp_arr = array_intersect($sku_val, $tmp_attrs);//剔除当前属性后的其他属性与sku属性做交集 
            $result = array_diff($tmp_attrs, $tmp_arr);//用差集函数对两个属性组做对比,完全一样,返回空,表示此sku可用
            if (empty($result)){
                unset($sku_list[$sku_key]);
            }
        }
    }
    //循环所有属性 与剩余sku的属性做对比,确定每个属性对应的sku
    foreach ($attr as &$att){
    //     //第一次循环时 1:1,1:2,哪个数据不在当前sku的属性集合中,谁就可以点击,然后再匹配对应的sku,绑定对应sku的url
        foreach ($att['attr_values'] as $atkey => &$atval){
            $at_str = $att['attr_id'].':'.$atval['id'];
            if (in_array($at_str, $curr_sku_attr)){
                $atval['checked'] = 1;
            }else{
                foreach($sku_list as $skukey => $skuval){
                    if (in_array($at_str, $skuval) !== false){
                        $atval['url'] = '/item/'.$skukey;
                    }
                }
            }
        }
    }
    print_r($attr);
    

    结果可以直接传给前端进行输出到页面,无需进行js处理,可以在上述基础上增加 库存字段,前端输出时,做一个库存字段判断,小于1时,不可点击即可
    输出结果如下:

    
    Array
    (
        [0] => Array
            (
                [attr_id] => 1
                [attr_name] => 颜色
                [attr_values] => Array
                    (
                        [0] => Array
                            (
                                [id] => 1
                                [value] => 红色
                                [checked] => 1
                                [url] => 
                            )
    
                        [1] => Array
                            (
                                [id] => 2
                                [value] => 蓝色
                                [checked] => 0
                                [url] => /item/130
                            )
    
                    )
    
            )
    
        [1] => Array
            (
                [attr_id] => 2
                [attr_name] => 尺码
                [attr_values] => Array
                    (
                        [0] => Array
                            (
                                [id] => 3
                                [value] => 41
                                [checked] => 1
                                [url] => 
                            )
    
                        [1] => Array
                            (
                                [id] => 4
                                [value] => 42
                                [checked] => 0
                                [url] => /item/126
                            )
    
                        [2] => Array
                            (
                                [id] => 7
                                [value] => 43
                                [checked] => 0
                                [url] => /item/128
                            )
    
                        [3] => Array
                            (
                                [id] => 8
                                [value] => 44
                                [checked] => 0
                                [url] => /item/130
                            )
    
                    )
    
            )
    
        [2] => Array
            (
                [attr_id] => 3
                [attr_name] => 款式
                [attr_values] => Array
                    (
                        [0] => Array
                            (
                                [id] => 5
                                [value] => 欧版
                                [checked] => 1
                                [url] => 
                            )
    
                        [1] => Array
                            (
                                [id] => 6
                                [value] => 美版
                                [checked] => 0
                                [url] => /item/130
                            )
    
                    )
    
            )
    
        [3] => Array
            (
                [attr_id] => 4
                [attr_name] => 年龄段
                [attr_values] => Array
                    (
                        [0] => Array
                            (
                                [id] => 9
                                [value] => 0-10
                                [checked] => 1
                                [url] => 
                            )
    
                        [1] => Array
                            (
                                [id] => 10
                                [value] => 10-20
                                [checked] => 0
                                [url] => /item/130
                            )
                    )
            )
    )
    
    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 5月3日
  • 赞助了问题酬金10元 4月28日
  • 创建了问题 4月27日

悬赏问题

  • ¥30 STM32 INMP441无法读取数据
  • ¥100 求汇川机器人IRCB300控制器和示教器同版本升级固件文件升级包
  • ¥15 用visualstudio2022创建vue项目后无法启动
  • ¥15 x趋于0时tanx-sinx极限可以拆开算吗
  • ¥500 把面具戴到人脸上,请大家贡献智慧
  • ¥15 任意一个散点图自己下载其js脚本文件并做成独立的案例页面,不要作在线的,要离线状态。
  • ¥15 各位 帮我看看如何写代码,打出来的图形要和如下图呈现的一样,急
  • ¥30 c#打开word开启修订并实时显示批注
  • ¥15 如何解决ldsc的这条报错/index error
  • ¥15 VS2022+WDK驱动开发环境