我用 AI + Taro 搓了个麻将计分小程序,从此牌桌上再也没人赖账了!
一、前言:一个被麻将逼疯的“懂点代码的普通人”
“刚才那局我输了多少来着?” —— 这是每个麻将桌上的灵魂拷问。
过年回家打麻将,每次算分都像在做数学期末考试:
- “你刚才给我加了10还是20?”
- “等等,我上一局是-5还是-15?”
- “这局到底谁赢了???”
纸笔记录太原始,心算到第三局就翻车,掏计算器又太破坏气氛。作为一个懂点前端代码、且熟练掌握 AI 工具的普通人,我决定不折磨自己的脑细胞了——直接让 AI 帮我写一个微信小程序!
经过几天的“人机协作”,这款名为 「鱼乐无穷」 的麻将计分小程序诞生了。扫码即用,4人同房,实时计分,再也不用为“你欠我多少”吵架了。
二、成品展示与核心功能
| 功能 | 说明 |
|---|---|
| 🎮 两种计分模式 | 累计模式(想加多少加多少)+ 倍率模式(选赢家定倍率) |
| 🏠 6位数字房间号 | 输入房间号就能加入,比输 WiFi 密码还简单 |
| 📋 对局记录弹窗 | 分页查看每一局的详细得分,年底“翻旧账”利器 |
| 🏅 结算排名奖牌 | 金银铜+参与奖,第四名也有尊严 |
| 🎏 横批俏皮提示 | 得分多了给你挂横幅,比过年贴春联还喜庆 |
| 🔄 实时同步 | 自己操作 0 延迟,别人 2 秒内同步 |
三、开发实录:AI 帮我从“翻车”到“翻盘”
1. 初始方案:AI 秒出 Web 版
一开始,我让 AI 用 React + Supabase 写个网页版。AI 确实给力,几分钟就给出了带 WebSocket 实时同步的完美代码,在浏览器里跑得很丝滑。
2. 遭遇毒打:微信小程序说“不”
当我天真地用 Taro 把代码转译成小程序时,微信环境给了我一套连环暴击。我没有自己死磕文档,而是把报错信息直接喂给 AI,让 AI 帮我重构。
💥 暴击 1 & 2:SDK 在小程序里水土不服
报错:
ReferenceError: Headers is not defined/Failed to construct 'URL'AI 诊断:小程序没有浏览器的Headers和URLAPI,Supabase 官方 SDK 跑不起来。 AI 解决方案:干掉 SDK,让我用纯wx.request调 Supabase 的 REST API。
AI 帮我生成的极简请求封装,简单粗暴但极其管用:
function singleRequest<T>(method: string, path: string, body?: any): Promise<T> {
return new Promise((resolve, reject) => {
wx.request({
url: BASE + '/rest/v1/' + path,
method,
header: headers(),
data: body || undefined,
success: (res: any) => {
if (res.statusCode >= 200 && res.statusCode < 300) resolve(res.data);
else reject(new Error(`Supabase ${res.statusCode}`));
},
fail: () => { reject(new Error('network fail')); },
});
});
}
💥 暴击 3:WebSocket 实时推送失效
AI 诊断:小程序不支持 Supabase 的 WebSocket 实时订阅。 AI 解决方案:改用“轮询 + 本地乐观更新”。自己操作必须 0 延迟,别人通过轮询同步。
AI 帮我写的核心状态管理逻辑(Zustand):
recordRound: (scores) => {
// 1. 本地立即更新(0延迟,自己看着爽)
set(state => ({ rounds: [...state.rounds, newRound] }));
// 2. 异步写库(不阻塞 UI)
recordRoundToSupabase(roomId, newRound).catch(() => {});
}
💥 暴击 4:CSS 被“阉割”
AI 诊断:小程序不支持
calc()、vh、radial-gradient等现代 CSS。 AI 解决方案:我直接把花里胡哨的 CSS 丢给 AI,让它“翻译”成小程序支持的丐版 CSS。
四、那些让 AI 帮我填平的“天坑”
在开发过程中,我遇到了几个诡异的 Bug,全靠把日志丢给 AI 分析才解决:
坑 1:双重 JSON.parse 报错
Taro.request 在 Content-Type: application/json 时已经自动解析了,再调 JSON.parse 就报错。 AI 修正后的安全解析代码:
if (typeof data === 'string') {
try { resolve(JSON.parse(data)); } catch { resolve(data); }
} else {
resolve(data);
}
坑 2:轮询请求堆积导致雪崩
轮询间隔 1500ms,但网络延迟 1576ms,请求越堆越多,最后小程序卡死。 AI 给出的“串行轮询”方案(等上一轮完成再发下一轮):
const doPoll = async () => {
if (isPolling) return; // 上一轮没结束,直接跳过
isPolling = true;
await pollRoomData();
isPolling = false;
pollTimer = setTimeout(doPoll, 2000);
};
坑 3:结算游戏互不影响
A 点击结算,B 的页面也跟着结算了?体验极差。 解决思路:我让 AI 把结算状态改为“仅存本地,不同步到远程”。每个人自己点结算才能看到结算页面,互不干扰。
坑 4:微信基础库的神秘 timeout
报错:
Error: timeout from WAServiceMainContext.jsAI 排查:AI 帮我查阅了微信社区,定位到这是微信框架 3.15.2 灰度版的内部 Bug。 解决:在开发者工具中降基础库到 3.4.0 稳定版,并去掉请求的 timeout 参数,瞬间清爽。
五、让 AI 注入灵魂的“小细节”
除了核心功能,我还让 AI 帮我设计了一些提升情绪价值的细节:
1. 第四名的尊严:参与奖
排名系统里,前三名有金银铜牌,第四名看着太惨了。我让 AI 帮忙想文案和样式,给第四名加了一个清新绿色渐变 + 🎖️勋章:
- 🥇 第1名 - 金牌:"牌神降临,所向披靡!"
- 🥈 第2名 - 银牌:"实力不俗,下次翻盘!"
- 🥉 第3名 - 铜牌:"稳扎稳打,潜力无限!"
- 🎖️ 第4名 - 参与奖:"重在参与,下次一定能赢回来!"
2. 横批效果:比春联还喜庆
当某个玩家得分超过一定次数,弹出一条铺满卡片宽度的俏皮提示(AI 帮我写的 Flex 布局):
┌─────────────────────────────────┐
│ 🎉 得分王!今天手气爆棚! │
└─────────────────────────────────┘
六、最终技术架构
经过 AI 辅助重构后,最终的架构非常轻量且稳定:
┌──────────────┐ wx.request ┌──────────────────┐
│ 微信小程序 │ ──────────────────→ │ Supabase REST │
│ (Taro 4) │ ←────────────────── │ (PostgreSQL) │
│ │ JSON Response │ │
│ ┌────────┐ │ └──────────────────┘
│ │ Zustand│ │
│ │ Store │ │ 本地即时更新 (0延迟)
│ │(persist)│ │ + 2秒串行轮询同步
│ └────────┘ │ + 3秒防覆盖保护期
└──────────────┘
七、总结:普通人用 AI 开发的正确姿势
从 React Web 到微信小程序,这条路走得不容易,但有了 AI 的辅助,开发效率提升了数倍。总结几条普通人用 AI 写代码的心得:
- 别指望 AI 一次生成完美代码:小程序环境 ≠ 浏览器,遇到报错不要慌,把完整的报错日志喂给 AI,让它帮你做环境适配。
- 让 AI 做“翻译”和“重构”:比如把浏览器 CSS 翻译成小程序 CSS,把 WebSocket 重构成轮询,AI 做这种“脏活累活”比人强。
- 把控核心业务逻辑:AI 负责写代码,你负责设计产品体验(比如“自己操作 0 延迟”、“第四名也需要尊严”),这才是产品的灵魂。
🔗 源码获取: 项目已开源至 GitHub:GitHub - hualiqiogn/mahjong-scores: 麻将计分微信小程序 - React + Taro + Supabase · GitHub (欢迎 Star ⭐,欢迎 Fork 🍴,欢迎提 Issue 🐛)
最后,祝大家打麻将天天赢,牌牌自摸!🀄🎉 如果这篇文章对你有帮助,点个赞 👍 再走呗~
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)