Skip to content

TrailMate 出游助手:跟车/营地/记账/变声 + 真实蓝牙多跳Mesh + iOS/Android原生 + CI出包#6

Open
webergithub wants to merge 26 commits into
masterfrom
claude/quirky-gates-p9q3du
Open

TrailMate 出游助手:跟车/营地/记账/变声 + 真实蓝牙多跳Mesh + iOS/Android原生 + CI出包#6
webergithub wants to merge 26 commits into
masterfrom
claude/quirky-gates-p9q3du

Conversation

@webergithub

Copy link
Copy Markdown
Owner

面向「朋友结伴出游」的完整应用:一套 React + Vite + TypeScript 代码,通过 Capacitor 打包为 iOS/Android 原生 App,并内置 GitHub Actions 自动出包。

五大功能模块

  • 👥 群组:面对面验证码 + 二维码创建/加入,可保存多个群组复用,成员管理
  • 🚗 跟车:Leaflet 道路/卫星地图、实时定位标识、按住说话对讲机(支持变声扩展选项)、屏幕常亮
  • 🏕️ 营地:无信号自组网群聊,文字/语音/视频,可叠加变声
  • 🧾 记账:AA 分摊(平均/按份/按额)、各家账单 + 最少笔数结算、拍照小票 OCR、分享账单
  • 🎭 变声:Web Audio 实时变声(汤姆猫/喜羊羊/小猪佩奇/孙悟空/猪八戒…),独立 App + 对讲/营地内可用

联网与跨设备

  • 可插拔 Transport 层:BroadcastChannel(同机)+ WebRTC(跨设备 P2P)+ BLE 蓝牙 Mesh(原生),业务层无感,链路优先级 蓝牙 > WiFi > 移动网络
  • 真实蓝牙自组网:自定义 Capacitor 插件 BleMesh,手机同时作外围(广播+GATT服务)与中心(扫描+连接),无移动网络/WiFi 也能互联;多跳 TTL 泛洪中继覆盖"朋友的朋友",msgId 去重防风暴
  • 不区分机型:iOS/Android/Web 同协议互通(同验证码房间 + 同蓝牙 UUID/分片协议 + 平台无关 WebRTC id),跟车页显示同行机型分布

原生工程与 CI

  • android/(Gradle)与 ios/(Xcode, SPM)原生工程,权限文案齐备(定位/相机/麦克风/蓝牙/本地网络/后台定位)
  • 原生能力:@capacitor/geolocation(定位)、@capacitor/camera(小票拍照)、@capacitor/network@capacitor/share、Wake Lock 等,原生/Web 自动切换
  • .github/workflows/build-mobile.yml:Android 产出可直接安装的 app-debug-apk;iOS 产出编译校验产物;CI 已全绿,同时验证了 Java/Swift 蓝牙插件可在真实 Android SDK / Xcode 16 下编译

验证

  • Web 端 Playwright 冒烟:建群→记账→最优结算正确;跨浏览器 WebRTC 双向互通;PTT 变声选项、分享、网络显示均正常,无控制台错误
  • 蓝牙 Mesh 因需真机硬件,请下载 APK 在多台安卓手机上实测(进「营地」授权蓝牙)

🤖 Generated with Claude Code

https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh


Generated by Claude Code

claude added 26 commits July 6, 2026 13:36
- 群组:面对面验证码+二维码创建/加入,多群组保存持久化,成员管理
- 跟车:Leaflet 道路/卫星地图,实时定位标识,按住说话对讲机
- 营地:自组网授权引导 + 文字/语音/视频群聊(可叠加变声)
- 记账:AA 分摊(平均/份数/精确),各家账单+最小转账结算,拍照小票 OCR
- 变声:Web Audio 实时变声引擎(Jungle 音高偏移+效果链),独立 App 并可在营地内使用
- 架构:可插拔对等传输层(Web BroadcastChannel / 原生 BLE·WiFi 适配位),PWA 离线安装

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 新增 WebRTCTransport:跨设备点对点网状连接,位置/语音/聊天走设备直连
- 新增 server/signaling.js:极简 WebSocket 信令服务器(仅转发 SDP/ICE)
- CompositeTransport 组合 BroadcastChannel(同机)+ WebRTC(跨机),业务层无感
- 频道以群组 6 位验证码为房间 key:不同手机输入同一验证码即入同一网状网
- 断线自动重连、ICE 候选缓冲、按 peerId 去重发起避免 glare
- 新增 npm run server / dev:all 脚本与 VITE_SIGNALING_URL 配置
- 实测:两个独立浏览器实例经 WebRTC 双向互通消息通过

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 引入 Capacitor 8:生成 android/(Gradle)与 ios/(Xcode, SPM)原生工程
- 接入原生插件:geolocation/camera/network/status-bar/keyboard/app
- src/lib/geo.ts:定位在原生(Capacitor GPS)与 Web(浏览器)间自动切换,跟车改用之
- src/lib/native.ts:原生启动初始化(状态栏),Web 端空操作
- 权限声明:AndroidManifest(定位/相机/录音/蓝牙/WiFi)、Info.plist(定位/相机/麦克风/蓝牙/本地网络/后台定位)
- 新增脚本 npm run sync / android / ios,README 补充原生构建运行说明
- cap sync 双端校验通过;WebRTC/getUserMedia 在原生 WebView 内可用

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 自定义 Capacitor 插件 BleMesh:手机同时作 BLE 外围(广播+GATT服务)与中心(扫描+连接),
  蓝牙范围内两机即可直连互发消息,无需服务器/移动网络/WiFi
- Android: BleMeshPlugin.java(Advertiser+GattServer+Scanner+Gatt),MainActivity 注册
- iOS: BleMeshPlugin.swift(CBPeripheralManager+CBCentralManager),CAPBridgedPlugin 自动注册,
  已写入 project.pbxproj 参与编译;两端同 UUID 与分片协议,iOS/Android 互通
- src/lib/bleTransport.ts 接入统一 Transport,纳入 CompositeTransport:有蓝牙走蓝牙、
  无蓝牙自动回落网络;按验证码分房间过滤,大消息(语音/视频)自动改走网络
- 链路优先级 蓝牙>WiFi>移动网络;营地页顶部实时显示当前链路与邻居数
- 分片重组、TTL 清理、去重发起避免双向重连;README 补充 BLE 使用与真机测试说明

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 帧头新增 1 字节 TTL(8 msgId + 1 ttl + 2 seq + 2 total),默认 4 跳
- 节点收到未见过的消息去重后转发给其它邻居,覆盖"朋友的朋友"范围
- 全局 msgId 去重(seen, 保留30s)防止转发风暴;源头自标记己见避免回环
- Android(BleMeshPlugin.java) 与 iOS(BleMeshPlugin.swift) 同步实现,帧格式一致互通
- 分片重组保留 ttl/msgId 以便中继;teardown/stop 清理 seen 与 reasm
- README 更新为多跳说明

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- android job: ubuntu + JDK21 + Android SDK(compileSdk 36),gradlew assembleDebug,产出可直接安装的 app-debug.apk
- ios job: macos-14,xcodebuild 设备架构不签名编译,打包 app-unsigned.ipa(需自行重签)
- 同时充当原生蓝牙插件(Kotlin/Java/Swift)的编译校验
- README 补充云端出包说明

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
上一轮 cap sync 因 Node 20 失败,两端 setup-node 升到 22。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
Android 已成功编译(含 Java 蓝牙插件)。iOS 改用 -scheme App。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
原生能力:
- 记账:拍照小票在原生端走 @capacitor/camera 原生相机(Web 仍用文件选择)
- 记账:结算页「分享账单」——原生系统分享面板 / Web navigator.share 或复制
- 跟车:@capacitor/network 显示实时网络类型(WiFi/移动网络/离线);Wake Lock 保持屏幕常亮
- 新增 nativeCamera/nativeShare/useNetwork(含 useKeepAwake) 工具,原生/Web 自动切换

CI:
- iOS job 改用 macos-15 + 选择 Xcode 16(Capacitor 8 需 Xcode16;macos-14 的 15.4 编译失败)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
Xcode 16 需显式 destination,否则报 no destinations for scheme。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
Xcode 16 未预装 iOS 设备平台导致 generic/platform=iOS 无目标。
改用 iphonesimulator 编译,完整校验 Swift 原生代码(含蓝牙插件),产出模拟器包。
真机安装走本机 Xcode(自动签名)。README 同步更新。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
强制选 Xcode_16.app 那份未装 iOS 平台(设备+模拟器都无目标)。
改用镜像默认 Xcode(自带 iOS 平台与模拟器运行时),并加运行时诊断。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
对讲机变声(2):
- 跟车对讲(PTT)新增「🎭 变声」折叠选项,按住说话前经 VoiceFX 实时变声再广播
- 复用现有变声引擎与预设;默认原声;变声Tab仍独立保留

不区分机型(1):
- 位置广播携带 platform(ios/android/web);地图标记弹窗与顶部信息条显示同行机型分布
- 明确 iOS/Android/Web 走同一协议(同验证码房间 + 同蓝牙UUID/分片协议 + 平台无关WebRTC id)互通
- README 增加"不区分机型互联"说明

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- vite base 按 GH_PAGES 环境变量切换:Pages 用 /weber-hello-world/,原生/本地用 /
- deploy-pages.yml:push 到 master 或 claude/** 时构建 dist 并部署到 Pages
- 得到公网链接可在手机(含 iPhone Safari)直接体验,可加到主屏;蓝牙 Mesh 仅原生 App 有

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
上一轮因仓库未开启 Pages 失败;加 enablement:true 由工作流自动开启。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 纯 UIKit/Swift、零依赖、最低部署 iOS 12.0,向上兼容最新 iOS
- 因 iOS12 WKWebView 缺 getUserMedia/BroadcastChannel,网页/Capacitor 无法上 iOS12,故原生重写
- Tab 骨架(跟车/记账/营地/变声) + 跟车页 MapKit 地图(道路/卫星)+CoreLocation 定位
- 未使用/未改动 guardcam 任何代码;全新独立实现
- XcodeGen(project.yml) 生成工程,避免手写 pbxproj;CI 编译 iOS 模拟器校验并出产物

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- deploy-pages: 仅 master 自动部署 + 手动 dispatch(Pages 未开启前不再每次 push 报红)
- build-mobile: 限定网页/Capacitor 相关路径,ios12/ 原生改动不再触发它
- ios12-build 已仅在 ios12/ 触发

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 记账:Swift/UIKit 原生页面——成员管理、记一笔(平均分摊)、各家账单、最优转账结算
- LedgerModel:分为单位整数、最小转账贪心算法、UserDefaults 持久化(iOS12 可用)
- 替换 Tab 里的记账占位为真实功能
- ios12-build 改为真机架构不签名编译并打包 trailmate-ios12-unsigned.ipa
  (用 Sideloadly/AltStore 免费 Apple ID 重签装到 iOS12 老机;预留签名归档说明)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- BleMesh.swift:iOS12 CoreBluetooth 双角色(外围广播+GATT / 中心扫描+连接)
  多跳 TTL 泛洪、msgId 去重防风暴、分片重组,与 Web/Capacitor 版同一帧协议
- CampViewController.swift:蓝牙群聊 UI(消息列表+输入栏+键盘跟随+昵称+邻居数)
- 替换营地占位;Info.plist 加蓝牙用途说明
- 无网络也能互通;真机测试

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- VoiceViewController:9 个角色预设(汤姆猫/喜羊羊/小猪佩奇/孙悟空/猪八戒/花栗鼠/机器人/大魔王/原声)
- 音高偏移(AVAudioUnitTimePitch)+音色(AVAudioUnitDistortion),实时试听 + 录制回放
- 替换变声占位;Info.plist 加麦克风用途
- 至此 iOS12 原生 App 四大页全部落地:跟车/记账/营地蓝牙/变声

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- MeshBus:全 App 单套 BLE,按类型路由(营地聊天/跟车位置复用一条链路)
- Identity:稳定设备ID + 昵称(营地/跟车共用)
- 跟车:节流广播自身位置(3s),地图显示同行者标注(KVO 动态更新),完全离线
- 营地:改用共享 MeshBus(不再各自起一套 BLE)
- 需真机测试(多台设备)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 队伍 Tab:显示/新建队伍码 + 二维码,扫码入队(CIQRCodeGenerator + AVCaptureMetadataOutput,iOS12)
- MeshBus 帧加队伍码字段并按 team 过滤:跟车位置/营地聊天仅本队互通
- Identity.team + newTeamCode;Info.plist 加相机用途
- 默认公共队;新建/扫码进入私有队

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- ReceiptOCR:iOS13+ 用 Vision 文字识别自动提取金额(关键词加权+两位小数偏好);iOS12 无 Vision 回退手填
- 记账页「📷小票」:拍照→识别→预填金额→选付款人;小票图存 Documents,账目显示 📷 标记
- Expense 增加可选 receiptPath(向后兼容);Info.plist 已含相机用途

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- ios12-signed.yml:workflow_dispatch 手动触发,导入证书+描述文件,archive+exportArchive 出已签名 IPA
- 平时不运行,不影响默认 CI;配好 5 个 Apple Secrets 后手动触发即可出直装包
- ios12/SIGNING.md:证书/描述文件/Team ID 转 base64 与 Secrets 配置步骤

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- android-native/:Kotlin + AndroidX/Material3,AGP 8.5.2 / Gradle 8.9 / JDK17,minSdk 21 覆盖老机
- 记账:成员/记一笔(平均分摊)/各家净额/最优转账结算,SharedPreferences+JSON 持久化
- Ledger.kt 与 iOS LedgerModel.swift 算法一致
- CI android-native-build.yml:生成 wrapper + assembleDebug,产出可直装 app-debug.apk
- 与 Capacitor android/ 并行,互不影响;后续补地图/蓝牙/变声/队伍

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
- 改为 BottomNavigationView 宿主:记账 / 跟车 两个 Fragment
- ConvoyFragment:osmdroid 地图,道路(MAPNIK)/卫星(ESRI World Imagery)切换 + MyLocation 定位
- 记账迁入 LedgerFragment
- 权限/依赖:INTERNET+定位、osmdroid、fragment-ktx
- 后续补 营地蓝牙/变声/队伍

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YSg1v3QaS7AYLHz4pfS3zh
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants