1. 这个项目要解决的不是“做一个电商”这么简单先说说我为什么会盯上这个题目。花卉电商和数码电商、服饰电商看着都是电商但骨子里完全是两回事。数码产品是标品参数一列用户比完价格就下单服饰是非标品但有尺码、有版型、有退货率兜底。花卉不一样——它是强时效、强损耗、强地域性的非标品一束鲜花从云南斗南的田里剪下来到用户手里超过三天品质就大打折扣。这意味着系统不能只做商品展示和下单还得管库存的实时扣减、冷链物流的节点跟踪、损耗率的动态修正甚至要处理“今天下单明天花就得到”这种极端履约场景。市面上很多现成的电商开源系统比如那些通用的二手商城、图书商城拿过来改改就上花卉大概率会死在两个地方一是库存模型跟不上花是成批进货、分批损耗的不能像卖手机一样按SKU锁死库存二是营销玩法错位花卉消费的决策链路里“送人”和“自用”是两套完全不同的心智模型通用系统里的满减、优惠券逻辑根本覆盖不了“代送贺卡”“定时送达”这类需求。所以当我看到这个标题的时候第一反应是这个项目不是单纯地“用DjangoVueMySQL攒一个商城”而是围绕花卉这个特殊品类把电商通用能力和品类特有逻辑重新做了一次组合。这篇博文我就想从头到尾拆一遍数据库怎么设计才对得上花卉的库存模型、Django后端怎么把订单状态机做扎实、Vue前端哪些地方最容易写飘、还有那套我管它叫“差一步就跪”的联调环节。不管你是毕业设计想找个完整可跑的题目还是工作里真的被排到“给花店做线上商城”这种需求这篇文章的内容都应该是直接能落地的。下面开始进入正题。2. 选型解析DjangoVueMySQL这个组合到底是为了谁的便利先说结论这套组合是当前做中小型垂直电商系统最稳的组合之一不算花哨但每一层都踩在“够用、好招人、好维护”这三个词上。2.1 为什么后端是Django而不是Spring Boot或GoSpring Boot确实企业级项目用得最多但它的学习曲线和工程重量对中小项目来说偏重。Go的并发能力强但生态里和业务相关的轮子得自己拼。Django的优势是三件事第一自带Admin后台。这个太关键了。花卉电商的管理员不需要是程序员花店老板要能自己上架商品、修改库存、查看订单。Django的Admin改一改就能把整套后台管理界面交付出去省掉了独立开发后台管理系统的工作量。这在项目周期按周计的实战环境里是压倒性的优势。第二ORM的模型设计和迁移机制。Django的ORM虽然不是性能最强的但它的模型层设计和数据库迁移工具配合得非常好。你写一个模型类跑一条命令就把表建好了字段改了再跑一条命令就能平滑迁移。对迭代速度要求极高的电商项目来说这个体验比手写MyBatis XML映射舒服太多。第三安全和会话管理的内置能力。电商涉及用户登录、支付回调、CSRF防护、XSS过滤。Django自带的认证系统、CSRF中间件、安全响应头都是开箱即用的。你不需要像Flask那样手动去拼Flask-Login、Flask-WTF这一堆插件。当然选Django也有代价它的同步模型在处理高并发I/O密集场景时会有瓶颈。但一个区域性的花卉电商平台峰值并发能到几百就已经很了不起了Django配上有状态的服务部署方式完全能扛住。这个后面部署章节我会细讲。2.2 为什么前端选Vue而不是React这是个容易引战的话题但放到这个项目的实际场景里答案其实非常务实Vue对中小型团队和单兵作战的开发者更友好。React本身很强大JSX的灵活性在大型项目里优势明显。但需要背靠一个完整的工程化体系和严格的代码规范否则组件写得再漂亮状态管理一样会乱。Vue的模板语法贴近HTML思维单文件组件把HTML、CSS、JS放在同一个文件里对一个人同时管前端后端的情况来说心智负担小得多。再就是Vue生态里的Element UI / Element Plus这对后台管理系统的开发效率是核弹级的提升。表格、表单、分页、弹窗、日期选择器全是现成的改改配置就能用。做管理端的时候你能把80%的时间花在业务逻辑上而不是抠组件的样式和行为。还有一个现实考量Vue的中文社区活跃度极高出了什么bug搜索一下基本都有对应的解决方案。做电商系统你大概率会在“表单校验”“路由权限控制”“跨域调试”这几个地方卡住Vue社区这些坑早就被踩平了这能帮你省下大量排查时间。2.3 为什么MySQL依旧是这个级别项目的理性选择这几年PostgreSQL的呼声很高JSON字段、GIS能力确实更强。但对花卉电商来说MySQL是更顺手的那个。核心原因是生态兼容性和运维习惯。Django的ORM在MySQL上跑得最顺Python的数据库驱动mysqlclient也成熟稳定。主机商的云数据库服务里MySQL的规格选择最丰富、价格最透明。你要找个懂MySQL的运维人员一抓一大把但要用PostgreSQL的冷门特性出了问题排查的时间成本明显更高。另一个原因是花卉电商的数据模型并不需要特别花哨的数据结构。我们用到的无外乎就是商品表、SKU表、库存表、订单表、订单明细表、用户表、地址表、优惠券表这些。关系型建模完全够用商品的规格属性和花的图片走标准关联表就行。等哪天数据量真的大到需要考虑读写分离和分库分表了MySQL的方案也是被无数公司验证过的。话说回来MySQL的隔离级别默认是可重复读在电商订单这个场景下要特别注意与Django的事务配合。这个问题我在第5节会详细展开不夸张地说它是这个系统里最容易踩但又很少有人提前意识到的一个坑。3. 花卉电商系统的数据库设计从字段到表关系一个都不能想当然很多参考项目把数据库表设计得非常“教科书”照抄一遍能跑但一遇到真实业务就露馅。这个项目我在设计数据表时有四个地方是反复推敲过的。3.1 商品与SKU别把“花”直接当成商品普通电商商品表通常长这样id、name、price、stock。但花卉不行。一束“玫瑰”有红玫瑰、白玫瑰、香槟玫瑰一束“百合”有单头、多头、不同包装等级。如果直接按商品管库存你可能把红玫瑰和白玫瑰的库存混在一起最后页面显示有货用户下单后才发现某个花色早就没了。所以我的设计是商品表commodity与SKU表sku分离商品表存的是描述性信息标题、详情、品类ID、主图、轮播图、上下架状态。SKU表存的是可售卖的具体规格花色、花材数量、包装风格、价格、折扣价、库存、SKU编码。用户在前端看到“红玫瑰11枝礼盒装”这个商品点击“加入购物车”时实际选的其实是某个具体的SKU。订单和购物车都只跟SKU关联不直接跟商品关联。这样库存扣减、价格锁定、优惠计算全部能在SKU粒度上做精确控制。3.2 库存模型的“批次感”才是花卉系统的灵魂我特别想强调这块花卉是有“生命周期”的库存不能用死数字来表示。比如说你周一到货了100扎玫瑰周二卖掉了60扎周三还有40扎。但周三的这40扎品质已经不如周一那批新鲜了。传统库存表直接写“库存40”是没问题的但如果你想做“临期打折”“每日鲜切专区”你需要在库存上附一个批次属性。我在项目里建立了一个库存流水表stock_log和库存批次维度每一次入库都生成一条批次记录包含花材ID、入库数量、入库时间、预计保质期截止时间。每次下单扣减库存时默认按批次剩余量和时间顺序先进先出扣减同时更新批次剩余量。前端可以根据批次截止时间做“今日特价”逻辑过期未售出的自动转入损耗处理。放到论文或毕设里这块是得分点放到真实项目里这块就是花店的命根子。跟着满减做库存的系统是撑不起“凌晨四点半的批发市场行情”的。3.3 订单状态机拒绝用“一个status字段打天下”订单表不要只设计一个status整型那会让你在写业务逻辑时痛不欲生。我推荐的方案是一个状态字段数值型方便索引和查询 一个状态时间线表记录每一次状态变更的时间、操作人和变更原因。订单状态机示例0 待付款1 已付款待发货2 已发货配送中3 已签收4 已完成可评价5 已取消6 售后处理中7 退款完成状态机的设计有两个核心原则一是状态流转只能走合法路径不允许从“待付款”直接跳到“已完成”这需要后端在更新的地方把所有可流转的状态列成映射表做校验二是任何状态变更都要写进时间线表电商售后扯皮的时候这个表就是你和用户沟通的凭证也是后查问题的唯一可靠依据。3.4 用户表与地址表要注意的“赠礼场景”花卉电商的用户不只是“买花的人”还可能是“收花的人”。订单表里除了买家信息一定要有收花人信息姓名、电话、城市、详细地址、期望送达时间、贺卡内容。这些字段千万别放在用户地址表里因为送花的人和收花的人往往不是同一个。所以表结构里用户地址表管理的是“自用”时的收货地址订单表里另建一份收花人快照。这个快照在订单生成时把收花人信息完整复制一份而不是外键关联用户地址表。道理很简单用户改了地址不能影响历史订单的履约信息。上面这几个设计点我在开发文档里都写了详细的建表SQL和ER图说明文档里光数据字典就是三十多页每一张表的每个字段都标了业务含义和取值规则。标题里说的12000字靠的就是这些实打实的细节不是凑字数。4. Django后端实现从用户登录到支付回调哪些功能值得写得“厚重”后端我拆成四大块讲认证与权限、商品模块、购物车与订单、支付回调。每块都说清楚我的设计理由和踩过的坑。4.1 认证与权限不要重复造轮子但要把轮子拧紧Django自带的User模型足够用不要上来就重写用户系统。但有几个地方必须做加强第一手机号登录。花卉电商很大一部分流量来自微信分享用户可能没有耐心注册邮箱用户名。所以我在Django里扩展了AbstractUser新增mobile字段并实现了手机号短信验证码登录和手机号密码登录两种方式。短信验证码的发送走的是第三方服务商后端只负责生成六位随机码、限制发送频率同手机号60秒一次、单日不超过10次、把验证码加密存到缓存并设置5分钟有效期。第二JWT而非Session。虽然Django的Session机制很完善但前后端分离后Vue跑在一个端口、Django跑在另一个端口Session的跨域处理要配置CORS之外的东西比较麻烦。直接上djangorestframework-simplejwt前端拿Token存到localStorage或pinia里之后每次请求带Authorization: Bearer token。这套方案对前后端分离项目是主流调试也简单。第三权限控制要细到“管理员只能看不能改”这种粒度。Django admin里注册模型时我用ModelAdmin的has_delete_permission、has_change_permission做了精细化的按钮控制避免运营人员误操作把商品下架或把订单改了。这个对真实项目来说不是小题大做而是底线问题。4.2 商品模块缓存、过滤、搜索别等卡了再优化商品列表页是最容易写飘的接口因为数据量一旦上千不加优化的查询会肉眼可见地变慢。列表接口用django-filter做参数过滤支持按品类、价格区间、销量排序、上架时间排序。搜索用Q对象做标题和描述的关键字匹配。数据量大了以后想省事可以直接接ElasticSearch或Meilisearch但中小项目用MySQL的LIKE配合前缀索引其实够用前提是搜索词不要太长、表里别放全文大字段。热门商品和首页推荐数据用Django自带cache框架缓存到Redis设置5分钟过期。花卉的商品时效性强缓存时间不能太长5分钟是经验值。商品详情页有个细节要特别提醒库存查询要实时。用户把商品加到购物车之前前端要显示“仅剩X件”这种信息这个X必须实时查SKU库存表不能读缓存。否则用户下单时才发现没货投诉率直线飙升。4.3 购物车和订单事务是底线锁要加对位置购物车这个功能看起来简单不就是增删改查吗但一牵扯到价格和库存问题立刻变复杂。下单这个操作的背后是创建订单主表 创建订单明细表 扣减SKU库存 写库存流水 清空购物车 生成支付单这一连串动作。任何一个步骤失败都不能让前面步骤的数据残留在库里。所以整个下单函数体必须包在transaction.atomic()里并且对SKU库存行使用select_for_update()做行级锁。这里要展开讲一下select_for_update()在MySQL的可重复读隔离级别下会对命中的行加排他锁直到事务结束。这样一来A用户下单扣库存的时候B用户过来下单同一SKU就会被阻塞要等A的事务提交或回滚后拿到最新库存再继续。这个机制天然防止了超卖。我见过不少代码里下单时是先SELECT stock判断stock大于0然后UPDATE stock SET stock stock - 1中间没有任何锁。这在并发稍微上去一点的情况下必出事。你不用MySQL默认隔离级别的深刻原理踩到一次超卖事故就懂了。4.4 支付回调幂等性设计是最容易被忽略的一环接入支付时Django后端要做的是在支付下单接口里生成平台订单号和支付平台交易号保存到支付记录表。把订单号、金额、回调地址、签名发给支付平台前端SDK。支付平台异步通知后后端收到回调验签、核对订单金额、核对订单状态。这里最容易踩的坑是支付平台的异步通知会发送多次如果你不做幂等判断同一个订单可能被回调三次订单金额被加多次、余额被多次更新。我的做法是在回调处理函数开头先查支付记录表如果这笔订单的支付状态已经是“成功”直接返回成功响应不再重复执行业务逻辑。另外回调接口的响应必须在处理完成后明确返回成功标记否则支付平台会按失败处理并继续重试造成不必要的日志轰炸和误报。再补充一个典型问题用户关闭了支付页面但订单还没取消。我的做法是订单表加一个created_at时间戳在查询待付款订单时超过30分钟未支付的自动标记为取消并恢复库存。这个定时任务用Django的celery-beat实现每分钟跑一次扫所有超时订单。真实项目还要加一个“取消前短信提醒”的功能但这属于业务运营层面的增强系统架构要预留好这个接口。5. 前端Vue实现页面可以漂亮但状态管理必须可靠前端部分我按“用户端”和“管理后台”两条线来讲。用户端要的是体验流畅管理后台要的是效率两者的侧重点完全不同。5.1 用户端页面商品列表、详情、购物车、结算用户端的核心交互链路很清晰看花 → 挑花 → 加购 → 结算 → 支付 → 等收货。商品列表页用Vue的v-for渲染卡片加上Element Plus的分页组件用query参数控制第几页和筛选条件。但要注意筛选条件改变时要把滚动条拉回顶部这是个交互细节不写的话用户会在列表很长时产生迷失感。商品详情页是转化率的核心。我推荐的做法是轮播图展示商品图SKU选择器根据后端返回的可选规格动态渲染。用户点选某个花色后前端要同步显示对应的价格、库存、图片背景色这些信息都放在SKU数组里前端做数据联动匹配。这里插一句不要在详情页让用户自己选数量时选择大于库存的值自定义指令或计算属性直接限制。购物车页的难点在“金额联动”。勾选、全选、修改数量、删除商品都要实时重新计算总价。我用Vuex或Pinia看你用哪个管理购物车状态把购物车数据放在全局store里这样在不同页面跳转之间数据不会丢。同时购物车数据每隔一定时间或关键操作后同步到后端这样即使用户换了设备登录历史购物车数据还能拉回来。注意如果用户未登录购物车数据存localStorage登录后要合并再同步到后端。结算页要处理两个隐藏功能贺卡填写和配送时间选择。贺卡内容限制50字以内前端做字数统计和截断配送时间分成“立即配送”和“指定时间配送”指定时间只能选未来三天的某个两小时区间这是跟花店实际配送能力对齐的。前端虽然能做校验但后端同样要校验配送时间防止用户绕过前端直接构造请求这我在文档的“接口安全设计”一节里专门写了。5.2 管理后台表格操作多但别在接口设计上拖后腿管理后台用的是Vue Element Plus的Admin布局左侧菜单、右侧内容区。功能包括商品管理、订单管理、库存管理、用户管理、优惠券管理、数据统计。订单管理列表要做的是按状态筛选、按时间搜索、点击查看详情。详情里要有完整的状态时间线我前端做成了一个垂直的时间轴组件每一项展示状态名称、时间、操作人。这虽然不复杂但对运营人员来说是最有价值的功能之一。还有一个体验优化点批量发货。花店来了100个订单店主不可能一个个点开页面对付后台要提供Excel导入物流单号、批量更新的功能。前端用Element Plus的el-upload组件上传Excel后端用Python的openpyxl库解析校验订单号、物流单号格式后批量更新。这个功能一旦上线运营会爱你。管理后台的权限我用后端返回的权限列表控制菜单显示和按钮可用状态前端路由守卫里判断当前用户是否有权限进入对应页面。路由级懒加载也是必须的花店老板用的电脑配置不一定高一个动辄几MB的JS包会让后台打开速度慢得非常明显。5.3 前后端联调跨域和接口约定是两个绕不开的问题这里重点聊聊跨域。开发环境Django跑在http://localhost:8000Vue跑在http://localhost:5173端口不同必然有跨域问题。Django后端要安装django-cors-headers并在settings里配置CORS_ALLOWED_ORIGINS列表里加入前端开发服务器地址。别图省事直接CORS_ALLOW_ALL_ORIGINS True那会带来安全隐患。生产环境里前后端部署在同一个域名下只需要配一个域名就行了。允许的请求方法、请求头也要明确配置否则前端请求带Authorization头的时候预检请求会直接失败。接口约定方面我推荐一个统一的返回结构{ code: 200, message: success, data: {} }前端封装的axios拦截器统一处理codecode为200时走正常逻辑code为401时自动跳转登录页code为其他值时弹出消息提示。后端统一异常处理用Django的exception_handler扩展确保所有接口的异常都能转换成这个结构返回。这套约定一旦定下来前后端并行开发时就能少扯皮。我的体会是比技术选型更重要的是接口文档的维护平时用Apifox或Swagger把接口管理好后面前后端对接的时间能压缩到两三天。6. 部署上线与性能优化一步没跑的部署方案等于白做很多教程讲到部署就“一键完成”实际上从本地跑起来到生产环境稳定运行中间隔着好几个具体问题。6.1 服务器部署的基本架构我的部署架构是经典的Nginx uWSGI MySQL Redis前端构建后的静态文件直接由Nginx托管。四层各司其职Nginx处理静态文件和反向代理动态请求uWSGI扛Django进程MySQL存业务数据Redis做缓存和Session外置存储。参考配置大概这样server { listen 80; server_name yourdomain.com; # 前端静态文件 root /var/www/flower-shop-frontend/dist; index index.html; location /api { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location /admin { proxy_pass http://127.0.0.1:8000; } location /static/ { alias /var/www/flower-shop-backend/staticfiles/; } location /media/ { alias /var/www/flower-shop-backend/media/; } }一个细节阿里云/腾讯云的安全组要放行80端口但不要把所有端口都开放数据库3306端口尤其不能暴露公网否则数据库被扫到就是灾难。我见过不止一个项目Redis端口裸奔在公网上被写入恶意数据后整个服务瘫痪。6.2 uWSGI进程数与数据库连接数怎么配有经验的运维会给一个经验值uWSGI进程数通常按CPU核心数×2来设置2核4G的服务器开4个进程就差不多了。但这里有个隐含问题——每个uWSGI进程会持有自己的MySQL连接4个进程就是4个连接。Redis连接数也一样。Django的数据库配置里有个CONN_MAX_AGE参数不设置意味着每个请求都新建连接性能差设置了又要注意连接数不能超过MySQL的max_connections。我给的配法一般是CONN_MAX_AGE 60然后MySQL的max_connections调到200Redis的maxclients默认足够。这个配不好上线后隔几天就会出现“Too many connections”的报错业务直接挂掉。6.3 静态文件和媒体文件图片是花卉电商的门面花卉商品的图片质量直接影响转化率。Django的media目录保存上传的图片Nginx配置里用alias指向它。但要注意不要让客户直接访问上传的原图不然一张几MB的照片会把带宽拖垮。图片处理上两个推荐方案后端用Pillow在缩略图接口里动态生成指定尺寸的图片前端按需请求/media/thumbs/200x200/xxx.jpg。或者用云存储对象服务上传后拿到CDN地址前端直接用CDN链接。中小项目用第一条就够了成本低还不用绑云服务。6.4 部署后必做的三件“自查”好多项目部署后能打开页面就以为成功了但至少这三件事要自查第一Django的Debug必须设为False否则错误页面会把数据库密码、代码路径等敏感信息直接暴露给访问者。第二ALLOWED_HOSTS必须配成生产域名不配置的话Django会拒绝所有非白名单域名的请求页面打开全是400错误。反过来说它也是防止恶意请求的一道闸。第三SQLite和本地文件存储的生产环境陷阱。如果你在本地开发用SQLite部署到服务器却切到MySQL记得把迁移文件完整跑一遍并且检查所有models里的TextField有没有在MySQL里被映射成longtext以外的奇怪类型。环境不同导致的行为差异只有部署到生产环境那一刻才会暴露。7. 源码结构、文档目录与二次开发思路拿到项目后先从哪里看先说明一下这个项目的交付物组织方式这直接关系到你会不会用。7.1 后端源码目录怎么拆的flower-shop-backend/ ├── manage.py ├── config/ # Django项目配置 │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── apps/ │ ├── users/ # 用户认证与权限 │ ├── commodities/ # 商品与SKU管理 │ ├── carts/ # 购物车 │ ├── orders/ # 订单与状态机 │ ├── payments/ # 支付与回调 │ ├── coupons/ # 优惠券 │ └── operations/ # 首页推荐、活动专区 ├── utils/ │ ├── response.py # 统一返回结构 │ ├── exceptions.py # 全局异常处理 │ └── pagination.py # 分页工具 ├── staticfiles/ └── media/每个app内部都是models.py、views.py、serializers.py、urls.py、admin.py的完整结构。如果从来没有接触过前后端分离项目的读者我建议直接从orders/views.py看起因为订单模块是整个系统的业务核心把它读透你基本就掌握了这个业务逻辑的六成。7.2 前端源码目录怎么拆的flower-shop-frontend/ ├── src/ │ ├── api/ # 接口请求封装 │ ├── assets/ # 样式与静态资源 │ ├── components/ # 公共组件 │ ├── layouts/ # 布局组件 │ ├── router/ # 路由与守卫 │ ├── stores/ # Pinia状态管理 │ ├── views/ │ │ ├── home/ │ │ ├── product/ │ │ ├── cart/ │ │ ├── checkout/ │ │ ├── order/ │ │ └── admin/ │ ├── utils/ # 请求封装、时间格式化 │ └── App.vue ├── package.json建议新人拿到后先看src/api/目录每个接口文件和后端app一一对应看完API封装你就能知道平台一共提供了哪些功能再对照views/目录去看页面调用关系整个项目就串起来了。7.3 12000字开发文档到底写了什么标题里强调的开发文档我见过很多项目是拿README充数。这个项目的文档我建议你重点看五部分技术架构说明包含系统架构图、技术选型的对比表、开发环境与生产环境的配置清单。数据库设计文档所有表的建表SQL、ER图、字段说明数据字典。这个对做毕设答辩或者交接给后手最有价值。接口文档每个接口的请求地址、请求方式、参数说明和响应示例。这个文档能让前后端开发对接口约定一目了然。部署文档从服务器初始化到代码部署、域名配置、HTTPS证书申请、Nginx配置的逐步说明。测试用例与踩坑记录我在开发过程中遇到的典型问题从问题描述、排查过程到解决方案都记录下来了。这部分是常规文档里最缺的也是最值钱的一部分。7.4 二次开发的话哪里最值得扩展如果这个项目你要作为毕业设计或课程项目继续扩展我建议三个方向第一个方向是增加花材的溯源信息。比如展示花材产地、采摘日期、护理建议加上这些可以明显提升用户信任感属于低成本高回报的扩展。第二个方向是增加预约定期送花功能。这个在礼品场景里非常常见用户买一个月每周送一次。实现上需要加一个“订阅计划”表和定期订单生成服务逻辑不复杂但业务价值很大。第三个方向是做一个小程序端。买花送花这个场景天然适合在微信生态里传播Vue技术栈过渡到小程序也相对平滑文档里把接口全部按HTTP REST风格设计好了小程序端直接复用后端API工作量主要在UI适配。8. 我在这个项目上踩过的“差一步就跪”的坑最后这部分我集中讲讲那些开发文档里通常没写、只有跑到真实环境里才暴露出来的问题。按我自己的体感从高到低排了五个。8.1 时区问题订单日期永远比实际晚8小时Django的TIME_ZONE默认是UTC而你在国内开发本地数据库里存的时间是UTC时间展示到前端要加8小时。最直接的处理方式是在settings.py里设TIME_ZONE Asia/Shanghai并保留USE_TZ True这样Django在数据库层存UTC但通过模板或序列化器输出时会自动转换到上海时区。但如果你的前端直接调接口拿时间戳还是要注意时间戳是UTC还是本地时区统一在接口文档里标明“所有接口时间字段采用ISO 8601格式、含时区偏移”前后端就都不会错。8.2 图片上传的成功与“假成功”Element Plus的el-upload组件默认用action属性发异步请求如果你不填这个属性它会发到自己当前页面路由结果后端返回404但前端依然显示上传成功。这是一个特别具有迷惑性的bug因为页面不报错只是数据库里没有图片数据。解决方法是给组件设置:http-requestcustomUpload自己写上传函数用封装的axios请求到后端的/api/upload/image/接口拿到返回的URL后再把它赋值给表单的图片字段。上传成功必须有后端的明确返回否则一律视为失败。8.3 订单超时未付款库存恢复的节奏订单超时取消功能加入后就出现一个新的并发问题用户下单后锁了库存30分钟内未付款系统自动取消并恢复库存。但如果用户在29分59秒刚刚付款成功定时任务也同时触发了取消就会出现“订单已支付但被标记取消”的事故。我的处理办法在取消订单的事务里先检查订单状态如果是“已支付”则跳过取消在支付回调的事务里先检查订单是否已经处于“取消”状态若是则拒绝支付成功并把订单转为“已取消退款处理中”同时提示用户联系客服。两个方向的事务都要把状态检查放在第一步。8.4 商品列表“加载更多”和“筛选”同时操作时的数据混乱用户端商品列表如果用的是“上拉加载更多”的分页方式那么筛选条件改变时页数必须重置为1并且历史数据要清空。否则会出现“第3页数据还是上个筛选条件的内容”这种状态错乱。我当时在Vue里花了不少时间调这个问题最后用watch监听筛选参数变化发生变化时先重置page为1、清空goodsList再触发请求。这个很小的问题在真实用户手里几乎天天能遇到值得专门提一下。8.5 移动端适配用户是用手机逛花的花卉电商用户很大一部分来自微信和朋友圈的分享页所以用户端前端必须做响应式布局。Element Plus默认偏桌面端不能用它直接套用户端页面用户端建议用Vant这类移动端UI组件库或者干脆在移动端单独做一套H5页面。我最后使用的是双端分离方案管理后台和用户端分开两个前端工程管理后台用Element Plus用户端用Vant。虽然维护成本多一套代码但移动端的体验细节触摸滑动、下拉刷新、安全区适配才真正控制得住。9. 最后再补一句关于复现这个项目的建议我给这个项目配的源码和文档目标是让一个有Django基础但没做过完整电商项目的人能在一个星期内跑起来并能在跑起来之后真正理解每一行核心代码的意图。我的建议是拿到源码不要急着想改功能先严格按照部署文档把系统从零跑一遍。跑通之后再回到数据库表设计那里把每一张表、每一个字段都看一遍然后带着“如果我要加一个功能得动哪些表、写哪些接口”这个问题去翻代码。这比你对着源码抄十遍都管用。这个项目本身不是那种“高并发、分布式、大规模”的架构但正因为它小你才有机会把电商系统从数据模型到订单状态机再到部署上线的完整链路捋清楚。把这一套吃透后面再去接触企业级的微服务电商系统你至少知道每个组件解决的是什么问题而不是被一堆名词唬住。我自己跑完这个项目最大的感受是电商的核心从来不是页面做得有多花哨而是数据模型设计得是否贴合业务、订单链路是否可靠、用户数据是否安全。这三点立住了系统就是个活系统立不住就算前端写出花来上线后也得被运营骂回来返工。希望这篇拆解能帮你在做同类系统的时候少走几个弯路。
阅读完成 · 觉得有帮助?