商品管理模块:分类、上下架、图片、规格管理
商品管理模块分类、上下架、图片、规格管理商品管理是无人售货柜的粮草官没有商品后面的订单、支付、库存全部是空谈。今天我们就来把商品管理这个基础模块拆开揉碎一文讲透。一、商品在无人售货柜中的角色在无人售货柜系统中商品是核数据源。用户扫码开门 → 看到商品 → 拿走商品 → 结算扣库存 → 生成订单整条链路的数据起点就是商品。没有商品数据设备就是个空壳子小程序也是白屏状态。商品管理模块需要解决的问题运营人员如何添加、编辑、下架商品商品如何分类饮料/零食/日用品每个柜子摆哪些商品摆在第几排第几列商品图片怎么存规格怎么定义二、商品表结构设计一张好的表结构是模块稳定的地基。以下是我们项目的商品主表设计CREATETABLEproduct(idbigintNOTNULLCOMMENT商品ID雪花算法生成,namevarchar(100)NOTNULLCOMMENT商品名称,category_idbigintNOTNULLCOMMENT分类ID,pricedecimal(10,2)NOTNULLCOMMENT售价(元),cost_pricedecimal(10,2)DEFAULTNULLCOMMENT成本价(元),main_imagevarchar(500)DEFAULTNULLCOMMENT主图URL,imagesjsonDEFAULTNULLCOMMENT多图URL数组,descriptiontextCOMMENT商品描述,specvarchar(200)DEFAULTNULLCOMMENT规格如500ml/瓶,barcodevarchar(50)DEFAULTNULLCOMMENT条码扫码识别用,statustinyintNOTNULLDEFAULT0COMMENT0-下架 1-上架,sort_orderintDEFAULT0COMMENT排序权重,shelf_timedatetimeDEFAULTNULLCOMMENT上架时间,create_timedatetimeNOTNULLDEFAULTCURRENT_TIMESTAMP,update_timedatetimeNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,deletedtinyintNOTNULLDEFAULT0COMMENT逻辑删除,PRIMARYKEY(id),KEYidx_category_id(category_id),KEYidx_barcode(barcode),KEYidx_status(status))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT商品表;几个设计要点说明主键用雪花算法分布式环境下避免自增ID冲突同时保持时间有序。images 字段用 JSON 类型商品可能有多张展示图JSON 比多表关联更直接。barcode 加索引扫码是高频操作必须走索引。deleted 逻辑删除商品关联订单历史数据不能物理删除。三、商品分类管理分类采用树形结构一张表搞定CREATETABLEcategory(idbigintNOTNULL,namevarchar(50)NOTNULLCOMMENT分类名称,parent_idbigintDEFAULT0COMMENT父分类ID0顶级,leveltinyintDEFAULT1COMMENT层级1/2/3,sort_orderintDEFAULT0,PRIMARYKEY(id))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT商品分类表;典型的分类树饮料(1) ├── 碳酸饮料(2) ├── 果汁(3) └── 茶饮(4) 零食(5) ├── 膨化食品(6) └── 坚果(7)分类 CRUD 的实现和常规项目差不多但有两个业务小细节删除分类前必须检查如果该分类及其子分类下还有商品不允许删除。分类下商品数量统计用 SQL 的COUNT GROUP BY或维护product_count冗余字段后者在经常展示的场景下性能更好。// 查询分类及其商品数量Select(SELECT c.*, COUNT(p.id) AS product_count FROM category c LEFT JOIN product p ON c.id p.category_id AND p.deleted 0 WHERE c.deleted 0 GROUP BY c.id)ListCategoryVOlistWithProductCount();四、商品上下架上下架逻辑不复杂重点是批量操作和缓存同步ServicepublicclassProductService{AutowiredprivateRedisTemplateString,ObjectredisTemplate;/** * 商品上架 */TransactionalpublicvoidonShelf(LongproductId){ProductproductproductMapper.selectById(productId);if(productnull)thrownewBusinessException(商品不存在);if(product.getStatus()1)thrownewBusinessException(商品已上架);product.setStatus(1);product.setShelfTime(LocalDateTime.now());productMapper.updateById(product);// 上架后清除商品缓存下次查询重建redisTemplate.delete(product:detail:productId);redisTemplate.delete(product:list);}/** * 批量下架 */TransactionalpublicvoidbatchOffShelf(ListLongproductIds){LambdaUpdateWrapperProductwrappernewLambdaUpdateWrapper();wrapper.in(Product::getId,productIds).set(Product::getStatus,0);productMapper.update(null,wrapper);// 批量删除缓存ListStringkeysproductIds.stream().map(id-product:detail:id).collect(Collectors.toList());redisTemplate.delete(keys);redisTemplate.delete(product:list);}}缓存清除的时机任何商品信息变更上下架、改价、换图都必须在事务提交后清除对应缓存否则用户看到的就是僵尸商品。五、商品图片管理图片管理的关键是OSS 存储 缩略图上传流程用户选图 → 前端上传至OSS → 回调后端保存URL → 返回给前端PostMapping(/upload/image)publicResultStringuploadImage(RequestParam(file)MultipartFilefile){// 1. 上传到阿里云OSSStringoriginalNamefile.getOriginalFilename();StringextoriginalName.substring(originalName.lastIndexOf(.));StringobjectNameproduct/DateUtil.format(LocalDate.now(),yyyy/MM/dd)/IdUtil.snowflake()ext;ossClient.putObject(bucketName,objectName,file.getInputStream());// 2. 生成缩略图使用时拼接 ?x-oss-processimage/resize,m_fill,h_200,w_200StringurlossConfig.getDomain()/objectName;returnResult.ok(url);}使用阿里云 OSS 的图片处理参数生成缩略图无需单独存储访问时带上?x-oss-processimage/resize,w_200即可实时缩放省钱又省事。主图设置逻辑main_image存一张imagesJSON 数组存全部。前端展示时优先展示主图。六、商品规格管理与条码关联规格字段spec存字符串如500ml/瓶、200g/袋。条码barcode是重要关联字段扫码 → 查询barcode → 确定商品ID → 后续结算/库存操作如果同一商品有不同规格如可乐 330ml vs 500ml应该是两个独立的 Product 记录各自有独立的 barcode而不是在同一商品下做规格子表。好处是库存、价格、销量统计全部独立逻辑清晰。七、商品与设备绑定每台售货柜需要知道它卖哪些商品以及每个商品的陈列位置CREATETABLEdevice_product(idbigintNOTNULL,device_idbigintNOTNULLCOMMENT设备ID,product_idbigintNOTNULLCOMMENT商品ID,row_numintDEFAULTNULLCOMMENT所在排,col_numintDEFAULTNULLCOMMENT所在列,stock_countintDEFAULT0COMMENT当前库存量,max_stockintDEFAULT10COMMENT最大库存量,PRIMARYKEY(id),UNIQUEKEYuk_device_product(device_id,product_id))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT设备商品关联表;row_num/col_num 用于在小程序端绘制柜子可视化货架让用户直观看到每排每列放了什么。八、Feign 远程调用商品服务需要对外暴露接口给订单、库存等服务调用FeignClient(nameproduct-service,path/product)publicinterfaceProductFeignClient{GetMapping(/{id})ResultProductVOgetById(PathVariable(id)Longid);GetMapping(/batch)ResultListProductVOgetByIds(RequestParam(ids)ListLongids);GetMapping(/by-barcode)ResultProductVOgetByBarcode(RequestParam(barcode)Stringbarcode);}九、Redis 缓存策略// 读取商品时先查缓存publicProductVOgetById(Longid){StringcacheKeyproduct:detail:id;ProductVOcached(ProductVO)redisTemplate.opsForValue().get(cacheKey);if(cached!null)returncached;ProductproductproductMapper.selectById(id);if(productnull)thrownewBusinessException(商品不存在);ProductVOvoBeanUtil.copyProperties(product,ProductVO.class);redisTemplate.opsForValue().set(cacheKey,vo,30,TimeUnit.MINUTES);returnvo;}十、常见问题缓存不一致是最典型的问题。商品信息变更后如果先更新 DB 成功、清除缓存失败用户读到的就是旧数据。解决方案先更新 DB再删缓存不是更新缓存是删除加双重过期时间缓存 30 分钟但 25 分钟时异步刷新使用 Canal 监听 binlogDB 变更后自动删缓存更高级方案商品管理说简单也简单说复杂也复杂关键在于表结构设计的合理性和缓存一致性的把控。下一关我们进入库存管理的深水区。

相关新闻

javascript之string正则式

javascript之string正则式

1.search方法search() 返回第一个匹配的索引,未找到返回-1const str "Hello World"; const index str.search(/World/); console.log(index); // 62 match方法match() 用于在字符串中执行正则匹配,返回匹配结果的数组或nullconst str "…

2026/11/9 8:39:19 阅读更多 →
随机森林原理与实践:从决策树到集成学习的机器学习实战指南

随机森林原理与实践:从决策树到集成学习的机器学习实战指南

1. 从“一棵树”到“一片森林”:为什么我们需要随机森林?如果你接触过机器学习,大概率听说过决策树。它就像一个流程图,通过一系列“是/否”问题(比如“年龄是否大于30岁?”、“收入是否高于5万&#xff1f…

2026/11/1 16:07:45 阅读更多 →
做自媒体半年,我总结了5个让视频体积减少80%的技巧

做自媒体半年,我总结了5个让视频体积减少80%的技巧

很多新人做短视频,都会遇到一个问题:视频拍完很好看,但导出来却有2GB。其实,大部分视频都可以在保证观看体验的情况下,减少不少体积。第一,不要一味追求最高码率很多剪辑软件默认导出"最高画质"。…

2026/11/9 23:33:47 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/9 14:01:10 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/9 14:56:39 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/10 2:03:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/10 16:14:15 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/10 12:51:50 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/9 14:01:11 阅读更多 →

日新闻

周新闻

月新闻