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() {//生成keyvar 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() {//生成keyvar 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信息插入数据库

php 商品多规格的实现,sku实现相关推荐

  1. java 开发之商品规格属性(SKU)组合算法

    java 开发之商品规格属性(SKU)组合算法 开发背景 一般在开发商城的时候都会遇到商品规格组合的问题, 在这个开发过程中就需要一套算法用来组合多个规格属性,用来给每个组合定一组封面图和价格 比如某 ...

  2. 商品规格属性(SKU)组合算法

    借鉴java 开发之商品规格属性(SKU)组合算法_Runt02的博客-CSDN博客_java 商品属性 public List<LinkedHashMap<String, String& ...

  3. 【VK】商品多规格SKU选择器组件豪华版(uniapp版,可编译成H5、APP、各大小程序)

    插件名称:vk-data-goods-sku-popup 作者:VK [开箱即用]商品sku选择器组件豪华独立版 插件Q群:22466457 插件下载地址:点击下载SKU组件 体验地址 组件安装到自己 ...

  4. VUE类似淘宝选择商品多规格(库存判断)

    1.组件效果展示 也可访问链接查看网页效果... 后面又用uni-app写过一次,比这次稍微清晰一些 uni-app类似淘宝选择商品多规格(库存判断) 瞎封装组件系列: VUE简单提示框 VUE树形图 ...

  5. Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十(商品的规格类型以及参数管理)

    一.商品规格数据结构 商品中都有属性,不同商品,属性往往不同,这一部分数据很重要,我们一起来看看: 1.规格属性内容 (1) 我们看下京东中商品的规格属性︰ -款华为手机的属性: (2)横表和竖表 值 ...

  6. 商品尺码规格和颜色需要支持双引号

    商品尺码规格和颜色需要支持双引号 商品尺码规格和颜色既然要支持双引号,不得不佩服这个需求: 如果支持英文双引号 就会是  "color":""red" ...

  7. 淘宝精准库存接口获取商品ID下所有的sku精准库存

    根据淘宝商品id获取所有的sku精准库存,实时数据 {atype: "app",code: 0,data: {itemId: 614420893258,itemSkuList: [ ...

  8. 谷粒商城P85问题记录—发布商品时规格参数不显示-2022/4/8

    谷粒商城P85问题记录-发布商品时规格参数不显示 这一p有2个问题,折腾了很久 问题1 :数据库表中不存在 valueType这个键 但是接口文档里是需要提供这个键(而且是不能为null) 所以需要: ...

  9. mysql中设计suk表_电商项目-商品表(spu)、规格表(sku)设计

    之前在工作中,需要实现商品规格功能,做了很长一段时间,现在回过头来整理下设计思路. sku,spu概念: SPU = Standard Product Unit (标准化产品单元),SPU是商品信息聚 ...

最新文章

  1. CMRNet++:在激光雷达地图中与地图和相机无关的单目视觉定位
  2. unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线
  3. 开发日记-20190505 关键词 汇编语言(四) 自定义分级视图demo
  4. npm获取配置,设置代理
  5. oschina代码仓库远程push,pull免密实操总结
  6. sql语句的学习(2)
  7. 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 17—Large Scale Machine Learning 大规模机器学习...
  8. 陕西省铜川市计算机学校,铜川市计算机专业学校怎么样?好不好?
  9. python画画需要什么模块_python实战练手项目---使用turtle模块画奥运五环
  10. automake连载--Linux下使用autoconfig automake进阶
  11. 【UML】聊聊系统建模
  12. imb服务器怎么拆硬盘,IBM P750更换本地硬盘
  13. 隐藏通信隧道技术:内网穿透工具 nps
  14. win7磁盘清理_电脑磁盘已满怎么清理?磁盘清理的注意事项有哪些?
  15. word表格中多行只有一行字,让一行字居中的设置操作
  16. 抖音小程序Tiktok开发教程之 基础组件 01 text文本组件
  17. Proxmox VE 配置桌面虚拟化
  18. 星际争霸2:自由之翼 作弊秘籍
  19. 关闭vscode中的eslint语法检查
  20. PyTorch:torch.nonzero——非零元素的定位

热门文章

  1. c语言不能输出字符A的语句的是,以下不能输出字符a的语句是( )。
  2. 关于对皮亚诺公理的理解
  3. getchar()的作用
  4. DB2数据库基本概念
  5. 教学|3DSMAX制作爆炸粒子的技巧,游戏特效这么做
  6. usb设备检测linux,Linux下USB设备检测全教程(转)
  7. 2014年华为南研所校园招聘---机试+面试
  8. 961. 重复 N 次的元素
  9. 用委托实现信用卡还款
  10. Word文档中不显示图片(只有框)