之前帮家人买过几次彩票,验奖时发现体验挺麻烦的:要么去投注站扫描,要么手动一个个核对号码。作为程序员当然想到能不能写个工具解决,于是就有了这个小程序项目。
技术选型上选择了微信小程序 + 腾讯云开发(CloudBase),主要是看中了云开发的 Serverless 架构,省去了运维的麻烦,可以专注在业务逻辑上。
最开始的想法是直接用 OCR 识别彩票上的号码,但实际遇到了几个问题:
后来采用了 OCR + LLM 结构化提取 的方案:
// 1. 先用腾讯云 OCR 识别文字
const ocrResult = await customOCRService.detectFromDataURL(imageData);
// 2. 将 OCR 结果交给智谱 AI 的 LLM 进行结构化解析
const lotteryInfo = await parseLotteryByZhipuLLM(ocrResult.ocr_result);
// 3. 获取开奖数据进行比对
const issue = await getIssue(app, lotteryType, lotteryInfo.issue);
const calcRes = await calculateWinning(lotteryInfo, issue);
LLM 的好处是可以理解上下文,自动识别出"这是双色球"、"这些是红球号码"、"这是蓝球",准确率比纯规则匹配高很多。
后端采用云托管(Cloud Run)部署 Express 服务,配合 CloudBase SDK 操作数据库:
// 使用数据模型而不是直接操作 database
const models = cloudBaseClient.getModels();
await models.tickets.create({
data: {
lottery_type,
issue,
numbers,
status: isOpened ? 'winning' : 'undrawn',
_openid: openId // 安全隔离,每个用户只能查看自己的数据
}
});
这样做的好处:
_openid)未开奖的彩票可以订阅开奖通知,技术上用的是微信小程序订阅消息能力:
// 前端申请订阅权限
wx.requestSubscribeMessage({
tmplIds: ['xxx'],
success: (res) => {
// 调用后端接口记录订阅
callCloudApi('/api/message/subscribe', { ticketId, issue })
}
})
// 后端定时任务检查开奖
// 当检测到新期开奖时,批量推送消息给订阅用户
最初直接上传原图,有些用户拍照动辄 5-8MB,上传慢还占存储。后来加了前端压缩,限制宽度 1200px,质量 0.8,效果不错。
腾讯云 OCR 按次计费,为了省钱做了些优化:
这个项目让我对 OCR + LLM 结合 有了新的认识。传统做法是 OCR 识别后用正则或规则提取信息,但面对非标准化的场景(比如各种彩票样式),维护成本很高。引入 LLM 做结构化提取后,准确率和鲁棒性都提升了不少,而且几乎不需要针对新样式单独写规则。
另外云开发这种 Serverless 模式确实适合个人开发者,不用操心服务器、域名备案、数据库运维这些琐事,专注写业务逻辑就行。
小程序搜索"彩运多"可以体验,欢迎交流技术实现细节。
项目还在持续优化中,后续计划:
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.