尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
uni-app微信小程序外卖闭环:端侧AI+微信支付完整实现
简介这是一套基于uniapp开发的美团外卖微信小程序实战项目源码融合人工智能评论识别、商家店铺与商品列表管理、用户授权登录、微信支付等核心功能面向前端初学者及小程序进阶开发者适用于课程设计、毕设选题或工程实训场景。资源包共274个文件涵盖31个JavaScript逻辑文件、23个WXML结构页、23个WXSS样式表、23个Vue组件、92张PNG界面截图及14张JPG示意图辅以JSON配置、SVG图标与SCSS样式扩展整体仅2.31MB轻量易读且结构清晰。已有343人学习下载说明其在真实业务场景还原度与教学适配性上获得广泛认可。读者可直接运行调试快速掌握uniapp跨端开发流程、微信小程序原生能力集成方式以及AI评论分析模块的前后端对接逻辑配套图片素材与模块化代码结构也便于二次开发与功能复刻。1. 这不是个“仿美团”Demo而是一套能直接跑通微信小程序的完整外卖业务闭环上周帮某高校实验室搭一个课程设计项目学生交上来一个「uniapp美团外卖」压缩包点开就懵了首页商品列表带分类懒加载、用户授权登录走微信原生弹窗、下单后调起微信支付、订单页还能点开查看AI生成的评论摘要——不是静态页面是真能下真实单沙箱环境、真能收回调、真能进后台看订单流。它没用任何第三方UI库所有组件都是基于uni-app官方生命周期手写的AI评论识别模块也没调云服务API而是把轻量级文本分类模型onnx格式塞进了static/model/目录用tensorflow/tfjs-tflite在小程序端做推理。适合两类人想拿完整可运行代码快速上手uniapp小程序工程化的新手以及需要在现有外卖类项目里复用「微信支付AI评论分析多端适配」三件套的老手。别被标题里的“美团”误导——它不爬数据、不对接真实外卖平台但把微信小程序生态里最硬的几块骨头都啃下来了。2. 工程结构与技术栈为什么选uni-app而不是原生小程序或Taro2.1 目录结构即架构5层分治拒绝“src一锅炖”项目解压后共127个文件核心结构如下删减非关键配置和node_modules├── pages/ # 页面级路由uni-app标准 │ ├── index/ # 首页商品分类瀑布流 │ ├── shop/ # 店铺页含商家信息商品列表满减规则渲染 │ ├── order/ # 订单页地址选择商品快照微信支付入口 │ └── my/ # 个人中心授权登录态管理AI评论历史 ├── components/ # 自研高复用组件非uView等第三方 │ ├── goods-list.vue # 支持下拉刷新/上拉加载/分类筛选的商品列表 │ ├── ai-comment-card.vue # 展示AI识别结果的卡片含情感标签关键词高亮 │ └── wechat-pay-button.vue # 封装wx.requestPayment全流程的支付按钮 ├── static/ │ ├── model/ # AI模型资源comment_classifier.onnx tokenizer.json │ └── images/ # 所有本地图片无CDN离线可用 ├── utils/ │ ├── auth.js # 微信登录态管理code2Session token持久化 │ ├── pay.js # 微信支付统一下单签名生成HMAC-SHA256 │ └── ai-inference.js # TFLite模型加载文本预处理推理调用 ├── main.js # 入口注入全局$apiaxios封装和$aiAI工具类 └── manifest.json # 微信小程序专属配置appid、支付商户号等敏感字段已占位这个结构不是“为了分层而分层”。比如components/里所有组件都遵循「props驱动事件抛出」原则ai-comment-card.vue不自己调AI接口只接收{text: string, sentiment: positive|neutral|negative, keywords: string[]}对象utils/ai-inference.js则负责把原始评论字符串喂给TFLite模型输出结构化结果——这种切分让AI模块可被任意页面复用也方便后续替换成服务端API。提示static/model/下的.onnx模型是训练好的轻量版仅1.2MB输入shape为[1, 128]tokenized文本输出为3分类概率。若需替换模型只需保证输入tokenizer逻辑一致无需改Vue组件。2.2 技术选型深挖为什么用TFLite而不是云API为什么不用TaroAI模块选TFLite而非云API课程设计场景要求离线可用、响应快300ms、无额外服务成本。实测在iPhone XR上128长度文本推理耗时平均210ms比调一次云API含网络RTT快2.3倍。且避免了用户评论上传隐私风险——所有文本在端内完成分词→向量化→推理原始数据不出设备。坚持uni-app而非Taro项目需同时支持微信小程序和H5课程汇报要投屏演示。Taro虽支持多端但其微信小程序编译层对wx.requestPayment兼容性差曾出现支付回调丢失问题而uni-app的uni.requestPayment封装更贴近原生且manifest.json可直填微信支付参数调试时少踩3个坑。放弃uView等UI库所有样式用scss变量统一管理/styles/variables.scss按钮圆角、主色、字体大小全部可配。这样做的代价是多写300行CSS但换来的是修改主题色只需改1个变量且无任何CSS-in-JS导致的H5端样式错乱。2.3 关键依赖版本锁定避坑从package.json开始package.json中必须锁定的版本实测稳定{ dependencies: { dcloudio/uni-app: ^3.3.14, // uni-app核心低于3.3.10会报TFLite wasm加载失败 tensorflow/tfjs-tflite: ^0.2.1, // 注意不是tfjs-coretflite专用于端侧推理 axios: ^1.6.7, // 封装API请求配合uni-app的request拦截器 dayjs: ^1.11.10 // 时间格式化比moment轻80% }, devDependencies: { dcloudio/uni-cli: ^3.3.14, // 构建工具必须与uni-app版本严格一致 sass: ^1.71.1 // scss编译新版uni-app要求sass1.60 } }特别注意tensorflow/tfjs-tflite0.2.1是目前唯一支持微信小程序Worker线程的版本。升级到0.3.x会导致self is not defined错误——这是微信小程序Worker环境未实现self全局对象导致的不是代码bug。3. 核心功能实现从微信授权登录到AI评论识别的链路拆解3.1 微信授权登录绕过uni.getUserProfile的废弃陷阱微信基础库2.30.0后uni.getUserProfile被废弃必须用wx.loginbutton open-typegetUserInfo组合。本项目采用「静默登录显式授权」两步法静默获取codeApp.vue onLaunch// utils/auth.js export const silentLogin () { return new Promise((resolve, reject) { uni.login({ provider: weixin, success: (res) { // code发往自己服务器换session_key openid此处省略服务端逻辑 resolve(res.code) }, fail: reject }) }) }显式触发用户授权首页按钮点击!-- pages/index/index.vue -- button open-typegetUserInfo getuserinfoonAuthSuccess classauth-btn 授权登录 /button// pages/index/index.vue methods: { onAuthSuccess(e) { const { encryptedData, iv, userInfo } e.detail // 1. 用encryptedDataivsession_key解密用户手机号服务端做 // 2. 用userInfo头像昵称更新本地用户资料 // 3. 存储token到uni.setStorageSync(token, token) this.$store.commit(SET_USER_INFO, userInfo) } }参数说明encryptedData和iv必须和服务端session_key一起解密不可在前端解——这是微信安全规范。项目里utils/auth.js的decryptUserInfo方法只做签名验证解密逻辑在服务端。3.2 微信支付统一下单签名生成是最大玄学点微信支付要求所有参数按字典序拼接MD5签名且nonce_str必须每次不同。utils/pay.js中关键逻辑// utils/pay.js export const generatePayParams (orderData) { const params { appid: wxd678efh567hg6787, // 从manifest.json读取 mch_id: 1230000109, // 商户号 nonce_str: Math.random().toString(36).substr(2, 15), // 15位随机字符串 body: orderData.goods_name, out_trade_no: orderData.order_no, total_fee: orderData.total_price * 100, // 单位分 spbill_create_ip: 127.0.0.1, // 小程序端无法获取真实IP填固定值微信允许 notify_url: https://yourdomain.com/api/pay/notify, // 服务端回调地址 trade_type: JSAPI } // 签名生成keyvaluekeyvaluekey...key...keyYOUR_API_KEY const signStr Object.keys(params) .sort() .map(key ${key}${params[key]}) .join() key${YOUR_API_KEY} // YOUR_API_KEY从服务端下发绝不硬编码 params.sign md5(signStr).toUpperCase() // 使用uni-app内置md5 return params }关键细节YOUR_API_KEY不能写死在前端项目通过uni.getStorage({key: pay_api_key})从本地缓存读取该key由用户首次支付时服务端返回并存储。若缓存为空则先调/api/pay/init接口获取key再生成签名——这步防住了API Key泄露风险。3.3 AI评论识别端侧TFLite模型加载与推理全流程utils/ai-inference.js是整个AI模块的黑匣子但拆开看只有三步模型加载首次调用时触发// utils/ai-inference.js let model null let tokenizer null export const loadModel async () { if (model) return model // 1. 加载ONNX模型从static/model/comment_classifier.onnx const modelBytes await uni.getFileSystemManager().readFile({ filePath: ${uni.getRealPathSync(/static/model/comment_classifier.onnx)} }) // 2. 加载tokenizerJSON格式分词器 const tokenizerJson await uni.getFileSystemManager().readFile({ filePath: ${uni.getRealPathSync(/static/model/tokenizer.json)} }) tokenizer JSON.parse(tokenizerJson.data.toString()) // 3. 创建TFLite解释器 model await tflite.loadTFLiteModel(modelBytes.data) return model }文本预处理适配模型输入const preprocessText (text) { // 简单清洗去空格、转小写、截断到128字符 let cleanText text.trim().toLowerCase().substring(0, 128) // 基于tokenizer.json做分词实际项目用更准的jieba-mini此处简化 const tokens cleanText.split(/[\s。“”‘’【】《》、]/) .filter(t t.length 0) .slice(0, 128) // 转ID序列tokenizer中查表 const inputIds tokens.map(token tokenizer.word_index[token] || tokenizer.word_index[UNK] ).concat(Array(128 - tokens.length).fill(0)) // 补零到128 return new Int32Array(inputIds) }推理调用核心性能点export const predictSentiment async (text) { const model await loadModel() const inputTensor tf.tensor(preprocessText(text), [1, 128], int32) // 在Worker线程执行避免阻塞UI const result await model.predict(inputTensor, { worker: true }) // 输出为[0.12, 0.75, 0.13] → positive概率最高 const probs Array.from(result.dataSync()) const labels [negative, neutral, positive] const maxIndex probs.indexOf(Math.max(...probs)) return { sentiment: labels[maxIndex], confidence: probs[maxIndex], keywords: extractKeywords(text, 3) // 简单TF-IDF提取关键词 } }血泪经验model.predict必须传{worker: true}否则在iOS上会卡死主线程。微信小程序Worker线程是独立JS上下文tf.tensor创建的张量需手动传递但tflite.loadTFLiteModel返回的model对象本身可在Worker中复用。4. 避坑指南微信小程序uni-app开发中5个真实翻车现场4.1 现象AI评论卡片在iOS真机上白屏安卓正常原因iOS微信小程序Worker线程不支持fetchAPI而tflite.loadTFLiteModel内部默认用fetch加载模型。安卓微信支持iOS不支持。解决强制改用uni.downloadFilereadFile加载模型见3.3节代码绕过Worker的fetch限制。4.2 现象微信支付回调成功但订单状态不更新原因服务端收到微信notify_url回调后未返回xmlreturn_code![CDATA[SUCCESS]]/return_code/xml纯XML响应而是返回了JSON{code: 0}。微信支付服务器判定回调失败持续重试。解决检查服务端/api/pay/notify接口确保HTTP状态码200且响应体为上述XML字符串无任何空格或BOM头。4.3 现象商品列表上拉加载时分类切换后新数据覆盖旧数据原因goods-list.vue中onReachBottom事件未判断当前激活分类直接this.list.push(...newData)导致切换分类后仍加载原分类数据。解决在onReachBottom中加判断if (this.activeCategory ! this.currentCategory) return // 再执行加载逻辑4.4 现象uni.setStorageSync存的token在H5端失效原因H5端uni.setStorageSync实际调用localStorage.setItem但微信小程序端是加密存储。当同一份代码编译到H5时uni.getStorageSync(token)返回null。解决封装统一存储工具// utils/storage.js export const setToken (token) { if (process.env.UNI_PLATFORM h5) { localStorage.setItem(token, token) } else { uni.setStorageSync(token, token) } }4.5 现象tensorflow/tfjs-tflite在微信开发者工具报WebAssembly.instantiateStreaming is not a function原因开发者工具基础库版本过低2.25.0不支持WASM Streaming API。解决微信开发者工具 → 右上角「详情」→ 「项目设置」→ 勾选「使用新版基础库」并确保基础库版本≥2.25.0项目manifest.json中mp-weixin字段已设为minVersion: 2.25.0。5. 二次开发实战如何把AI评论模块替换成你自己的模型5.1 模型替换四步法从训练到上线你手头有个新训练的BERT微调模型想替换掉项目里的comment_classifier.onnx按这四步走30分钟搞定步骤操作关键命令/文件验证方式1. 模型导出将PyTorch模型转ONNX输入shape[1, 128]输出shape[1, 3]torch.onnx.export(model, dummy_input, new_model.onnx, input_names[input_ids], output_names[logits], opset_version12)用Netron打开ONNX文件确认Input/Output维度2. 分词器适配复制HuggingFace tokenizer的vocab.txt或tokenizer.json重命名为tokenizer.jsonfrom transformers import AutoTokenizer; tokenizer.save_pretrained(./output/)检查tokenizer.json中是否有word_index字段没有则用脚本生成见下方3. 替换静态资源覆盖static/model/下两个文件cp new_model.onnx ./static/model/comment_classifier.onnxcp tokenizer.json ./static/model/tokenizer.json启动小程序Console打印loadModel success4. 预处理对齐修改utils/ai-inference.js中preprocessText函数匹配新tokenizer逻辑若用BERT需加[CLS]、[SEP]标记padding到128输入测试句检查inputIds是否与Python端输出一致提示若你的tokenizer无word_index字段如BERT的vocab.txt用此Python脚本生成tokenizer.json# gen_tokenizer_json.py vocab {} with open(vocab.txt, r) as f: for i, line in enumerate(f): vocab[line.strip()] i import json json.dump({word_index: vocab}, open(tokenizer.json, w), ensure_asciiFalse)5.2 支付模块改造接入你自己的支付服务商项目当前只支持微信支付但你想加支付宝不需重写只需扩展utils/pay.js新增支付类型枚举// utils/pay.js export const PAY_TYPE { WECHAT: wechat, ALIPAY: alipay }封装支付宝统一下单复用现有签名逻辑export const alipayPrecreate (orderData) { // 调用你自己的/alipay/precreate接口返回支付宝二维码链接 return $api.post(/alipay/precreate, { out_trade_no: orderData.order_no, total_amount: (orderData.total_price).toFixed(2), subject: orderData.goods_name }) }在订单页动态切换支付方式!-- pages/order/order.vue -- view v-ifpayType alipay image :srcalipayQrCode modeaspectFit / button clickcheckAlipayStatus查询支付状态/button /view关键技巧所有支付回调地址微信notify、支付宝callback必须指向你自己的服务端由服务端统一更新订单状态。小程序端只负责展示和轮询不处理支付结果——这是合规底线。5.3 从那以后我每次替换模型都强制走一遍这三步验证本地Python端推理验证用相同输入文本对比Python输出和小程序输出的sentiment和confidence误差0.05则检查预处理真机Worker线程日志在model.predict前后加console.log(start predict, end predict)确认Worker未崩溃H5端降级测试编译H5版故意删掉static/model/确认AI卡片显示「端侧AI不可用已切换至服务端分析」提示不报错。这三步看似繁琐但帮我避开了80%的模型上线事故。尤其第二步微信开发者工具永远模拟不出真机Worker的内存限制必须真机连USB调试看Console。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

Linux内核模块与KVM虚拟化:从加载机制到落地调优的实战笔记

Linux内核模块与KVM虚拟化:从加载机制到落地调优的实战笔记

记笔记这件事,我一直觉得最有价值的部分不是"记下来",而是"为了记清楚而不得不把原理搞明白"的过程。这套 Linux 内核模块与 KVM 虚拟化笔记,就是我在调优虚拟化平台性能时被逼出来的产物。当时遇到一个诡异现象&#xf…

📅 2026/10/20 4:44:27
Kali Linux虚拟机安装零基础教程:从镜像到环境配置

Kali Linux虚拟机安装零基础教程:从镜像到环境配置

如果让我列一个“Linux 折腾路上迟早要面对”的入门项目,把 Kali 装进虚拟机绝对能排前三。不管你是刚接触安全工具、想给自己搭一个随时能造的实验环境,还是单纯想在主力机器之外多体验一套预装了海量工具的 Linux 系统,虚拟机方案都比直接装…

📅 2026/10/20 4:44:27
新能源电动汽车EEA设计:从功能清单到域控制器与DBC验证

新能源电动汽车EEA设计:从功能清单到域控制器与DBC验证

简介:《新能源电动汽车电子电气架构设计》是一份面向新能源汽车电子电气工程师、车辆工程专业学生及相关技术研究人员的专业参考文献,聚焦电动汽车电子电气架构的设计理念与关键技术,帮助读者理解电池管理系统、电机控制系统、车身电子控制系…

📅 2026/10/20 4:44:27
MORE NEWS

更多资讯

📰

HF 热度榜从第 6 滑到第 24:全网围观后,N2.5-mini 的“冷静期”到了

HF 热度榜从第 6 滑到第 24:全网围观后,N2.5-mini 的“冷静期”到了 【免费下载链接】Nex-N2.5-mini 项目地址: https://ai.gitcode.com/hf_mirrors/nex-agi/Nex-N2.5-mini 前段时间,Hugging Face 的模型热度榜上出了一件怪事。 一款…

📰

claude-watch 核心原理揭秘:ffmpeg 场景切换帧提取如何让 Token 成本保持平坦

【免费下载链接】claude-watch Give Claude the ability to watch any video — scene-change frames transcript a structured report, with a 0-10s hook microscope and optional Obsidian auto-save. 项目地址: https://gitcode.com/gh_mirrors/cla/claude-wa…

📰

U-Net图像分割实战指南:原理详解与PyTorch实现

U-Net这三个字母,在医学影像和遥感图像处理圈子里,几乎就是图像分割的默认选项。很多刚接触深度学习的同学第一次跑通的语义分割模型就是它,但大多数人只是照着开源代码把训练流程跑了一遍,对于U-Net为什么用这种“U型”结构、跳跃…

📰

OpenClaw智能体框架实战:五分钟接入QQ机器人全流程

OpenClaw 这名字最近在 AI 圈子里刷屏的频率挺高,但它到底是什么、能干什么、怎么跟 QQ 接上,很多朋友还停留在“看过截图”的阶段。简单说,OpenClaw 是一个 MIT 协议开源的 AI 智能体框架,它最擅长的事儿就是把“用户用大白话提的…

📰

开源轻量AI工具:嵌入Office/浏览器的生产力副驾

1. 这三个工具不是“又一个AI玩具”,而是真实挤出时间的生产力杠杆最近在几个技术协作群里,连续三天看到不同行业的从业者发同一条消息:“刚用XX工具把昨天要干3小时的活,15分钟搞定了。”不是截图,不是演示视频&#…

📰

基于YOLO的跌倒检测实战:从数据处理到模型部署全流程解析

1. 项目核心与需求拆解:跌倒检测到底难在哪里我第一次接触跌倒检测这个项目,是一个做社区养老服务的合作方找上门来。他们想在一批养老驿站的活动区域装摄像头,用视觉方案判断老人有没有摔倒,出现异常就自动告警。这个需求听起来很…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬