043 商品详情
文章目录
- 详情页数据
- 表结构
- vo
- SkuItemVo.java
- SkuItemSaleAttrVo.java
- AttrValueAndSkuIdVo.java
- SpuAttrGroupVo.java
- GroupAttrParamVo.java
- pom.xml
- SkuSaleAttrValueDao.xml
- SkuSaleAttrValueDao.java
- AttrGroupDao.xml
- AttrGroupServiceImpl.java
- SkuInfoServiceImpl.java
- SkuSaleAttrValueServiceImpl.java
- AttrGroupDao.java
- SkuSaleAttrValueDao.java
- SkuItemController.java
- 默认
- 点击选中
详情页数据
1.sku基本信息
2.sku图片信息(多个图片)
3.spu的销售属性
4.spu的描述信息
5.sku分组规格参数属性值
表结构
vo
SkuItemVo.java
package com.xd.cubemall.product.vo;import com.xd.cubemall.product.entity.SkuImagesEntity;
import com.xd.cubemall.product.entity.SkuInfoEntity;
import com.xd.cubemall.product.entity.SpuInfoDescEntity;
import lombok.Data;
import lombok.ToString;import java.util.List;@ToString
@Data
public class SkuItemVo {//1.sku基本信息private SkuInfoEntity info;//2.sku图片信息private List<SkuImagesEntity> images;//3.spu的销售属性组合private List<SkuItemSaleAttrVo> attrSales;//4.spu描述信息private SpuInfoDescEntity desc;//5.spu分组(主体,基本信息...)规格属性private List<SpuAttrGroupVo> attrGroups;}
SkuItemSaleAttrVo.java
package com.xd.cubemall.product.vo;import lombok.Data;
import lombok.ToString;import java.util.List;@ToString
@Data
public class SkuItemSaleAttrVo {private Long attrId;private String attrName;//属性值private List<AttrValueAndSkuIdVo> attrValues;}
AttrValueAndSkuIdVo.java
package com.xd.cubemall.product.vo;import lombok.Data;
import lombok.ToString;@ToString
@Data
public class AttrValueAndSkuIdVo {// skuids组合idprivate String skuIds;// 属性值: 白色,128Gprivate String attrValue;
}
SpuAttrGroupVo.java
package com.xd.cubemall.product.vo;import lombok.Data;
import lombok.ToString;import java.util.List;@ToString
@Data
public class SpuAttrGroupVo {private String groupName;// 属性参数private List<Attr> attrs;
}
GroupAttrParamVo.java
package com.xd.cubemall.product.vo;import lombok.Data;
import lombok.ToString;@ToString
@Data
public class GroupAttrParamVo {private Long spuId;private Long categoryId;
}
pom.xml
<!--添加模板技术渲染页面--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency>
在MySQL中,当启用了ONLY_FULL_GROUP_BY SQL模式时,如果一个SELECT查询包含聚合函数(如GROUP_CONCAT),那么所有非聚合的列都必须在GROUP BY子句中明确指定。这是因为ONLY_FULL_GROUP_BY模式要求所有的结果列要么是通过聚合函数处理的,要么是在GROUP BY子句中明确指定的。
从错误信息来看,查询试图在不使用GROUP BY子句的情况下选择非聚合列v.attr_id、v.attr_name和v.attr_value,同时还使用了聚合函数GROUP_CONCAT(v.sku_id)。这违反了ONLY_FULL_GROUP_BY的规则。
为了解决这个问题,需要修改查询,添加一个GROUP BY子句,包含所有非聚合的列。这样,每个组都会有唯一的attr_id、attr_name和attr_value,而GROUP_CONCAT则会将同一组内的sku_id连接起来。
SkuSaleAttrValueDao.xml
<resultMap id="spuSaleAttrMap" type="com.xd.cubemall.product.vo.SkuItemSaleAttrVo"><result property="attrId" column="attr_id"></result><result property="attrName" column="attr_name"></result><collection property="attrValues" ofType="com.xd.cubemall.product.vo.AttrValueAndSkuIdVo"><result property="skuIds" column="skuIds"></result><result property="attrValue" column="attr_value"></result></collection></resultMap><!--sql: tb_sku_info,tb_sku_sale_attr_value--><select id="getSaleAttrs" resultMap="spuSaleAttrMap" parameterType="java.lang.Long">SELECTv.attr_id,v.attr_name,v.attr_value,GROUP_CONCAT( v.sku_id ) AS skuIdsFROMtb_sku_info iLEFT JOIN tb_sku_sale_attr_value v ON i.id = v.sku_idWHEREspu_id = #{spuId}GROUP BYv.attr_id,v.attr_name,v.attr_value;</select>
SkuSaleAttrValueDao.java
package com.xd.cubemall.product.dao;import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xd.cubemall.product.vo.SkuItemSaleAttrVo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** sku销售属性值* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Mapper
public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> {public List<SkuItemSaleAttrVo> getSaleAttrs(Long spuId);
}
AttrGroupDao.xml
<resultMap id="spuAttrGroupMap" type="com.xd.cubemall.product.vo.SpuAttrGroupVo"><result property="groupName" column="groupName"></result><collection property="attrs" ofType="com.xd.cubemall.product.vo.Attr"><result property="attrName" column="attrName"></result><result property="attrValue" column="attrValue"></result></collection></resultMap><!--SQL: 根据spuID,categoryId 查询 sku分组规格参数属性值--><select id="getGroupAttr" resultMap="spuAttrGroupMap" parameterType="com.xd.cubemall.product.vo.GroupAttrParamVo">SELECTg.NAME AS groupName,v.attr_name AS attrName,v.attr_value AS attrValueFROMtb_product_attr_value vJOIN tb_attr_attrgroup_relation r ON v.attr_id = r.attr_idJOIN tb_attr_group g ON r.attr_group_id = g.idWHEREspu_id = #{spuId}AND g.category_id = #{categoryId}</select>
AttrGroupServiceImpl.java
//根据spuID,categoryId 查询 sku分组规格参数属性值@Overridepublic List<SpuAttrGroupVo> getGroupAttr(Long spuId, Long categoryId) {GroupAttrParamVo paramVo = new GroupAttrParamVo();paramVo.setSpuId(spuId);paramVo.setCategoryId(categoryId);List<SpuAttrGroupVo> attrGroupVos = this.baseMapper.getGroupAttr(paramVo);return attrGroupVos;}
SkuInfoServiceImpl.java
@Autowiredprivate SkuImagesService skuImagesService;//注入销售属性组合服务@Autowiredprivate SkuSaleAttrValueService skuSaleAttrValueService;//注入spu描述服务@Autowiredprivate SpuInfoDescService spuInfoDescService;@Autowiredprivate AttrGroupService attrGroupService;@Overridepublic SkuItemVo skuItem(Long skuId) {// 新建一个包装类对象SkuItemVo itemVo = new SkuItemVo();/*1.sku基本信息2.sku图片信息(多个图片)3.spu的销售属性4.spu的描述信息5.sku分组规格参数属性值*/// 1.根据skuId 查询 sku基本信息SkuInfoEntity skuInfoEntity = this.getById(skuId);itemVo.setInfo(skuInfoEntity);// 获取sku与之对应的spuIdLong spuId = skuInfoEntity.getSpuId();// 获取分类idLong categoryId = skuInfoEntity.getCategoryId();// 2.根据skuId查询sku图片信息(多个图片),skuId是外键List<SkuImagesEntity> imageList = skuImagesService.list(new QueryWrapper<SkuImagesEntity>().eq("sku_id", skuId));itemVo.setImages(imageList);//3.根据spuID获取spu的销售属性List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrs(spuId);itemVo.setAttrSales(saleAttrVos);//4.根据spuId查询spu的描述信息SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getOne(new QueryWrapper<SpuInfoDescEntity>().eq("spu_id",spuId));itemVo.setDesc(spuInfoDescEntity);//5.根据spuID,categoryId查询 sku分组规格参数属性值List<SpuAttrGroupVo> attrGroupVos = attrGroupService.getGroupAttr(spuId,categoryId);itemVo.setAttrGroups(attrGroupVos);return itemVo;}
SkuSaleAttrValueServiceImpl.java
/*** 根据id查询销售属性组合* @param spuId* @return*/@Overridepublic List<SkuItemSaleAttrVo> getSaleAttrs(Long spuId) {//List<SkuItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrs(spuId);List<SkuItemSaleAttrVo> saleAttrVos = this.baseMapper.getSaleAttrs(spuId);return saleAttrVos;}
AttrGroupDao.java
package com.xd.cubemall.product.dao;import com.xd.cubemall.product.entity.AttrGroupEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xd.cubemall.product.vo.GroupAttrParamVo;
import com.xd.cubemall.product.vo.SpuAttrGroupVo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** 属性分组表* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Mapper
public interface AttrGroupDao extends BaseMapper<AttrGroupEntity> {//根据spuID,categoryId 查询 sku分组规格参数属性值public List<SpuAttrGroupVo> getGroupAttr(GroupAttrParamVo paramVo);
}
SkuSaleAttrValueDao.java
package com.xd.cubemall.product.dao;import com.xd.cubemall.product.entity.SkuSaleAttrValueEntity;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xd.cubemall.product.vo.SkuItemSaleAttrVo;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** sku销售属性值* * @author xuedong* @email email@gmail.com* @date 2024-08-13 01:36:04*/
@Mapper
public interface SkuSaleAttrValueDao extends BaseMapper<SkuSaleAttrValueEntity> {public List<SkuItemSaleAttrVo> getSaleAttrs(Long spuId);
}
SkuItemController.java
package com.xd.cubemall.product.web;import com.xd.cubemall.product.service.SkuInfoService;
import com.xd.cubemall.product.vo.SkuItemVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@Controller
public class SkuItemController {@Autowiredprivate SkuInfoService skuInfoService;/*** 根据skuId查询商品详情信息*/@GetMapping("/{skuId}.html")public String skuItem(@PathVariable Long skuId, Model model){// 调用服务层商品详情接口SkuItemVo itemVo = skuInfoService.skuItem(skuId);// 输出日志log.info("商品详情接口,查询的数据:{}",itemVo);// 把数据放入模型驱动model.addAttribute("item",itemVo);// 返回视图页面,做视图数据渲染return "item";}
}
默认
<a href="javascript:;" th:attr="class=${#lists.contains(#strings.listSplit(attrvalues.skuIds,','),item.info.id.toString())?'sku_attr_value selected':'sku_attr_value'},skus=${attrvalues.skuIds}"><!--th:v-bind:class="|{selected:sel('${spec.key}','${arrValue}')}|"-->
<!-- th:@click="|selectSpecification('${spec.key}','${arrValue}')|" >-->
<!-- <i th:text="${arrValue}"></i>-->[[${attrvalues.attrValue}]]<span title="点击取消选择"> </span></a>
点击选中
$(".sku_attr_value").click(function () {// 移除选中状态$(this).parent().parent().find(".sku_attr_value").removeClass("selected");// 给点击元素添加选中状态属性$(this).addClass("selected");let skus = new Array();//选择不同的规格属性后,根据不同的属性id重新加载相应的数据$("a[class='sku_attr_value selected']").each(function () {skus.push($(this).attr("skus").split(","));})// 获取第0个元素let sku_1 = skus[0];// 白色: skuIds = {1,3}// 128GB : skuIds = {3,9}// 白色+128GB 规则属性组合的id : 求交集 ,skuId = 3for(let i=1;i<skus.length;i++){// 遍历每一个属性的skuids,获取交集// 比如:白色: skuIds = {1,3},128GB : skuIds = {3,9} ,此时: {1,3}.filter({3,9}) = 3sku_1 = $(sku_1).filter(skus[i])[0];}// 拼接请求location.href = "http://localhost:8081/"+sku_1+".html";})
相关文章:

043 商品详情
文章目录 详情页数据表结构voSkuItemVo.javaSkuItemSaleAttrVo.javaAttrValueAndSkuIdVo.javaSpuAttrGroupVo.javaGroupAttrParamVo.java pom.xmlSkuSaleAttrValueDao.xmlSkuSaleAttrValueDao.javaAttrGroupDao.xmlAttrGroupServiceImpl.javaSkuInfoServiceImpl.javaSkuSaleAtt…...
【人工智能】Python与Scikit-learn的模型选择与调参:用GridSearchCV和RandomizedSearchCV提升模型性能
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在机器学习建模过程中,模型的表现往往取决于参数的选择与优化。Scikit-learn提供了便捷的工具GridSearchCV和RandomizedSearchCV,帮助我们在参数空间中搜索最佳组合以提升模型表现。本文将从理论和实践两个角度…...

深入探讨 Puppeteer 如何使用 X 和 Y 坐标实现鼠标移动
背景介绍 现代爬虫技术中,模拟人类行为已成为绕过反爬虫系统的关键策略之一。无论是模拟用户点击、滚动,还是鼠标的轨迹移动,都可以为爬虫脚本带来更高的“伪装性”。在众多的自动化工具中,Puppeteer作为一个无头浏览器控制库&am…...

<OS 有关> ubuntu 24 不同版本介绍 安装 Vmware tools
原因 想用 apt-get download 存到本地 / NAS上,减少网络流浪。 看到 VMware 上的确实有 ubuntu,只是版本是16。 ubuntu 版本比较:LTS vs RR LTS: Long-Term Support 长周期支持, 一般每 2 年更新,会更可靠与更稳定…...
C#调用JAVA
参考教程:使用IKVMC转换Jar为dll动态库(含idea打包jar方法)-CSDN博客 已经实践过,好使。...

JavaEE-多线程基础知识
文章目录 前言与回顾创建一个多线程线程的创建以及运行机制简述step1: 继承Thread类step2: 实现Runable接口step3: 基于step1使用匿名内部类step4: 基于step2使用匿名内部类step5: 基于step4使用lambda表达式(推荐) Thread的常见方法关于jconsole监视线程的工具构造方法解析获取…...

Pulid:pure and lightning id customization via contrastive alignment
1.introduction 基于微调的方案,对每个id进行定制需要花费数十分钟。另一项研究则放弃了对每个id进行微调,而是选择在一个庞大的肖像数据集上预训练一个id适配器。这些方法通常利用编码器例如clip来提取id特征,提取的特征随后以特定方式例如嵌入到cross attention集成到基础…...
什么是GraphQL,有什么特点
什么是GraphQL? GraphQL 是一种用于 API(应用程序编程接口)的查询语言,由 Facebook 在 2012 年开发,并于 2015 年开源。它提供了一种更高效、强大的方式来获取和操作数据,与传统的 RESTful API 相比&#…...

Java项目-基于SpringBoot+vue的租房网站设计与实现
博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…...

【SQL Server】华中农业大学空间数据库实验报告 实验三 数据操作
1.实验目的 熟悉了解掌握SQL Server软件的基本操作与使用方法,以及通过理论课学习与实验参考书的帮助,熟练掌握使用T-SQL语句和交互式方法对数据表进行插入数据、修改数据、删除数据等等的操作;作为后续实验的基础,根据实验要求重…...

【大数据学习 | Spark】RDD的概念与Spark任务的执行流程
1. RDD的设计背景 在实际应用中,存在许多迭代式计算,这些应用场景的共同之处是,不同计算阶段之间会重用中间结果,即一个阶段的输出结果会作为下一个阶段的输入。但是,目前的MapReduce框架都是把中间结果写入到HDFS中&…...
ruoyi框架完成分库分表,按月自动建表功能
前提 这个分库分表功能,按月自动建表,做的比较久了,还没上线,是在ruoyi框架内做的,踩了不少坑,但是已经实现了,就分享一下代码吧 参考 先分享一些参考文章 【若依系列】集成ShardingSphere S…...

Antd中的布局组件
文章目录 一、Layout二、Menu三、Grid栅格 布局组件涉及项目框架的搭建,往往被忽略和低关注,毕竟不是经常用到,但是在调整项目结构的时候往往又需要重新设计布局,所以有必要提前归纳分析; 一、Layout Layout导出Sider,…...

一文详解kafka知识点
目录 1、kafka定义 2、消息队列 2.1、产品选择 2.2、应用场景 2.3、消息队列的两种模式 3、kafka架构 4、kafka生产者 4.1、kafka生产者原理 4.2、kafka生产者异步发送 4.3、同步发送 4.4、分区 4.4.1、kafka分区好处 4.4.2、分区策略 4.4.3、自定义分区 4.5、生成吞…...

C语言基础学习:抽象数据类型(ADT)
基础概念 抽象数据类型(ADT)是一种数据类型,它定义了一组数据以及可以在这组数据上执行的操作,但隐藏了数据的具体存储方式和实现细节。在C语言中,抽象数据类型(ADT)是一种非常重要的概念&…...

提升性能测试效率与准确性:深入解析JMeter中的各类定时器
在软件性能测试领域,Apache JMeter是一款广泛使用的开源工具,它允许开发者模拟大量用户对应用程序进行并发访问,从而评估系统的性能和稳定性。在进行性能测试时,合理地设置请求之间的延迟时间对于模拟真实用户行为、避免服务器过载…...
施密特正交化与单位化的情形
在考研数学的线性代数部分,施密特正交化和单位化是两种不同的处理向量的方法,它们在特定的情况下被使用。以下是详细说明: 施密特正交化的应用场景 施密特正交化(Gram-Schmidt Orthogonalization)是一种从线性无关向…...

ROS机器视觉入门:从基础到人脸识别与目标检测
前言 从本文开始,我们将开始学习ROS机器视觉处理,刚开始先学习一部分外围的知识,为后续的人脸识别、目标跟踪和YOLOV5目标检测做准备工作。我采用的笔记本是联想拯救者游戏本,系统采用Ubuntu20.04,ROS采用noetic。 颜…...

2024 APMCM亚太数学建模C题 - 宠物行业及相关产业的发展分析和策略(详细解题思路)
在当下, 日益发展的时代,宠物的数量应该均为稳步上升,在美国出现了下降的趋势, 中国 2019-2020 年也下降,这部分变化可能与疫情相关。需要对该部分进行必要的解释说明。 问题 1: 基于附件 1 中的数据及您的团队收集的…...
C#里怎么样访问文件时间
C#里怎么样访问文件时间 文件时间也是一个关键信息, 因为很多数据处理需要时间来判断数据的有效性,比如股票中的股价, 它是的权重,是随着时间递减的。 一般来说,超过5年以上的数据,都是可以删除掉了。 或者说超过三年的数据,就需要压缩保存了,这样可以省掉很多磁盘空…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...