
简介一份面向微信小程序开发学习者、高职及本科毕业设计人群的鲜花销售小程序完整项目包含微信小程序前端、Vue后台管理端和Java SSM服务端并配有覆盖需求分析、数据库设计、系统测试与项目总结的说明文档。压缩包共1342个文件体积约19.19MB主要文件类型包括Java源码、Vue组件、js逻辑、wxml/wxss页面、png图片、SQL脚本和docx文档还含配置与运行脚本整体目录结构完整清晰。目前已有1573人学习下载适合需要参照真实项目完成课程设计、毕业设计或进行微信小程序与SSM整合练习的读者。借助本项目可理解前后台交互流程、数据库表结构设计以及商家/管理员功能划分说明文档从可行性分析写到系统测试为阅读源码、二次开发和项目答辩提供了完整参考。1. 基于微信平台的鲜花销售小程序源码与文档摆在一起才有交付价值“基于微信平台的鲜花销售微信小程序源码 说明文档”这类项目最常出现在毕业设计、课程设计和接私活的交付场景里。和普通网页商城不一样鲜花商品有两个硬约束短保质期带来的配送时段校验以及“当天截单前必须锁定库存”的库存逻辑。如果只写增删改查页面没有订单状态机和库存扣减项目演示完后没法真正经营。另一个容易被忽略的点是交付物里同时包含源码和文档意味着代码要在另一台电脑上能跑起来文档要能指导对方换AppID、开云环境、连数据库和测试微信支付。下面按从页面骨架到交付自检的顺序把这套体系讲清楚。2. 微信小程序电商骨架从项目结构到商品页的首次渲染2.1 先搞清“微信平台”限定了什么注册、AppID 与开发者工具小程序不是把网页代码改改就能运行的。所有页面都要通过微信开发者工具编译真机体验要绑定开发者或体验成员云开发和 request 合法性都依赖微信后台配置。所以拿到一个“基于微信平台”的源码包第一步不是看代码而是确认主体类型个人主体不能开通微信支付鲜花销售若涉及线上收款必须企业主体如果只是课程演示个人主体配合微信云开发足够。开发者工具的“导入项目”窗口里要填 AppID。我一般建议把源码里的appid字段设置成touristappid游客模式让别人第一次导入时不至于因为 AppID 被占用而失败。如果对方要真机预览文档里必须给出替换路径。project.config.json里的appid决定了编译目标不能漏。2.2 app.json 路由与页面参数首页、分类、详情、购物车、结算小程序的页面注册在app.json的pages数组里第一项是启动页。一个完整鲜花销售小程序的页面清单如下表页面路径功能是否需要 tabBarpages/index/index首页、活动 banner、今日花束是pages/category/category分类浏览按品种筛选是pages/detail/detail商品详情、规格选择、配送时段否pages/cart/cart购物车、数量调整是pages/checkout/checkout订单确认、留言、支付入口否pages/order/list/list订单列表、状态切换是pages/order/detail/detail订单详情、物流信息否如果pages里漏掉页面编译时会直接报page not found但模拟器里不一定每次都报错。收到“源码说明文档”第一件事就是打开这个文件看页面路径和实际文件夹是否一致。我遇到过不少工程文件里写了pages/index/index目录却是pages/index/index/index.js导致导入工程白屏的情况。{ pages: [ pages/index/index, pages/category/category, pages/detail/detail, pages/cart/cart, pages/checkout/checkout, pages/order/list/list, pages/order/detail/detail ], window: { navigationBarTitleText: 鲜花速递, navigationBarBackgroundColor: #fbedd5, navigationBarTextStyle: black }, tabBar: { list: [ { pagePath: pages/index/index, text: 首页 }, { pagePath: pages/category/category, text: 分类 }, { pagePath: pages/cart/cart, text: 购物车 }, { pagePath: pages/order/list/list, text: 订单 } ] } }这段配置里pagePath不需要前导斜杠tabBar.list最多五个页签图标要用 png 且不能使用网络图片。window是全局窗口如果某个页面需要自定义顶部导航栏在该页面的json里覆盖navigationStyle就行。2.3 首页数据流mock 兜底、云函数优先与加载页处理商品数据放在哪我一般准备两层miniprogram/data/products.js里存一份 mock 数据api/product.js里封装请求云函数的逻辑。首页优先调云函数云函数未部署或超时则回退 mock。这样源码拿到手后立即可以编译对方不需要先建云环境才能看到效果。// miniprogram/api/product.js const fallback require(../data/products.js) async function fetchProducts() { try { const res await wx.cloud.callFunction({ name: getProducts }) if (res.result res.result.list) { return res.result.list } throw new Error(empty) } catch (e) { return fallback } }为什么先判断res.result.list云函数如果报错进入 catch 返回 mock页面不会白屏。加载页方面微信小程序“刚进入的加载页面”往往不是启动图而是首页onLoad里的wx.showLoading。如果想把它改成骨架屏做法是移除showLoading在data里加loading变量用wx:if控制骨架屏 view。这个修改很小但能明显提升首屏观感。如果首页用了onShow去刷新数据每次从详情页返回都会重新弹 loading文档里最好注明这一点。用onLoad还是onShow取决于是否需要回看刷新库存。3. 商品分类、购物车与“易腐”库存鲜花业务的数据边界3.1 分类与规格花束、花盒、绿植怎么建模订单之外的数据关系很多是查询分类列表、商品列表、商品详情、购物车、订单列表。数据库表可以按关系型设计也可以用云开发集合。为了说明文档易读我倾向于给出一个 SQL 结构来约束概念实际实现时再换成云数据库集合。CREATE TABLE categories ( id INT PRIMARY KEY, name VARCHAR(50) NOT NULL, sort INT DEFAULT 0 ); CREATE TABLE products ( id INT PRIMARY KEY, category_id INT NOT NULL, name VARCHAR(100) NOT NULL, cover_url VARCHAR(255), price DECIMAL(10,2) NOT NULL, stock INT NOT NULL DEFAULT 0, delivery_today TINYINT DEFAULT 1, status TINYINT DEFAULT 1 ); CREATE TABLE product_specs ( id INT PRIMARY KEY, product_id INT NOT NULL, spec_name VARCHAR(50), spec_value VARCHAR(50), price_delta DECIMAL(10,2) DEFAULT 0 );鲜花 SKU 不像服装那样是“颜色尺码”更常见的是“玫瑰礼盒贺卡”组合。product_specs用spec_name代表“花材”“包装”“卡片”spec_value是具体选项相比把多个属性打在一个字段里这种表结构更容易在商品详情页用单选框分组渲染。3.2 购物车本地状态与下单前的库存校验购物车放在wx.setStorageSync还是服务端大部分项目会在本地维护一份用户点加购时请求服务端库存。为什么不是每次操作都调服务端因为购物车交互频繁仓储缓存会更流畅但要接受一个事实本地数量不是可信库存只有订单提交时才以服务端为准。function addToCart(product, selectedSpec) { const cart wx.getStorageSync(cart) || [] const key ${product.id}-${selectedSpec} const index cart.findIndex(item item.key key) if (index -1) { cart[index].quantity 1 } else { cart.push({ key, productId: product.id, spec: selectedSpec, quantity: 1, price: product.price }) } wx.setStorageSync(cart, cart) }这里把商品 id 和规格拼接成key是为了让一样的花束因包装不同而分成两行。提交订单时把 cart 传给云函数云函数里要加一个“预期配送日期”的校验如果用户选的配送日是今天但当前时间已超过delivery_today对应的截止时间订单不能创建。3.3 云开发还是私有后端让源码能立刻跑起来从交付角度我优先推荐微信云开发。云开发在个人主体下也可以开通有免费额度不需要自己买服务器、配 HTTPS 域名和 ICP 备案。缺点是数据库的操作习惯是 NoSQL文档里要把云集合结构和 SQL 对应关系写清楚。下面是一段云函数里扣减库存的示例重点是“条件更新”// cloudfunctions/checkout/index.js const cloud require(wx-server-sdk) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db cloud.database() const _ db.command exports.main async (event) { const { goods, deliveryTime } event for (const item of goods) { const res await db.collection(products) .where({ _id: item.productId, stock: _.gte(item.quantity) }) .update({ data: { stock: _.inc(-item.quantity) } }) if (res.stats.updated 0) { return { ok: false, msg: 库存不足${item.productId} } } } return { ok: true, deliveryTime } }_.gte保证库存大于或等于购买数量才更新_.inc(-item.quantity)在原值基础上减少。如果更新条数是 0说明库存不足这时要把前面已经扣减的商品回滚——云函数里没有数据库事务稳妥的做法是先做一次查询锁库存、再扣减或者把整个购物车扣减放到一个 for 循环里失败时反向补偿。4. 登录、下单与支付从临时 code 到订单状态流转4.1 wx.login 与 openid 的用法小程序登录不需要自己存密码。前端调wx.login拿到临时 code传给云函数云函数从上下文里直接取OPENID。// cloudfunctions/login/index.js const cloud require(wx-server-sdk) cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) exports.main async () { const { OPENID, APPID, UNIONID } cloud.getWXContext() return { openid: OPENID, appid: APPID, unionid: UNIONID || } }这个云函数没有入参也能拿到身份因为 openid 是由微信平台根据 AppID 和用户身份生成的不需要自己解密 code。不要把 code 存到数据库它是单次使用。对于鲜花电商用户登录后不需要强制收集手机号手机号可以作为收货联系人的可选字段在结算页手动填写。4.2 订单状态机与超时关闭鲜花订单比普通电商多一个“配送时效”字段但状态流转相对固定状态含义可流转到PENDING待支付PAID, CANCELLEDPAID已支付SHIPPED, CANCELLEDSHIPPED配送中DONEDONE已完成无CANCELLED已取消无用状态机而不是 if 判断是为了防止订单从 DONE 退回 PAID 这种脏数据。代码const NEXT { PENDING: [PAID, CANCELLED], PAID: [SHIPPED, CANCELLED], SHIPPED: [DONE], DONE: [], CANCELLED: [] } function changeStatus(from, to) { return NEXT[from].includes(to) }待支付订单要有超时机制。可以在云函数里定期扫描超过 15 分钟未支付的订单将状态置为 CANCELLED同时释放锁定库存。注意释放库存的时间点生单时预先锁库超时取消后再加回库存。这两个操作之间不能只做一个不然要么超卖要么库存越积越多。4.3 微信支付与 mock 切换“源码说明文档”项目里最常见的问题是拿到代码的人没有微信支付商户号。所以源码里不要硬编码支付参数要留一个PAYMENT_MOCK开关。// miniprogram/config/index.js module.exports { PAYMENT_MOCK: true, CLOUD_ENV: your-env-id }当PAYMENT_MOCK为true时结算页点“支付”直接把订单置为已支付并跳转订单详情为false时调用云函数发起云支付。微信支付云调用的参数如下await cloud.cloudPay.unifiedOrder({ body: 鲜花支付, outTradeNo: orderNo, spbillCreateIp: 127.0.0.1, subMchId: 商户号, totalFee: totalFee * 100, envId: your-env-id, functionName: payCallback })totalFee单位是分outTradeNo不能重复成功后的回调通过云函数payCallback接收。没有商户号时subMchId需要留空否则云调用会报商户号不存在。5. 源码说明文档的交付件怎么组织才不是“能编译”而是“能看懂”5.1 源码目录规范把文档放进仓库而不是压缩包很多“源码说明文档”的压缩包打开后只有源码.zip和需求文档.docx。我一般会把代码仓库按下面结构整理flower-shop-miniprogram/ ├── miniprogram/ │ ├── pages/ │ ├── components/ │ ├── data/ │ ├── api/ │ ├── styles/ │ ├── utils/ │ └── app.js ├── cloudfunctions/ │ ├── login/ │ ├── getProducts/ │ └── checkout/ ├── doc/ │ ├── 01-环境部署.md │ ├── 02-数据库设计.md │ ├── 03-接口说明.md └── README.mdminiprogram是前端根目录cloudfunctions是云函数目录doc放文档而不是放在压缩包外层。README 开头给出“运行环境要求”和“导入步骤”让人打开仓库五分钟内知道怎么启动。不要用“微信小程序代码”这种命名。5.2 说明文档的四件事环境变量、初始化、接口、测试账号文档不是论文说明文档要解决四个问题章节回答的问题必须写的内容环境部署怎么跑起来Node 版本、微信开发者稳定版、AppID、云环境 ID数据初始化表和数据哪里来SQL 文件、云数据库集合名称、初始商品列表接口说明前后端怎么对接云函数名称、入参出参、错误码测试账号怎么验证流程一个微信测试号、一个 mock 订单、无商户号时的说明文档里最容易缺的是“没有支付商户号时怎么测试”。如果不写清楚对方就会以为代码有问题反复来问“为什么点了支付没反应”。5.3 从 uni-app 到 HBuilderX如果代码是 uni-app 写的市面上同样主题的“微信小程序源码”有不少是用 uni-app 开发的场景是以后要发支付宝小程序、抖音小程序。如果你从标题里只能看到“微信小程序”而源码里有pages.json、manifest.json而不是app.json那就要意识到这是个 uni-app 工程。uni-app 用 HBuilderX 打开后在manifest.json里选择微信小程序然后“运行到小程序模拟器”。要注意 uni-app 里rpx和px混用、内置组件的click事件会编译成小程序绑定的问题。如果拿到的是原生微信小程序源码想迁到 uni-app不要试图自动转换页面逻辑可以复用模板语法要重写。6. 验收不是“编译通过”鲜花小程序交付前的自检清单6.1 静态检查三件套日志、todo、appid在交付前先跑一段命令检查最明显的坑cd miniprogram echo console.log grep -rn console\.log pages/ || echo clean echo TODO grep -rn TODO pages/ api/ || echo no todo echo touristappid grep -n touristappid ../project.config.json || echo appid replacedconsole.log在生产包中会保留代码里的调试输出影响排查问题但让它出现在源码交付里只能说明没有清理。TODO要逐条处理不然对方看到一堆未完成注释会认为项目不完整。touristappid是游客模式如果要用真机体验必须替换为实际 AppID。6.2 功能自检表配送时段、库存、订单状态检查点操作期望结果首次加载清缓存后进入首页显示加载页或骨架屏商品列表不出错规格选择点单选框价格跟着规格变加入购物车 key 唯一过期配送选择今天的配送时段已过截止时间的时段不可选库存不足把商品数量加到库存之上提交订单提示库存不足不产生脏订单超时取消等待 15 分钟订单变为已取消库存回补最后一步是拿一台关掉开发者工具的真机做测试先用测试号登录再走一遍“浏览-加购-下单-模拟支付”的完整链路。这个流程如果能在另一台电脑上由不看说明文档的人跑通交付件才算真正合格。本文还有配套的精品资源点击获取