php 商品多规格的实现,sku实现

1 篇文章 0 订阅
1,规格名称表
CREATE TABLE `fa_item_attr_key` (
  `attr_key_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `item_id` int(10) unsigned DEFAULT '0',
  `attr_name` varchar(50) NOT NULL,
  PRIMARY KEY (`attr_key_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8

 2,规格属性表

CREATE TABLE `fa_item_attr_val` (
  `symbol` int(10) NOT NULL AUTO_INCREMENT,
  `attr_key_id` int(10) unsigned DEFAULT NULL,
  `item_id` int(10) unsigned DEFAULT '0',
  `attr_value` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`symbol`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
3,商品sku表

CREATE TABLE `fa_item_sku` (
  `sku_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `item_id` int(10) unsigned DEFAULT '0',
  `attr_symbol_path` varchar(255) NOT NULL,
  `price` double(15,2) NOT NULL DEFAULT '0.00' COMMENT '价格',
  `freight` double(15,2) DEFAULT '0.00' COMMENT '运费',
  `stock` int(10) unsigned NOT NULL DEFAULT '0',
  `original_price` double(15,2) DEFAULT NULL COMMENT '原始价格',
  PRIMARY KEY (`sku_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8




1,前端样式(参考资料:https://www.cnblogs.com/moumou0213/p/7233357.html    https://wenku.baidu.com/view/12fc20e10740be1e640e9ae5.html)



2,添加页代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
</head>
<body>
<div class="control-group">
    <label class="control-label"> </label>
    <div class="controls" >
        <button id="add_lv1" class="btn btn-primary" type="button">添加规格项</button>
        <button id="update_table" class="btn btn-success" type="button">生成规格项目表</button>
    </div>
</div>
<div>
    <button id="save_product" style="display: none;">保存商品</button>
</div>
<div id="lv_table_con" class="control-group" style="display: none;">
    <label class="control-label">规格项目表</label>
    <div class="controls">
        <div id="lv_table">

        </div>
    </div>

</div>
<script src="http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    var lv1HTML = '<div class="control-group lv1 item-attr">' +
            '<label class="control-label">规格名称</label>' +
            '<div class="controls">' +
            '<input type="text" name="lv1" placeholder="规格名称">' +
            '<button class="btn btn-primary add_lv2" type="button">添加参数</button>' +
            '<button class="btn btn-danger remove_lv1" type="button">删除规格</button>' +
            '</div>' +
            '<div class="controls lv2s"></div>' +
            '</div>';

    var lv2HTML = '<div style="margin-top: 5px;">' +
            '<input type="text" name="lv2" placeholder="参数名称">' +
            '<button class="btn btn-danger remove_lv2" type="button">删除参数</button>' +
            '</div>';

    $(document).ready(function() {
        $('#add_lv1').on('click', function() {
            var last = $('.control-group.lv1:last');
            if (!last || last.length == 0) {
                $(this).parents('.control-group').eq(0).after(lv1HTML);
            } else {
                last.after(lv1HTML);
            }
        });

        $(document).on('click', '.remove_lv1', function() {
            $(this).parents('.lv1').remove();
        });

        $(document).on('click', '.add_lv2', function() {
            $(this).parents('.lv1').find('.lv2s').append(lv2HTML);
        });

        $(document).on('click', '.remove_lv2', function() {
            $(this).parent().remove();
        });
        $(document).on('click', '#save_product', function () {

            var obj = {};
            var i = 0;
            var first = '';
            var tmp = {};
            $('#lv_table input').each(function (index, e) {
                var name = $(e).attr('name');
                var value = $(e).val();
                symbol = name.split('|')[0];
                key = name.split('|')[1];
                if (index == 0) {
                    first = symbol;
                    tmp = {symbol: symbol, item_id: 1};
                } else if (first != symbol) {
                    first = symbol;
                    i++;
                    tmp = {symbol: symbol, item_id: 1};
                }
                tmp[key] = value;
                obj[i] = tmp;

            });
            $.ajax({
                'url': '/api/test/test/save_sku',
                'method': 'post',
                'data': obj,
                'success': function (e) {

                }
            });
            console.log(obj);
        });


        $(document).on('click', '#save_attr', function() {
            save_attr();
        });
        $('#update_table').on('click', function() {
            save_attr();
//            update_table();
        });

        function update_table() {
            var lv1Arr = $('input[name="lv1"]');
            if (!lv1Arr || lv1Arr.length == 0) {
                $('#lv_table_con').hide();
                $('#lv_table').html('');
                return;
            }
            for (var i = 0; i < lv1Arr.length; i++) {
                var lv2Arr = $(lv1Arr[i]).parents('.lv1').find('input[name="lv2"]');
                if (!lv2Arr || lv2Arr.length == 0) {
                    alert('请先删除无参数的规格项!');
                    return;
                }
            }

            var tableHTML = '';
            tableHTML += '<table class="table table-bordered">';
            tableHTML += '    <thead>';
            tableHTML += '        <tr>';
            for (var i = 0; i < lv1Arr.length; i++) {
                tableHTML += '<th width="50">' + $(lv1Arr[i]).val() + '</th>';
            }
            tableHTML += '            <th width="20">现价</th>';
            tableHTML += '            <th width="20">原价</th>';
            tableHTML += '            <th width="20">库存</th>';
            tableHTML += '        </tr>';
            tableHTML += '    </thead>';
            tableHTML += '    <tbody>';

            var numsArr = new Array();
            var idxArr = new Array();
            for (var i = 0; i < lv1Arr.length; i++) {
                numsArr.push($(lv1Arr[i]).parents('.lv1').find('input[name="lv2"]').length);
                idxArr[i] = 0;
            }

            var len = 1;
            var rowsArr = new Array();
            for (var i = 0; i < numsArr.length; i++) {
                len = len * numsArr[i];

                var tmpnum = 1;
                for (var j = numsArr.length - 1; j > i; j--) {
                    tmpnum = tmpnum * numsArr[j];
                }
                rowsArr.push(tmpnum);
            }
            key='test';

            for (var i = 0; i < len; i++) {
                tableHTML += '        <tr data-row="' + (i+1) + '">';

                var name = '';
                var value = '';
                for (var j = 0; j < lv1Arr.length; j++) {
                    var n = parseInt(i / rowsArr[j]);
                    if (j == 0) {
                    } else if (j == lv1Arr.length - 1) {
                        n = idxArr[j];
                        if (idxArr[j] + 1 >= numsArr[j]) {
                            idxArr[j] = 0;
                        } else {
                            idxArr[j]++;
                        }
                    } else {
                        var m = parseInt(i / rowsArr[j]);
                        n = m % numsArr[j];
                    }

                    var text = $(lv1Arr[j]).parents('.lv1').find('input[name="lv2"]').eq(n).val();
                    var id = $(lv1Arr[j]).parents('.lv1').find('input[name="lv2"]').eq(n).attr('data-id');
                    if (j != lv1Arr.length - 1) {
                        value += id + ',';
                        name += text + ',';
                    } else {
                        name += text;
                        value += id;

                    }

                    if (i % rowsArr[j] == 0) {
                        tableHTML += '<td width="50" rowspan="' + rowsArr[j] + '" data-rc="' + (i+1) + ',' + (j+1) + '">' + text + '</td>';
                    }
//                    key=$(lv1Arr[j]).val();
//                    key=$(lv1Arr[j]).attr('data-id');
                }
                tableHTML += '<td width="20"><input type="text" name="'+ value + '|price" value="'+ '"/></td>';
                tableHTML += '<td width="20"><input type="text" name="' + value + '|original_price"  value="'+ '" /></td>';
                tableHTML += '<td width="20"><input type="text" name="' +  value + '|stock"  value="'+ '" /></td>';
                tableHTML += '</tr>';
            }
            tableHTML += '</tbody>';
            tableHTML += '</table>';

            $('#lv_table_con').show();
            $('#lv_table').html(tableHTML);

        }
        function save_attr() {
            //生成key
            var key=[];
            $('.item-attr input[name=lv1]').each(function (index,ele) {
                key.push($(ele).val());
            });
            //生成值
            var need=[];
            for ( j=0;j<key.length;j++){
                need[j]=[];
            }
            i=0;
            $('.item-attr input').each(function (index,ele) {
                if($(ele).attr('name')=='lv1' && index!=0){
                    i++;
                }else if(index!=0){
                    need[i].push($(ele).val());
                }
            });


            $.ajax({
                'url':'/api/test/test/save_attr',
                'method':'post',
                'data':{key:JSON.stringify(key),'value':JSON.stringify(need)},
                'sync':0,
                'success':function (e) {
                    key=e.data.key;
                    value=e.data.value;
                    create_attr_id(key,value);
                }
            });
        }

        function create_attr_id(key,value) {
            console.log(key,value);
            $('.item-attr input[name=lv1]').each(function (index,ele) {
              $(ele).attr('data-id',key[index]);
            });
            $('.item-attr input[name=lv2]').each(function (index,ele) {
               $(ele).attr('data-id',value[index]);
            });
            update_table();
            $('#save_product').show();
        }


    });
</script>
</body>
</html>
3,编辑页代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="http://cdn.bootcss.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
</head>
<body>
<div class="control-group">
    <label class="control-label"> </label>
    <div class="controls">
        <button id="add_lv1" class="btn btn-primary" type="button">添加规格项</button>
        <button id="update_table" class="btn btn-success" type="button">生成规格项目表</button>
    </div>
</div>
{foreach $itemAttr as $key=> $item}
<div class="control-group lv1 item-attr"><label class="control-label">规格名称</label>
    <div class="controls"><input type="text" name="lv1" data-id="{$item.attr_key_id}" value="{$item.attr_name}" placeholder="规格名称">
        <button class="btn btn-primary add_lv2" type="button">添加参数</button>
        <button class="btn btn-danger remove_lv1" type="button">删除规格</button>
    </div>
    <div class="controls lv2s">
        {foreach $item.itemattrval as $value}
        <div style="margin-top: 5px;"><input type="text" name="lv2" data-id="{$value.symbol}" value="{$value.attr_value}" placeholder="参数名称">
            <button class="btn btn-danger remove_lv2" type="button">删除参数</button>
        </div>
        {/foreach}
    </div>
</div>
{/foreach}


<div>
    <button id="save_product" style="display: none;">保存商品</button>
</div>
<div id="lv_table_con" class="control-group" style="display: none;">
    <label class="control-label">规格项目表</label>
    <div class="controls">
        <div id="lv_table">

        </div>
    </div>
</div>
<script src="http://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
    var lv1HTML = '<div class="control-group lv1 item-attr">' +
            '<label class="control-label">规格名称</label>' +
            '<div class="controls">' +
            '<input type="text" name="lv1" placeholder="规格名称">' +
            '<button class="btn btn-primary add_lv2" type="button">添加参数</button>' +
            '<button class="btn btn-danger remove_lv1" type="button">删除规格</button>' +
            '</div>' +
            '<div class="controls lv2s"></div>' +
            '</div>';

    var lv2HTML = '<div style="margin-top: 5px;">' +
            '<input type="text" name="lv2" placeholder="参数名称">' +
            '<button class="btn btn-danger remove_lv2" type="button">删除参数</button>' +
            '</div>';



    $(document).ready(function () {


        $('#add_lv1').on('click', function () {
            var last = $('.control-group.lv1:last');
            if (!last || last.length == 0) {
                $(this).parents('.control-group').eq(0).after(lv1HTML);
            } else {
                last.after(lv1HTML);
            }
        });

        $(document).on('click', '.remove_lv1', function () {
            $(this).parents('.lv1').remove();
        });

        $(document).on('click', '.add_lv2', function () {
            $(this).parents('.lv1').find('.lv2s').append(lv2HTML);
        });

        $(document).on('click', '.remove_lv2', function () {
            $(this).parent().remove();
        });
        $(document).on('click', '#save_product', function () {
            var obj = {};
            var i = 0;
            var first = '';
            var tmp = {};
            $('#lv_table input').each(function (index, e) {
                var name = $(e).attr('name');
                var value = $(e).val();
                symbol = name.split('|')[0];
                key = name.split('|')[1];
                if (index == 0) {
                    first = symbol;
                    tmp = {symbol: symbol, item_id: 1};
                } else if (first != symbol) {
                    first = symbol;
                    i++;
                    tmp = {symbol: symbol, item_id: 1};
                }
                tmp[key] = value;
                obj[i] = tmp;


            });
            $.ajax({
                'url': '/api/test/test/save_sku',
                'method': 'post',
                'data': obj,
                'success': function (e) {

                }
            });
            console.log(obj);
        });


        $('#update_table').on('click', function () {
            save_attr();

        });

        function save_attr() {
            //生成key
            var key = [];
            $('.item-attr input[name=lv1]').each(function (index, ele) {
                key.push($(ele).val());
            });
            //生成值
            var need = [];
            for (j = 0; j < key.length; j++) {
                need[j] = [];
            }
            i = 0;
            $('.item-attr input').each(function (index, ele) {
                if ($(ele).attr('name') == 'lv1' && index != 0) {
                    i++;
                } else if (index != 0) {
                    need[i].push($(ele).val());
                }
            });
            $.ajax({
                'url': '/api/test/test/save_attr',
                'method': 'post',
                'data': {key: JSON.stringify(key), 'value': JSON.stringify(need)},
                'sync': 0,
                'success': function (e) {
                    key = e.data.key;
                    value = e.data.value;
                    create_attr_id(key, value);
                }
            });
        }

        function create_attr_id(key,value) {
            console.log(key,value);
            $('.item-attr input[name=lv1]').each(function (index,ele) {
                $(ele).attr('data-id',key[index]);
            });
            $('.item-attr input[name=lv2]').each(function (index,ele) {
                $(ele).attr('data-id',value[index]);
            });
            update_table();
            $('#save_product').show();
        }

        function update_table() {
            var lv1Arr = $('input[name="lv1"]');
            if (!lv1Arr || lv1Arr.length == 0) {
                $('#lv_table_con').hide();
                $('#lv_table').html('');
                return;
            }
            for (var i = 0; i < lv1Arr.length; i++) {
                var lv2Arr = $(lv1Arr[i]).parents('.lv1').find('input[name="lv2"]');
                if (!lv2Arr || lv2Arr.length == 0) {
                    alert('请先删除无参数的规格项!');
                    return;
                }
            }

            var tableHTML = '';
            tableHTML += '<table class="table table-bordered">';
            tableHTML += '    <thead>';
            tableHTML += '        <tr>';
            for (var i = 0; i < lv1Arr.length; i++) {
                tableHTML += '<th width="50">' + $(lv1Arr[i]).val() + '</th>';
            }
            tableHTML += '            <th width="20">现价</th>';
            tableHTML += '            <th width="20">原价</th>';
            tableHTML += '            <th width="20">库存</th>';
            tableHTML += '        </tr>';
            tableHTML += '    </thead>';
            tableHTML += '    <tbody>';

            var numsArr = new Array();
            var idxArr = new Array();
            for (var i = 0; i < lv1Arr.length; i++) {
                numsArr.push($(lv1Arr[i]).parents('.lv1').find('input[name="lv2"]').length);
                idxArr[i] = 0;
            }

            var len = 1;
            var rowsArr = new Array();
            for (var i = 0; i < numsArr.length; i++) {
                len = len * numsArr[i];

                var tmpnum = 1;
                for (var j = numsArr.length - 1; j > i; j--) {
                    tmpnum = tmpnum * numsArr[j];
                }
                rowsArr.push(tmpnum);
            }
            key='test';

            for (var i = 0; i < len; i++) {
                tableHTML += '        <tr data-row="' + (i+1) + '">';

                var name = '';
                var value = '';
                for (var j = 0; j < lv1Arr.length; j++) {
                    var n = parseInt(i / rowsArr[j]);
                    if (j == 0) {
                    } else if (j == lv1Arr.length - 1) {
                        n = idxArr[j];
                        if (idxArr[j] + 1 >= numsArr[j]) {
                            idxArr[j] = 0;
                        } else {
                            idxArr[j]++;
                        }
                    } else {
                        var m = parseInt(i / rowsArr[j]);
                        n = m % numsArr[j];
                    }

                    var text = $(lv1Arr[j]).parents('.lv1').find('input[name="lv2"]').eq(n).val();
                    var id = $(lv1Arr[j]).parents('.lv1').find('input[name="lv2"]').eq(n).attr('data-id');
                    if (j != lv1Arr.length - 1) {
                        value += id + ',';
                        name += text + ',';
                    } else {
                        name += text;
                        value += id;

                    }

                    if (i % rowsArr[j] == 0) {
                        tableHTML += '<td width="50" rowspan="' + rowsArr[j] + '" data-rc="' + (i+1) + ',' + (j+1) + '">' + text + '</td>';
                    }
//                    key=$(lv1Arr[j]).val();
//                    key=$(lv1Arr[j]).attr('data-id');
                }
                tableHTML += '<td width="20"><input type="text" name="'+ value + '|price" value="'+ '"/></td>';
                tableHTML += '<td width="20"><input type="text" name="' + value + '|original_price"  value="'+ '" /></td>';
                tableHTML += '<td width="20"><input type="text" name="' +  value + '|stock"  value="'+ '" /></td>';
                tableHTML += '</tr>';
            }
            tableHTML += '</tbody>';
            tableHTML += '</table>';

            $('#lv_table_con').show();
            $('#lv_table').html(tableHTML);

        }
        function edit() {
            var attr=JSON.parse('{$itemSku}');
//            $('#update_table').trigger('click');
            update_table();
            $('#lv_table tbody tr').each(function (index,ele) {
               for (i=0;i<attr.length;i++){
                   if(index==i){
                       attr_symbol_path=attr[i].attr_symbol_path;
                       $(ele).find('input[name="'+attr_symbol_path+'|price"]').val(attr[i].price);
                       $(ele).find('input[name="'+attr_symbol_path+'|original_price"]').val(attr[i].original_price);
                       $(ele).find('input[name="'+attr_symbol_path+'|stock"]').val(attr[i].stock);
                   }
               }
            });
        }
        edit();
    });
</script>
</body>
</html>
4,后台代码
首页 ,编辑页
public function index(){

        return $this->view->fetch();
    }


    public function edit(){
        $item_id=1;
        $data=ItemAttrKey::where(['item_id'=>$item_id])->with(['itemattrval'])->select();
        $need=[];
        foreach ($data as $item) {
            $need[]=$item->toArray();
        }

        $sku=ItemSku::where(['item_id'=>$item_id])->select();
        $skus=[];
        foreach ($sku as $item) {
            $skus[]=$item->toarray();
        }

        $this->view->assign('itemAttr',$need);
        $this->view->assign('itemSku',json_encode($skus,320));
        return $this->view->fetch();
    }
5,api接口

   public function save_sku(){
        if(request()->isPost()){
            $data=request()->post();
            $bool=ItemSku::where(['item_id'=>$data[0]['item_id']])->delete();
            console($bool);

            foreach ($data as $item) {
                $sku=new ItemSku();
                $sku->item_id=$item['item_id'];
                $sku->original_price=$item['original_price'];
                $sku->price=$item['price'];
                $sku->stock=$item['stock'];
                $sku->attr_symbol_path=$item['symbol'];
                $sku->save();
            }

        }

    }

    public function save_attr()
    {
        if(request()->isPost()){
            $data=request()->post();
            $key=json_decode($data['key'],true);
            $value=json_decode($data['value'],true);
            $item_id=1;
            $key_id=[];
            ItemAttrKey::where(['item_id'=>$item_id])->delete();
            foreach ($key as $k) {
                $attr_key=ItemAttrKey::where(['attr_name'=>$k,'item_id'=>$item_id])->find();
                if(!$attr_key){
                    $attr_key=new ItemAttrKey();
                    $attr_key->attr_name=$k;
                    $attr_key->item_id=$item_id;
                    $attr_key->save();
                }
                $key_id[]=$attr_key->attr_key_id;
            }
            $tm_v_in=[];
            $tm_v=[];
            ItemAttrVal::where(['item_id'=>$item_id])->delete();
            foreach ($value as $key=>$v){
                $attr_key_id=$key_id[$key];
                foreach ($v as $v1){
                    $attr_value=ItemAttrVal::where(['attr_value'=>$v1,'attr_key_id'=>$attr_key_id])->find();
                    if(!$attr_value){
                        $attr_value=new ItemAttrVal();
                        $attr_value->attr_key_id=$attr_key_id;
                        $attr_value->attr_value=$v1;
                        $attr_value->item_id=$item_id;
                        $attr_value->save();
                    }
                    $tm_v[]=$attr_value->symbol;

                }
//                $tm_v[]=$tm_v_in;
            }

            $this->success('请求成功',['key'=>$key_id,'value'=>$tm_v]);

        }

        $this->success('请求成功');
    }
6,使用方法:
1,点击生成规格选项,首先调用后台,保存规格属性接口
2,点击保存商品,会将sku信息插入数据库













  • 5
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值