不用守着闹钟:campus-imaotai i茅台自动预约部署与调参实战
【免费下载链接】campus-imaotaii茅台app自动预约,每日自动预约,支持docker一键部署(本项目不提供成品,使用的是已淘汰的算法)项目地址: https://gitcode.com/GitHub_Trending/ca/campus-imaotai
早上 8 点 55 的闹钟响起来,你打开 i茅台 app 输完验证码,页面转了一圈,申购按钮已经灰了。campus-imaotai 就是为这个场景做的 i茅台自动预约工具:Java Spring Boot(Campus 框架)后端 + Vue 管理后台,定时任务在 9 点整替你完成申购,支持 Docker 一键部署。
项目能做什么(能力速览)
| 能力 | 解决什么问题 | 对应模块/配置项 |
|---|---|---|
| 每日自动预约 | 人工 9 点申购手速拼不过服务器 | CampusIMTTask定时任务,campus-modular |
| 多账号管理 | 每个账号都要单独登录、单独点 | i_user表 + 用户管理页 |
| 门店策略选择 | 不知道该抢哪家门店 | i_user.shop_type(1 出货量最大 / 2 附近门店) |
| 商品与门店数据自动刷新 | 预约项目过期、门店列表过期 | 7:10 / 7:55 / 8:10 / 8:55 的refresh任务 |
| 申购结果推送 | 18 点还要人工看结果 | push_plus_token+PushPlusApi |
| 小茅运旅行奖励 | 每天手动点一遍 | 11 点整点批量任务 |
架构上是一个 Maven 多模块工程:campus-common、campus-framework、campus-admin是通用管理后台脚手架,真正的 i茅台业务全在campus-modular。
⚡️3 分钟跑起来(最小化部署)
环境要求只有几条硬性的:
- Docker 与 Docker Compose 已安装
- Linux 服务器(compose 文件用了
network_mode: host和/docker/...绝对路径挂载,Windows 上跑不了) - 至少 2GB 空闲内存、10GB 磁盘
- 宿主机 3306、6379、80、8160 端口未被占用(host 网络模式直接占用宿主机端口)
下面这条命令序列完成克隆、拉起 4 个容器(mysql、redis、nginx-web、campus-imaotai)并导入初始表结构:
# 克隆代码并进入部署目录 git clone https://gitcode.com/GitHub_Trending/ca/campus-imaotai cd campus-imaotai/doc/docker # 一键启动所有服务 docker-compose up -d # 导入表结构和初始数据(含管理员账号、菜单权限) docker exec -i mysql mysql -uroot -p123456789 campus_imaotai < ../sql/campus_imaotai-1.0.5.sql部署完用这两条验证:
docker ps curl -I http://localhost预期输出:docker ps里 4 个容器全部Up;curl返回HTTP/1.1 200 OK。之后浏览器访问http://你的服务器IP,用admin / admin123登录管理后台。
📌影响效果的关键配置
账号加进系统后,真正决定 9 点那一下表现的就是i_user表里三个字段。
minute(默认 5 → 各账号错开到 1~10 内不同值)
为什么改:9 点的 cron 按每个账号的minute字段触发,全部账号都是 5 的话,请求会挤在同一分钟、同一出口 IP 上连续打出去。怎么改:
-- 把某个账号固定在 3 分执行,并锁定不被重算 UPDATE i_user SET minute=3, random_minute='1' WHERE mobile=13800000001;改完验证:在用户管理页看该账号的分钟列,或者 9 点结束后在操作日志里搜这个手机号,操作时间应该是 09:03。
random_minute(默认 0 随机 → 锁定账号改成 1)
为什么改:1:10 有个批量任务会把所有random_minute=0的账号分钟重新随机一遍,你前一天设好的固定值第二天就没了。怎么改:上一条 SQL 里的random_minute='1'就是干这个的,想保留随机行为就维持默认值 0。改完验证:等到 1:10 之后查一次i_user.minute,random_minute=1的账号数值不应变化。
shop_type(默认 1 → 按取酒场景二选一)
| 策略 | 适用场景 | 配置写法 | 注意事项 |
|---|---|---|---|
| 出货量最大门店(1) | 只关心能不能中 | UPDATE i_user SET shop_type=1 | 依赖 7:10 / 8:10 刷新出的门店数据 |
| 附近门店(2) | 想就近自提 | 新增/修改账号时在"预约项目"里选门店 | 经纬度、省市由所选门店自动带出,手填不生效 |
改完验证:门店列表页按省市筛选确认数据在,用户列表页"类型"列应为 1 或 2。剩下的配置一笔带过:push_plus_token决定申购结果是否走 PushPlus 推送到微信,不用就留空。
进阶玩法(按难度递进)
玩法一:单账号手动跑通一遍(入门)
前提:已添加一个账号且 token 未过期。
- 用户管理页输入手机号,点"发送验证码",填码登录后账号入库
- 在预约项目、门店列表页确认今天有可预约商品和门店
- 把该账号
minute设为 10 分钟后、random_minute=1 - 在用户列表点该账号的"预约"按钮手动触发一次
- 到操作日志页搜这个手机号,看是否出现"i茅台预约"记录
预期效果:日志里出现成功记录,说明 9 点批量任务走的是同一条链路,当晚就可以放着不管。
玩法二:多账号错峰(进阶)
前提:已添加 2 个以上账号。
- 按组分分钟,间隔至少 10 分钟
- 各组
random_minute都设 1,防止 1:10 被重算打乱 - 不同组设不同
shop_type或不同门店,把请求打散 - 9 点结束后在操作日志按手机号筛成功率
- 依据
i_log里的失败记录,微调下一天的分钟值
-- 3 个账号错峰 12 分钟 UPDATE i_user SET minute=3, random_minute='1' WHERE mobile=13800000001; UPDATE i_user SET minute=15, random_minute='1' WHERE mobile=13800000002; UPDATE i_user SET minute=27, random_minute='1' WHERE mobile=13800000003;预期效果:9 点请求分布在 3 个分钟里,同一 IP 不再连续打满 1 分钟。
玩法三:换成自己的通知渠道(高级)
前提:会改 Java 代码并能重新构建镜像。
- 看 PushPlusApi.java,推送接口和报文都写死在这里
- 把
sendNotice里的请求改成自己的 webhook / 邮件通道,保留(token, title, content)三参 - 在日志落库链路里确认调用点,别漏了成功/失败两个分支
- 用玩法一的手动预约验证一次
// PushPlusApi.java AsyncManager.me().execute(sendNotice(token, title, content, "txt")); // 把 sendNotice 内部换成你自己的通知逻辑即可预期效果:申购成功或失败时,你自己的渠道收到带手机号和日志内容的推送。
踩坑记录与快速排错
campus-imaotai 容器反复重启
docker logs campus-imaotai | tail -50 docker exec -it mysql mysql -uroot -p123456789 -e "SHOW DATABASES;"判断依据:日志里出现Communications link failure,基本是 SQL 没导入(campus_imaotai库不存在或没表);容器起不来还可能是宿主机 3306 / 6379 被占用,host 网络模式会直接抢端口。修复:先让 mysql、redis 两个容器稳定Up,导入 SQL 后重新docker-compose up -d。
9 点没有动作,日志提示 token 过期
docker exec -it mysql mysql -uroot -p123456789 campus_imaotai \ -e "SELECT mobile,expire_time FROM i_user; SELECT * FROM i_log ORDER BY log_id DESC LIMIT 5;"判断依据:i_log.status=1(异常)且内容提到 token / 认证失败,就是账号问题;如果所有账号同一分钟集体失败,优先怀疑服务器时间不准,cron 完全依赖系统时钟。修复:删掉该账号重新发验证码登录,整批失败先校时。
门店列表为空或类型列一直是默认值
docker logs campus-imaotai 2>&1 | grep "刷新数据"判断依据:每天 7:10、7:55、8:10、8:55 各应有一条"「刷新数据」开始刷新"日志;全是报错说明容器访问app.moutai519.com.cn不通或 redis 没起来。修复:在容器内测试外网连通性,或到门店列表页点"刷新茅台商品列表"按钮手动触发。
页面能打开但接口 401 / 404
curl -I http://localhost # 80:nginx 前端页面 curl -I http://localhost:8160 # 8160:纯后端 API判断依据:80 是 Vue 页面,8160 是裸接口,直接拿浏览器访问 8160 必然失败;前端的/prod-api/前缀由 nginx 转发到 8160。修复:后台入口固定用http://IP(80 端口)进。
通用排查四步:
docker ps确认 4 个容器全部Updocker logs campus-imaotai看最新报错的堆栈第一行- 检查容器内 MySQL / Redis 连通性和服务器时间
- 用管理后台手动点一次"预约",靠
i_log记录定位是账号问题还是系统问题
⚠️合规与安全红线
- README 的声明写得很明确:项目内容仅供学习和研究使用,要求"24 小时内完成学习和研究,并及时删除本项目中的所有内容"——长期挂产、商用已经超出授权边界。
- 不要在同一 IP 下堆大量账号,也不要用脚本循环调
sendCode刷验证码,这两件事最容易触发风控。 i_user表里 token、cookie 是明文存的,数据库还是 root/123456789 且默认无网络隔离,别把它暴露到公网,也别把 admin 账号交给别人。- 项目自带说明"不提供成品,使用的是已淘汰的算法",接口一变整体就会失效,请把"可能随时不能用"作为基线预期。
i茅台平台的接口和规则会不定期调整,建议定期对照官方条款核对自己的用法;一旦预约逻辑集体失败,先怀疑接口变更,再回头查自己的配置。
后续可以折腾的方向
- 通知集成:
business/api/PushPlusApi.java替换成自己的 webhook / 邮件通道,主流程不用动。 - 门店策略:用
i_log历史成功率替换"出货量最大"的固定规则,改动集中在 IMTServiceImpl.java。 - 数据统计:从
i_log表按分钟聚合成功率,把统计结果反哺给minute的分配。
下次 9 点整的闹钟再响,你可以选择让它响完,再花一分钟翻一下操作日志——这比在灰掉的按钮前输验证码从容得多。
【免费下载链接】campus-imaotaii茅台app自动预约,每日自动预约,支持docker一键部署(本项目不提供成品,使用的是已淘汰的算法)项目地址: https://gitcode.com/GitHub_Trending/ca/campus-imaotai
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考