资讯详情 智慧农场V2.1.1源码全解析:认养农业小程序从0到上线
📅 2026/10/28 9:11:44
简介智慧农场V2.1.1小程序源码是一套面向认养农业场景的完整商业源码适合小程序开发者、农场运营者与农业创业者。覆盖租地种植、畜牧领养、智慧农场商城、拼购组团、签到积分、直播对接、众筹投资及活动报名等模块帮助城市用户远程认养果蔬禽畜同时缓解传统农业预售难、资金回笼慢的问题。压缩包共2000个文件、约60.6MB以793个php、482个png、360个dat、292个html、257个js、168个json、167个wxss、164个wxml、155个jpg及50个css为主php承载后端业务逻辑wxml/wxss/js负责小程序界面与交互png/jpg为图片素材便于部署与二次开发。作者亲测除模板消息外其余功能正常附安装说明已有1849人学习下载适合快速搭建智慧农场小程序或参考完整商业项目的代码结构与功能设计。1. 智慧农场 V2.1.1 亲测版源码认养农业的完整信任链怎么落地做认养农业小程序的人大部分不是被种地功能难住的而是被「信任」难住的用户付了钱怎么让他相信那二十平米的地真的种着他选的番茄、那只戴耳标的羊真的在长大。这套智慧农场 V2.1.1 亲测版源码核心就是把这件事做成了一条看得见的链路——租地种植有地块状态机畜牧领养有成长记录认养订单、农场商城、直播活动共用一套订单体系。整套工程是微信小程序原生项目含云开发后端功能覆盖农场租地种植、畜牧领养、智慧农场商城、农场直播、认养农业五条业务线。适合两类人一是想快速搭出认养农业小程序、少踩支付和直播坑的开发者二是手里有农场资源、想用小程序做会员运营的运营方。接下来的章节按「拆模块→部署→二次开发→避坑→上线验证」的顺序把这套源码拆开看。2. 拆透 V2.1.1 的功能模块租地、领养、商城怎么共用一套订单模型打开这套源码工程第一感觉是页面不少首页、地块认领、畜牧领养、商城、直播间、个人中心十几个页面文件叠在一起。但把页面剥开看底层的业务关系其实非常集中——所有功能都围绕「认养一份资产跟踪它的成长最后拿到实物」这条主链路。所以拆模块的重点不在页面长什么样而在数据模型怎么设计。我拆包时的习惯是先看云函数目录和数据集合定义再回头看页面的数据绑定。亲测版把数据集合按业务分成 plots、livestock、orders、points_log、growth_logs、live_rooms 六类每一类对应一个页面群。下面按业务线逐个说同时给出关键代码片段的映射关系。2.1 租地种植地块状态机决定认养协议是否成立租地种植的页面交互不复杂用户选地块、选作物、付定金然后看到一块地进入「种植中」。复杂的是地块状态不能乱跳否则就会出现「地还没付钱就显示在种」这类业务事故。源码里用了一个状态机地块的流转路径是可认领 → 待支付定金 → 种植中 → 已收获 → 休整。// utils/plotStatus.js 地块状态机 const PLOT_STATUS { AVAILABLE: available, // 可认领列表页可展示 PENDING: pending, // 已锁定额度等待支付定金 GROWING: growing, // 定金已付进入种植周期 HARVESTED: harvested, // 作物成熟等待配送或自提 FALLOW: fallow, // 收获后休整不可认领 }; // 只有合法状态转移才落库非法转移直接抛错 function transitPlot(current, next, orderStatus) { const allowMap { [PLOT_STATUS.AVAILABLE]: [PLOT_STATUS.PENDING], [PLOT_STATUS.PENDING]: [PLOT_STATUS.GROWING], // 需要 orderStatus PAID [PLOT_STATUS.GROWING]: [PLOT_STATUS.HARVESTED], // 需要种植周期结束 [PLOT_STATUS.HARVESTED]: [PLOT_STATUS.FALLOW], [PLOT_STATUS.FALLOW]: [PLOT_STATUS.AVAILABLE], }; if (!allowMap[current]) throw new Error(非法的地块状态源); if (!allowMap[current].includes(next)) throw new Error(状态不允许流转: ${current} - ${next}); return next; }这段代码的关键在 allowMap它把状态流转限制死了支付回调没确认前地块永远停在 PENDING。实际接入时要注意两个参数——第一个是 orderStatus它是订单集合里的支付标记定金支付回调返回后才会更新为 PAID第二个是地块的种植周期源码里通过选择 crop_type 对应的生长天数自动算收获时间而不是手动改状态。我一般会把这块状态机的校验逻辑同时放在前端提示和云函数里各一份前端只是防手滑云函数才是真正的守门员。因为小程序前端代码可以被绕过直接调云函数接口篡改地块状态是真实存在过的攻击路径。2.2 畜牧领养成长记录是信任链的核心畜牧领养比租地更强调「眼见为实」所以源码里单独设计了 livestock 档案表和 growth_logs 成长记录子集合。每只牲畜有一个耳标号用户领养后看到的不只是静态照片而是按天追加的体重、进食、活动记录。这个设计直接解决了认养农业最大的痛点用户反复问「我的羊怎么样了」。// 云函数 livestockProfile/index.js 领养份额配置 const SHARE_TYPE { WHOLE: { label: 整只认养, priceRate: 1.0, maxHolders: 1 }, HALF: { label: 半只认养, priceRate: 0.55, maxHolders: 2 }, QUARTER: { label: 拼团认养, priceRate: 0.3, maxHolders: 4 }, }; function createLivestockOrder({ animalId, shareType, userId }) { const share SHARE_TYPE[shareType]; const animal getAnimal(animalId); // 校验当前持有人数超过 maxHolders 则认养失败 const holderCount animal.holderIds.length; if (holderCount share.maxHolders) { throw new Error(该份额已满员当前持有人数 ${holderCount}); } return { bizType: livestock, bizId: animalId, shareType, price: Math.round(animal.basePrice * share.priceRate), holderIds: [...animal.holderIds, userId], }; }这段逻辑里值得注意的价格设计半只认养不是简单按 50% 算而是 55%多出的 5% 是屠宰、分割、包装的额外成本四分之一拼团也只收 30%因为拼团用户数和履约成本低于整只散客。这个定价模型对真实农场运营很有参考价值做二次开发时可以直接用。growth_logs 子集合的写入我建议做成定时任务每天凌晨从养殖员的录入端批量写入体重数据而不是让用户端自己刷新。因为用户端频繁拉取成长记录会消耗云开发读次数一天一拉和一天十拉的成本差很多。2.3 商城订单积分、会员价与直播优惠的耦合商城模块是这套源码里订单模型最重的地方因为农场商城不只是卖农产品还要叠加认养用户的会员价、积分抵扣、直播间的限时优惠。源码的订单字段设计避免了「每个渠道各建一套订单表」的常见错误而是在同一张 orders 集合上扩展渠道字段。// 云函数 createOrder/index.js 订单价格计算 function calcOrderPrice({ goods, user, usePoints, livePromo }) { let basePrice goods.price; // 会员价认养用户享有 price.memberPrice if (user.isMember goods.memberPrice 0) { basePrice goods.memberPrice; } // 直播优惠直播间活动价叠加需校验活动时间窗 if (livePromo livePromo.isActive) { basePrice Math.min(basePrice, livePromo.promoPrice); } // 积分抵扣100 积分抵 1 元上限为订单金额的 20% const maxDeduct Math.floor(basePrice * 0.2); const pointsDeduct Math.min(usePoints / 100, maxDeduct); return { finalPrice: basePrice - pointsDeduct, pointsDeduct, pointsCost: pointsDeduct * 100, // 扣减的用户积分 channel: livePromo ? live : normal, }; }这里有个容易被忽略的边界积分抵扣上限写得是订单金额的 20%而不是无限制抵扣。如果农场做促销时想让某场直播支持更高抵扣得在 livePromo 里加一个 extraDeduct 字段单独配置不要在 calcOrderPrice 里写死。直播渠道还有一个隐藏问题直播间进来的用户和认养用户可能同时下单订单里如果没存 channel 字段后续运营统计「直播带来多少成交额」就只能靠猜。源码里把 channel 落库这点值得保留。2.4 后台管理农场主视角的配置中心后端管理能力决定了这套源码能不能被农场主真正用起来而不仅是开发者自嗨。亲测版里配了一个简易管理端入口农场主可以上下架地块、批量导入牲畜批次、设置商城商品库存、配置直播预告。这些操作落在独立的 admin 集合和云函数里与用户端接口隔离。以批量导入牲畜批次为例源码的做法是导出 CSV 模板农场主填好后上传云函数解析并批量写入 livestock 集合。我复现这个功能时改为分批次导入每批 50 条因为云函数批量写入有单次上限一次硬塞几百条很容易触发超时。如果你接到这类需求建议在上传接口里直接限制文件行数并做格式预检减少无效写入。3. 部署上线全流程从导入开发者工具到发布体验版这套源码能跑通「亲测版」三个字说明工程本身是完整的但拿到手直接打开大概率报错——因为缺了三样东西AppID、云开发环境 ID、数据库集合索引。这一章按部署顺序写每步做完都能在开发者工具里看到可验证的结果。3.1 导入工程与目录结构用微信开发者工具导入工程根目录不是导入 miniprogram 子目录。导入后先看 project.config.json 里的 appid 和 miniprogramRoot 字段确认工具能识别工程结构。{ miniprogramRoot: miniprogram/, cloudfunctionRoot: cloudfunctions/, appid: touristappid, compileType: miniprogram }project.config.json 里的 appid 如果是 touristappid说明作者用游客模式测试过你在自己工具里要替换成自己的小程序 AppID。cloudfunctionRoot 指向 cloudfunctions 目录云函数和前端代码是分离的部署时两端要分别处理。导入后如果模拟器白屏优先检查这两项不要急着改业务代码。提示cloudfunctionRoot 目录下每个子目录都是一个独立的云函数右键每个子目录选择「上传并部署云端安装依赖」不能整个 cloudfunctions 一次性上传。3.2 AppID 与合法域名配置开发阶段最简单的方式是在开发者工具「详情 → 本地设置」里勾选「不校验合法域名、web-view业务域名、TLS 版本以及 HTTPS 证书」。这样本地请求不会被拦截能快速跑通流程。但要发布体验版这个勾选不生效必须在 mp 后台配置 request 合法域名。配置项值说明request 合法域名https://api.yourfarm.cn业务后端接口域名uploadFile 合法域名https://upload.yourfarm.cn图片上传场景downloadFile 合法域名https://static.yourfarm.cn商品图片/直播封面socket 合法域名wss://ws.yourfarm.cn直播互动消息需申请需要说明的是这套源码默认走微信云开发云开发自带域名不占用 request 合法域名配额所以如果你全用云开发这步可以直接跳过。只有把订单、库存这类接口挪到自建后端时才需要配。3.3 云开发环境与数据库集合初始化打开云开发控制台创建环境后要做两件事建集合、配权限。集合按前文提到的 plots、livestock、orders、points_log、growth_logs、live_rooms 六个建权限全部设为「仅创建者可读写」——认养用户只能读写自己创建的记录农场主管理端通过云函数访问不走前端直连。app.js 里的云环境初始化代码需要改成你自己的环境 ID// app.js App({ onLaunch() { if (!wx.cloud) { console.error(当前基础库版本过低请使用 2.2.3 以上版本); return; } wx.cloud.init({ env: your-env-id, // 替换成云开发控制台的环境 ID traceUser: true, // 记录访问用户便于排查白屏问题 }); }, });env 字段填错是最常见的坑填成环境名称而不是环境 ID前端会一直报 resource not found。环境 ID 在云开发控制台右上角能看到是一串类似 cloud1-xxxx 的字符串。traceUser 建议生产环境保留排查「某个用户看不到自己地块」这类问题时能直接定位 openid。3.4 真机预览与体验版发布开发者工具里点「预览」会生成二维码但这个二维码只有你自己能扫。要发给农场主或测试用户需要点「上传」按钮填版本号和备注然后在 mp 后台「版本管理」里把上传的版本设为体验版生成体验版二维码。血泪经验上传前先把「本地设置」里的「不校验合法域名」取消勾选用体验版完整跑一遍支付和直播。因为真机环境下任何未配置的域名都会直接请求失败而模拟器里勾选后不会被拦截很多问题在模拟器上根本暴露不出来。发布前至少让两个不同手机系统各跑一轮安卓和 iOS 在小程序直播组件上的表现差异很明显。4. 二次开发实战直播预约、支付状态机与自定义导航栏亲测版能直接跑但真正上线时几乎都要动三块直播插件、支付状态机、导航栏适配。这一章讲清楚每一块改什么文件、为什么这么改。4.1 直播房间接入live-player 组件与插件配置小程序直播不能自己写播放器硬接必须用官方插件。先在 mp 后台「设置 → 第三方设置 → 插件管理」里添加直播插件拿到插件 AppID然后在 app.json 里声明{ plugins: { wxliveroom: { version: 1.3.6, provider: wx1a-bz64xxxx } } }直播间列表页写入直播房间组件未开播时显示预告开播后显示 live-player。页面代码的关键在 loadRoomInfo// pages/live/list.js 片段 async loadRoomInfo(roomId) { const db wx.cloud.database(); const res await db.collection(live_rooms).doc(roomId).get(); const room res.data; // liveStatus: 1 直播中2 未开始3 已结束 this.setData({ room, isLiving: room.liveStatus 1, notStarted: room.liveStatus 2, }); }liveStatus 字段由运营后台每天同步不要在前端去猜直播状态。我在接入时踩过一个坑room 对象里的 liveStatus 在直播插件回调里也有一个两者不同步会导致页面显示「直播中」但黑屏。处理方式是以插件回调为准db 里的 liveStatus 只用于列表页展示。提示直播类目需要企业主体 电商平台类目资质个人开发者无法开通签约前先确认主体资质。4.2 认养支付的完整状态机定金、尾款和退款认养农业的支付和普通商城不一样常见的是「定金 尾款」模式用户先付 30% 定金锁定地块作物成熟后再付尾款。如果收货前用户反悔定金退还规则又和种子、农资成本挂钩。源码里的订单状态机需要扩展出 DUE、REFUNDING 两个状态。// 云函数 payment/status.js 状态常量 const ORDER_STATUS { UNPAID: 0, // 待付定金 DEPOSIT_PAID: 1, // 已付定金等待尾款 PAID: 2, // 尾款已付清 DISPATCHED: 3, // 已配送 DONE: 4, // 已收货 REFUNDING: 5, // 退款中 CLOSED: 6, // 超时关闭 };尾款支付的触发条件是种植周期结束由定时任务批量生成待支付尾款订单而不是用户自己点。退款要单独走人工审核因为地块一旦开始种植种子、灌溉成本已经发生全额定金退回会让农场亏本。这块逻辑建议做成「部分退款」根据种植天数计算已发生的成本剩余部分退回。4.3 自定义导航栏iPhone 刘海屏高度适配这套源码的首页和直播间页用了自定义导航栏好处是能把直播入口按钮做成沉浸式代价是必须自己算导航栏高度。直接写死 64 或 80 在 iPhone 上会翻车正确做法是动态获取胶囊按钮位置// utils/navbar.js 动态导航栏高度 function getNavBarRect() { const menu wx.getMenuButtonBoundingClientRect(); // 新基础库优先用 getWindowInfo旧库回退到 getSystemInfoSync const sys wx.getWindowInfo ? wx.getWindowInfo() : wx.getSystemInfoSync(); const statusBarHeight sys.statusBarHeight || 44; const navBarHeight (menu.top - statusBarHeight) * 2 menu.height; return { statusBarHeight, navBarHeight, menu }; }这段代码背后的逻辑胶囊按钮到状态栏底部的距离乘以 2加上胶囊自身高度就是导航栏总高。不同机型这个值波动很大安卓普遍比 iOS 高。拿到返回值后页面的 paddingTop 要设为 statusBarHeight navBarHeight否则内容会被刘海屏遮住。每次都强制走一遍这个计算不要为了省事写死。4.4 分包加载把商城和直播拆出主包微信小程序主包上限 2MB超了直接上传失败。直播组件体积大商城页面图片多二开时这三块最容易被压进主包。用分包把这三块拆出去是性价比最高的优化{ subpackages: [ { root: pages/live/, name: livePack, pages: [room, list, replay] }, { root: pages/mall/, name: mallPack, pages: [goods-list, goods-detail, cart, checkout] } ], preloadRule: { pages/index/index: { network: all, packages: [livePack] } } }preloadRule 的作用是用户进首页后预下载直播分包点直播入口时不用等待加载。注意分包之间不能互相 require公共代码要放到主包的公共目录里。我把商城拆出去后主包体积从 1.9MB 降到 1.2MB加载速度体感快了一截。5. 避坑排查亲测版也会翻车的六个典型问题这套源码说是亲测版但亲测是在作者的开发环境里测的换一套 AppID、换一个手机、换一个网络环境问题就出来了。下面是复现过程中实际遇到过的六类问题按「现象→原因→解决」写。5.1 真机预览白屏模拟器正常现象开发者工具模拟器一切正常扫码预览后页面白屏控制台报wx is not defined或Failed to load image。原因通常是基础库版本不一致。模拟器用的基础库是工具内置的最新版真机上用户微信的基础库可能停留在旧版本API 调用直接失败。另一种常见原因是 app.js 里云初始化代码抛错整个页面没渲染出来。解决在 mp 后台「设置 → 基础库最低版本」里设成源码要求的版本并在 app.js 的 onLaunch 里加 catch把初始化错误打印到 console先定位到底哪一步断了。5.2 支付回调不触发订单一直停在待支付现象用户能正常拉起微信支付付完钱后订单状态不更新页面还是「待支付」。原因支付回调地址配置错误或云函数处理回调的路径和微信支付后台配置不一致。亲测版里的支付回调走的是云函数升级时云函数路径变了后台回调地址没同步改。解决检查微信支付商户平台的「支付回调通知」配置确保指向当前环境的云函数 HTTP 触发路径。云函数开发环境改版后旧回调地址会失效把所有环境列出来逐一核对。5.3 直播组件黑屏安卓机重现率高现象直播房间能进但画面黑屏只有声音或什么都没有iOS 正常安卓部分机型复现。原因安卓端 live-player 组件和页面里某些 CSS 动画冲突尤其是transform: translateX这类位移动画。小程序直播组件的层级是原生层CSS 动画会导致渲染错位或黑屏。解决直播页面不要放任何带动画的元素尤其是循环动画。如果必须保留入场动画用wx.createAnimation控制结束态动画结束后移除 transform。5.4 重复点击支付生成两笔订单现象用户手快连点两次「立即认养」系统生成两笔相同订单支付一笔后另一笔变成死单。原因前端按钮没有防重复提交云函数也没做幂等校验。数据库没有唯一索引兜底同一时间两个请求都能通过查询校验。解决云函数写订单前先查 orders 集合里是否已有相同 bizType bizId userId 的记录存在就直接返回已存在订单。更稳的做法是给 order_no 字段建唯一索引写入冲突时捕获异常返回DUPLICATE_ORDER这一次性根治。5.5 图片上传失败单张超 2MB现象农场真实照片像素高上传时反复报uploadFile: fail。原因小程序 uploadFile 单文件限制 2MB真实拍摄的图片动辄 3~5MB不压缩直接传必失败。解决上传前用wx.compressImage压缩到质量 80%长边限制在 1920px再传云存储。云存储本身支持更大的文件但这个限制在小程序端绕不过去。5.6 自定义导航栏遮挡内容现象改成自定义导航栏后页面顶部内容被状态栏遮住一部分设置页面里怎么调都不对。原因页面没有读取 getNavBarRect 的计算结果paddingTop 用的是固定值。iPhone 状态栏高度是 44~47安卓是 24~30差出一截。解决全局封装一个 navBar 组件统一读取胶囊位置页面引入后在 view 上绑定 paddingTop。重要的事情说两遍不要写死每个机型都测一遍。6. 上线后的验证手法小程序抓包与云函数定时任务部署完只是开始真正上线前我一般会花一整天做两件事抓包验证接口链路、配置定时任务。前者解决「前端到底发了什么请求」后者解决「农事提醒和尾款订单谁来触发」。6.1 用 Charles 抓取小程序真实请求证书与端口配置小程序模拟器也走本机网络但真机调试时请求走的是手机流量直接抓不到。这里的做法是用 Charles 之类支持 SSL 解密的工具电脑上启动 Charles默认监听 8888 端口手机和电脑连同一 WiFi在手机 WiFi 高级设置里把服务器地址填成电脑的 IP、端口填 8888然后在手机浏览器访问 chls.pro/ssl 下载证书并安装信任。完成后在 Charles 里能看到小程序的全部 HTTPS 请求明文。如果看到的全是 CONNECT 头而没有实际内容说明证书没有安装到系统信任区。安卓 7.0 以上默认不信任用户证书需要把证书装进系统证书目录或者直接换一台测试机。抓包不是为了看数据而是查三件事登录态有没有正确带上、request 域名有没有走错、云函数返回的错误码到底是什么。很多「模拟器正常、真机报错」的玄学问题抓一次包就现原形。6.2 登录态链路wx.login、手机号获取与 session 校验这套源码的登录链路是wx.login 拿到 code → 云函数用 code 换 openid 和 session_key → 自行维护登录态。手机号获取走的是getPhoneNumber按钮云函数端通过云调用拿到解密后的手机号。这个链路有两个注意点一是 code 只能换一次重复换取会报错所以登录云函数里要做 code 使用标记二是 getPhoneNumber 需要企业主体且小程序已认证个人主体开发者点了按钮只会拿到 errCode。6.3 农事提醒定时触发器与云函数配置农事提醒是认养农业最容易忽略的环节——用户认养了地块如果一直没有消息触达流失率会很高。源码里给了定时任务示例在云函数目录下新建 config.json 配置定时触发{ triggers: [ { name: dailyFarmRemind, type: timer, config: 0 0 8 * * * * } ], permissions: { openapi: [subscribeMessage.send] } }定时触发器的时间是 UTC所以0 0 8对应的是北京时间下午 4 点想在北京时间早上 8 点发提醒要写0 0 0。这个坑我踩过一次上线第一天提醒全在下午发出去用户一脸懵。部署后在云开发控制台的「云函数 → 触发器」里能看到下次执行时间先等一个周期观察别急着大批量推送。验证完接口和定时任务后还要把代码用体验版跑一遍完整的用户路径选地块 → 付定金 → 看到地块进入种植中 → 收到第一次农事提醒 → 尾款订单生成 → 模拟收货完成。任何一环断掉都在这一步暴露。说个自己的翻车记录。第一次给农场部署这套源码时我图省事没单独建云开发环境直接拿演示环境的数据库集合名硬套结果上线第一天用户领养了一只羊成长记录却写到了别人的地块下。从那以后我每次部署都会先列一遍集合索引和权限规则再让认养用户完整走一遍流程。希望这个习惯也能帮到你。本文还有配套的精品资源点击获取