商品管理模块:分类、上下架、图片、规格管理
商品管理模块分类、上下架、图片、规格管理商品管理是无人售货柜的粮草官没有商品后面的订单、支付、库存全部是空谈。今天我们就来把商品管理这个基础模块拆开揉碎一文讲透。一、商品在无人售货柜中的角色在无人售货柜系统中商品是核数据源。用户扫码开门 → 看到商品 → 拿走商品 → 结算扣库存 → 生成订单整条链路的数据起点就是商品。没有商品数据设备就是个空壳子小程序也是白屏状态。商品管理模块需要解决的问题运营人员如何添加、编辑、下架商品商品如何分类饮料/零食/日用品每个柜子摆哪些商品摆在第几排第几列商品图片怎么存规格怎么定义二、商品表结构设计一张好的表结构是模块稳定的地基。以下是我们项目的商品主表设计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/10/7 3:55:12 阅读更多 →
随机森林原理与实践:从决策树到集成学习的机器学习实战指南

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

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

2026/10/7 18:00:15 阅读更多 →
做自媒体半年,我总结了5个让视频体积减少80%的技巧

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

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

2026/10/8 9:13:52 阅读更多 →

最新新闻

Elasticsearch Reindex 实战指南:从机制解析到性能调优避坑

Elasticsearch Reindex 实战指南:从机制解析到性能调优避坑

1. 为什么需要 reindex:五个让我踩过坑的典型场景先给没接触过的朋友一个基本认知:reindex 不是某个数据库独享的功能,主流存储引擎基本都有类似的能力。我最早接触是在 Elasticsearch 上,后面在消息队列、关系型数据库分库分表扩…

2026/10/12 2:07:10 阅读更多 →
固定资产管理系统怎么选?从生命周期、折旧到RFID与盘点落地全拆解

固定资产管理系统怎么选?从生命周期、折旧到RFID与盘点落地全拆解

固定资产管理软件这个词,做企业服务和IT的人都绕不开,但真正被问住的时候往往在客户现场:对方拿出采购清单,说要买一套固定资产管理系统,理由是盘点太累了、审计总找麻烦、资产管理岗的人换了好几拨每次都从头理。你会…

2026/10/12 2:07:10 阅读更多 →
C语言实现广度优先搜索:马走日遍历算法详解

C语言实现广度优先搜索:马走日遍历算法详解

1. 项目背景与需求拆解1.1 什么是“之马遍历”?初次看到“广度优先搜索(之马遍历)C语言”这个标题,很多人可能会先愣一下。“之马”其实是象棋中“马走日”的另一种叫法,也叫“日字跳”或“骑士走法”。把一只马放在88…

2026/10/12 2:07:10 阅读更多 →
Nexent 工程规范全解:面向 AI Agent 的仓库地图、编码约束与开发验证流程

Nexent 工程规范全解:面向 AI Agent 的仓库地图、编码约束与开发验证流程

AI AgentAI 应用后端前端大模型RAG 【免费下载链接】nexent Nexent is a zero-code platform for auto-generating production-grade AI agents using Harness Engineering principles — unified tools, skills, memory, and orchestration with built-in constraints, feedba…

2026/10/12 2:07:10 阅读更多 →
Sherpa-onnx 跑 Zipformer ONNX 推理:3 步绕开 Required inputs missing

Sherpa-onnx 跑 Zipformer ONNX 推理:3 步绕开 Required inputs missing

Sherpa-onnx 跑 Zipformer ONNX 推理:3 步绕开 Required inputs missing 【免费下载链接】sherpa-onnx Speech-to-text, text-to-speech, speaker diarization, speech enhancement, source separation, and VAD using next-gen Kaldi with onnxruntime without Int…

2026/10/12 2:07:10 阅读更多 →
物理与动画系统架构深度解析:从帧循环到Transform协同的引擎设计要点

物理与动画系统架构深度解析:从帧循环到Transform协同的引擎设计要点

做引擎这几年,最常被问到的一个问题就是:物理和动画这两个模块放在一起讲,是不是有点强行组CP?其实不是,这俩在帧循环里的位置紧挨着,数据耦合又深,渲染那边等着同一份Transform结果。你拆开看会…

2026/10/12 2:06:09 阅读更多 →

日新闻

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

复古胶片颗粒感噪点合成器:Canvas ImageData 像素高斯杂色注入算法

在数码相机、高清显示屏与现代矢量图形技术高度发达的今天,画面可以做到绝对的锐利、平滑与无瑕。然而,当一张秋日手账插画或拍立得照片过于“平整无瑕”时,往往会散发出一种冰冷生硬的“数码塑料感(Digital Plasticity&#xff0…

2026/10/12 0:00:59 阅读更多 →
活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

活字印刷古籍线装排版:Canvas 竖排文字与栏线自适应算法

在现代网页与移动端设计中,横排(Horizontal Layout)早已经成为了绝对的主流。然而,当我们翻开泛黄的线装古籍、宋版木刻诗集,或是欣赏一张茶道雅集的手写便签时,那种**自上而下纵向书写、自右向左逐列铺展&…

2026/10/12 0:00:59 阅读更多 →
周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

周日晚间的“精神松绑减震器”:无压力情绪倾倒箱与温和轻声陪伴

每到周日的晚上八点到十点,很多人心里都会悄悄亮起一盏警示灯。 在心理学上,这种现象有一个专门的称谓——“周日夜晚焦虑症(Sunday Scaries)”。明天又是周一,闹钟又要重新在七点响彻卧房;脑海里仿佛有一个…

2026/10/12 0:00:59 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/12 0:16:30 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/12 0:16:43 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 10:45:37 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:53 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/11 14:36:54 阅读更多 →