killapp/README.md
“虞渠成” 8074ba71c0 更新readme
2026-09-07 09:17:25 +08:00

134 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# killapp —— 激光灭蚊设备控制 App
控制「激光灭害虫设备」photonmatrix的配套手机 AppUnity 制作Android + iOS 双平台。
用户通过 App 完成设备绑定BLE 扫描 + 扫码)、配网、日常控制(工作模式 / FOV / 透镜 / 补光灯 / 定时任务)、
杀蚊数据统计(柱状图 / 雷达热力图 / 杀蚊视频)、固件 OTA 升级、设备共享等。
---
## 技术栈与环境
| 项 | 值 |
|---|---|
| Unity | 2022.3.62f3c1 |
| 应用包名 | `com.photonmatrix.photonmatrix`Android / iOS 相同) |
| 当前版本 | bundleVersion 1.0.7AndroidBundleVersionCode 4均在 `ProjectSettings/ProjectSettings.asset` |
| UI 方案 | UGUI + DOTween无 Addressables |
| 热更方案 | 自研 AssetBundle 热更(`LoadRes` + `NetworkCtrl` |
| 第三方 | Firebase SDK仅 Auth、apple-signin-unity、Shatalmic BLE 插件、zxing、NativeGallery、ExternalDependencyManager |
| 主场景 | `Assets/Scenes/MainScene.unity`(唯一业务场景);`BlueToothTest.unity` 为蓝牙调试场景 |
`Packages/manifest.json` 非常精简ugui、timeline、visualscripting、assetbundlebrowser、android-logcat 等),
Firebase 是以 Assets 方式导入而非 UPM。
## 整体架构
**单场景 + 常驻 Manager + AssetBundle 动态页面**
- `MainScene``Manager` 节点挂载全部管理器:`NetworkCtrl``DataManager``UIManager``LoadRes``LanguageManager``FirebaseAuthManager`
- `Canvas/bg` 是页面容器,页面按 prefab 从 AssetBundle 动态加载实例化(旧的销毁、新的实例化)。
- 页面逻辑全部写在 prefab 挂的 Ctrl 类里,各单例之间直接互相引用(`HomePageCtrl.Instance``DataManager.Instance` 等)。
**启动流程**`NetworkCtrl.Init()`
`LoadRes.Init`AB 环境)→ 创建 `HttpRequestManager` / `RequestQueueManager` / `NetworkStateManager`
从服务器查 AB 版本并差量热更下载MD5 校验)→ `DataManager.Init`token 自动登录)→ `UIManager.Init`(有 token 进主页,否则进登录页)。
## 目录结构
```
Assets/
├── Scenes/ MainScene主场景、BlueToothTest蓝牙调试
├── Scripts/
│ ├── Bluetooth/ BLE 核心(当前开发重点)
│ │ ├── BluetoothManager.cs Shatalmic 插件封装:扫描/连接/断开事件
│ │ ├── BLECommunicationManager.cs 协议层:指令收发、事件分发(全项目最大文件)
│ │ ├── BLEDeviceState.cs 按 MAC 隔离的设备运行状态模型
│ │ ├── OTAManager.cs 固件版本解析与升级传输
│ │ ├── Protocol/ 帧结构体 BLEProtocolStructs.cs + CRC16.cs
│ │ └── BLE通信方案V2.2.md BLE 协议文档App ↔ BLE 透传 ↔ STM32H7 MCU
│ ├── Core/ LoomBLE 回调线程切主线程)、状态栏沉浸、安卓文件选择
│ ├── Managers/ DataManager / DataBase(DTO) / FirebaseAuthManager / LanguageManager / LoadRes / FireBaseCtrl(死代码)
│ ├── Network/ NetworkCtrl(门面+启动编排) / HttpRequestManager / RequestQueueManager / NetworkStateManager
│ ├── UI/
│ │ ├── UIManager.cs 页面管理、安卓返回键、token 自动登录
│ │ ├── Pages/ 各页面逻辑Home / Login / ConnectDevice / DeviceInfo / Video / Self / Rank / Safetylearning
│ │ └── Components/ Toast / Loading / Barchart / RadarHeatmap / SectorScanEffect / QRCode 等通用控件
│ └── Utils/ MainThread、ValidationUtils、iOSWiFiHelper
├── Res/ AB 包源资源bluetooth / common / language / ui
├── StreamingAssets/ 首包 ABcommon.ab、language.ab、ui_common.ab + list.json
├── Plugins/ Shatalmic 运行脚本、NativeGallery、DOTween、zxing、iOS 原生桥(.mm)
├── AppleAuth/ Sign in with Apple
└── Firebase/ Firebase SDK实际只用 Auth
```
## 核心模块备忘
### 蓝牙 BLE开发重点
- 链路App ↔ BLE 模块透传Service `FFE0`,读/写/Notify 均走 `FFE1`)↔ MCUUART9
- `BLECommunicationManager` 是几十条指令的收发与事件分发中心:
注册/指纹认证、定时任务、语言、LCD/RGB、WiFi 配网、补光灯、激光、角度/距离、
毫米波雷达、视觉检测、工作模式、硬件状态、统计数据、蚊子数据等。
每条指令对应 `XxxRead` / `XxxWrite` 方法 + `OnXxxReceived` 事件。
- 设备**主动通知**(状态变化 0x01 / 错误 0x02 / 参数变化 0x06 / 蓄能 0x08 / 补光灯连接 0x09 等)
汇入 `OnDeviceNotificationReceived`,再**按设备 MAC 隔离**后广播;分支名
`feature/ble-config-notification` 即指这套「配置变更主动上报」机制。
- 设备状态保存在 `BLEDeviceState`(按 MAC 为边界),统一通过
`OnDeviceStateChanged(BLEDeviceState, BLEDeviceStateField)` 通知 UI。
- Shatalmic 回调来自非主线程UI 相关处理必须 `Loom.QueueOnMainThread` 切回主线程。
- Android/iOS 无法直接取 BLE 真实 MAC设备 MAC 通过 BLE 命令从设备端获取(设备序列号用于绑定)。
### 网络与后端
- **服务器地址**(配置在 MainScene 里 `NetworkCtrl.serverBaseUrls`
测试 `https://nextreal.cn/photon-matrix-api`,正式 `https://api.photonmatrixlab.com`
**切换后门**:首页左下角连点 5 次(`enableServerBackdoor` 控制开关,发布前应置 0
环境持久化在 PlayerPrefs `network_server_env`
- `HttpRequestManager`UnityWebRequest 封装,重试(指数退避)、**SSE 流式**WiFi OTA 进度)、多平台超时。
- `RequestQueueManager`:优先级请求队列,并发上限 5。
- `NetworkStateManager`:每 3 秒轮询 `internetReachability`,发连接/断开事件。
- `ResponseCode`:业务码统一处理,**601 = Token 失效 → 全局登出**。
- 主要接口(`{Base}/api/v1/...`认证login/register/email-code/token-login/firebase-bind
设备bind/list/config/schedule-tasks/fingerprints/share/command、统计上报与查询
kill-count/records/videos/heatmap/leaderboard、通知、OTAlatest/push/transfer 进度 SSE
考试、反馈、`app/version/bundle`AB 热更清单)。
### 数据与账号
- `DataManager`运行时数据中枢token、用户信息、自有/共享设备、当前选中设备、设备配置、指纹、定时任务)。
PlayerPrefs 持久化:`token``userData``selectedDeviceMac`、设备列表缓存 `ownedDevicesCache_<userId>` 等。
- `DataBase.cs`:纯 DTO 定义(登录/用户/设备/配置/OTA/消息/统计/考试…),非 Mono。
- 第三方登录:`FirebaseAuthManager`Google 用 FederatedOAuthProviderApple 用 apple-signin-unity + nonce
结果换自家后端 token`auth/firebase/bind`)。旧版 `FireBaseCtrl.cs` 已无任何引用,属死代码。
### UI 框架
- `UIManager.PageName` 枚举 8 个主页面login / safetylearning / home / connectDevice / deviceInfo / self / video / rank。
- 页面 prefab 按 bundle 名 `ui_xxxpage` 从 AB 加载(配置在 MainScene 的 UIManager `pages` 列表)。
- 设置类子弹窗不走 UIManager由各 Ctrl 自己 Instantiate + `RegisterBackAction`(返回键栈,双击退出)。
- 首页 `HomePageCtrl` 是功能核心:蓝牙/WiFi 双通道控制、状态订阅、
**锁扣防误触LockButtonPlane180 秒无操作自动上锁)**、下拉刷新、统计上报、跳转子页面。
### 资源与热更
- `LoadRes`:编辑器「本地」模式直读 `Assets/Res/`;真机「资源包」模式优先 `persistentDataPath/*.ab`(热更落盘),
回退 StreamingAssets 首包bundle 缓存在内存字典。
- 热更清单来自 `app/version/bundle`,由 `NetworkCtrl` 做差量下载 + MD5 校验,进度显示在 `updateLoading`
- 语言词条也在 AB 里:`language/language.json``country.json``LanguageManager` 读取PlayerPrefs `LanguageType`)。
### 其他关键组件
- `Loom`:线程池 + 主线程队列派发BLE 回调切主线程用)。`Utils/MainThread.cs` 功能重复,并存。
- `RadarHeatmap`:按角度(0-180)+距离换算极坐标摆放热力点(数据来自 `stats/device/heatmap`)。
- `SectorScanEffect`首页扇形扫描波纹动画fillAmount 表现 FOV、缩放表现探测距离
- `iOSWiFiHelper`iOS14+ 取当前 WiFi SSID需定位权限配网页自动填 SSIDAndroid 直接读。
- `NativeGallery`:杀蚊视频保存到系统相册。
## 构建与发布备忘
- 版本号:`ProjectSettings/ProjectSettings.asset``bundleVersion` / `AndroidBundleVersionCode`
- Android 签名:`user.keystore`(项目根目录)。
- iOS`ITSAppUsesNonExemptEncryption` 已配置避免每次手动答加密问卷commit 457fee5
- 根目录的 `*.apk` / `*_mapping.txt` 为历史构建产物(含 Release 符号表),命名习惯如
`photonmatrix_1.0.7_0903.apk`;测试构建会带后缀如 `ota蓝牙优先`
- 打正式包前检查:`NetworkCtrl.enableServerBackdoor` 应为 0场景内字段