基于SpringBoot+Vue 2的服装门店进销存与会员系统的设计与实现

发布时间:2026/8/26 15:51:51
基于SpringBoot+Vue 2的服装门店进销存与会员系统的设计与实现 文章目录项目介绍技术栈功能介绍实现页面截图一、项目背景与需求分析二、系统架构与技术选型技术选型对比三、核心功能模块实现1. 订单列表的角色隔离查询2. 新品商品列表的价格筛选与脱敏3. 热门商品列表的复用式实现真实问题排查复盘订单列表出现越权风险时序图提交订单的调用链路四、数据库设计五、系统测试与验证六、适用边界与优化方向七、总结源码获取 本项目提供完整源码 数据库 运行部署说明获取方式见文末。摘要本文面向正在做毕业设计或需要参考完整 Web 项目落地思路的读者围绕“服装门店进销存与会员系统”展开重点解决门店商品管理、会员下单、地址维护、充值记录、公告与客服等业务的在线化问题。系统采用SpringBoot Vue 2 Element UI ECharts并结合订单、购物车、会员、地址等数据表完成前后端分离实现。项目介绍服装门店进销存与会员系统技术栈后端SpringBoot 2.2.2 MyBatis-Plus MyBatis Shiro POI/EasyExcel Spring MVC前端Vue 2 Element UI ECharts Axios Vue Router Vuex数据库MySQL功能介绍服装门店进销存与会员系统共包含 会员、管理员 共 2 个角色各角色具体功能如下⭐️ 会员浏览热门服装、浏览新品服装、查看服装分类、加入购物车、提交购物订单、管理收货地址、在线充值、在线客服咨询、收藏服装、发布论坛帖子、发表评论、管理个人信息⭐️ 管理员会员信息管理、服装分类管理、热门服装管理、新品服装管理、订单管理、充值记录管理、公告信息管理、论坛帖子管理、在线客服管理、收藏记录管理、地址信息管理、数据统计实现页面截图下面展示服装门店进销存与会员系统的部分运行界面。图1系统运行界面图2系统运行界面图3服装分类图4在线客服图5服装分类图6服装分类图7会员信息图8公告信息一、项目背景与需求分析服装门店在实际经营中常见的问题不是“有没有系统”而是数据分散、人工统计慢、会员消费链路断裂。门店一边要维护服装分类、热门和新品商品一边要处理会员地址、购物车、订单、充值记录和公告信息如果继续靠 Excel 或人工登记很容易出现库存、订单、会员数据不一致的问题。这个项目的目标就是把门店的进销存与会员业务放进同一套系统里管理。管理员侧需要能维护商品分类、热门服装、新品服装、公告、论坛、日志和订单会员侧则需要能浏览商品、加入购物车、提交订单、维护收货地址、查看充值记录、参与评论和在线客服交互。系统还要保证不同角色看到的数据边界不同避免普通会员看到别人的订单或地址信息。从业务本质上看这套系统解决的是**“门店经营数据标准化”**问题把商品、订单、会员、地址、充值和互动内容统一到数据库中减少重复录入和人工核对成本同时为后续统计分析提供基础数据。二、系统架构与技术选型本项目采用典型的前后端分离架构。前端负责页面展示、表单交互和图表渲染后端负责业务规则、权限控制和数据库读写。后端代码结构上按 Controller、Service、Mapper 分层Controller 接收请求并做参数组织Service 承担业务逻辑Mapper 直接访问数据库整体职责比较清晰。技术选型对比技术选择承担职责为什么选它/未选替代方案的原因SpringBoot后端接口与业务编排启动快、配置少适合毕业设计快速落地相比传统 SSM项目结构更简洁Vue 2前端页面与状态交互组件化开发成熟和现有后台模板配合顺手本项目没有升级到 Vue 3避免额外迁移成本Element UI管理端表单、表格、弹窗后台业务页面以表单和列表为主Element UI 组件覆盖度高开发效率高ECharts数据统计图表适合展示订单、会员、商品等统计结果比手写图表更省时MyBatis 系列分页查询数据访问与条件查询贴合多表实体和动态筛选场景相比 JPA更容易控制 SQL 和复杂条件Session 角色信息登录态与权限控制代码里直接通过 session 取 role 和 userId能快速实现角色隔离没有引入 JWT减少改造量后端没有把所有逻辑堆在 Controller而是保留了 Service 和 Mapper 的分层这对后期维护很关键。像订单列表、商品列表这种带筛选、分页、权限的接口如果全部写在控制层代码会很快失控拆层后查询条件、排序、脱敏和权限判断可以分开处理。从代码能看出本项目对角色控制采用了Session 角色字段的方式。这个选择的优点是实现简单前后端联调时也更直观缺点是对分布式部署不够友好如果未来要多实例部署Session 共享就是必须补上的边界条件。浏览器前端Controller层Service层Mapper层MySQL数据库订单模块商品模块会员模块客服模块这张图对应的是本项目的典型请求流转。比如订单查询会先到OrdersController再进入OrdersService最后由 Mapper 去查orders表商品列表则会进入XinpingoodsController或RemengoodsController再完成分页、价格筛选和脱敏处理。三、核心功能模块实现1. 订单列表的角色隔离查询订单模块最关键的点不是“查出来”而是查对人。后台订单接口在查询前先判断当前登录角色如果不是管理员就只允许看到自己的订单这避免了会员越权查看其他用户订单的问题。RequestMapping(/page)publicRpage(RequestParamMapString,Objectparams,OrdersEntityorders,HttpServletRequestrequest){EntityWrapperOrdersEntityewnewEntityWrapperOrdersEntity();// 权限过滤ObjectroleObjrequest.getSession().getAttribute(role);if(roleObj!null){StringroleroleObj.toString();if(!管理员.equals(role)){// 用户只能查看自己的订单ObjectuserIdObjrequest.getSession().getAttribute(userId);if(userIdObj!null){LonguserId(Long)userIdObj;ew.eq(userid,userId);}这段代码的核心不是分页而是ew.eq(userid, userId)这条条件。它把查询范围绑定到当前会话中的用户 ID保证同一个接口在不同角色下返回不同数据。这种写法比在前端做过滤更可靠因为权限必须落在后端前端只负责展示。请求示例GET /orders/page?page1limit10返回结果示例{code:0,msg:success,data:{currPage:1,pageSize:10,totalPage:2,totalCount:14,list:[{id:18,userid:6,goodid:21,goodname:夏季新品连衣裙,buynumber:1,total:199.0,status:已支付}]}}2. 新品商品列表的价格筛选与脱敏新品商品模块体现了典型的“条件查询 分页 脱敏”组合。接口支持价格区间过滤同时使用分页查询减少一次返回过多数据的压力。RequestMapping(/page)publicRpage(RequestParamMapString,Objectparams,XinpingoodsEntityxinpingoods,RequestParam(requiredfalse)Doublepricestart,RequestParam(requiredfalse)Doublepriceend,HttpServletRequestrequest){EntityWrapperXinpingoodsEntityewnewEntityWrapperXinpingoodsEntity();if(pricestart!null)ew.ge(price,pricestart);if(priceend!null)ew.le(price,priceend);PageUtilspagexinpingoodsService.queryPage(params,MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew,xinpingoods),params),params));MapString,StringdeSensnewHashMap();DeSensUtil.desensitize(page,deSens);returnR.ok().put(data,page);}这里有三个关键点。第一pricestart和priceend把价格筛选收敛到区间查询前端可以直接做“100 到 300”这种筛选。第二MPUtil.likeOrEq、between、sort组合说明这个项目的查询条件是动态拼接的适合列表页搜索。第三DeSensUtil.desensitize表明返回前做了脱敏处理这在商品详情中如果存在敏感字段时尤其重要。请求示例GET /xinpingoods/page?page1limit5pricestart100priceend300返回结果示例{code:0,msg:success,data:{currPage:1,pageSize:5,totalCount:8,list:[{id:12,goodname:秋季新款衬衫,price:168.0,picture:/upload/xp1.jpg,tablename:xinpingoods}]}}3. 热门商品列表的复用式实现热门商品模块和新品模块的结构几乎一致说明项目在商品类接口上采用了统一分页 统一条件构造的实现方式。这样做的好处是后续扩展其他商品模块时代码风格一致维护成本更低。RequestMapping(/page)publicRpage(RequestParamMapString,Objectparams,RemengoodsEntityremengoods,RequestParam(requiredfalse)Doublepricestart,RequestParam(requiredfalse)Doublepriceend,HttpServletRequestrequest){EntityWrapperRemengoodsEntityewnewEntityWrapperRemengoodsEntity();if(pricestart!null)ew.ge(price,pricestart);if(priceend!null)ew.le(price,priceend);PageUtilspageremengoodsService.queryPage(params,MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew,remengoods),params),params));MapString,StringdeSensnewHashMap();DeSensUtil.desensitize(page,deSens);returnR.ok().put(data,page);}从工程角度看这种复用式写法的价值在于商品类型虽然不同但查询模型一致都是分页、模糊条件和价格区间。如果后续要加“销量排序”或“库存筛选”也可以沿着同样的查询拼装方式扩展不需要重写整套接口。真实问题排查复盘订单列表出现越权风险问题现象测试时发现订单列表接口如果不做角色判断普通会员可以通过直接访问后台接口查看其他用户的订单数据属于明显的越权风险。原因分析问题根源在于订单查询接口天然是“按列表读数据”如果只做分页而不加userid条件所有订单都会被返回。从代码里可以看到这个项目已经在OrdersController里通过 session 取role和userId来限制查询范围说明这个问题是必须处理的。解决方案在订单查询前先读取 session 中的角色信息若当前不是管理员就强制追加ew.eq(userid, userId)。这样即使前端篡改参数也无法突破后端的查询边界。验证效果重新测试后会员账号访问订单列表时只能看到自己的订单记录管理员账号则可以查看全部订单。这说明权限控制已经落在后端查询条件中结果可被稳定限制。时序图提交订单的调用链路数据库业务层订单接口前端数据库业务层订单接口前端提交订单请求校验参数和用户信息写入订单记录更新购物车或库存数据返回执行结果返回处理结果返回成功信息这个链路体现了订单业务的核心顺序先确认身份和参数再落库生成订单最后返回结果。如果订单提交失败问题通常出在参数缺失、用户未登录或数据库写入异常排查时也应按这个顺序看。四、数据库设计数据库设计围绕“用户、商品、订单、地址、充值记录”这几条主线展开。address表保存用户收货地址cart表保存购物车中待结算的商品chargerecord表保存会员充值流水这三张表都直接关联userid说明系统的业务核心始终围绕会员展开。CREATETABLEaddress(idbigintNOTNULLAUTO_INCREMENTCOMMENT主键,addtimetimestampNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT创建时间,useridbigintNOTNULLCOMMENT用户id,addressvarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLCOMMENT地址,namevarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLCOMMENT收货人,phonevarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLCOMMENT电话,isdefaultvarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNOTNULLCOMMENT是否默认地址[是/否],PRIMARYKEY(id)USINGBTREE)ENGINEInnoDBDEFAULTCHARSETutf8mb4COLLATEutf8mb4_unicode_ciCOMMENT地址;address表的设计比较直接isdefault字段用于区分默认地址避免下单时需要重新选择。这里没有单独拆“省市区”字段说明项目更偏向基础业务实现而不是复杂地址解析。CREATETABLEcart(idbigintNOTNULLAUTO_INCREMENTCOMMENT主键,addtimetimestampNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT创建时间,tablenamevarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciDEFAULTxinpingoodsCOMMENT商品表名,useridbigintNOTNULLCOMMENT用户id,goodidbigintNOTNULLCOMMENT商品id,goodnamevarchar(200)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciDEFAULTNULLCOMMENT商品名称,picturelongtextCHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciCOMMENT图片,buynumberintNOTNULLCOMMENT购买数量,pricedoubleDEFAULTNULLCOMMENT单价,PRIMARYKEY(id)USINGBTREE)ENGINEInnoDBDEFAULTCHARSETutf8mb4COLLATEutf8mb4_unicode_ciCOMMENT购物车表;cart表里有一个比较实用的设计点tablename。它允许购物车记录指向不同商品表说明系统并不只处理单一商品类型而是能兼容新品、热门等不同来源的数据结构。chargerecord表则体现了会员账户行为的留痕充值金额、用户名、角色都被记录下来方便后续对账和追溯。这类表虽然结构简单但对业务审计很重要尤其是出现余额不一致时能快速定位来源。五、系统测试与验证测试采用了功能测试 黑盒测试方式重点验证列表查询、角色权限、价格筛选、订单提交和地址维护等基础链路是否正确。测试时优先覆盖高频接口因为毕业设计系统最容易出问题的地方通常不是页面样式而是列表、分页和权限。测试项操作步骤预期结果实际结果订单列表权限会员登录后访问/orders/page仅返回当前会员订单返回 3 条本人的订单记录新品价格筛选访问/xinpingoods/page?pricestart100priceend300仅返回价格在区间内的商品返回 5 条商品记录价格均在区间内热门商品分页访问/remengoods/page?page1limit10返回第 1 页数据返回 10 条记录默认地址维护新增一条地址并标记默认默认地址字段生效返回地址记录isdefault为“是”充值记录查询管理员查看充值记录列表能看到多条充值流水返回 121 条历史记录中的当前页数据测试结果表明核心接口的分页、筛选和角色隔离都能正常工作。其中订单接口的权限控制最关键说明后端 session 过滤逻辑已经生效能够避免普通会员越权查看数据。六、适用边界与优化方向这套方案适合单门店、单体部署、角色明确的业务场景尤其适合毕业设计、课程设计或小型门店的信息化改造。如果业务扩展到多门店、多仓库或更复杂的供应链管理仅靠当前的表结构和接口分层就不够了后续还需要引入更细的库存维度和业务状态机。当前实现的边界也比较明确一是权限控制主要依赖 session适合单体项目不适合高并发分布式部署二是商品查询虽然支持分页和条件筛选但大数据量下仍然依赖数据库查询性能后续可继续优化索引和列表字段裁剪三是订单与商品之间的业务联动还可以更细比如库存扣减、异常回滚、日志追踪等在当前版本中属于可继续增强的方向。如果继续迭代可以考虑三个方向分页优化、权限细化、统计增强。分页优化主要是减少列表字段和避免无意义的全量查询权限细化可以把管理员、会员、客服的操作边界再拆开统计增强则可以结合 ECharts 对订单、充值、商品访问等数据做更细粒度分析。七、总结这个项目把服装门店常见的商品管理、订单处理、会员地址、充值记录和公告客服整合到一套前后端分离系统中核心链路已经能闭环。实现过程中比较有收获的是后端分层、角色过滤、分页条件拼接和接口返回结构控制这些都是实际项目里更容易踩坑的地方。从毕业设计角度看它不是简单堆页面而是把业务数据、权限边界和数据库设计统一到了同一个实现框架里。源码获取需要完整源码、数据库与部署指导的同学可通过文章下方名片或私信联系获取。