feat(scale): 新增主从设备秤数据联网同步功能

- 新增 ScaleWebSocketServer/Client、ScaleDataAggregator、ScaleServiceManager 等秤服务模块
- 新增 MasterScaleActivity(主设备秤数据总览,按设备分组展示IP+秤列表)
- 新增 SlaveActivity(子设备专属页面,显示IP、主设备连接状态及本机秤数据)
- SlaveActivity 改为横屏,MasterScaleActivity 保持竖屏
- 子设备连接状态通过 WebSocket onOpen/onClose 回调实时更新
- GlobalData 新增 DeviceRole 枚举,BaseApp 启动时初始化角色并启动秤服务
- SettingActivity 新增设备角色展示和秤数据监控入口
- Weigher2 支持外部设置串口路径,适配不同硬件子设备

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 17:15:48 +08:00
co-authored by Claude Sonnet 4.6
parent d6a9c3562d
commit 29228b069b
25 changed files with 1398 additions and 9 deletions
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:background="@color/bg_color">
<!-- 顶部标题 -->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:layout_marginBottom="10dp"
android:text="全设备秤数据监控"
android:textColor="@color/home_title"
android:textSize="36sp"
android:textStyle="bold" />
<!-- 主设备连接状态栏 -->
<TextView
android:id="@+id/tvConnectionStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginBottom="16dp"
android:textColor="@color/home_sub_title"
android:textSize="24sp"
tools:text="已发现设备:3 台" />
<!-- 秤数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvScaleList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never"
android:padding="16dp" />
</LinearLayout>
@@ -37,6 +37,25 @@
android:textSize="26sp"
android:background="@android:color/transparent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnDeviceRole"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_weight="1"
android:text="设备角色:子设备"
android:textSize="22sp"
android:background="@android:color/transparent" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btnScaleMonitor"
android:layout_width="0dp"
android:layout_height="70dp"
android:layout_weight="1"
android:text="秤数据监控"
android:textSize="26sp"
android:visibility="gone"
android:background="@android:color/transparent" />
</LinearLayout>
<!-- Fragment 容器 -->
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="12dp"
tools:background="@color/bg_color">
<!-- 本机IP地址 -->
<TextView
android:id="@+id/tvDeviceIp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp"
android:textSize="22sp"
android:textStyle="bold"
android:textColor="@color/home_title"
tools:text="IP192.168.1.100" />
<!-- 设备信息 -->
<TextView
android:id="@+id/tvDeviceId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp"
android:textSize="18sp"
android:textColor="@color/home_sub_title"
tools:text="设备:device_02" />
<!-- 主设备连接状态 -->
<TextView
android:id="@+id/tvMasterStatus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="0dp"
android:layout_marginBottom="12dp"
android:textSize="16sp"
tools:text="主设备:未连接" />
<!-- 本机秤数据列表 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvScaleList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:overScrollMode="never" />
</LinearLayout>
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 设备卡片:竖向排列,显示设备号、IP、以及该设备下所有秤数据 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<!-- 设备 IP -->
<TextView
android:id="@+id/tvDeviceIp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/home_title"
tools:text="IP192.168.1.100" />
<!-- 设备号 -->
<TextView
android:id="@+id/tvDeviceLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/home_sub_title"
android:textSize="14sp"
tools:text="设备:device_01" />
<!-- 该设备下所有秤数据行,由代码动态填充 -->
<LinearLayout
android:id="@+id/llScaleContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_marginTop="5dp" />
</LinearLayout>
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 单行秤数据:秤编号 + 重量 + 状态 -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp">
<!-- 秤编号 -->
<TextView
android:id="@+id/tvScaleLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="22sp"
android:textColor="@color/home_sub_title"
tools:text="秤 1" />
<!-- 重量 -->
<TextView
android:id="@+id/tvWeight"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="center"
android:textSize="26sp"
android:textStyle="bold"
android:textColor="@color/home_title"
tools:text="235.5 g" />
<!-- 状态 -->
<TextView
android:id="@+id/tvState"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="end"
android:textSize="18sp"
android:textColor="@color/home_sub_title"
tools:text="稳定" />
</LinearLayout>