项目型号确认:项目负责人于 2026-09-09 确认,本仓库对应 410 型优卡特称重台。代码拉取、分支核验、构建和真机验收请阅读
COLLABORATION_GUIDE.md;浏览版见COLLABORATION_GUIDE.html。
- 代码仓库:https://codeup.aliyun.com/60069db88deaa14d9e02b875/zhct/device/restaurant/billedBygram/ZhctWeightingTableYoukate
- 本 README 保留项目技术说明;协作流程独立维护在
COLLABORATION_GUIDE.md。 - 源码中的“称重台450型”和通用应用名属于历史兼容标识,修改前必须核验服务端和 410 真机兼容范围。
项目概述
ZhctWeightingTableYoukate 是智慧餐厅称重台 Android 应用,用于在取餐场景中实时识别餐盘、读取称重数据、展示当前菜品和营养建议,并把取餐记录上传到服务端。
典型流程:
- 用餐人员将餐盘放到识别区。
- 扫码器读取餐盘/码牌上的二维码,秤体读取菜盆载荷重量。
- 应用根据餐盘码查询绑定人员和营养推荐。
- 用餐人员取餐后移走餐盘。
- 应用计算本次取餐重量,先把完整记录写入本地库,再由后台任务上传。
当前工程是单模块 Android 项目,包名为 com.cpt.zhct.weighting,主入口是 StartActivity。
核心能力
- 设备初始化:启动后申请存储、网络、相机等权限,检查接口地址、设备编号、配对码等本地配置。
- 云端排菜:启动时拉取当前设备排菜信息,未排菜时进入未排菜页面,已排菜时进入首页。
- 称体硬件适配:通过
DeviceSDK-80.1.10.12.20260129.aar对接 PC681 扫码秤,统一封装在YoukateHardwareManager。 - 取餐识别:扫码码长默认 6 位,识别到有效餐盘码后查询人员绑定关系和推荐信息。
- 称重与上传:根据稳定重量变化计算单次取餐量,重量大于 5g 时上传取餐记录。
- 离线补传:取餐记录先写入本地 SQLite,再由带联网约束的唯一 WorkManager 任务串行补传。
- MQTT 菜品同步:启动接口返回 MQTT 配置后,
CustomMqttService订阅阿里云 MQTT 消息,处理type=2的云端排菜同步。 - 心跳与状态上报:
HeartBeatWorker每 30 秒执行心跳;日志、异常、告警通过本地文件、阿里云 SLS、RUM 和业务日志接口上报。 - UI 展示:首页当前使用深色主题 Fragment,按服务端
showModel切换汇总余额、纯营养、现金余额+补贴余额等展示模式,支持营养建议、菜品余量提醒、灯带和语音提示。
启动流程
StartActivity
启动页负责应用初始化和页面分流:
- 申请运行权限。
- 校验
API_ADDRESS、TERMINAL_NUMBER、PAIR_CODE。 - 配置缺失时进入
SetActivity。 - 调用
/p/api/equipmentStart获取 MQTT、首页展示模式、单次最大取餐重量等配置。 - 启动
CustomMqttService。 - 调用
/api/weigh/dishes同步当前排菜。 - 有排菜进入
HomeActivity,无排菜进入UnSetDishActivity。
HomeActivity
首页负责核心取餐链路:
- 初始化称体扫码秤。
- 切换到“打餐前”页面。
- 拉取或读取当前菜品信息。
- 监听称重和扫码数据。
- 识别餐盘后切换到“打餐中”页面,并查询取餐人。
- 餐盘离开后计算取餐重量。
- 上传取餐记录,失败时写入本地库。
- 处理 MQTT 云端排菜消息和首页展示刷新。
主要代码结构
app/src/main/java/com/cpt/zhct/weighting/
├── StartActivity.java # 启动初始化和页面分流
├── activity/ # 首页、设置、排菜、未排菜、调试页面
├── application/CustomCptApplication.java
│ # 全局初始化:MMKV、数据库、网络、日志、RUM、定时任务、崩溃恢复
├── database/ # 本地取餐记录缓存和补传 DAO
├── entity/ # 菜品、取餐记录、MQTT 消息等实体
├── fragment/ # 首页打餐前/打餐中展示 Fragment
├── hardware/ # 称体扫码秤、灯带、称重工具封装
├── mqtt/ # 阿里云 MQTT 连接、订阅、消息分发
├── network/ # Retrofit 接口、请求、响应和网络管理
├── receiver/ # 开机广播和闹钟广播
├── service/CustomMqttService.java # MQTT 后台服务
├── utils/ # 配置、日志、上传、声音、崩溃、MMKV 等工具类
└── workmanager/ # 心跳和离线取餐记录补传任务
关键配置
本地配置主要通过 MmkvUtils 读写,常量集中在 Constants:
| 配置项 | 说明 |
|---|---|
API_ADDRESS |
服务端接口地址 |
TERMINAL_NUMBER |
设备编号 |
PAIR_CODE |
设备配对码 |
CURRENT_DISH_ID |
当前已排菜品 UUID |
CURRENT_DISH_NAME |
当前菜品名称 |
SPOON_WEIGHT |
勺重,默认 20g |
SKIP_WEIGHT |
起跳值,默认 5g |
DISH_LOW_REMINDER_VALUE |
菜品余量提醒值,默认 2000g |
SINGLE_PICK_WEIGHT_MAX |
单次取餐最大重量,服务端下发,默认 5000g |
SETTING_VOICE_SWITCH |
语音开关 |
SETTING_LIGHT_SWITCH |
灯带开关 |
SETTING_SUGGEST_SWITCH |
菜品取用建议开关 |
SETTING_SUGGEST_SWITCH_STATUS |
菜品取用建议展示状态 |
STYLE_HOME_DISPLAY |
首页展示模式,1 汇总余额,2 纯营养,3 现金余额+补贴余额 |
WEIGHER_INTERVAL_MS |
称体采样间隔,默认 100ms,支持 50/100/150/200/250ms |
默认接口地址为 http://zlssdev.cptshop.net.cn。实际部署时通常在设置页写入正式地址、设备编号和配对码。
服务端接口
接口定义集中在 CPTNetworkRequest,主要接口包括:
| 接口 | 用途 |
|---|---|
POST /p/api/equipmentStart |
启动初始化,返回 MQTT、展示模式、取餐限制等配置 |
POST /p/api/getMeal |
获取排菜用菜品列表 |
POST /p/api/find |
获取菜品详情 |
POST /p/api/zhctPushMeal |
上传取餐记录 |
POST /p/api/selectPlate |
根据餐盘码查询取餐人、营养和推荐 |
POST /p/api/currentMealNutrition |
获取取餐人当前餐次营养详情 |
POST /p/api/matecode |
根据配对码获取设备配对信息 |
POST /p/api/heartbeat |
设备心跳 |
POST /p/api/CaterList |
获取菜品库列表 |
POST /p/api/addRecipe |
添加菜品到菜谱库 |
POST /p/api/getRestaurantsInfo |
获取当前餐段时间 |
POST /p/api/delRecipe |
从菜谱库删除菜品 |
POST /p/api/feedback |
MQTT 消息处理反馈 |
POST /api/weigh/pushDishes |
推送设备排菜结果 |
POST /api/weigh/dishes |
获取当前设备排菜信息 |
POST /api/weigh/pushWeight |
轮询上传当前菜品重量 |
POST /p/api/getNewVersion |
获取版本更新信息 |
硬件说明
当前项目面向称体 PC681 扫码秤:
- 第三方依赖:
app/libs/DeviceSDK-80.1.10.12.20260129.aar - 统一入口:
hardware/YoukateHardwareManager.java - 数据回调:重量状态、净重、二维码扫码结果(SDK字段
rfidData)会统一回调到HomeActivity - 灯带控制:重量变化时红灯,稳定时绿灯;超重会显示告警并上报
- 初始化兜底:SDK 初始化 10 秒无回调时按失败处理,并退出应用
- 采样间隔:默认 100ms,可通过设置页调试入口保存为 50/100/150/200/250ms
注意:当前 SDK 的 release() 路径存在 native 字段契约不一致风险,YoukateHardwareManager.release() 已避开直接调用 scaleManager.release(),改为停止监听、关闭输入输出流并清理 SDK 状态。不要在业务代码里绕过封装直接调用 SDK release。
构建环境
工程使用较旧的 Android 构建栈。下表版本信息已按 2026-09-09 只读核验的远端 master@2f759f9415b4 更新:
| 项 | 当前值 |
|---|---|
| Gradle Wrapper | 5.1.1 |
| Android Gradle Plugin | 3.4.1 |
| compileSdkVersion | 30 |
| minSdkVersion | 26 |
| targetSdkVersion | 30 |
| Java compatibility | 1.8 |
| applicationId | com.cpt.zhct.weighting |
| versionName | 2.6.0 |
| versionCode | 21 |
本机验证建议使用 JDK 8:
JAVA_HOME=$(/usr/libexec/java_home -v 1.8) bash ./gradlew :app:assembleDebug
如果 ./gradlew 有执行权限,也可以运行:
JAVA_HOME=$(/usr/libexec/java_home -v 1.8) ./gradlew :app:assembleDebug
当前 app/build.gradle 未声明自定义 signingConfigs,debug 包使用 Android Gradle Plugin 默认 debug 签名。
运行与调试
- 使用 Android Studio 打开项目根目录。
- 确认本机 JDK 切到 1.8。
- 连接目标硬件设备。
- 构建并安装 debug 包。
- 首次启动进入设置页,配置接口地址、设备编号、配对码。
- 确认服务端有当前设备排菜信息。
- 回到首页后放置餐盘,观察扫码、人员信息、称重、上传日志。
调试入口:
SetActivity:设备和接口配置。DishSetActivity:手动排菜。UnSetDishActivity:未排菜状态页。- 首页隐藏调试:连续点击
reset区域可显示当前重量浮层。
日志与后台任务
- 本地文件日志:通过
LocalFileRecorder写入。 - 业务日志上传:通过
UploadLogUtils统一上报。 - 企业告警:通过
EnterpriseAlertUploader上报异常和关键告警。 - 阿里云日志:
CustomCptApplication初始化 SLSLogProducerClient。 - 阿里云 RUM:应用启动时初始化。
- 心跳任务:
AlarmUtils.sendAlarm触发HeartBeatWorker,间隔 30 秒。 - 离线补传:新增记录和应用启动时调度
UploadPickMealRecordWorker;网络不可用或上传失败时按 3 分钟线性退避重试。
常见注意事项
- 旧 Gradle/AGP 在较新 JDK 下可能出现 Groovy 或 Gradle 初始化失败,优先切 JDK 8 再构建。
- 称体 SDK release 不要直接调用第三方
PC681ScaleManager.release(),应通过YoukateHardwareManager.release()。 - 未配置接口地址、设备编号或配对码时,启动页会跳转设置页,不会进入首页。
- 没有当前排菜信息时,启动页会进入未排菜页;首页也会提示去排菜。
- 餐盘码默认要求 6 位,长度不合法会记录日志并上报告警。
- 单次取餐重量不大于 5g 时不会上传取餐记录。
- 取餐记录会先落本地库;服务端明确成功后删除,网络或服务异常时保留并等待 WorkManager 重试。
- MQTT 只处理 JSON 中
type=2的菜品同步消息,其他消息会记录为非菜品同步消息。 - Android 12 及以上如调整 targetSdk 或 PendingIntent 相关代码,需要补充
FLAG_IMMUTABLE/FLAG_MUTABLE兼容性处理。