1. “衣依”到底要做什么服装销售平台的业务底色先说结论这套系统解决的是中小型服装业务的线上化问题。实际开发里我们经常碰到这类需求——一家服装店想把商品挂到网上顾客能浏览、加购、下单店长能在后台维护商品、处理订单、管理库存。全套技术栈是SpringBoot Vue数据落在MySQL里持久层用MyBatis。这套东西不追求大而全但它把商城类系统最核心的链路做完整了商品上架 → 前台展示 → 加入购物车 → 下单结算 → 后台发货处理。很多初学者拿到这类项目第一反应是去看页面好不好看、功能多不多。但真正决定系统能不能用的是背后的业务结构。服装销售平台有一个明显的特点商品属性复杂。同样是T恤可能有颜色、尺码两个维度库存要能精确到“红色M码还剩几件”而不是一个笼统的库存数字。这就是服装系统和一般商品系统的最大差异点后面数据库设计部分我会重点展开。如果你是做毕业设计、课程设计或者想快速搭一套小型商城接点私活“衣依”这套系统的结构是足够当蓝本的。它不是玩具项目该有的模块都有而且因为用了SpringBoot Vue这种前后端分离结构代码组织相对清晰改起来不费劲。先把整个系统的业务版图看明白后面所有技术细节才有落脚点。1.1 前台商城与后台管理一条链路拆成两侧先看前台。顾客进入系统后能做的事很直接注册登录、浏览商品、按分类筛选、搜索关键字、看商品详情、把不同颜色尺码的款式丢进购物车、确认订单、填写收货地址、提交订单。这个流程看起来简单但每个环节都有对应的数据表和接口支撑。后台管理侧则是另一套操作逻辑。管理员进入后台后主要干这些事维护商品分类、新增或编辑商品、给商品上传图片、管理库存数量、查看和处理用户订单、确认发货、处理用户信息。整个后台面向的是“经营”视角不关心页面多好看更关心数据准不准、操作快不快。前后台共用同一套后端API只是前端工程不同。这也是前后端分离模式的好处用户端和管理端可以独立部署、独立迭代。我当时拿到这套代码第一感受就是路由上直接把/admin路径和普通用户路径区分开后端再用拦截器校验管理员权限整体权限边界画得很清楚。1.2 商品、库存、订单、会员四个核心实体怎么咬合把这套系统拆开看业务上真正在转的是四类数据商品含分类、库存含SKU维度、订单含明细、会员用户信息。它们不是孤立的表而是通过状态流转串联起来的。商品是静态的描述“卖什么”库存是动态的描述“还有多少”订单是过程记录描述“谁买了什么、多少钱”会员是身份的载体承载收货地址、联系方式、历史订单。顾客在页面上的每一次点击最终都会落到这四个实体上。比如用户提交一个订单系统至少要同时做这几件事生成订单主表记录、生成订单明细记录、扣减对应SKU的库存、清除购物车中已下单的商品。实体之间还有一个容易忽略的问题冗余字段。订单明细里绝不能只存一个商品ID后面商品改名或下架历史订单就没法看了。我在实际开发中见过不少这种问题订单详情查出来是个空的商品名体验很差。所以订单明细里冗余一份商品名称、单价快照是必要的这也是这套系统设计时的一个隐性规范。1.3 状态设计决定系统复杂度商城类系统的复杂度很大程度来自状态。一个订单从生成到完成不是一锤子买卖它要经历待支付、待发货、待收货、已完成、已取消可能还有售后状态。每一步状态变化都可能触发通知、库存变动、权限变化。“衣依”里订单状态的设计逻辑我是建议拿到源码后第一个去读的地方。它本质是一个状态机什么状态下可以做什么操作操作后跳转到什么状态都要在代码里约束清楚。比如只有待发货状态的订单后台才能点击“发货”只有待收货状态的订单用户才能确认收货。如果状态乱跳数据就失去了可信度。我当时读过一些类似的商城项目最怕看到状态更新散落在各个业务代码里没有任何约束想在订单列表加个筛选都无从下手。这套系统把状态定义放在常量或枚举层面逻辑集中后面扩展退款、退货之类的新需求时会省非常多事。2. 技术选型为什么锁定SpringBootVue每一层在做什么很多同学看到SpringBoot Vue这个组合第一反应是“这是标配大家都在用”。但标配之所以成为标配背后是有具体原因的。你把这套组合拆开看每一层承担的职责其实非常清晰SpringBoot负责后端API和业务逻辑Vue负责前端页面和交互MySQL负责数据落盘MyBatis负责把Java对象和数据库行记录相互转换。为什么不选传统方案比如用JSP渲染页面或者用Thymeleaf做服务端模板原因在于前端交互的复杂度。商城系统有大量的异步刷新、局部状态管理、动态路由用服务端模板硬渲染会很别扭。而Vue的组件化开发天然适合这种场景——商品卡片是一个组件购物车列表是一个组件结算页面是把多个组件拼起来复用度很高。2.1 SpringBoot让后端开发量大减SpringBoot解决的最大痛点是“配置地狱”。在它出现之前搭一个Spring MVC项目要写一堆XML配置还要考虑各种jar包版本兼容。SpringBoot把这些大量吞掉了约定大于配置启动一个Web项目只需要一个入口类加几个注解。在这套“衣依”系统里SpringBoot主要在三个层面发挥作用一是暴露RESTful接口给前端调用二是承载业务逻辑并管理事务三是整合MyBatis完成数据库操作。每一层都有明确的SpringBoot对应机制比如控制器就是RestController业务服务就是Service数据库映射就是Mapper。学习价值在于你能看到一套“标准企业级分层”的最小形态。2.2 Vue的组件化开发适合商城这种多页面高频交互Vue在这里不是花架子。商城前台有商品列表、筛选栏、分页器、商品卡片、购物车弹窗这些如果做成一个整页代码会膨胀到没法维护。但在Vue里商品卡片可以抽成独立的ProductCard组件分类筛选抽成CategoryFilter组件多个页面复用同一个组件改一处全站生效。还有一个关键是Vue Router。商城的路由天然分前台和后台两条线前台有首页、商品详情、购物车、订单页后台有商品管理、订单管理、分类管理。用Vue Router做路由配置和导航守卫可以很自然地控制页面访问权限——未登录用户不能进结算页非管理员不能进后台。2.3 MySQL在数据一致性上要提前设计MySQL在这个项目里承担的可能比你想象的更多。不只是存数据更重要的是通过表结构约束和事务机制保护数据一致性。比如订单表和订单明细表必须放在一个事务里提交否则可能订单主表建了明细却没写进去后面对账都对不上。另一个数据库层面的坑是字符集。MySQL默认的字符集如果还是latin1中文会直接变成乱码。导入SQL文件后第一件事就是确认库表字符集是utf8mb4这是处理服装名、地址这类中文数据的基础保障后面源码运行部分我会再次提醒。3. 数据库设计商品、订单、库存的建模取舍数据库设计是整个系统里最值得花时间研究的部分。很多项目后期改不动、加需求就崩根源往往不是代码而是表结构从一开始就设计错了。这套“衣依”系统的表不算多但每一张表的设计都有讲究。3.1 商品表和分类表SPU/SKU先想清楚服装商品必须区分SPU和SKU。SPU是“商品”比如“夏季纯棉短袖T恤”SKU是“具体款式”比如“夏季纯棉短袖T恤-红色-M码”。用户浏览的是SPU加入购物车、下订单时锁定的是SKU。库存数量也要挂在SKU粒度上不是挂在SPU上。“衣依”的商品表结构如果我没记错主表存的是商品公共信息名称、描述、封面图、价格区间、分类ID另外有一张商品规格/库存表存SKU维度信息颜色、尺码、库存数量、单价。两张表通过商品ID关联。这个设计不复杂但非常实用。有些初学项目把所有字段塞一张表里颜色尺码拼接成字符串存查询和扣库存全都变成灾难。3.2 订单表和订单明细表为什么一定要拆两张订单主表和订单明细表拆分是商城系统的铁律。主表存一次下单的公共信息比如订单编号、用户ID、总金额、订单状态、下单时间、收货人信息明细表存每个商品的购买记录比如商品ID、SKU信息、商品名快照、单价、数量、小计金额。为什么要拆因为一个订单包含多个商品。如果所有商品信息都塞进主表要么字段不够用要么只能存成一个JSON字符串查询统计完全没法搞。拆成两张表后一套订单就是“1条主表记录 N条明细记录”所有按商品维度的统计都能用SQL轻松完成。3.3 库存扣减下单时更新还是支付后更新这是商城项目最经典的分歧点。下单时扣库存能防止超卖但如果用户下单不支付库存会被占用影响其他顾客购买支付后扣库存用户体验好但并发高时有超卖风险。“衣依”这类小体量系统我的建议是下单时扣库存订单超时未支付则释放。实现上可以加一个定时任务把超过30分钟未支付的订单自动取消并把库存回补。这个方案虽然简单但能满足绝大多数中小型服装业务的需求。如果在代码里看到真正的库存更新语句尽量用UPDATE stock SET quantity quantity - ? WHERE product_sku_id ? AND quantity ?这种带条件的更新天然防止负数库存。3.4 辅助表轮播图、收货地址、购物车除了四个核心实体还有几张辅助表容易被忽略但它们影响日常使用。轮播图表管理首页的促销图管理员可以替换图片和跳转链接收货地址表关联用户ID用户可以维护多个地址并设置默认购物车表其实就是“用户 SKU 数量 勾选状态”的弱实体不需要复杂设计。这些表没有技术难度但接口设计要顺手。比如购物车的增删改查、勾选状态切换、批量删除都会直接影响前端的交互流畅度。我建议拿到源码后把所有表都过一遍理解外键关系和字段含义后面改需求时才能精准定位到表和对应接口。4. 后端核心登录鉴权、商品接口与订单提交的事务后端代码的分层逻辑是这套系统的骨架。Controller负责接收请求、校验参数、返回结果Service层写业务逻辑Mapper层通过MyBatis操作数据库。这个分层方式看起来很基础但恰恰是初学者最需要建立的习惯——业务逻辑不要堆在Controller里。4.1 登录注册与密码加密登录模块看着简单实际容易踩坑。密码绝对不能明文存数据库也不建议用简单的MD5——MD5可以暴力破解彩虹表一查就出来。这套系统里用的加密方案是加盐哈希比如BCrypt每次加密结果都带上随机盐安全性好很多。登录态的保持用的是Token机制。前端登录成功后后端返回一个Token字符串前端存在本地存储里每次请求都通过请求头带上。后端写一个拦截器统一从请求头里解析Token、校验有效期、把当前用户信息放进请求上下文。比传统的Session方案更适合前后端分离因为后端API是无状态的部署多台机器扩展也不需要额外处理Session同步。4.2 商品分页与条件筛选商品列表是商城访问量最大的接口设计不好会卡成幻灯片。分页是必须的MyBatis里可以手写LIMIT offset, size也可以用PageHelper插件。条件筛选建议用动态SQL分类、价格区间、关键字这些条件不是固定的用if标签拼SQL片段比写多条固定SQL再判断分支调用可维护性高得多。还有一点容易忽略排序字段要按实际需求设计。服装商城最常见的排序是新上架、价格升序、价格降序、销量优先。每一个排序选项对应SQL里的ORDER BY子句不要把排序逻辑写死在SQL里而是要接收一个排序参数动态拼接同时注意字段名用白名单校验防止SQL注入。4.3 购物车逻辑购物车这块代码不复杂但细节很多。加入购物车时先查购物车表里有没有用户已存在的同款SKU记录有就把数量加一没有就新增一条。数量修改时要限制不能超过库存。勾选/取消勾选直接更新字段结算时只统计被勾选的条目。另外购物车的展示接口一定要联查出SKU信息和商品信息否则前端只知道一个SKU ID根本渲染不出商品名、图片和价格。这就要用关联查询三张表join一下一次接口把前端要的数据全给足前端不需要发多个请求去拼数据。4.4 订单提交的重头戏事务与数据一致性订单提交是后端逻辑里最重要的一块也是面试和答辩最喜欢问的地方。一次订单提交操作会涉及多张表的写入订单主表、订单明细表、库存扣减、购物车清理可能还有地址信息读取和用户信息校验。中间哪一步失败前面写入的数据就必须全部回滚否则数据库里会出现“半截订单”。这就要靠Spring的Transactional注解。在Service方法上加上这个注解方法内任何一个数据库操作抛出异常整个事务自动回滚。但要注意Transactional默认只回滚运行时异常RuntimeException如果是受检异常需要显式指定rollbackFor我见过不少事务“没生效”的案例根因就是这里。下单并发也是要注意的点。同一件商品同时被多个用户下单库存可能被扣成负数。前面提过更新库存的SQL要带数量条件比如WHERE quantity #{num}这样可以避免用Java代码先查再更新的竞态问题。4.5 后台管理的权限控制后台接口不能裸奔必须校验管理员身份。实现方式有两种一种是在登录接口区分用户角色Token里带上role字段后台接口的拦截器校验角色是否等于管理员另一种是独立的管理员表和管理员登录接口。小体量系统用第一种就够了代码更简单。权限校验的代码最好抽成注解或工具方法而不是在每个后台Controller里手动判断。不然接口一多漏加校验的接口就是安全隐患。这套系统的后台接口统一走一个前置拦截逻辑新增后台接口时只要按规范写就会自动被保护起来。5. 前端Vue的工程组织页面路由、状态管理与请求封装前端工程写得好不好直接决定这个项目改起来痛不痛苦。“衣依”的前端部分用Vue组织后台和前台分目录管理整体结构清晰。但前端不是只有页面请求封装、路由守卫、状态管理这些基础设施才是提高开发效率的关键。5.1 目录与路由规划前端工程里views目录按业务模块划分首页、商品、购物车、订单、个人中心、后台管理。每个模块一个子目录内部再按页面拆文件。路由的规划要跟前端目录对应比如/home对应首页组件/product/:id对应商品详情页/admin/product对应后台商品管理页。有一点容易被忽略前端路由不要直接用中文或带空格的路径最好全部用语义化的英文短横线命名。商品详情页的路径用/product/123比/productDetail?id123更干净URL可读性好也更利于分享和SEO虽然SPA的SEO本身有限但规范的URL总归是好的习惯。5.2 拦截器与登录态管理Axios请求封装是前端工程里必做的一件事。统一设置baseURL统一在请求头里带上Token统一处理401未授权跳转登录页统一拦截后端返回的错误码弹提示。这一套做完业务页面里的请求代码会非常简洁只需要关心业务数据不用每个请求都写错误处理。路由守卫同样重要。未登录用户直接访问购物车、订单结算这些需要登录的页面导航守卫要做拦截跳转。后台路由更严格要校验Token里的角色信息非管理员直接踢回登录页或首页。前端守卫是后端权限拦截的第一道体验层做得好能省很多后端报错排查时间。5.3 商品列表到下单的一连串交互服装商城前端的核心交互是“浏览 → 选款 → 加购 → 结算”每一个环节都有对应的组件和状态。商品卡片组件展示封面图、名称、价格进入详情页后用户要选择颜色和尺码选完组件要能实时联动显示对应SKU的库存和价格加购成功后列表上方要弹出购物车徽标数字更新。这些交互如果不用组件化开发页面会变得非常臃肿。把选款逻辑抽成一个SkuSelector组件商品详情页和电商活动页都能复用。购物车徽标的数字更新可以用Vuex或Pinia管理全局购物车计数避免每次都得重新请求接口提升交互流畅度。5.4 后台管理页面的表单与表格后台管理的核心是数据录入和列表操作最常见的形态是“表格 表单弹窗 分页”。商品管理页就是典型表格展示商品列表支持分页、搜索新增/编辑时弹出表单表单里有分类下拉、商品图上传、SKU规格动态添加删除时二次确认弹窗。后台的表单交互细节值得打磨。SKU规格的动态添加是比较复杂的表单逻辑因为颜色、尺码的排列组合是动态的用户得能自行添加几行规格数据每行包含颜色、尺码、价格、库存四个字段。这个功能初写很头大但做出来之后对服装类后台来说价值巨大几乎是刚需。6. 源码到手之后从环境准备到本地跑通拿到完整源码第一件事不是看代码而是先把项目跑起来。一个能跑起来的项目在手对照代码去理解业务会快得多。我按实际操作顺序把整个流程拆成几步每一步的坑都会点出来。6.1 环境要求与版本建议这套系统的环境要求不复杂但对版本有讲究。JDK建议用8或11太新的版本容易遇到框架依赖不兼容MySQL建议5.7或8.0字符集选utf8mb4后端构建工具是Maven。前端需要Node.js环境建议用14以上的LTS版本npm或yarn都行。版本匹配是最容易出问题的环节。不少项目在我本机跑不起来最后发现是JDK版本太高SpringBoot老版本对高版本JDK的兼容性并不好会出现一些奇怪的反射异常。稳妥起见直接按项目文档或pom文件里声明的版本装环境不要追求最新。6.2 数据库导入与配置检查数据库导入路径一般是找项目里的.sql文件。用Navicat或命令行执行source命令导入导入后核对一下表数量和数据。重点看字符集有些SQL文件本身编码有问题导入后中文乱码就要重新用utf8mb4字符集建库。连接配置在application.yml里要改三处数据库地址、用户名、密码。这里我特别提醒一个坑SpringBoot读取配置时password字段如果包含特殊字符要在配置里转义或使用环境变量否则字符串解析会出问题。数据库连接成功后后端启动日志里不会立刻显示表信息但接口请求如果报数据库错误大概率就是连接配置出了问题。6.3 后端启动的具体操作后端启动没有太多玄学。命令行进入后端工程目录执行mvn spring-boot:run或者在IDEA里直接运行启动类。如果Maven依赖下载慢可以配置阿里云镜像仓库。启动成功的标志是看到“Started Application in x seconds”类似日志然后端口默认8080开始监听。启动失败的高频原因有三个一是端口被占用二是MySQL没启动三是依赖没下载完整。从业经验来看“端口被占用”是第一大坑直接用netstat -ano查端口占用把占用进程结束或改配置端口即可。6.4 前端依赖安装与开发服务器前端工程执行npm install安装依赖这个环节有可能遇到版本问题常见的是node-sass这种强编译依赖装不上。解决思路有两个换用对应的镜像源安装或者升级Node版本后重新安装。启动开发服务器用npm run serve启动成功后浏览器访问前端地址。前端和后端的联调是另一个高频踩坑点。前端localhost:8080后端localhost:8080/后端路径跨域问题肯定存在解决方案是在后端加CORS配置或者前端配置开发代理。看源码时注意一下vue.config.js里的proxy配置这类内容通常是已经配好的但环境变了之后需要适配调整。6.5 高频报错排查清单我整理几个最常见的问题你如果跑项目碰上了可以对照排查。现象根因解决方案前端页面能开但接口全挂前端代理没生效或后端地址配错检查vue.config.js的proxy配置和application.yml的端口数据库中文乱码库表字符集不是utf8mb4重建库建库语句指定utf8mb4Maven依赖下载失败网络原因或镜像未配置配置阿里云Maven镜像后端启动报端口占用8080被其他进程占用换端口或结束占用进程登录接口报Token异常前后端Token字段名不一致统一请求头里的Token字段名7. 实战复盘踩过的坑和改进方向代码跑通了业务理解了接下来要聊聊我在实际开发这类系统时踩过的坑。这些经验不是看文档能知道的全是实际操作里一点一点试出来的。7.1 金额字段别用double商品价格和订单总金额是商城系统的核心数据精度要求极高。用Java的double或MySQL的float做金额计算会出现10.2 - 9.3 0.899999这种误差账面金额算不平。正确做法是Java侧用BigDecimal数据库侧用decimal类型所有金额运算走BigDecimal避免浮点运算。这个坑在订单模块里尤其危险。多个商品价格求和、满减优惠计算、订单金额比较任何一步用了double最后的总金额都可能带误差。前端展示可以转成字符串或分单位处理但后端计算必须保证精确。7.2 事务注解的几种失效场景Transactional不是加上就万事大吉。失效场景主要有三种第一种是方法内部自调用就是同类里一个方法调另一个带事务注解的方法Spring代理机制下事务不生效第二种是异常被catch住没抛出来事务感知不到异常自然不会回滚第三种是方法不是public的Spring的事务切面默认代理不了非public方法。理解这三种场景特别重要。订单提交这种核心业务一定要测试异常回滚可以在代码里故意抛一个异常验证数据库数据是不是完整回滚。如果事务没生效订单主表写入了但明细没写入这种脏数据在真实业务里是要出事故的。7.3 图片上传的路径与访问问题后台管理要上传商品图片这里有几个坑。第一个是上传文件的保存路径如果存的是绝对路径部署换一台机器就失效第二个是访问路径前端通过什么URL能访问到图片第三个是文件大小限制SpringBoot默认单文件上传大小只有1MB服装商品高清图动不动就超。处理方案是文件保存到项目中配置的相对路径目录在application.yml里做静态资源映射比如file:D:/upload/映射到/upload/**前端访问图片时统一走/upload/xxx.jpg。文件大小限制在application.yml里显式调大比如单文件20MB整个请求100MB这个值是动态调的不能拍脑袋要看后台实际要传的图片规格。7.4 项目后续可以怎么扩展这套系统跑通之后扩展空间其实很大。第一优先级是支付模块可以接入第三方支付把订单状态从“待支付”真正推进到“已支付”第二是物流模块订单发货后录入快递单号用户端能查看物流轨迹第三是营销模块优惠券、满减、限时折扣这些玩法在服装销售里很常见。数据统计也是值得做的方向。后台增加销售报表、热门商品排行、用户增长曲线这些不复杂就是从订单明细表里做汇总查询但对服装店经营非常有用。技术层面还可以把MyBatis升级成MyBatis-Plus单表CRUD就不用写SQL了开发效率能提升一大截。7.5 源码之外的一点个人体会最后说点实在的。源码在网上能找到很多类似的版本但真正把一套系统吃透需要自己动手改造几个功能。我建议拿到“衣依”这套源码后先别急着交差或部署而是给它加一个小功能比如商品收藏、按品牌筛选或者做一个简单的销售统计页面。当你亲手在别人的代码结构里增加一个完整功能你对这个系统的理解会远超只看代码的阶段。我在实际项目里接手过不少类似系统最大的体会是这类系统真正难的地方不在写代码而在于把业务流程理解清楚并用数据库结构和代码把流程固化成可靠的逻辑。商品状态怎么流转、库存怎么保证不超卖、订单事务怎么保证完整这三个问题想透了服装商城这类项目对你来说就没有秘密了。