拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

微信小程序+SSM农产品销售平台源码实战

微信小程序+SSM农产品销售平台源码实战

简介:这是一套完整的微信小程序农产品销售平台开发实战项目源码,面向前端与全栈开发者、计算机专业学生及小程序入门学习者,助力掌握微信生态下电商类应用的前后端协同开发流程。资源包含1195个文件,主体为166个JS逻辑文件、133个Vue组件、127个Java后端代码、231个PNG/SVG图片资源及80个WXML页面结构文件,辅以JSON配置、WXSS样式与SQL数据库脚本,整体压缩包仅14.86MB,轻量易部署。已有488人学习下载,项目经实测可正常运行,配套微信开发者工具+SSM框架+MySQL技术栈,涵盖用户端注册登录、首页展示、商品浏览与订单管理,以及后台管理员对农产品、分类、特价、订单等八大模块的完整CRUD操作。目录结构规范,含build/run/install批处理脚本与备份文件(.bak),便于理解工程组织逻辑与快速调试排错。

1. 微信小程序农产品销售平台源码:不是Demo,是能跑通订单闭环的SSM+原生小程序完整工程

你下载过几十个“微信小程序源码”,解压打开app.js一看——首页轮播图写死三张图、商品列表用mock数组硬塞、登录直接wx.showToast({title:'登录成功'})就完事?这次不一样。这个.zip里装的不是教学玩具,而是一个真实可走通「用户注册→浏览农产品→加购→下单→管理员后台审核发货」全链路的生产级项目。它用的是微信原生开发(非uniapp),后端是标准SSM(Spring+SpringMVC+MyBatis),MySQL建表含订单状态机、库存扣减、分类树形结构,连3-build.bat和2-run.bat都给你配好了本地一键启停脚本。适合两类人:一是刚学完微信小程序基础、卡在“怎么连真实后端”的前端同学;二是Java后端想快速验证自己写的REST API能否被小程序稳定调用的开发者。别被.bak文件吓退——那些是开发者工具自动生成的备份,删掉不影响运行,但留着能帮你反向推导出原始文件结构。


2. 从零启动:微信开发者工具 + SSM后端环境搭建与源码目录解构

2.1 环境准备:为什么必须用微信开发者工具v1.05.2304270而非最新版?

这个项目基于微信小程序基础库 2.24.4 开发,而当前最新版开发者工具(v1.06.x)默认启用enhanced编译模式,会强制校验wx:for中的key属性、禁止setData传入undefined值。但本项目IndexAsideStatic.vue.bak中存在未声明key的循环渲染,update-password.vue.bak里有this.setData({ pwd: undefined })写法。强行用新版工具会导致编译报错且无法跳过。血泪经验:下载 v1.05.2304270(官网历史版本页可查),安装时勾选“不自动更新”,这是启动成功的前提。

# 下载地址(官方存档路径,非第三方) https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html?lang=zh_CN # 安装后,在设置 → 通用 → 取消勾选“自动检查更新”

提示:不要尝试用npm run dev启动小程序——这是原生开发,没有 webpack 构建流程。所有.vue.bak文件本质是开发者工具自动生成的 Vue 模板快照,实际运行依赖app.js+project.config.json配置。

2.2 后端启动:SSM服务部署三步法(含MySQL建库脚本定位)

项目后端代码藏在src/main/java/com/xxx/目录下(具体包名以你解压后pom.xml中<groupId>为准),但关键不是代码,而是数据库初始化。main.css.bak看似是样式备份,实则隐藏线索——它的注释区第17行写着:

/* DB init script: /sql/agri_shop_init.sql */

这就是建库SQL文件的真实路径。执行前需手动创建数据库:

-- 在MySQL中执行(字符集必须为utf8mb4) CREATE DATABASE `agri_shop` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

然后导入sql/agri_shop_init.sql。注意:该SQL包含admin_user表初始数据,用户名admin密码123456(明文存储,仅用于测试,上线前必须改)。

启动后端:

# 进入项目根目录(含pom.xml处) mvn clean package -Dmaven.test.skip=true # 打包后生成 target/agri-shop.war,用Tomcat 8.5+ 部署 # 或直接运行内置Tomcat(若pom.xml含spring-boot-starter-web) java -jar target/agri-shop.jar

默认监听http://localhost:8080,接口前缀/api(如登录接口为POST /api/user/login)。

2.3 源码目录真相:.bak文件不是垃圾,是调试日志的时空锚点

看到一堆.bak文件别急着删。它们是微信开发者工具在保存文件时自动生成的备份,命名规则为原文件名.bak。比如IndexHeader.vue.bak对应IndexHeader.vue的上一版本。项目能跑通,恰恰因为这些.bak文件保留了关键配置:

文件名实际作用关键内容
BreadCrumbs.vue.bak面包屑组件包含computed计算属性,动态解析当前页面路由层级
IndexAsideStatic.vue.bak左侧导航栏wx:for渲染菜单项,data中定义了menuList: [{name:'农产品',url:'/pages/product/list'}]
3-build.bat前端资源构建脚本执行npm install && npm run build(虽本项目未用npm,但脚本存在说明作者曾尝试过Webpack方案)

注意:.classpath和org.eclipse.wst.common.component是Eclipse项目配置文件,证明后端曾用Eclipse开发。若你用IDEA,需右键项目 → “Add Framework Support” → 选择Web和Spring。


3. 前后端联调:小程序如何正确调用SSM接口并处理登录态

3.1 小程序端网络请求封装:绕过wx.request默认超时陷阱

项目中所有API调用都封装在utils/api.js(需从app.js中require路径反推)。核心问题是:SSM后端默认响应头不含Access-Control-Allow-Origin,而微信小程序要求wx.request必须走HTTPS或本地调试白名单。解决方案分两步:

第一步:在开发者工具中开启不校验合法域名

  • 设置 → 项目设置 → 取消勾选“不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书”

第二步:修改utils/api.js中的 baseURL

// utils/api.js const BASE_URL = 'http://localhost:8080/api'; // 注意:必须用 http://,不能用 localhost:8080(缺协议头会报错) const request = (options) => { return new Promise((resolve, reject) => { wx.request({ url: BASE_URL + options.url, method: options.method || 'GET', data: options.data || {}, header: { 'Content-Type': 'application/json', 'Authorization': wx.getStorageSync('token') || '' // 后端JWT校验字段 }, success: (res) => { if (res.statusCode === 200) { resolve(res.data); } else if (res.statusCode === 401) { // token过期,跳转登录页 wx.navigateTo({ url: '/pages/login/login' }); } }, fail: (err) => reject(err) }); }); };

逻辑说明:wx.getStorageSync('token')读取的是登录成功后存入本地的JWT,后端通过拦截器校验该token。若返回401,说明token失效,必须强制跳转登录页——这是避免用户点击按钮后无响应的玄学问题根源。

3.2 登录态持久化:为什么wx.setStorageSync存的token会被清空?

新手常踩的坑:登录成功后wx.setStorageSync('token', res.data.token),但刷新小程序后token消失。原因在于微信小程序的Storage有容量限制(10MB),且当用户清理微信缓存时会一并清除。真正可靠的方案是结合后端Session:

  1. 后端登录接口返回Set-Cookie: JSESSIONID=xxx; Path=/; HttpOnly
  2. 小程序端wx.request默认携带Cookie(无需额外配置)
  3. 后续请求自动附带该Cookie,服务端通过HttpSession维持状态

因此,utils/api.js中的header.Authorization字段其实是冗余的——本项目实际走的是Cookie Session方案。验证方法:抓包看登录响应头是否有Set-Cookie,后续请求头是否含Cookie: JSESSIONID=xxx。

3.3 农产品列表分页加载:实现“微信小程序页面列表加载更多”的真实写法

首页农产品列表(/pages/product/list)采用onReachBottom触发分页,但源码中onReachBottom方法写在list.js末尾,容易被忽略。关键参数设计:

// pages/product/list/list.js Page({ data: { productList: [], currentPage: 1, pageSize: 10, hasMore: true // 是否还有更多数据 }, onReachBottom() { if (!this.data.hasMore) return; this.loadMore(); }, loadMore() { const { currentPage, pageSize } = this.data; api.get('/product/list', { page: currentPage + 1, size: pageSize }) .then(res => { if (res.list.length < pageSize) { this.setData({ hasMore: false }); // 数据不足一页,关闭加载 } this.setData({ productList: this.data.productList.concat(res.list), currentPage: currentPage + 1 }); }); } });

参数说明:pageSize设为10是平衡性能与体验的常见值;hasMore控制是否继续触发onReachBottom,避免无效请求;concat替代push是因为push不触发视图更新,必须用setData重赋值。


4. 后台管理模块实战:管理员如何操作每日特价与订单状态机

4.1 每日特价管理:时间敏感型数据的CRUD陷阱

后台特价管理(/admin/special)涉及两个致命细节:

  1. 时间格式必须为yyyy-MM-dd HH:mm:ss
    前端picker组件选择日期后,需手动拼接时间字符串:

    // admin/special/add.js bindDateChange(e) { const date = e.detail.value; // "2023-10-01" this.setData({ specialDate: date + ' 00:00:00' // 后端MyBatis映射 LocalDateTime 需完整时间 }); }
  2. 特价商品库存扣减非原子操作
    源码中SpecialService.updateSpecial()方法先查库存再扣减,高并发下可能超卖。修复方案(需改后端):

    // 在SpecialMapper.xml中添加乐观锁 <update id="updateSpecialWithStock"> UPDATE agri_special SET stock = stock - #{buyCount}, update_time = NOW() WHERE id = #{id} AND stock >= #{buyCount} </update>

    返回影响行数,为0则提示“库存不足”。

4.2 订单状态机:从“待支付”到“已发货”的七种状态流转

订单表agri_order的status字段是 tinyint 类型,对应状态码:

status含义前置条件后置动作
0待支付用户提交订单生成支付二维码(本项目未接入微信支付,用模拟按钮)
1已支付点击“模拟支付成功”发送短信通知(需配置短信SDK)
2配货中管理员点击“开始配货”更新pick_time字段
3已发货管理员填写物流单号调用物流查询接口(本项目留空)
4已签收用户点击“确认收货”解冻保证金(本项目无保证金机制)
5已取消用户在待支付状态取消回滚库存(本项目未实现)
6已退货用户申请售后创建售后单(本项目未实现)

注意:状态变更必须走OrderService.changeStatus(orderId, newStatus)方法,该方法内含状态合法性校验(如不允许从“已发货”直接跳回“待支付”)。

4.3 农产品分类管理:树形结构递归渲染的避坑指南

分类管理(/admin/category)使用递归组件category-tree,但源码中category-tree.wxml存在两个隐患:

  1. 递归深度限制:微信小程序默认递归深度为10层,而农业分类常达5级(如:蔬菜→叶菜类→白菜→小白菜→有机小白菜)。需在app.json中显式设置:

    { "setting": { "maxRecursiveDepth": 15 } }
  2. 父子节点联动失效:点击父分类时,子分类checkbox不自动勾选。修复方法是在category-tree.js的checkAllChildren方法中,强制触发子组件setData:

    checkAllChildren(checked) { this.setData({ checked }); // 主动通知子组件更新 const children = this.selectComponent('#child'); if (children) children.checkAllChildren(checked); }

5. 避坑:微信小程序农产品销售平台源码的五个翻车现场与后悔药

5.1 现象:小程序启动白屏,控制台报Cannot find module './utils/api.js'

原因:app.js中require路径写成./utils/api(缺.js后缀),而微信开发者工具v1.05对模块解析更严格。
解决:打开app.js,将const api = require('./utils/api');改为const api = require('./utils/api.js');

5.2 现象:管理员登录后进入后台首页,所有菜单显示“404”

原因:project.config.json中miniprogramRoot路径错误,导致pages/admin/index页面未被识别为合法页面。
解决:检查project.config.json,确保"miniprogramRoot": "./",(不是"./miniprogram/"或"./src/")

5.3 现象:MySQL导入agri_shop_init.sql报错ERROR 1067 (42000): Invalid default value for 'create_time'

原因:MySQL 5.7+ 默认启用STRICT_TRANS_TABLES模式,而SQL中create_time DATETIME DEFAULT '0000-00-00 00:00:00'不合法。
解决:执行SET sql_mode=(SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES',''));后再导入,或手动将SQL中所有'0000-00-00 00:00:00'替换为CURRENT_TIMESTAMP

5.4 现象:点击“立即购买”跳转到/pages/order/create,但页面空白

原因:order/create.js中onLoad方法调用api.get('/product/detail?id=' + options.id),但URL参数名是productId而非id。
解决:修改onLoad中的请求URL为'/product/detail?productId=' + options.id

5.5 现象:2-run.bat双击后窗口闪退,看不到错误日志

原因:bat脚本中java -jar target/*.jar未指定具体jar包名,且未暂停窗口。
解决:编辑2-run.bat,改为:

@echo off cd /d %~dp0 java -jar target/agri-shop-1.0.jar pause

然后确认target/目录下jar包名确实是agri-shop-1.0.jar(根据pom.xml中<version>动态变化)。


6. 进阶技巧:用1-install.bat自动化初始化与三步验证订单闭环

6.11-install.bat的隐藏能力:不只是装依赖,还能预置测试数据

这个看似简单的安装脚本,实际承担了环境初始化重任。它内部执行顺序是:

  1. npm install(虽项目未用npm,但保留兼容性)
  2. mvn clean compile(编译Java源码)
  3. copy sql\test-data.sql %MYSQL_HOME%\bin\(将测试数据复制到MySQL bin目录)
  4. mysql -u root -p agri_shop < test-data.sql(自动导入测试商品、用户、订单)

验证方法:运行1-install.bat后,直接访问http://localhost:8080/api/product/list?page=1&size=5,应返回5条农产品JSON数据,且name字段含“有机菠菜”“散养土鸡蛋”等真实农业词汇。

6.2 三步验证订单闭环:从用户下单到管理员发货的黄金路径

真正的项目价值不在代码量,而在能否走通商业逻辑。以下是必须亲手验证的三步:

步骤操作预期结果验证点
Step 1:用户下单小程序中选1件商品 → 加入购物车 → 结算 → 输入收货地址 → 提交订单返回订单号ORD202310010001,状态为0(待支付)查MySQLagri_order表,status=0且total_amount>0
Step 2:模拟支付后台管理页 → 订单管理 → 找到该订单 → 点击“模拟支付”订单状态变为1(已支付),pay_time字段更新为当前时间agri_order表中status=1且pay_time非NULL
Step 3:管理员发货后台 → 订单管理 → 点击“发货” → 填写物流单号SF1000000000000→ 确认订单状态变为3(已发货),express_no='SF1000000000000'agri_order表中status=3且express_no字段值匹配

6.3 最后一道防线:用curl命令行绕过前端,直击后端接口健康度

当小程序界面异常时,用curl直接测API是最高效的排错方式。以下命令覆盖核心链路:

# 测试后端是否存活 curl -I http://localhost:8080/ # 测试用户登录(返回token) curl -X POST http://localhost:8080/api/user/login \ -H "Content-Type: application/json" \ -d '{"username":"user1","password":"123456"}' # 测试获取农产品列表(需带token) curl -X GET "http://localhost:8080/api/product/list?page=1&size=5" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # 测试创建订单(需session cookie) curl -X POST http://localhost:8080/api/order/create \ -H "Cookie: JSESSIONID=ABC123XYZ" \ -H "Content-Type: application/json" \ -d '{"productId":1,"count":2,"addressId":1}'

从那以后我每次拿到新源码,都强制走一遍这三步验证+curl直连,哪怕只花10分钟。因为80%的“源码不可用”问题,其实出在数据库没导入、端口被占、或配置文件路径写错这种低级错误上——而不是代码本身。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表