🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~
兄弟们都在夸我 "领姨夹钱" - 记我为兄弟们开发的一款欠酒记录小程序
1. 开发背景(酒精考验的兄弟情)
每到周末又是放松的日子,博主总会和兄弟们围坐在烟雾缭绕的烧烤摊前,酒杯碰撞的脆响混着「感情深一口闷」的豪言壮语,构成了当代都市最硬核的兄弟情仪式。然而,在这看似和谐的江湖酒局中,却暗藏着一套堪比《三十六计》的逃酒秘术:
- 手滑表演艺术家:酒杯永远在 不小心 打翻的瞬间
- 永远下次的谎言:❶ 帮我喝下次还你!❷ 喝不下先记着!
当这些「酒桌老赖」的欠酒行为成为常态时,身为全栈开发践行者的我终于拍案而起:「都是兄弟,不能只有我的肝在负重前行!」
2. 最终演示效果
作为一个被Bug磨平棱角的开发者,我决定用最擅长的方式发起反击——「欠酒记录」小程序应运而生!经过博主不懈的努力~ 最终展现效果如下:
欠酒记录排行榜:
- 圈子中用户欠酒记录
- 圈子中其它用户可以对其进行评价
结合腾讯AI服务识别:
- AI服务:腾讯云API(人脸识别+图像识别)
- 存储:腾讯云COS(替代云存储)
兄弟们第一眼看懂这个排行榜,就得到了一致的好评,都在夸我 “领姨夹钱” ~
3. 技术架构
3.1 使用的技术
前端:uniapp
微信小程序
后端:Spring Boot 3.x
+ MySQL 8.x
+ Redis
AI服务:腾讯云API(人脸识别+图像识别)
存储:腾讯云COS
-
微信小程序前端:
- 实现微信登录、页面渲染、拍照上传。
- 调用后端接口展示圈子、排行榜、邀请二维码等。
-
Spring Boot 后端:
- 提供
RESTful API
,处理业务逻辑、鉴权、数据持久化。 - 调用腾讯云人脸识别、人像属性/物体检测接口。
- 使用
MySQL
存储用户、圈子、欠酒记录等。
- 提供
-
腾讯云 AI:
- 人脸识别:检测并识别人脸,匹配用户身份。
- 图像识别:检测并计数酒杯(或其他容器)数量。
3.2 核心功能拆解
功能模块 | 主要技术点 |
---|---|
1. 微信授权登录 | wx.login → 后端换取 session / JWT |
2. 圈子管理 | 创建圈子、加入圈子、生成圈子邀请二维码 |
3. 人员画像维护 | 用户首次使用需拍摄基础人脸库(多角度),保存 faceId |
4. 拍照欠酒记录 | 小程序拍照上传 → 后端保存原图 → 调用 AI 接口 |
5. AI 解析合并 | 人脸匹配 → 返回 userId 列表;物体检测 → 返回杯数 |
6. 记录累加与排行 | 根据 userId+circleId 累加杯数 → 排行榜查询接口 |
4. 示例数据模型(MySQL)
用户表 user
-- 用户表
CREATE TABLE user (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
openid VARCHAR(64) UNIQUE NOT NULL,
nickname VARCHAR(50),
avatar_url VARCHAR(255),
face_id VARCHAR(64), -- 人脸库中的人脸标识
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
圈子表 circle
-- 圈子表
CREATE TABLE circle (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100) NOT NULL,
owner_id BIGINT NOT NULL, -- 创建者 userId
invite_code VARCHAR(32) UNIQUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
圈子成员表 circle_member
-- 圈子成员表
CREATE TABLE circle_member (
circle_id BIGINT,
user_id BIGINT,
joined_at DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(circle_id, user_id)
);
欠酒记录表 drink_record
-- 欠酒记录表
CREATE TABLE drink_record (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
circle_id BIGINT,
user_id BIGINT,
cups INT, -- 本次检测到的酒杯数累加
photo_url VARCHAR(255),
recorded_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
5. 关键接口设计
目前博主规划的功能接口设计如下:
5.1 用户登录 & 人脸库注册
- POST /api/auth/login 【参数:
code
(微信 login 接口返回)】
流程:
- 用 code 调用微信服务换取
openid
、session_key
.- 查库或新建 user,并返回 JWT token。
@PostMapping("/api/auth/login")
public Result<String> wxLogin(@RequestParam String code) {
// 调用微信接口获取openid
String url = "https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}";
WxResponse response = restTemplate.getForObject(url, WxResponse.class);
// 注册或更新用户
User user = userRepository.findByOpenid(response.getOpenid())
.orElseGet(() -> new User(response.getOpenid()));
return Result.success(jwtUtil.generateToken(user));
}
- POST /api/auth/register-face 【参数:
token
,face_image
(多角度人脸照片)】
流程:上传人脸到腾讯云人脸库,保存返回的
face_id
。
5.2 圈子管理
- POST /api/circle/create 【参数:
token
,name
】
流程:创建圈子 返回成功失败
- POST /api/circle/join 【参数:
token
,inviteCode
】
流程:加入圈子 返回成功失败
- GET /api/circle/{id}/members 【参数:
token
】
流程:返回圈子成员列表
5.3 拍照欠酒记录
- POST /api/circle/{id}/record 【参数:
token
,circleId
,photo
(multipart)】
业务流程:
- 接收并落库原图,生成
photoUrl
。- 异步调用腾讯云:
人脸识别:DetectFace
→CompareFace
;
图像识别:DetectLabels
或定制化酒杯检测模型 → 杯数。- 合并结果,按每个人分配杯数(可按人均或用户前端指定)
- 插入
drink_record
并更新当日/总欠杯数。
- GET /api/circle/{id}/ranking 【参数:
token
】
流程:按累计
SUM(cups)
排序的成员排行榜。
6. AI 对接示例(伪代码)
具体可以查阅腾讯云相关API,这里仅仅贴出大致的业务流程
// Spring Boot Service
@Autowired TencentCloudClient tencentClient;
public DrinkResult processDrinkPhoto(Long circleId, Long uploaderId, MultipartFile photo) {
// 1. 上传原图到对象存储,获取 photoUrl
String photoUrl = storageService.upload(photo);
// 2. 检测人脸
List<FaceInfo> faces = tencentClient.detectFaces(photo);
Map<String, Float> faceMatches = tencentClient.compareFaces(faces, userFacesInCircle(circleId));
// 3. 检测酒杯数
int cupCount = tencentClient.detectObjects(photo, "wine_glass");
// 4. 分配杯数(示例:均分)
int perUser = cupCount / faceMatches.size();
faceMatches.keySet().forEach(faceId -> {
Long userId = lookupUserByFaceId(faceId);
drinkRecordRepository.save(new DrinkRecord(circleId, userId, perUser, photoUrl));
});
return new DrinkResult(cupCount, perUser, faces.size());
}
7. 前端关键点
- 微信登录:
wx.login
→ 拿到code
→ 调用后端登录接口。 - 拍照上传:使用
wx.chooseImage
+wx.uploadFile
,并显示上传进度。 - 邀请好友:利用
wx.getShareInfo
+scene=1000
生成带inviteCode
的分享卡片。 - 排行榜展示:请求
/ranking
,配合<scroll-view>
或<list>
渲染。
8. 后续优化更新方向
- 多人场景优化:多人合照时,按坐标或姿态分析,将酒杯与最邻近人物自动关联。
- 自定义酒类:支持啤酒杯、白酒杯、红酒杯等多类别检测并分类统计。
- 实时提醒:欠酒超阈值时,推送微信模板消息提醒。
9. 结语
当撸串的竹签遇上代码的字符,当兄弟的嬉笑怒骂撞上AI算法的冰冷计算——我们不是在开发程序,而是在用科技重新定义「歃血为盟」。毕竟,真正的兄弟情就该是:你逃过的酒,我一行行写成段子;你欠下的债,我用像素永久封印。
谨以此项目,献给博主所有在酒桌上相爱相杀的兄弟们——代码或许会报错,但我们的情谊,永远 SUCCESS !
关注博主公众号 - 跟麦可乐学编程 掌握最新的资源~