当前位置: 首页 > news >正文

微信小程序水果电商源码,带登录、支付、用户中心和云函数全套功能

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

简介:直接可用的微信水果商城小程序源码,覆盖完整购物流程:首页展示新鲜水果、分类浏览、商品详情、加入购物车、下单结算、订单管理、个人中心等页面;内置微信授权登录、自动获取用户昵称头像、openid与IP地址识别能力;已对接微信支付接口,支持真实交易流程;后端由云函数支撑,按功能拆分为login、pay、userInfo、getOpenid、getIP、add等独立模块,结构清晰便于调试和扩展;项目包含标准小程序目录结构(pages、components、utils、style、images)、app.配置、sitemap.站点地图、project.config.开发环境设置,以及npm依赖管理(package.、miniprogram_npm)和云开发必需的cloudfunctions目录;适合想快速上线小型生鲜电商、学习小程序云开发或进行二次定制的开发者使用。

1. 项目概述:这不是一个“模板”,而是一套能直接跑通真实交易的小程序骨架

我做小程序开发快八年了,从最早用腾讯云CVM搭后端,到后来切到云开发,再到现在带团队做生鲜类SaaS小程序,见过太多标榜“开箱即用”的源码——点开一看,登录页能进,商品列表空着,支付按钮点了弹个Toast说“支付功能未实现”,云函数目录倒是齐整,但里面全是console.log('hello world')。这套水果电商源码,是我最近帮一个社区团购主上线时顺手沉淀下来的实战产物,不是教学Demo,也不是半成品,它从第一天起就按“明天就要上架卖橙子”来设计。

核心关键词你已经看到了:水果小程序、微信支付、云函数、用户登录、小程序源码。但光看词容易误解——它不是只适合“卖水果”的专用系统,而是以水果为业务场景,把中小型生鲜电商最刚需的闭环链路(身份识别→商品触达→决策下单→资金结算→履约追踪→用户沉淀)全部跑通的一套可裁剪骨架。比如它的“分类浏览”页面,底层是动态标签体系,你把“脐橙”“车厘子”换成“有机蔬菜”“冷冻海鲜”,改三处配置就能复用;它的购物车逻辑支持“按件计价”和“按重量计价”双模式,后者正是水果电商绕不开的痛点——买两斤苹果和买两个西瓜,结算逻辑完全不同。

它真正解决的是三个现实卡点:第一,微信登录不是只拿个昵称完事,而是完整串联了wx.login()code2SessiongetOpenid云函数 → 用户表自动创建/更新 → IP地址记录(用于风控初筛),整个链路在真机调试下毫秒级响应;第二,微信支付不是调个wx.requestPayment就交差,而是包含了订单生成(含防重幂等)、库存预占、支付结果异步回调校验(含签名验签、金额比对、状态机流转)、支付失败自动释放库存等生产环境必需环节;第三,云函数不是堆代码,而是按职责边界清晰切分——login只管鉴权,pay只管钱,userInfo只管资料,getIP独立成服务不耦合其他模块,这种结构让你加个“优惠券核销”功能,只需新增一个coupon云函数,不用动现有任何一行。

适合谁?如果你是刚学完小程序基础、正愁找不到一个“能真下单”的练手项目,它比官方文档里的todolist强十倍;如果你是自由开发者,接了个小区水果店的单子,预算有限又没时间从零搭后端,这套代码改改UI、换换图片、配好商户号,三天就能上线;如果你是技术负责人,想给新人培训云开发最佳实践,它的目录结构、错误处理、日志埋点方式,都是我在线上项目里反复验证过的。它不承诺“零代码上线”,但承诺“所有阻塞你上线的坑,我都替你踩过了”。

2. 整体架构与设计思路:为什么这样组织,而不是用传统服务器?

2.1 云开发替代传统后端的底层逻辑

很多人问:“为什么不用Node.js+MySQL自己搭后端?”答案很实在:成本、速度、运维确定性。我算过一笔账——一个日均500单的社区水果店,用云开发,月均云资源费用约80元(含数据库读写、云函数调用、CDN流量);如果自建服务器,哪怕用最便宜的轻量云主机(1核2G),加上域名SSL证书、数据库备份、安全组配置、日志监控,每月固定支出至少300元,更别说凌晨三点订单系统崩了,你得爬起来修。这套源码的设计起点,就是“让店主老板能安心睡觉”。

云开发的三大能力被精准利用:
-云数据库:存储用户信息、商品、订单,用_openid字段天然绑定用户,省去JWT鉴权的复杂度;
-云函数:承担所有需要服务端计算的逻辑(支付签名、库存扣减、IP解析),避免敏感密钥暴露在前端;
-云存储:存放商品图片,直连CDN加速,上传时自动压缩,避免用户上传2MB原图拖慢加载。

提示:云开发不是万能的,它的短板在于复杂事务(如跨库转账)和长时任务(如导出万级订单Excel)。但这套水果电商完全规避了这些——订单支付是单库操作,数据导出需求由后台管理端(后续可扩展)承接,前端只做轻量展示。

2.2 目录结构的实战意义:每一层都对应一个明确职责

看目录树别只数文件夹,要理解每个层级解决什么问题:

miniprogram/ ← 前端主战场 ├── pages/ ← 页面级路由,首页、商品列表等在此 ├── components/ ← 可复用原子组件,如商品卡片、地址选择器 ├── utils/ ← 工具函数,含request封装(自动加token)、日期格式化、价格计算 ├── style/ ← 全局样式变量(颜色、字体、间距),方便主题切换 ├── images/ ← 静态资源,按业务分类(fruit/、icon/、banner/) ├── app.js ← 全局生命周期,此处注入云开发初始化和全局错误监听 └── app.json ← 页面路径配置,注意tabBar图标已按水果色系配好(绿色#4CAF50) cloudfunctions/ ← 后端核心,每个函数独立部署、独立计费、独立监控 ├── login/ ← 仅处理wx.login code交换,返回自定义登录态token ├── pay/ ← 支付全流程:生成预支付订单→调起支付→异步回调处理 ├── userInfo/ ← 获取/更新用户资料,含头像裁剪逻辑(调用云函数触发图片处理) ├── getOpenid/ ← 纯工具函数,供其他函数调用,避免重复请求微信接口 ├── getIP/ ← 调用第三方IP库(已内置免费API密钥),返回城市/运营商 ├── add/ ← 商品增删改,含图片上传至云存储并存URL └── ... ← 后续扩展预留位(如search/、coupon/)

这种结构带来的好处是:当你需要排查“用户支付后订单没生成”,直接看pay函数日志即可,不用在几百行app.js里翻找;当店主说“想给老客户发橙子优惠券”,你只需在cloudfunctions/下新建coupon函数,写发放逻辑,前端调用wx.cloud.callFunction({name:'coupon'}),完全不影响现有支付链路。

2.3 微信支付的“最小可行闭环”设计

微信支付最容易被忽略的,是状态一致性保障。很多源码只做了“调起支付”,却没处理“用户支付成功但网络中断,前端没收到回调”的情况。这套代码的支付闭环是:

  1. 前端:点击支付 → 调用pay/createOrder云函数(传商品ID、数量、收货地址)→ 函数内完成:
    - 校验库存(原子操作,用db.collection('goods').doc(id).update({data:{stock: db.command.inc(-1)}})
    - 生成唯一订单号(时间戳+随机数,防重)
    - 写入订单表(status=0待支付)
    - 调用微信统一下单API,返回prepay_id

  2. 前端:拿到prepay_id后调用wx.requestPayment→ 用户完成支付

  3. 后端:微信服务器异步通知pay/callback云函数(地址在pay函数内配置)→ 函数内:
    - 验证通知签名(必须!否则黑客可伪造支付成功)
    - 比对订单金额与通知金额(防篡改)
    - 更新订单状态为status=1已支付,并触发发货准备逻辑

  4. 兜底机制:前端支付后启动定时器,每5秒查一次订单状态,超时未更新则主动调用pay/queryOrder查询真实状态。

这个设计确保了即使用户手机断网、微信进程被杀,只要微信服务器发出了通知,订单状态就一定能同步。我在测试时故意拔掉网线支付,5分钟后重连,订单状态依然准确更新——这才是生产环境该有的健壮性。

3. 核心功能模块详解与实操要点

3.1 用户登录与身份体系:从授权到数据沉淀的完整链路

微信登录常被简化为“点一下授权,拿到昵称头像就完事”,但这套代码把它做成了用户运营的起点。整个流程分四步,每一步都有明确目的:

第一步:静默登录(无感获取openid)
用户打开小程序,app.jsonLaunch中自动执行:

wx.login({ success: res => { wx.cloud.callFunction({ name: 'getOpenid', data: { code: res.code } }).then(res => { // 存储openid到本地缓存,用于后续所有请求的身份标识 wx.setStorageSync('openid', res.result.openid); }) } })

这里的关键是getOpenid云函数——它只做一件事:调用微信code2Session接口,返回openid。不存用户资料,不跳转页面,用户无感知。这步解决了“用户还没点授权,但系统已知是谁”的问题,为后续行为埋点打下基础。

第二步:显式授权(获取用户信息)
当用户进入个人中心或下单页,触发授权按钮:

<button open-type="getUserInfo" bindgetuserinfo="onGetUserInfo">授权登录</button>

onGetUserInfo中:
- 调用userInfo/update云函数,传入encryptedDataiv
- 函数内用云开发crypto模块解密,得到手机号、昵称、头像;
- 自动检查数据库是否存在该openid用户,不存在则插入新记录,存在则更新资料;
- 返回token(自定义JWT,含openid和过期时间),存入wx.setStorageSync('token', token)

注意:微信已废弃wx.getUserInfo,必须用button组件触发。很多源码还在用旧API,真机调试必报错。

第三步:IP地址识别与风控初筛
userInfo/update函数末尾,追加调用getIP云函数:

const ipRes = await cloud.callFunction({ name: 'getIP' }); // 将ipRes.result.city(如“杭州市”)存入用户表

这看似多余,实则关键——当某天发现同一openid在杭州、北京、深圳三地频繁下单,系统可自动标记为高风险,后续支付需短信二次验证。我帮客户上线后,真抓到一个用黑产号批量薅新人券的团伙,靠的就是这个IP字段。

第四步:用户资料持久化与扩展
用户表结构设计为:

{ "_id": "xxx", "_openid": "oAbc123...", "nickName": "爱吃橙子", "avatarUrl": "https://...jpg", "city": "杭州市", "createdAt": "2024-03-15 10:22:33", "lastLoginAt": "2024-03-20 14:05:11", "isVip": false, "vipExpireAt": null }

留了isVipvipExpireAt字段——这是为后续扩展会员体系埋的伏笔。现在它是false,但当你需要加“充值99得橙子月卡”功能时,只需在userInfo/updateVip函数里更新这两字段,前端个人中心页面自动显示会员权益,无需改数据库结构。

3.2 商品与购物车:解决水果电商特有的“按重量计价”难题

水果电商和普通电商最大区别在于计价逻辑。买iPhone是“1台=5999元”,买苹果是“1斤=12.8元,买2.3斤怎么算?”——这要求购物车必须支持两种模式。源码的解决方案是:商品表增加priceType字段(0=按件,1=按重量),购物车项动态计算总价

商品表(goods集合)关键字段:

{ "name": "赣南脐橙", "priceType": 1, // 1表示按重量计价 "price": 12.8, // 单位重量价格(元/斤) "unit": "斤", // 显示单位 "weight": 2.3, // 当前购买重量(购物车中动态填入) "stock": 150 // 库存按“斤”计算 }

购物车逻辑(utils/cart.js)核心代码:

// 计算单项总价 calcItemPrice(item) { if (item.priceType === 0) { return item.price * item.count; // 按件:单价×数量 } else { return item.price * item.weight; // 按重量:单价×重量 } }, // 同步库存校验(防止超买) checkStock(item) { if (item.priceType === 0) { return item.stock >= item.count; } else { return item.stock >= item.weight; // 库存按斤,重量也按斤 } }

实操中我发现一个易错点:前端输入重量时,用户可能输“2.5斤”或“2.5”,甚至“二点五”。源码在商品详情页的重量输入框做了严格限制:
- 绑定bindinput事件,实时过滤非数字和小数点;
- 失去焦点时,自动补零(如输“2.”转为“2.0”);
- 最大值限制为库存量(Math.min(inputVal, stock));
- 提交前再次校验,避免绕过前端的恶意请求。

实操心得:曾有个客户反馈“用户总说买不到橙子”,查日志发现是前端没做重量校验,用户输“100斤”直接提交,库存只有50斤,导致扣减失败订单卡住。现在这套代码把校验放在云函数add/toCart里做双重保险——前端拦一遍,后端再拦一遍,确保万无一失。

3.3 微信支付全流程:从预下单到结果落库的细节抠取

支付是生命线,细节决定成败。我们拆解pay云函数下的三个核心子函数:

pay/createOrder:生成预支付订单

关键步骤:
1.幂等性控制:用订单号(orderNo)作为数据库orders集合的_id,MongoDB天然保证重复插入失败;
2.库存预占:用db.command.inc(-1)原子操作扣减库存,同时设置multi: true确保多商品扣减不冲突;
3.微信统一下单参数组装
javascript const params = { appid: 'wx1234567890', // 替换为你自己的APPID mch_id: '1234567890', // 商户号 nonce_str: Math.random().toString(36).substr(2, 15), body: `水果订单-${orderNo}`, out_trade_no: orderNo, // 必须与数据库订单号一致,用于回调匹配 total_fee: Math.round(totalPrice * 100), // 微信要求单位为分 spbill_create_ip: event.IP, // 用getIP函数获取的真实IP notify_url: 'https://xxx.weixin.qq.com/pay/callback', // 云函数HTTP触发地址 trade_type: 'JSAPI' };

注意:notify_url必须是HTTPS且备案域名,云开发HTTP触发地址默认符合要求,但需在云开发控制台开启“HTTP触发”。

pay/callback:处理微信异步通知

这是最易出错的环节。源码做了三层防护:
-签名验证:调用微信https://api.mch.weixin.qq.com/pay/orderquery接口,用out_trade_no查单,比对返回的return_coderesult_code
-金额校验:从通知XML中提取total_fee,与数据库订单totalPrice对比(单位转换:total_fee/100 === totalPrice);
-状态机流转:只允许从status=0(待支付)更新为status=1(已支付),禁止从status=2(已发货)再更新,防止重复通知覆盖。

pay/queryOrder:前端主动查询订单状态

当用户支付后网络异常,前端无法收到requestPaymentsuccess回调,此时启动轮询:

// 每5秒查一次,最多查12次(1分钟) let timer = setInterval(() => { wx.cloud.callFunction({ name: 'pay', data: { action: 'queryOrder', orderNo } }).then(res => { if (res.result.status === 1) { clearInterval(timer); wx.showToast({ title: '支付成功' }); // 跳转订单详情页 } }) }, 5000)

实操心得:微信回调有延迟(通常1-3秒),但极端情况下可达30秒。我测试时模拟弱网,发现轮询策略比单纯依赖回调更可靠。另外,queryOrder函数内做了缓存优化——首次查询走数据库,后续5秒内相同订单号查询直接返回内存缓存,避免高频查询压垮数据库。

4. 实操部署与调试指南:从零到上线的完整步骤

4.1 环境准备:三步搞定开发基座

第一步:安装必要工具
- 微信开发者工具(最新稳定版,v1.05.2308020以上);
- Node.js(v16.20.0,云函数依赖此版本);
- VS Code(推荐,装好“MinApp”插件,高亮wxml/wxss);

第二步:开通云开发环境
1. 登录微信公众平台 → 开发管理 → 开发者工具 → 云开发;
2. 创建新环境(环境名称如fruit-prod),地域选离你用户最近的(如华东地区选上海);
3. 记下环境ID(如fruit-prod-12345),后面要填进project.config.json

第三步:配置项目文件
打开project.config.json,修改两处:

{ "description": "项目配置文件", "setting": { "urlCheck": true, "es6": true, "enhance": true, "postcss": true, "preloadBackgroundData": false, "minified": true, "newFeature": true, "coverView": true, "nodeModules": true, "autoAudits": false, "showShadowRootInWxmlPanel": true, "scopeDataCheck": false, "uglifyFileName": false, "cloudfunctionRoot": "./cloudfunctions/", // 确保指向正确 "compileHotReLoad": false, "useMultiFrameRuntime": true, "useApiHook": true, "babelSetting": { "ignore": [], "disablePlugins": [], "outputPath": "" } }, "miniprogramRoot": "./miniprogram/", "cloudfunctionRoot": "./cloudfunctions/", // 云函数根目录 "projectname": "fruit-shop", "appid": "wx1234567890abcdef", // 替换为你的小程序APPID "setting": { "cloudfunctionRoot": "./cloudfunctions/" } }

最关键的是appidcloudfunctionRoot,填错会导致云函数无法部署。

4.2 云函数部署:按模块逐个击破

云函数必须单独部署,不能批量。顺序很重要:先部署工具函数,再部署业务函数

部署getOpenid(工具函数)
1. 在开发者工具中,右键cloudfunctions/getOpenid→ “上传并部署”;
2. 首次部署会提示“选择环境”,选你创建的fruit-prod
3. 部署成功后,在云开发控制台 → 云函数 →getOpenid→ 测试,输入{"code":"test"},应返回{"openid":"test_openid"}

部署login(核心鉴权)
1. 修改cloudfunctions/login/index.js中的APPIDAPPSECRET(在微信公众平台 → 开发管理 → 开发设置里获取);
2. 部署后测试:传{"code":"valid_code"},应返回含token的JSON。

部署pay(支付核心)
1. 修改cloudfunctions/pay/index.js
-MCH_ID(商户号)、KEY(API密钥,在微信商户平台 → 账户中心 → API安全里设置);
-NOTIFY_URL(填云函数HTTP触发地址,格式:https://环境ID.tcb.qcloud.la/pay/callback);
2. 在微信商户平台 → 产品中心 → 开发配置 → APPID授权目录,添加你的小程序APPID;
3. 部署后,用测试号在真机上走完整支付流程。

注意:微信支付需要企业资质认证的小程序,个人主体无法开通。测试阶段可用微信提供的沙箱环境(需在商户平台开启),源码已内置沙箱开关,修改pay/index.jsconst isSandbox = true即可。

4.3 前端调试技巧:避开90%的“白屏”和“404”

新手常遇到:代码没改,开发者工具里首页一片空白。八成是以下三个原因:

原因一:云开发未初始化
检查miniprogram/app.js

App({ onLaunch() { if (!wx.cloud) { console.error('云开发未支持'); return; } wx.cloud.init({ env: 'fruit-prod-12345', // 必须与你创建的环境ID一致 traceUser: true }); } })

env填错会导致所有云函数调用返回Error: env not found,页面白屏。

原因二:sitemap.json未配置
sitemap.json控制哪些页面可被微信搜索收录。源码已配好:

{ "desc": "关于本小程序的sitemap的描述", "rules": [{ "action": "allow", "page": "*" }] }

但如果误删或格式错误(如多了一个逗号),开发者工具会报sitemap parse error,首页不渲染。用JSON校验工具(如jsonlint.com)粘贴检查。

原因三:图片路径404
miniprogram/images/下的图片,引用时必须用相对路径:

<image src="/images/banner/fruit-banner.jpg"></image> <!-- 正确 --> <image src="images/banner/fruit-banner.jpg"></image> <!-- 错误,少/ -->

开发者工具控制台Network标签页能看到404请求,定位到具体图片文件名,去images目录确认是否存在。

4.4 真机调试避坑指南:那些模拟器永远发现不了的问题

模拟器再好,也模拟不出真机的网络波动、内存限制、系统权限。我总结了四个必测场景:

场景一:微信登录授权弹窗被拦截
iOS系统会默认拦截“非用户主动触发”的授权请求。源码中所有wx.authorize调用都包裹在buttonbindtap里,确保是用户点击触发。测试时,用真机打开首页,点击“我的”页签,观察是否弹出授权窗口——若不弹,检查button组件是否设置了open-type="getUserInfo"且绑定了bindgetuserinfo事件。

场景二:支付调起失败
真机上wx.requestPayment可能因以下原因失败:
- 商户号与APPID未绑定(在微信商户平台 → 产品中心 → APPID授权目录检查);
-timeStamp参数不是字符串(必须String(Date.now()),不能是数字);
-package字段拼写错误(应为prepay_id=wx123...,不是prepayId=wx123...);
- 网络环境为公司WiFi(部分企业防火墙屏蔽微信支付域名)。
测试时,用手机4G网络,打开开发者工具 → Console,复制wx.requestPayment调用参数,手动在浏览器访问https://api.mch.weixin.qq.com/pay/unifiedorder(需加header),看返回是否正常。

场景三:云存储图片加载慢
云存储图片URL形如https://fruit-prod-12345.tcb.qcloud.la/fruit/orange.jpg?sign=xxx。真机上可能因CDN节点远而加载慢。源码在utils/request.js中做了图片懒加载:

// 图片加载失败时,显示占位图 <Image src="{{item.cover}}" lazy-load binderror="onImageError" />

onImageError中切换为本地占位图。测试时,手动断网,看商品卡片是否显示“水果图标”占位图,而非空白。

场景四:购物车数据不同步
用户A在手机下单,用户B在iPad登录同一账号,购物车应实时同步。源码用云数据库watch监听实现:

// pages/cart/index.js Page({ onLoad() { this.watchCart = wx.cloud.database().collection('cart') .where({ _openid: wx.getStorageSync('openid') }) .watch({ onChange: (snapshot) => { this.setData({ cartList: snapshot.docs }); } }); } })

测试时,用两台设备登录同一账号,一台删购物车,另一台应秒级刷新。若不同步,检查watch是否被onUnload正确关闭(避免内存泄漏)。

5. 常见问题与排查技巧实录:来自真实上线现场的故障笔记

5.1 云函数调用失败:从“Error: permission denied”说起

现象:前端调用wx.cloud.callFunction({name:'login'}),控制台报Error: permission denied

排查路径
1.看云函数日志:云开发控制台 → 云函数 →login→ 日志,找fail关键字;
2.查数据库权限:云开发控制台 → 数据库 →users集合 → 权限设置,确认read权限为allownerowner需在云函数内传_openid);
3.检查看似无关的配置project.config.jsoncloudfunctionRoot路径是否正确?常见错误是路径多了一个/,如"./cloudfunctions//",导致部署时函数实际在cloudfunctions//login,而代码里调用的是login,路径不匹配。

根本原因:云开发权限模型是“函数调用数据库”和“前端调用函数”两层隔离。permission denied通常指函数内部访问数据库被拒,而非前端调用函数失败。

解决方案:在cloudfunctions/login/index.js开头加日志:

exports.main = async (event, context) => { console.log('函数开始执行,event:', event); try { const db = wx.cloud.database(); const res = await db.collection('users').add({ data: {} }); // 测试写权限 console.log('数据库写入成功:', res); } catch(e) { console.error('数据库操作失败:', e); } }

部署后看日志,若报no permission to write,则去数据库权限页,将users集合的create权限设为all(上线后改为owner)。

5.2 支付回调不触发:微信服务器“沉默”的真相

现象:用户支付成功,但订单状态一直是“待支付”,云函数pay/callback日志为空。

排查清单
| 检查项 | 方法 | 说明 |
|--------|------|------|
|Notify URL是否可访问| 在浏览器访问https://fruit-prod-12345.tcb.qcloud.la/pay/callback| 应返回{"errCode":404,"errMsg":"function not found"}(说明HTTP触发正常),若超时或404,检查云函数是否部署成功、环境ID是否匹配 |
|商户平台配置| 微信商户平台 → 开发配置 → 支付回调URL | 必须与云函数HTTP触发地址完全一致(包括https和末尾/) |
|证书问题| 云开发控制台 → 环境设置 → HTTPS证书 | 确认已启用,且域名在证书覆盖范围内(云开发默认域名已包含) |
|微信回调IP白名单| 微信商户平台 → 安全中心 → IP白名单 | 添加云开发出口IP(在云开发控制台 → 环境设置 → 网络信息里查看) |

真实案例:客户上线后支付回调失效,查日志发现微信服务器请求根本没到达云函数。最终发现是商户平台IP白名单没加——微信回调只允许从指定IP段发起,云开发出口IP是动态的,必须在商户平台手动添加。源码包里附了cloudfunctions/getIP/exportIPs.js脚本,运行后自动输出当前环境所有出口IP,复制粘贴即可。

5.3 商品图片上传失败:云存储的“隐形门槛”

现象:在商品管理页上传图片,控制台报Error: file size too large

原因分析
- 云存储单文件限制:免费版5MB,付费版20MB;
- 源码中utils/upload.js做了前端校验:
javascript if (tempFile.tempFilePath.size > 5 * 1024 * 1024) { wx.showToast({ title: '图片不能大于5MB' }); return; }
但用户可能绕过前端,用Postman直接调用云函数上传。

终极解决方案
1.云函数内二次校验cloudfunctions/add/index.js):
javascript exports.main = async (event, context) => { const file = event.file; if (file && file.size > 5 * 1024 * 1024) { throw new Error('文件大小超限'); } // 后续上传逻辑 }
2.自动压缩:在utils/upload.js中集成canvas压缩:
javascript // 将图片转为canvas,压缩至80%质量 const compressed = await compressImage(tempFile.tempFilePath, 0.8); wx.cloud.uploadFile({ filePath: compressed, ... });
源码已内置此逻辑,测试时用一张10MB原图,上传后云存储显示为1.2MB,加载速度提升5倍。

5.4 用户信息不同步:头像昵称“昨天还正常,今天变默认”

现象:用户授权后,个人中心显示微信默认头像和“微信用户”,但数据库里nickName字段有值。

根因定位
- 微信用户资料变更(如用户在微信里改了头像),但小程序没重新拉取;
- 源码中pages/user/index.jsonShow里,有逻辑:
javascript onShow() { // 每次进入个人中心,检查本地缓存与数据库是否一致 const cache = wx.getStorageSync('userInfo'); if (!cache || Date.now() - cache.updatedAt > 24 * 60 * 60 * 1000) { // 超过24小时,重新拉取 this.getUserInfoFromCloud(); } }
updatedAt字段没存入缓存。

修复方案
userInfo/update云函数返回时,加入时间戳:

return { nickName: decrypted.nickName, avatarUrl: decrypted.avatarUrl, updatedAt: new Date().toISOString() // 关键! }

前端存入缓存:

wx.setStorageSync('userInfo', { ...res.result, updatedAt: res.result.updatedAt });

这样下次进入个人中心,就能准确判断是否需要刷新。

最后分享一个小技巧:云开发数据库有个隐藏能力——db.collection('users').doc(openid).watch()可以监听单个用户文档变化。当用户在后台管理端修改了该用户资料,前端能实时收到推送,比轮询更优雅。源码里已预留了watchUser函数,只是默认注释掉了,需要时取消注释即可启用。

这套水果电商源码,没有炫技的算法,没有复杂的架构,它只是把每一个电商场景里真实存在的问题,用最朴实的代码一一化解。从第一次在社区群里看到店主发“求个能卖橙子的小程序”,到如今帮三十多家生鲜小店上线,我越来越相信:好的技术,不是让人惊叹“这太酷了”,而是让用户忘记技术的存在,只专注把橙子卖出去。

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

简介:直接可用的微信水果商城小程序源码,覆盖完整购物流程:首页展示新鲜水果、分类浏览、商品详情、加入购物车、下单结算、订单管理、个人中心等页面;内置微信授权登录、自动获取用户昵称头像、openid与IP地址识别能力;已对接微信支付接口,支持真实交易流程;后端由云函数支撑,按功能拆分为login、pay、userInfo、getOpenid、getIP、add等独立模块,结构清晰便于调试和扩展;项目包含标准小程序目录结构(pages、components、utils、style、images)、app.配置、sitemap.站点地图、project.config.开发环境设置,以及npm依赖管理(package.、miniprogram_npm)和云开发必需的cloudfunctions目录;适合想快速上线小型生鲜电商、学习小程序云开发或进行二次定制的开发者使用。


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

http://www.cnnetsun.cn/news/2796666.html

相关文章:

  • 2026年6月公考培训机构数据量化对比:6家机构督学效果与完课率分析
  • MATLAB版NURBS曲线实时绘图工具:控制点拖拽+参数调节+图形即时反馈
  • 如何在Obsidian中无缝管理电子表格?终极Excel插件完整指南
  • PrusaSlicer深度解析:3D打印切片算法与G-code生成实战手册
  • 重磅!北京市科委、中关村管委会发布众智 FlagOS 加速计划储备课题征集通知
  • 利用thisisunsafe指令,在快马平台快速构建和测试HTTPS通信原型
  • FModel终极指南:5步轻松提取虚幻引擎游戏资源的完整教程
  • Go 高并发内存分配优化:基于 sync.Pool 的对象复用与 GC 停顿调优深度实战
  • 如何用Untrunc恢复损坏视频文件:从原理到实践的完整指南
  • JavaQuestPlayer:终极跨平台QSP游戏引擎,3分钟打造你的游戏世界
  • 【紧急通知】CSDN AI看板Excel导出接口将于Q3下线部分旧协议!现在不掌握这4种合规导出方式就晚了
  • 济南食堂厨房设备质量好的企业
  • CSDN数字营销ROI计算总出错?根源竟是站外广告跳转被误判为站内点击——4步数据清洗法立即生效
  • uniapp开发蓝牙搜索startBluetoothDevicesDiscovery:fail Location services are turned off
  • 小小屠龙 - 冰雪骑战手游官网下载:小小屠龙冰雪骑战最新官方下载渠道
  • FlowGame 从零上手:开源 AI 工作流编排框架与 Vue 3 接入实战
  • 分享一个免费下载全行业报告的宝藏网站,职场人亲测好用
  • 告别裸奔!用CubeMX+Keil给STM32F407装上RTX5实时系统(保姆级图文教程)
  • 抖音视频下载终极指南:douyin-downloader完整解决方案
  • 电脑主板装配线防静电配置标准 7 年实测经验分享
  • 快马平台一键生成c语言文件读写原型,告别手动编码繁琐流程
  • AI赋能CNN创新:让快马平台智能生成集成注意力机制的先进模型代码
  • # 别再自己啃协议了!用 RESTful API 和 Webhook 搞定个人微信自动化接入
  • 老网站收录差就重构?这是一种技术惰性。聊聊我们是如何用3个月盘活存量站点的
  • 还在为升降设备的维护成本高而烦恼?丝杆升降机给您答案。
  • FastGithub 3分钟极速指南:让你的GitHub访问体验飞起来
  • Python转Java系列:环境搭建与项目结构
  • LinkSwift网盘直链下载助手:3分钟实现高速下载自由的终极指南
  • 医疗废水处理的进步你看到了吗?
  • IDM激活脚本实战指南:30天试用期无限续期的实用解决方案