ARTICLE DETAIL

资讯详情

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

微信小程序农产品销售系统毕设全攻略:从选题到答辩

微信小程序农产品销售系统毕设全攻略:从选题到答辩 每年到这个节点都会有一批同学抱着题目清单来找我参谋。十个里面有六七个问的是“微信小程序做什么题好”剩下三四个问的是“电商类小程序怎么才能做得不烂大街”。如果你手里拿着的也是“基于微信小程序的农产品销售系统”这个题目那这篇内容应该能帮你省掉不少弯路。这篇文章我会按自己做项目、也帮别人调毕设时的习惯把这个题目从头到尾拆一遍选题怎么找亮点、技术栈怎么定、数据库怎么设计、代码怎么写才不像“凑字数”、哪些坑是老师盯着的重点以及答辩时最容易被问到的几个问题。不管你是刚准备开题还是已经写了一部分代码卡住了这篇都值得存一下写完的不妨也对照检查看有没有漏掉关键点。1. 选题拆解农产品销售系统为什么是“毕设常青树”1.1 需求分析里真正能写出的亮点先说一个事实电商类系统确实是毕业设计里最“安全”的一类题目因为它的功能边界清晰、业务场景成熟、参考资料多。但这不代表随便做都能拿高分。用“农产品”而不是“普通商品”恰恰是拉开差距的第一张牌。农产品和标准工业品最大的不同是它带有极强的非标属性同一批土豆可能大小不一、成熟度各异水果有产地、有等级、有时令蔬菜放不住库存和安全库存的逻辑也和图书、数码产品完全不同。这些特点如果能在你的需求分析里体现出来评委一眼就能看出你是真的思考过而不是在“图书管理系统”的模板上改了三个字。我建议在开题报告和论文的“研究意义”部分重点写这三层第一层是渠道优化。产地直采、产地直发减少中间商赚差价。农产品从田间到餐桌的链条太长损耗率高小程序直销模式能缩短链条这是宏观意义也是评委爱听的“社会价值”。第二层是信息透明。农产品最大的信任成本是“我不知道你这桃子到底哪来的”所以系统里如果能带上产地、生产者、质检报告、采摘时间这类溯源信息就能解决买卖双方信息不对称的问题。这一条是带货类农产品小程序最重要的特色也是和普通电商拉开差异的关键。第三层是助农与精准推荐。结合时令节气做推荐、按“最近上新”做排序、用户下单后还能继续回购这些功能看起来不起眼但写进论文里就是“基于用户行为的商品推荐”的雏形比单纯堆CRUD要高级得多。1.2 角色划分与核心模块先想清楚“谁在用”需求分析能不能拿高分看的是你有没有把角色理清楚。农产品销售系统里我建议至少划分出这么几类角色核心诉求对应功能普通消费者快速找到想要的农产品、下单方便、能了解到货信息商品浏览、分类搜索、商品详情、购物车、下单支付、订单查询、售后申请入驻农户/商户商品上架、发货、处理订单商品管理、库存管理、订单发货、销量查看平台管理员审核商品与商家、处理纠纷、看运营数据用户管理、商品审核、类目管理、订单总览、数据统计系统游客想看看但不注册商品浏览部分页面开放、登录引导功能模块按这个思路去拆至少能拆出用户端小程序商品展示、购物车、订单、个人中心、商家管理端商品/订单/数据、平台后台审核/管理/统计、后端服务接口/鉴权/支付模拟四个子系统。论文结构也能顺着这条线一条条写清楚不会给人“东一榔头西一棒子”的感觉。有一点必须提醒很多同学会把“管理端”做成小程序里的隐藏页面或者一个简陋的列表页这是很吃亏的。管理端是体现你“全栈能力”的地方认真做一个独立的管理后台哪怕是简化的在答辩展示时的说服力完全不一样。2. 技术选型不要在第一步就被比下去2.1 小程序端原生还是 uni-app这是最常被问到的技术决策。我直接给结论如果你除了毕业设计还想留着这套技能将来做点副业、接点外包那就用 uni-app如果你对 Vue 不熟、时间又紧就老实写原生小程序。原生小程序的优点很直接微信开发者工具里跑起来就是最终效果不用考虑编译链的坑WXML 标签和组件文档跟着官方走出问题网上一搜一大把答案。缺点也明显只能跑微信将来想发抖音小程序、支付宝小程序、App代码基本要重写。uni-app 的优点是 Vue 语法一套代码可以编译到微信小程序、H5、App、鸿蒙等平台。对于将来有“多端发布”需求的项目这个优势很实在。但代价是你要多理解一层编译同样一段逻辑在 H5 里正常编译到小程序可能就要适配第三方插件和原生小程序组件混用的时候也会有些麻烦。我做过的几个类似项目给的建议比较明确毕设周期在三个月以上、自己又想往前端方向发展的直接选 uni-app周期紧、求稳、对 Vue 还不熟的原生微信小程序会更省心。在论文里写“为什么选 uni-app/原生”的时候把这个思考和取舍写进去本身就是一个得分点。还有一个隐藏点如果选 uni-app答辩时被问到“为什么不用原生”时你还能讲清楚 Vue 的响应式原理和编译到不同端的差异如果选原生就要把小程序自定义组件的生命周期、setData 的性能机制吃透。选哪个都行关键是要能自圆其说。2.2 后端Spring Boot 是稳妥牌但别忽略其他选项后端技术栈的选择我把它当成“毕业设计里最不该纠结”的问题。现在主流的几套方案都非常成熟我列个表你按自己的基础对号入座技术栈优点缺点适合谁Spring Boot MyBatis-Plus MySQL资料最多、企业用得多、答辩印象好Java 基础薄弱会觉得繁琐学过 Java、想走后端方向Flask/Django MySQLPython 生态、代码量小、上手快并发与大项目表现一般Python 熟悉、想快速出活Node.js Express/KoaJS 全栈统一类型约束弱、大型系统相对费力前端比较强的人PHP ThinkPHP/Laravel入门简单、部署容易技术显得“不够新”预算型方案不太推荐答辩选以我自己带项目的经验Spring Boot 依然是毕业设计的最优解不是因为它最高级而是因为评委里大概率有 Java 方向的老师你用了 Java 技术栈他们评委起来更顺手、也更愿意给高分。再者Spring Boot 的生态确实太完善了MyBatis-Plus 帮你把单表 CRUD 写得跟填空题一样Spring Security 或 Sa-Token 做登录鉴权也都有现成模板。Python 选型也不是不行但你要有心理准备如果答辩组老师主要是 Java 背景看到你用 Python 会有两个反应要么觉得“挺有新意”要么就会追问 Python 在高并发场景下的性能瓶颈。如果论文里写清楚了自己的系统定位是“中小规模助农平台”、并发量不可能到互联网大厂那种量级这个问题也能圆回来。2.3 数据库设计这些表一张都不能少数据库表设计是整个项目中真正决定“能不能跑起来”的部分。一个农产品销售系统核心表至少包括下面这些用户表useropenid、昵称、头像、手机号、角色普通用户/商家/管理员、状态、注册时间商品分类表category分类名称、父分类、排序商品表product所属商家、分类、标题、主图、轮播图、详情富文本、价格、原价、单位、库存、销量、产地、采摘/生产日期、上下架状态、审核状态购物车表cart用户ID、商品ID、数量、是否选中、加入时间收货地址表address用户ID、收货人、手机号、省市区、详细地址、是否默认订单表orders订单号、用户ID、商家ID、总金额、运费、实付金额、支付方式、订单状态、收货地址快照、下单时间、支付时间、发货时间、完成时间订单明细表order_item订单ID、商品ID、商品快照名称/图片/单价、数量、小计售后表after_sale订单ID、用户ID、类型退款/退货退款、原因、金额、状态、处理结果评价表review订单ID、商品ID、用户ID、评分、内容、回复内容、评价时间有几个细节值得单独说道说道。订单明细里的商品快照是很多学生容易漏掉的点。商品信息是会变的——你下单时土豆是2块钱一斤发货前商家改价成2块5总不能让订单也跟着变吧。所以订单明细里必须冗余保存“下单这一刻”的商品名称、图片、单价。这在大厂的订单系统里叫快照你把它的意义写到论文里老师一看就知道你理解订单系统的核心。订单号的生成尽量别用数据库自增ID。我做过的系统一般会生成类似年月日用户ID后四位随机数的订单号这样便于查询和对账又不暴露业务量。商品表里我建议加一个audit_status审核状态字段这是农产品平台和普通电商的一个差异点不是所有商家上传的东西都能马上上架的平台要审核。有审核环节管理员端才有事情做管理员的角色才有存在感。3. 核心功能怎么实现从登录到下单的完整链路3.1 登录模块openid 是你的用户身份证小程序登录和网页登录完全不同它不靠“输入用户名密码”而是靠微信的授权体系。完整流程是这样的小程序端调用wx.login()拿到一个临时code把这个 code 传给后端后端拿着 code 去微信接口换用户的openid然后自己生成一个 token 返回给前端。以后前端每次请求都带上这个 token后端校验通过就算登录。在这个过程里最关键的字段就是openid它是用户在某个小程序内的唯一标识。你可以这样理解openid 就是这个用户在这家“店”里的终身会员卡号换一家店另一个小程序卡号就变了所以它天然适合用来做用户唯一标识。代码层面登录态管理我会用 token 过期时间的方式。后端签发 tokenJWT 或者自造的 token 串都行小程序端存在 storage 里请求时统一在 header 里带上。如果后端返回 401就清掉本地 token引导用户重新登录。这里有个容易踩的坑现在微信的 getUserProfile 接口已经调整了用旧的wx.getUserInfo拿不到真实头像昵称了也不再自动弹窗授权。新方案是让用户点击头像昵称填写区域或者用wx.getUserProfile由用户主动触发。毕设里如果做“微信一键登录”把 openid 登录做通就行头像昵称可以让用户在个人中心手动上传修改这样反而少了很多麻烦。3.2 商品浏览搜索、分类与商品详情商品展示是整个小程序的“脸面”也是评审老师点开小程序后最先看的东西。所以别用死数据也别只做静态页面。我建议至少把这几块做好分类导航左侧分类栏 右侧商品列表这种布局在小程序里很常见也好实现。分类数据从后端读不要写死在前端数组里。搜索关键词模糊匹配商品名称、产地、标签。后端用 like 查询即可简单实用。排序按综合、销量、价格进行排序切换。销量排序就需要在商品表里维护一个sold_count字段每笔订单支付完成时同步更新。列表分页用“下拉加载更多”的分页方式一页10条或20条不要一次性 setData 渲染几百条数据性能会明显卡顿。商品详情页的富文本是一个容易出问题的地方。农产品需要展示产地、种植环境、质检报告之类的图文信息这些内容通常是从后台上传的富文本。小程序端渲染富文本用rich-text组件如果图片是外链地址注意域名必须在小程序后台配置为合法域名否则真机上看不到图片。还有个小建议详情页里把“产地直发”“当日采摘”“坏果包赔”这些卖点标签放前面。一方面农产品用户吃这套另一方面答辩演示时观感会非常好一打开就感觉是个正经商城。3.3 购物车与订单把状态机想明白购物车功能大家都会写但真正写好的不多。核心点有三个第一购物车数据是放本地还是服务器毕设层面我建议放服务端因为这样换设备购物车还在也更符合电商系统的真实形态。前端交互时选中状态、数量变化都做得即时性强一点。第二结算流程要完整。从购物车进入结算页 → 选收货地址 → 核对商品清单 → 提交订单 → 模拟支付 → 支付成功跳转订单列表。这里每一步都是一个页面别把提交订单和支付做成一个按钮糊弄过去。第三库存校验必须放在后端。这是我最想强调的一点前端再怎么限制数量都是“面子”真正防止超卖的是后端的原子操作。下单时用类似下面的逻辑UPDATE product SET stock stock - #{count} WHERE id #{productId} AND stock #{count}这条 SQL 返回的影响行数如果为 0说明库存不足下单失败。这样既保证了不会出现负库存也不需要搞复杂的锁机制理解成本低、面试答辩也好讲清楚。订单状态的设计我建议按下面的状态流转来做状态值含义可执行操作0待支付取消订单、去支付1已支付/待发货商家发货2已发货/待收货用户确认收货3已完成发起售后、评价4已取消无5已退款无状态字段不要存中文用数字存展示的时候再映射成文案。这样数据库更规范之后做统计也更方便。3.4 商家端与管理后台拉开档次的关键刚才说过管理端是拉开档次的地方。商城类的毕设管理后台可能占到整个系统工作量的40%但也正是这40%让你的系统从“一个 Demo”变成“一个系统”。商家端的功能定位很明确商家登录后能看到自己店铺的商品列表、上架/下架商品、修改库存和价格看到自己的订单列表点击发货、填写物流单号看到自己的经营数据比如累计销售额、订单数。这些功能的实现并不难核心是“数据隔离”——商家只能看到自己的数据查询SQL里加上WHERE merchant_id 当前用户ID就行。平台管理后台建议单独做一个 Web 页面Vue Element Plus 这类模板很多功能包含用户管理查看用户列表、禁用账户、商家审核审核入驻申请、商品审核审核商品上架、平台总览总用户数、总订单数、销售额趋势图、全站订单查询。这里建议你把管理后台做成一个独立项目前后端分离用 token 鉴权。答辩演示的时候一边看小程序怎么下单一边切到管理后台看到订单出现这个“闭环演示”的冲击力很强比你口头描述一百句都管用。4. 实操过程我带你把关键代码过一遍4.1 请求封装小程序的“网络层”打开任意一个正式小程序项目第一个要写的公共模块就是请求封装。原生小程序没有 axioswx.request是底层 API每个页面都直接调wx.request会让代码重复到怀疑人生。我的做法是封装一个request.js统一处理 baseURL、token 注入、错误码提示、登录过期跳转。// utils/request.js const BASE_URL https://你的后端地址/api function request(path, method GET, data {}) { return new Promise((resolve, reject) { wx.request({ url: BASE_URL path, method, data, header: { Content-Type: application/json, Authorization: wx.getStorageSync(token) || }, success(res) { // 后端统一返回 { code, message, data } if (res.statusCode 200 res.data.code 0) { resolve(res.data.data) } else if (res.statusCode 401 || res.data.code 401) { // token 过期清掉登录态跳登录页 wx.removeStorageSync(token) wx.navigateTo({ url: /pages/login/login }) reject(res.data) } else { wx.showToast({ title: res.data.message || 请求失败, icon: none }) reject(res.data) } }, fail(err) { wx.showToast({ title: 网络异常请稍后重试, icon: none }) reject(err) } }) }) } module.exports { request }如果你用的 uni-app封装逻辑几乎一样把wx.request换成uni.request即可还可以配合uni.request的拦截器。这段代码看上去简单但它决定了你后面几十个页面的开发效率值得一开始就写对。4.2 后端接口一个完整的商品列表接口长什么样我拿 Spring Boot 写个最简单的商品列表接口让你感受一下后端需要提供的“标准姿势”。后端 Controller 层接收查询条件Service 层做业务处理如果全程都在 Controller 里写 SQL 逻辑不但代码难看答辩老师也会觉得你不懂分层。RestController RequestMapping(/api/product) public class ProductController { Autowired private ProductService productService; // 商品列表支持分类、关键词、排序、分页 GetMapping(/list) public Result list(RequestParam(required false) Long categoryId, RequestParam(required false) String keyword, RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { PageResultProductVO result productService.listProducts(categoryId, keyword, page, size); return Result.ok(result); } // 商品详情 GetMapping(/detail/{id}) public Result detail(PathVariable Long id) { return Result.ok(productService.getProductDetail(id)); } }无论用不用 Spring Boot我都建议你保持“Controller 薄、Service 厚、Mapper 专管数据”的分层思想。这套分层在论文里也特别容易写每个层干什么、为什么这么分都是标准知识点。4.3 订单状态流转后端代码怎么控制流程订单模块里最典型的一段逻辑是“下单 扣库存 生成明细”。这段逻辑里有一个很关键的概念叫事务如果扣库存成功了但是生成订单明细失败了那库存就少了但订单不存在了数据就脏了。所以下单的 Service 方法上要加Transactional让这几个操作要么全部成功、要么全部回滚。我自己的习惯是这样下单方法里先校验商品是否可售、校验库存然后生成订单主记录然后循环商品列表插入订单明细同时执行扣库存 SQL最后把购物车里对应的商品删掉。整个方法用Transactional包住中间任何一步抛异常数据库回滚。模拟支付那步也值得说明一下因为个人开发者很难申请到微信支付商户号毕设里我建议做“模拟支付”而不是硬接微信支付。具体做法可以是提交订单后进入支付页面点击“确认支付”时调后端接口payOrder(orderId)后端模拟将订单状态置为“已支付”顺便把商品销量加一、库存最终落定。论文里就写“本系统采用模拟支付方式预留微信支付接口”这个说辞在答辩场景下完全可以接受。4.4 缓存和本地存储别什么都往 setData 里塞小程序开发的性能瓶颈十次有八次出在setData上。setData会把数据从逻辑层传到渲染层如果数据太大页面就会卡顿、白屏。我的几个经验是第一列表页数据量控制住。分页加载既然一次只拿10条渲染就只渲染这10条。第二商品图片必须压缩。很多人直接从网上下载原图塞上去一张图两三兆小程序页面刷出来慢得离谱。图片宽度压到750px以内、转成 jpg/webp体感会好非常多。第三本地缓存不要存太多图片 base64那会让 storage 爆炸。缓存时间管理也是热词里频繁出现的问题。微信小程序没有自带“缓存过期”的概念存进去的东西除非主动 remove 否则一直在。我的做法是存的时候带上时间戳const KEY cart_list const CACHE_TIME 5 * 60 * 1000 // 5分钟 const cached wx.getStorageSync(KEY) if (cached Date.now() - cached.timestamp CACHE_TIME) { // 使用缓存数据 } else { // 重新请求后端 }对于用户登录态这个过期时间就设到和后端 token 有效期一致能大幅减少“登录状态明明过期了但页面还显示正常”的尴尬场景。自定义顶部导航栏也是一个常见的适配问题。如果你不想用默认导航栏想做沉浸式自定义导航就需要动态计算导航栏高度和胶囊按钮位置const rect wx.getMenuButtonBoundingClientRect() const statusBarHeight wx.getSystemInfoSync().statusBarHeight const navBarHeight (rect.top - statusBarHeight) * 2 rect.height这段代码在 iPhone 和 Android 上的表现不一样真机调试时务必两边都看一眼。这个细节虽然小但如果你做了论文里写一句“自定义导航栏适配各机型”也是加分点。5. 常见问题复盘这些都是真实踩过的坑5.1 开发阶段最容易翻车的几个场景我从自己给人调代码和带学生项目里挑几个出现率最高的坑。第一个是域名白名单问题。小程序真机上调用后端接口要求后台配置的 request 合法域名必须是 https 且已备案。很多同学在开发者工具里勾了“不校验合法域名”就能跑但一上真机就白屏报错。毕设阶段想省事开发时可以在工具里勾选不校验但要给老师做真机演示最好提前在微信公众平台里把域名配好或者演示时用开发者工具演示不要临时抱佛脚。第二个是农民式报错接口返回 200但数据是 null。小程序端请求成功不代表数据正常很多同学登录、下单失败的时候一看 request 返回 200 就觉得没问题了。正确的排查姿势是看后端接口的响应体——在 Network 面板里看 response 里的 code 字段是什么、message 写了什么。我建议后端全部统一返回{ code, message, data }结构不要有的接口返回数组、有的返回对象前端就可以用统一的方式处理。第三个是模拟器正常真机拉胯。模拟器和真机在渲染、存储、网络策略上都有差异特别是 iPhone 和 Android 上键盘弹起、日期格式化、图片上传这些方面。做到一定阶段一定要用真机跑一遍核心流程登录、浏览、加购、下单、支付。如果流程在真机上跑通答辩基本就稳了。5.2 毕设文档和答辩准备代码写完只是第一步毕业设计的评分很大一部分在论文和答辩表现上。论文里我给你一个目录参考第一章 绪论背景、意义、国内外研究现状、论文主要工作第二章 相关技术介绍微信小程序、uni-app/原生、Spring Boot、MySQL、Redis第三章 系统分析可行性分析、需求分析、用例图、业务流程第四章 系统设计总体架构、功能模块设计、数据库设计、接口设计第五章 系统实现各模块核心代码与截图第六章 系统测试测试环境、测试用例、测试结果总结与展望答辩演示的动线我建议按“用户视角 → 商家视角 → 管理员视角”来走先用小程序注册/登录逛商品加购物车下单支付然后切换商家账号看到订单发货最后打开管理后台看到用户、订单、商品统计。整个演示大概 10 到 15 分钟。演示前一定要把测试数据准备好比如先把几个商品放上去、把订单做一单避免现场打字折腾。评委老师最爱问的几个问题提前准备一下回答“你的系统相比普通商城有什么创新点”——答结合农产品的非标特性、溯源信息展示、产地直发逻辑、助农场景。“并发下单怎么防止超卖”——答数据库原子更新扣减库存 事务控制。“为什么用 Redis / 为什么不用 Redis”——答就按你项目里实际用没用来答用没用都别慌讲清楚选择逻辑即可。“小程序为什么不能直接访问数据库”——答从安全、性能、维护性三个角度讲这一题几乎是必问的。临了说几句实在话毕业设计到了最后拼的往往不是谁技术更炫而是谁把“一件事做完整”的毅力更足。数据库表设计得再漂亮不如真正跑通一个订单代码注释写得再满不如把手上的源码文档整理整齐。做毕设这一年要是能养成“每完成一个小目标就顺手写文档”的习惯后面写论文会轻松很多。这几年帮人看毕设看到最多的通病不是技术不行而是项目只做到“能跑”就停了。其实往前走一步——把数据统计做出来、把防超卖的逻辑写上、把自定义导航栏适配了这些边际成本都不高但它们才是让你的系统从及格到优秀的最后一级台阶。
返回列表