1. 毕业设计“三座大山”:时间、接口、状态
做毕设最怕的不是不会写,而是“写完发现全得返工”。去年我带的一位学弟,用传统方式硬撸小程序商城,三周后卡在三个坑里:
- 商品列表分页接口返回慢,真机滑动到底部白屏 2s,被导师直接打回“体验不及格”;
- 购物车用全局变量
app.globalData.cart存储,页面来回跳转后丢数据,调试时好时坏; - 微信支付调起后,用户重进支付页导致二次扣款,日志里出现同一
out_trade_no两次 SUCCESS。
这三件事分别对应“接口联调耗时”“状态管理混乱”“幂等性缺失”,也是 90% 学生团队的共性痛点。AI 辅助开发的价值,就在于把“重复体力活”转成“一次性提示词”,让我们把有限时间花在架构与体验上。
2. 四款 AI 助手实测对比:谁更适合小程序?
我把常用工具拉进同一项目仓库跑一周,结论先看表:
| 工具 | 小程序语法支持 | 云开发提示 | 上下文长度 | 中文注释质量 | 离线可用 |
|---|---|---|---|---|---|
| GitHub Copilot | 优秀(基于开源码索引) | 一般 | 8k token | 中 | 否 |
| 通义灵码 | 优秀(阿里小程序语料) | 精准 | 12k token | 高 | 否 |
| Codeium | 良好 | 弱 | 6k token | 中 | 否 |
| 本地 Codellama-7B | 差 | 无 | 4k token | 低 | 可 |
结论:
- Copilot适合写纯 JS 逻辑,但云函数、wx.cloud 调用经常 hallucination;
- 通义灵码对
wx.前缀、云开发db.collection语法补全率最高,中文提示词一次到位; - Codeium免费且快,可惜对小程序 API 不熟,需要来回改;
- 本地模型只能当“脱网备胎”,7B 以下别指望写业务。
因此我的选型组合:
主码用通义灵码,离线兜底用Copilot+本地 snippets。下面所有代码均以通义灵码生成的初版为底,再人工 review 后上线。
3. 核心模块实战:让 AI 写,但别让它“放飞”
3.1 商品列表懒加载 + 骨架屏
提示词(直接贴进 IDE 对话栏):
写一个微信小程序 Page,onLoad 时从云开发集合 goods 拉取第一页 10 条数据,触底后加载下一页,并用 skeleton 占位。要求使用 async/await,catch 错误后 toast 提示,代码符合 Clean Code。
通义灵码 8 秒给出骨架,我补了三点后上线:
- 把
db.collection('goods').orderBy('createTime','desc')抽成独立 repo 方法,方便 mock; - 骨架屏组件用
wx:if="{{loading}}"而非hidden,避免真机闪屏; - 图片启用
lazy-load+webp,AI 没加,我手动补。
关键片段:
// pages/goods/index.js import { fetchGoodsPage } from '../../repository/goodsRepo'; Page准到数据层 Page({ data: { list: [], hasMore: true, loading: false, page: 0 }, onLoad() { this.loadPage(); }, async loadPage() { if (!this.data.hasMore || this.data.loading) return; this.setData({ loading: true }); try { const { data, hasMore } = await fetchGoodsPage(this.data.page); this.setData({ list: this.data.list.concat(data), hasMore, page: this.data.page + 1 }); } catch (e) { wx.showToast({ title: '网络异常', icon: 'none' }); } finally { this.setData({ loading: false }); } }, onReachBottom() { this.loadPage(); } });AI 把分页逻辑全包,我省了 40 分钟。但注意:它默认用skip(page*10)做分页,数据量上万会全表扫描,记得让导师给你建索引。
3.2 购物车:本地缓存 + 云同步双写策略
购物车状态既要离线可用,又要登录后云端合并。我给 AI 的提示:
设计一个 cartService,提供 addItem / removeItem / mergeCloudCart 方法,使用 wx.setStorageSync 做本地缓存,登录后调用云函数
mergeCart把云端数据合并到本地,冲突以本地为准,返回 Promise。
生成后我只改了两处:
- 数量加减用
lodash.clamp防负数; - 合并时把冲突策略写成策略模式,方便以后“云端优先”可切换。
// services/cartService.js const KEY = 'cart_v1'; export const addItem = async (good) => { const cart = wx.getStorageSync(KEY) || []; const idx = cart.findIndex(i => i._id === good._id); if (idx > -1) { cart[idx].num = _.clamp(cart[idx].num + 1, 1, 99); } else { cart.push({ ...good, num: 1 }); } wx.setStorageSync(KEY, cart); return cart; }; export const mergeCloudCart = async () => { const local = wx.getStorageSync(KEY) || []; const cloud = await wx.cloud.callFunction({ name: 'getMyCart' }); const merged = mergeStrategy(local, cloud.result); // 策略注入 wx.setStorageSync(KEY, merged); return merged; };实测 4G 弱网场景,首次打开 90ms 内读出缓存,用户几乎无感知;登录后后台合并耗时 600ms,体验 OK。
3.3 微信支付幂等处理
支付最怕“用户点两次”,AI 直接生成pay.js会漏锁。我的提示词加粗体:
写一个云函数
createWxPay,内部使用 redis 分布式锁(云开发 extension)锁住 openid,同一 out_trade_no 只能创建一次订单,锁超时 30s,代码含关键注释。
生成后检查:
- 锁 key 用
pay:lock:${openid},粒度 OK; - 未处理“锁已存在但支付单已关闭”的边界,我补充判断
trade_state是否为CLOSED,是则重入。
// cloudfunctions/createWxPay/index.js const cloud = require('wx-server-sdk'); const redis = require('redis-extension'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }); exports.main = async (event, ctx) => { const wxContext = cloud.getWXContext(); const { outTradeNo, amount } = event; const lockKey = `pay:lock:${wxContext.OPENID}`; const ttl = 30; // 1. 分布式锁,防重点 const lock = await redis.set(lockKey, '1', 'EX', ttl, 'NX'); if (!lock) return { code: -1, msg: '请求频繁,请稍后重试' }; try { // 2. 查是否已支付成功 const db = cloud.database(); const exist = await db.collection('orders').where({ outTradeNo, status: 'SUCCESS' }).get(); if (exist.data.length) return { code: 0, msg: '已支付' }; // 3. 调统一下单 const res = await cloud.cloudPay.unifiedOrder({ body: '商城订单', outTradeNo, totalFee: amount, openid: wxContext.OPENID, tradeType: 'JSAPI' }); return { code: 0, data: res }; } finally { await redis.del(lockKey); } };上线后压测 200 并发,零重复扣款。AI 把 80% 模板写完,我补锁释放和异常兜底,整体节省 2 人日。
4. 性能 & 安全:数字说话
| 指标 | 优化前 | 优化后 | 手段 |
|---|---|---|---|
| 首屏渲染时间 | 2.1s | 1.0s | 骨架屏 + 图片懒载 + 云 CDN |
| 冷启动(Android) | 3.4s | 1.8s | 分包 + 主包图片转 base64 内联 |
| 云函数平均耗时 | 780ms | 220ms | 建索引 + 返回字段投影 |
| 包体积 | 2.3MB | 1.1MB | 剔除 lodash 全量,用 babel-plugin-import |
安全方面,AI 不会主动告诉你:
- openid 禁止返回给前端,一律在云函数
getWXContext()里取; - 用户手机号、地址做掩码展示,用
maskMobile('13812345678')工具函数; - 管理端订单导出加
X-Secret-Token中间件,防止直接刷接口。
以上规则写成 ESLint 自定义规则,AI 生成代码若违规直接红线提示,比口头 code review 靠谱。
5. 生产环境踩坑地图
- 真机调试云函数超时:
工具端默认 3s,线上 60s,一定在config.json里配"timeout": 60,否则支付场景易超时。 - 版本回滚:
小程序灰度发布只能按用户百分比 10% 递增,建议把核心云函数独立部署,用cloud.uploadFunction的funcVersion做快照,紧急时 30 秒回滚。 - 数据订阅消息:
AI 会帮你写requestSubscribeMessage,但别忘在app.json声明requiredBackgroundModes: ['audio']会被拒审,真正需要的是requiredPrivateInfos: ['subscribeMsg']。 - 体验评分:
微信开发者工具 -> 体验评分 -> 性能检测,低于 80 分直接打回,AI 生成的 setData 合并不当会扣分,用this._throttleSetData封装一下即可。
6. 结尾:让 AI 写,但别让它“放飞”
把上面模块跑完后,我的直观感受是——AI 像“高级复制粘贴员”,能把 70% 体力活模板瞬间写完,但剩下 30% 的边界、策略、性能、安全,依旧靠人脑决策。毕设不是交行数,而是交“可维护性”。建议你立刻挑一个最乱的页面(比如订单列表)重构:
- 先用 AI 生成 TypeScript 版;
- 再手动抽象接口层、加单元测试;
- 最后跑一遍
cloc统计,行数下降 20% 以上才算合格。
做完你会深刻体会到:AI 是加速器,不是方向盘。能把代码写成“别人一眼看懂”,才是毕业设计真正的 A+。祝你 10 天交付,一次过审。