谷粒商城实战笔记-131~132-商城业务-商品上架-构造sku检索属性和库存查询
文章目录
- 一,131-商城业务-商品上架-构造sku检索属性
- 1,开发目标
- 2,详细设计
- 2.1,根据spu_id获取所有的规格参数
- 2.2,根据上一步中查询结果进一步确认是否可搜索
- 2.3,将可搜索的属性封装到Java模型中
- 二,132-商城业务-商品上架-远程查询库存&泛型结果封装
- 1,开发目标
- 2,详细设计
- 2.1 调用库存服务的接口
- 2.2,库存服务根据sku_id查询库存量
- 2.3,根据查询结果填充模型
一,131-商城业务-商品上架-构造sku检索属性
1,开发目标
这一节的主要内容是完成获取规格属性信息的功能:
- 从数据库中获取与 SPU 关联的所有规格属性。
- 筛选出可被用于搜索的属性,并转换为 ES 所需的格式。
- 注意点1:SPU的规格参数是这个SPU下所有SKU公用的,查询一次即可。
- 注意点2:规程参数分为两类,一类是可搜索的,一类是不可搜索的。这里需要的是可搜索的规格参数。
2,详细设计
- ① 从
pms_product_attr_value表中根据spu_id查出这个spu下所有的属性。 - ② 根据属性Id从属性表中
pms_attr查询属性是否可搜索。 - ③ 将可搜索的属性信息封装到Es的Java模型中。
2.1,根据spu_id获取所有的规格参数
List<ProductAttrValueEntity> baseAttrs = productAttrValueService.baseAttrList4Spu(spuId);
对应的Service实现非常简单。
public List<ProductAttrValueEntity> baseAttrList4Spu(Long spuId) {List<ProductAttrValueEntity> attrValueEntityList = this.baseMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));return attrValueEntityList;}
2.2,根据上一步中查询结果进一步确认是否可搜索
汇总所有属性Id,一次性查询出其中所有可搜索的属性Id。
List<Long> attrIds = baseAttrs.stream().map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());// 查询可搜索的规格属性List<Long> searchAttrIds = attrService.selectSearchableAttrs(attrIds);
对应的Service实现如下。
public List<Long> selectSearchableAttrs(List<Long> attrIds) {List<Long> searchAttrIds = this.baseMapper.selectSearchAttrIds(attrIds);return searchAttrIds;}
对应的Sql如下。
<select id="selectSearchAttrIds" resultType="java.lang.Long">SELECT attr_id FROM pms_attr WHERE attr_id IN<foreach collection="attrIds" item="id" separator="," open="(" close=")">#{id}</foreach>AND search_type = 1</select>
注意,search_type = 1 表示这个属性可搜索。
2.3,将可搜索的属性封装到Java模型中
将前两步的结果结合起来,把spu下所有可搜索的属性封装到Java模型中。
Set<Long> idSet = new HashSet<>(searchAttrIds);List<SkuEsModel.Attrs> attrsList = baseAttrs.stream().filter(item -> idSet.contains(item.getAttrId())).map(item -> {SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();BeanUtils.copyProperties(item, attrs);return attrs;}).collect(Collectors.toList());

二,132-商城业务-商品上架-远程查询库存&泛型结果封装
1,开发目标
获取库存信息:
- 通过远程调用库存服务,获取每个 SKU 的库存状态。
- 库存状态用于确定 SKU 是否有货。
2,详细设计
- ① 调用库存服务的接口
- ② 库存服务根据sku_id查询库存量
- ③ 根据查询结果填充模型
2.1 调用库存服务的接口
通过Feign调用库存服务的接口,并处理返回结果。
List<Long> skuIdList = skuInfoEntities.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList());R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};stockMap = skuHasStock.getData(typeReference).stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
通过Feign将spu下所有的sku_id传递给库存服务。
2.2,库存服务根据sku_id查询库存量
① ware服务WareSkuController中定义供调用的接口。
(value = "/hasStock")public R getSkuHasStock( List<Long> skuIds) {//skuId stockList<SkuHasStockVo> vos = wareSkuService.getSkuHasStock(skuIds);return R.ok().setData(vos);}
对应的Service实现如下。
public List<SkuHasStockVo> getSkuHasStock(List<Long> skuIds) {List<SkuHasStockVo> skuHasStockVos = skuIds.stream().map(item -> {Long count = this.baseMapper.getSkuStock(item);SkuHasStockVo skuHasStockVo = new SkuHasStockVo();skuHasStockVo.setSkuId(item);skuHasStockVo.setHasStock(count == null?false:count > 0);return skuHasStockVo;}).collect(Collectors.toList());return skuHasStockVos;}
对应的Dao层Sql如下,逻辑非常简单,查询可用库存大于0的sku_id。
<select id="listWareIdHasSkuStock" resultType="java.lang.Long">SELECTware_idFROMwms_ware_skuWHEREsku_id = #{skuId}AND stock - stock_locked > 0</select>
2.3,根据查询结果填充模型
调用库存接口查询到结果之后,从响应R中取出数据,注意因为R本质是一个Map,所以需要将Map中的数据序列化为我们需要的类型,这里使用了阿里的FastJson工具包中的TypeReference完成这个任务。
R skuHasStock = wareFeignService.getSkuHasStock(skuIdList);TypeReference<List<SkuHasStockVo>> typeReference = new TypeReference<List<SkuHasStockVo>>() {};stockMap = skuHasStock.getData(typeReference).stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, item -> item.getHasStock()));
public <T> T getData(TypeReference<T> typeReference) {Object data = get("data"); //默认是mapString jsonString = JSON.toJSONString(data);T t = JSON.parseObject(jsonString, typeReference);return t;}
拿到结果之后,在遍历Sku的循环体中填充库存信息。
// 4.2 设置库存信息if (finalStockMap == null) {esModel.setHasStock(true);} else {esModel.setHasStock(finalStockMap.get(sku.getSkuId()));}
这样注意从响应中取得结果的方式,是开发中常用的技巧。
相关文章:
谷粒商城实战笔记-131~132-商城业务-商品上架-构造sku检索属性和库存查询
文章目录 一,131-商城业务-商品上架-构造sku检索属性1,开发目标2,详细设计2.1,根据spu_id获取所有的规格参数2.2,根据上一步中查询结果进一步确认是否可搜索2.3,将可搜索的属性封装到Java模型中 二…...
【Python学习-UI界面】PyQt5 QLabel小部件
序号组件说明详细介绍链接1QLabel用作占位符,用于显示不可编辑的文本、图像,或者动画GIF的电影。它也可以用作其他小部件的助记符键。2QLineEdit是最常用的输入字段。它提供了一个框,可以输入一行文本。要输入多行文本,需要使用QT…...
vue项目打包问题
缓存导致打包后js文件404 修改vue.config.js打包输出文件名为动态,例如取当前时间戳。 在index.html文件添加meta标签设置不缓存。 更新完包,假如用户此刻正访问某一个页面时,访问的包还是原来的情况导致出现bug 解决VUE项目更新后需要客户手…...
C++标准模板库(STL)|容器|vector| queue|
对STL进行总结,STL是standard template library的简写,是C中的一个标准模板库,用于实现常用的数据结构和算法,它是C程序员经常使用的一个工具箱。STL 的主要目的是提高开发效率和代码质量,使得程序员可以更加便捷地完成…...
【Android】安卓四大组件之Service用法
文章目录 使用Handler更新UIService基本特点启动方式非绑定式服务使用步骤 绑定式服务步骤 生命周期非绑定式启动阶段结束阶段 绑定式启动阶段结束阶段 前台Service使用步骤结束结束Service本身降级为普通Service降级为普通Service 使用Handler更新UI 主线程创建Handler对象&a…...
Python爬虫入门实战(详细步骤)
1. 技术选型 爬虫这个功能,我个人理解是什么语言都能写的,只要能正常发送 HTTP 请求,将响应回来的静态页面模版 HTML 上把我们所需要的数据提取出来就可以了,原理很简单,这个东西当然可以手动去统计收集,但…...
5、Linux : 网络相关
OSI七层网络模型 TCP/IP四层 概念模型 对应网络协议 应用层(Application) HTTP、TFTP, FTP, NFS, WAIS、 表示层(Presentation) 应用层 Telnet, Rlogin, SNMP, Gopher 会话层(Session) SMTP…...
Linux中针对文件权限的解析
1.文件权限详细解析: -rw-r--r--. 1 root root 114 4月 10 16:32 100.txt 1)-rw-r--r--. 总共11位 第一个“-”和最后一个“.”不用去管,剩下 rw- r-- r-- 属主 属组 其他人 u g o 第一个是“-”表示普通文件 第一个是“d”表示文件目录 …...
【0304】psql 执行“VACUUM FULL”命令的背后实现过程
1. 概述 在前面讲解Postgres内核中解析器相关(【0297】Postgres内核之 INSERT INTO 原始解析树 转 Query 树 (1))内容时,曾提到过,Postgres内核大致将用户下发的SQL语句分为三大类,这里的VACUUM FULL属于CMD_UTILITY; 因此直接调用utility.c(实用程序)中的对应函数。…...
Java常见面试题-11-MongoDb
文章目录 MongoDB 是什么?MongoDB 和关系型数据库 mysql 区别MongoDB 有 3 个数据库分别是什么?MongoDB 中的数据类型MongoDB 适用业务场景 MongoDB 是什么? mongodb 是属于文档型的非关系型数据库,是开源、高性能、高可用、可扩…...
PBLOCK
PBLOCK是附加到Vivado中分配给Pblocks的单元格的只读属性 设计套房。 Pblock是一组单元格,以及一个或多个指定 Pblock所包含的设备资源。在平面规划过程中使用了Pblocks 将其放置到组相关逻辑中,并将其分配到目标设备的某个区域。请参阅 Vivado设计套件用…...
电子纸打造智能、自动化、绿色的工作流程
电子纸打造智能、自动化、绿色的工作流程 RFID技术最早在1940年代问世,1980年开始商业化使用。直到现在RFID(无线射频识别)技术已经深入到我们生活的方方面面。特别是在工业生产、物流运输等领域,RFID技术发挥着越来越重要的作用…...
Redis 的6种回收策略(淘汰策略)详解
Redis 的6种回收策略(淘汰策略)详解 1、Redis的六种淘汰策略1. volatile-lru2. volatile-ttl3. volatile-random4. allkeys-lru5. allkeys-random6. no-eviction 2、使用策略规则 💖The Begin💖点点关注,收藏不迷路&am…...
SQL注入sqli-labs-master关卡一
本文环境搭建使用的是小皮,靶机压缩包:通过百度网盘分享的文件:sqli-labs-php7-master.zip 链接:https://pan.baidu.com/s/1xBfsi2lyrA1QgUWycRsHeQ?pwdqwer 提取码:qwer 下载解压至phpstudy的WWW目录下即可。 第一…...
LeetCode面试题Day6|LeetCode238 除自身以外数组的乘积、LeetCode134 加油站
题目1: 指路: . - 力扣(LeetCode)238 除自身以外数组的乘积 思路与分析: 除去自身元素求其他元素的乘积,或许第一反应会是数组元素积乘再除以遍历到的元素,定义一个结果数组再对应放结果值&…...
猫头虎分享:Python库 FastAPI 的简介、安装、用法详解入门教程
🐯 猫头虎分享:Python库 FastAPI 的简介、安装、用法详解入门教程 🚀 📄 摘要 作为一名专注于Python和人工智能开发的技术博主,猫头虎经常在开发过程中遇到各种挑战。最近,有粉丝问到如何高效地构建API&a…...
python连接MySQL数据库使用pymysql
开头 经过这么一段时间的学生信息管理系统的摸爬滚打,不断的学习更新的知识,不断修改自己的认知,针对pymysql以及MySQL数据库的知识做个总结,以纪念我这段时间的学习。 目录 开头 pymysql的使用流程 1.导入pymysql的工具包 方…...
AI时代下的编程趋势:程序员如何提升核心竞争力
随着人工智能和机器学习技术的飞速发展,大型语言模型和AI生成代码(AIGC)工具如ChatGPT、Midjourney、Claude等层出不穷,AI辅助编程逐渐成为现实。在这一变革的浪潮中,程序员群体面临着前所未有的挑战和机遇。一些人担忧…...
C#:基本语法
写在前面 本人在实习过程需要用C#进行开发,但本人之前的技术栈是C方向,所以在菜鸟教程上速通了一下C#的基本语法,总的来说和C还是非常相似的。 1 关键字 using关键字:使用命名空间class:使用类 2 注释 /* 这个程序…...
Redisson 实现分布式锁
文章目录 Redisson 是什么Redisson 使用客户端模式单节点模式哨兵模式主从模式集群模式Spring Boot 整合 Redisson 中的锁Redisson 可重入锁Redisson 公平锁Redisson 联锁Redisson 读写锁Redisson Redlock Redisson 的看门狗机制RedLock 解决单体故障问题如何使用 RedLockMarti…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
如何为服务器生成TLS证书
TLS(Transport Layer Security)证书是确保网络通信安全的重要手段,它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书,可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
