目录

1.功能介绍:

2.核心功能实现:


1.功能介绍:

当我们进入商品详情页面时

①、商品的规格选项栏,规格选项栏目展示(可选择———部分展示,即已有规格选项

默认展示基础价格商品,基础价格=商品默认价格+规格价格(前提:不同规格价格不同

②、选择不同规格的组合,展示对应的商品价格

2.核心功能实现:

第一部分:

sql语句逻辑操作实现

-- 查询sku对应的规格以及规格中的规格选项
SELECThg_spec.*,hg_spec_option.id  spec_option_id,hg_spec_option.option_name,hg_spec_option.orders
FROM hg_specLEFT JOIN hg_spec_optionON hg_spec.id = hg_spec_option.spec_id
WHERE hg_spec.id IN(SELECT DISTINCT(spec_id)FROM hg_sku_specWHERE sku_id = 3);

左外连接查询规格表hg_spec,规格选项中间表hg_spec_option中 相应参数,使用in关键字操作(根据商品规格中间表hg_sku_spec查询该商品的所有规格参数

做题思路:为了效果展示明确,可以三表连查获取商品规格的明确信息,也就是对应的id值,同时根据商品的skuId来查询相应的商品规格,但是商品对应多个规格值,所以要子查询出该商品的多个规格的id,利用in关键字查询出当前商品的正确规格

java代码实现(后台操作)

xml文件

 <!-- 实体类与数据库映射 --><resultMap type="Specs" id="specsMap" autoMapping="true"><id column="id" property="id" /><collection property="specOptions" ofType="SpecOptions"column="id" select="selectSpecOptionsBySpecId"></collection></resultMap><!-- 查询sku拥有的spec规格 --><select id="selectBySkuId" resultType="Integer">SELECT DISTINCT(spec_id)FROM hg_sku_spec WHERE sku_id=#{value}</select><!-- 根据规格ids查询 规格下的规格选项 --><select id="selectByIds" resultMap="specsMap">SELECT * FROM hg_spec WHERE id IN<foreach collection="list" open="(" close=")" separator="," item="id">#{id}</foreach></select>

service实现类调用

   /*** 根据skuId查询当前商品的规格*/@Overridepublic List<Specs> selectBySkuId(Integer skuId) {List<Integer> specIds = specMapper.selectBySkuId(skuId);if (specIds != null && specIds.size() > 0) {return specMapper.selectByIds(specIds);}return null;}

controller层

// 查询当前商品拥有的规格
List<Specs> specList = specsService.selectBySkuId(skuId);

根据前端页面传递的skuId,查询商品拥有的规格

第二部分:

功能体现:默认展示基础规格商品信息,选择不同的规格组合,可查询对应的价格

xml文件

   <resultMap type="SpecVo" id="specVoMap"><id column="spec_id" property="specId"/><result column="spec_option_id" property="specOptionId"/><result column="orders" property="orders"/></resultMap><!-- 展示默认商品 --><select id="selectBySkuId" resultMap="specVoMap">SELECT *FROM (SELECThg_sku_spec.spec_id,hg_sku_spec.spec_option_id,hg_spec_option.ordersFROM hg_skuLEFT JOIN hg_sku_specON hg_sku.id = hg_sku_spec.sku_idLEFT JOIN hg_specON hg_sku_spec.spec_id = hg_spec.idLEFT JOIN hg_spec_optionON hg_sku_spec.spec_option_id = hg_spec_option.idWHERE sku_id = 3ORDER BY hg_spec.id, hg_spec_option.orders ASC) tmp<!-- flag状态为真,则选择默认商品 --><if test="flag">GROUP BY spec_id</if>      </select>

service实现类调用

    /*** 根据商品skuId,状态值flag 查询*/@Overridepublic List<SpecVo> selectSpecVoBySkuId(Integer skuId, boolean flag) {return specVoMapper.selectBySkuId(skuId, flag);}

可以大胆设计方法参数,传递一个flag状态值,如果为ture,代表我们查询的是默认值;如果为false,则代表查询当前商品的规格

controller层

// 默认选项List<SpecVo> specVos = null;if (specId == 0) {//查询默认商品specVos = specsService.selectSpecVoBySkuId(skuId, true);//第一种方式
//          BigDecimal sum = new BigDecimal(0);
//          for (SpecVo specVo : specVos) {
//              sum = sum.add(specVo.getOrders());
//          }
//          sum = sum.add(skus.getPrice());
//          skus.setPrice(sum);//第二种方式 lamda表达式List<BigDecimal> stockList = new ArrayList<BigDecimal>();for (SpecVo sv : specVos) {stockList.add(sv.getOrders());}BigDecimal stockAmt = stockList.stream().reduce(BigDecimal::add).orElse(BigDecimal.ZERO);计算价格skus.setPrice(skus.getPrice().add(stockAmt));}else {//查询默认商品specVos = specsService.selectSpecVoBySkuId(skuId, true);//设置初始值BigDecimal sum = new BigDecimal(0);for (SpecVo specVo : specVos) {//如果是同一种规格类型if(specVo.getSpecId()==specId) {//如果规格选项不同if(specVo.getSpecOptionId()!=specOptionId) {//修改规格选项对应的optionIdspecVo.setSpecOptionId(specOptionId);//查询是否存在这种规格的商品SpecVo vo = specsService.selectBySkuIdAndSpecIdAndOptionId(skuId, specId, specOptionId);if(vo!=null) {specVo.setOrders(vo.getOrders());//为商品重新赋值}else {//重新查询规格选项SpecOptions specOption = specsService.findSkuOption(specOptionId);specVo.setOrders(specOption.getOrders());flag=true;//状态为true 代表商品查找不到 即商品没有货}}}//计算价格sum = sum.add(specVo.getOrders());}sum = sum.add(skus.getPrice());skus.setPrice(sum);}

这块代码不能完全实现多个规格组合的操作,有一个bug,只能更改一个规格,其余规格都是默认值

所以,以下是更新后的代码:

思路:利用ajax发送规格id和规格选项id拼接的String类型的数组,在controller层获取相应的id组合值,设置一个新的规格集合,根据规格id组合值重新查询商品,当做默认商品使用,可以修复这个bug

但是当该商品不存在时,回显的数据会丢失,所以要获取当前商品已有的规格来修改,最终可以实现多规格点击的效果

核心代码 如下

            //先查询是否存在该规格商品 如果存在 则根据所传规格选项设为默认商品//如果不存在 则直接设为无货状态 但是数据会丢失 所以要获取一个同类的规格进行修改specVos = new ArrayList<SpecVo>();Integer specOptionId = null;for (int i = 0; i < strs.length; i++) {String[] split = strs[i].split(",");for (int j = 0; j < split.length; j++) {System.out.println("规格组合:"+split[j]);String[] split2 = split[j].split("@");specId = Integer.valueOf(split2[0]);//规格specIdspecOptionId = Integer.valueOf(split2[1]);//规格选项specOptionId//根据不同规格组合查询商品SpecVo vo = specsService.selectBySkuIdAndSpecIdAndOptionId(skuId, specId, specOptionId);if(vo==null) {//为回显效果单独设置一个规格List<SpecVo> list = specsService.selectSpecVoBySkuId(skuId, false);for (SpecVo specVo : list) {if(specVo.getSpecId()==specId) {specVo.setSpecOptionId(specOptionId);//修改规格选项OptionIdspecVo.setOrders(specsService.findSkuOption(specOptionId).getOrders());//根据规格选项设置增加金额System.out.println("----------------"+specVo+"---------------");specVos.add(specVo);flag = true;break;//结束外层循环}}}else {specVos.add(vo);}}}//计算价格BigDecimal sum = new BigDecimal(0);for (SpecVo specVo : specVos) {System.out.println("新建规格"+specVo);sum = sum.add(specVo.getOrders());}sum = sum.add(skus.getPrice());System.out.println("计算后价格:"+sum);skus.setPrice(sum);

 前段js 代码

<li class="sku-line ${flag?'selected':'' }" onclick="goodsDetail(${spec.id},${option.id})"><input type="hidden" class="specOptions ${flag?'selected':''}" value="${spec.id}@${option.id}">
<i></i>${option.optionName}</li>
             //获取被选中的规格id+规格选项id 拼接字符串 传递到webfunction goodsDetail(specId,optionId){var strs = $(".specOptions.selected").map(function(){specid =  this.value.split("@");if(specId==specid[0]){return specId+'@'+optionId;}else{return this.value;}}).get().join(",");var skuId = $("#skuId").val();location.href="${pageContext.request.contextPath}/goodsDetail?skuId="+skuId+"&specId="+specId+"&strs="+strs;}

以上是bug修复代码

前段操作实现原理:

场景一:默认传一个specId,设置为0,代表查询默认商品(即基础价格商品),采用BidDecimal类自带方法计算(和Double类型有区别),计算出价格,存入model域中,在前段页面展示

可参考lamda 表达式对BigDecimal类型数据操作

使用lamda表达式对list进行求和_yuanwxcsdn的博客-CSDN博客_lambda表达式求和

Java8新特性学习-Stream的Reduce及Collect方法详解_icarusliu的专栏-CSDN博客

lambda中orElse(null)使用_小泽-CSDN博客

场景二:每次更改规格时,只会改变一个规格选项,原选中规格不变,只把规格选项id值改变(规格选项specOptionId循环内部更改),规格specId不用改变,再根据不同规格组合计算出价格,存入model域,在前段页面展示

特殊情况:但是,规格如果是全展示,有可能出现规格组合不存在情况,要判断该组合是否存在,并根据组合重新修改金额

情况一:数据库不存在该组合,即设为无货状态,flag值为false

情况二:商品库存为空,也是无货状态

无货状态,可以不展示库存量和购物车选项,展示为无货(红色)即可

js前段回显操作(复习复选框回显)

<c:forEach items="${spec.specOptions}" var="option" varStatus="status"><c:set var="flag" value="false"></c:set><c:forEach var="specVo" items="${specVos}"><c:if test="${spec.id==specVo.specId && option.id==specVo.specOptionId}"><c:set var="flag" value="true" /></c:if></c:forEach><a href="${pageContext.request.contextPath}/goodsDetail?skuId=${skus.id}&specId=${spec.id}&specOptionId=${option.id}">
<li  class="sku-line ${flag?'selected':'' }">${option.optionName}<i></i></li>
</a>
</c:forEach>

这是本人的第一篇博客文章,语言不太成熟,希望多多提出意见,我会虚心接受的。

电商项目--------------------商品(SKU)规格、价格功能相关推荐

  1. 电商项目—商品的spu、sku概念及其之间的关系

    电商项目-商品的spu.sku概念及其之间的关系 电商项目中涉及到商品时必然会遇到的几个概念,SPU.SKU.单品等.彻底搞懂和明白了这几个概念对我们设计商品表是十分必要的前提条件. SPU:标准化产 ...

  2. 电商项目——商品服务-API-属性分组——第十一章——上篇

    电商项目--初识电商--第一章--上篇 电商项目--分布式基础概念和电商项目微服务架构图,划分图的详解--第二章--上篇 电商项目--电商项目的虚拟机环境搭建_VirtualBox,Vagrant-- ...

  3. 微信小程序电商项目商品详情页开发实战之数据绑定与事件应用

    各位CSDN的朋友,我们都知道,现在微信小程序电商平台特别火爆,所以我将以一个生鲜电商项目为例,为大家讲述微信小程序的实战化开发,价值几万元的成熟项目,你可千万不要错过哦. 大家直接通过视频链接直接看 ...

  4. 商品sku算法php,笛卡尔乘积-电商网站商品sku组合算法应用

    笛卡尔乘积是指在数学中,两个集合X和Y的笛卡尓积(Cartesian product),又称直积,表示为X × Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员. 利用笛卡尔乘积 ...

  5. 电商项目(一)---------Sku和Spu以及电商项目商品的设计思路

    一,在电商项目里面为了准确的描述商品的区别,我们抽象出来两个概念,Spu和Sku这两个概念. Spu(标准产品单位 ):一组具有共同属性的商品集 Sku(库存量单位):SPU商品集因具体特性不同而细分 ...

  6. 电商项目——商品规格管理

    商品规格管理 商品规格数据结构 淘淘商城是一个全品类的电商网站,因此商品的种类繁多,每一件商品,其属性又有差别.为了更准确描述商品及细分差别,抽象出两个概念:SPU和SKU SPU和SKU SPU:S ...

  7. 【愚公系列】2022年10月 微信小程序-电商项目-商品购物车功能实现

    文章目录 前言 一.商品购物车功能实现 二.效果 前言 在电商的核心交易流程中,购物车是其中非常重要的一环,它承担商品加购.价格计算.促销活动展示等功能,与会员系统.商品系统.库存系统.订单系统等紧密 ...

  8. 【愚公系列】2022年10月 微信小程序-电商项目-商品详情页面规格选择功能实现

    文章目录 前言 一.商品详情页面规格选择功能实现 二.效果 前言 vant-weapp的Popup 弹出层api Props 参数 说明 类型 默认值 show 是否显示弹出层 boolean fal ...

  9. 电商项目商品详情页架构设计

    当用户进入京东首页,点击搜索手机进入搜索页面,点击一款手机进入商品详情页面,主要展示商品的信息,主要分为三块信息: 1:基本信息:展示商品的基本信息,包括sku价格等基本信息. 2:商品描述(商品详情 ...

最新文章

  1. sencha touch 模仿tabpanel导航栏TabBar(2013-11-7)
  2. lombok null字段不显示 继承_Lombok 要知道的 8 个点
  3. 学习笔记-第四周-心得体会
  4. jpannel设置位置xy_实用的摄影技巧!10种常见摄影场景的单反相机设置技巧!
  5. Xformode的坑
  6. Java项目——个人博客系统
  7. Hadoop原理——HDFS原理
  8. 高数下学习笔记——思维导图
  9. 黑马java架构师课_【黑马精品】Java架构师实战训练营
  10. 笔记本电脑插入耳机仍然外放(亲测有效)
  11. Java中使用isAlphabetic()办法无法解决判断一个char是英文字母,该用别的方法解决
  12. random.sample函数
  13. 《周一清晨的领导课》--司机与乘客 - [读书笔记]
  14. win10下装mysql-5.7.18-winx64
  15. 扩展名是.class.php,php 获取文件扩展名的函数 - strtolower
  16. 计算机开机慢的原因及解决方法,电脑开机速度慢怎么解决?Win10电脑开机速度变慢的原因及解决方法(2)...
  17. 弘辽科技:美团和阿里的恩爱情仇
  18. 求过圆心直线与圆的两个交点
  19. matlab函数equalize
  20. 打造跳跃音波播音乐放器(Electron+Nodejs+React)

热门文章

  1. python 正则表达式生成_python正则表达式
  2. 鲍姆-韦尔奇算法求解HMM参数
  3. python 如何绘制ppt折线图
  4. 机器人末端力/力矩控制实用简述——以Franka机器人为例
  5. win10任务栏透明_干货分享丨让你的win10桌面既整洁又美观
  6. android service是什么,Android service是什么 Android service详解
  7. 以太坊系列---ipc实现方式---管道通信库npipe
  8. B站课程排行榜,这届大学生最爱学什么
  9. 小D课堂 - 新版本微服务springcloud+Docker教程_汇总
  10. 户外测量工具“Moasure魔尺”登录国内,一款神奇的测量工具