# 化学品智能管理终端 App 业务与技术分析 ## 1. 文档说明 本文基于当前仓库源码静态阅读整理,目标是说明该 Android 终端 App 的: - 业务功能模块 - 关键业务路径 - 业务规则与角色权限 - 主要技术实现策略 - 软硬件接入方式 - 关键源码位置 仓库定位不是通用库存 App,而是**实验室化学品安全管理一体机/壁挂终端**,围绕“实验室、化学品、安全柜/柜门、领用归还、废弃、预警、MSDS、双人认证、RFID/扫码/蓝牙秤/打印”等能力展开。 --- ## 2. 项目整体定位 ### 2.1 产品定位 该项目是一个部署在实验室场景下的化学品智能管理终端,典型硬件环境包括: - 壁挂 Android 一体机 - 智能化学品柜/柜门锁控设备 - 蓝牙电子秤 - 标签打印设备 - 摄像头 - 内置刷卡/扫码/人脸识别硬件 - 可能的 RFID 标签与串口扫码外设 ### 2.2 核心业务目标 从代码可以确认,该系统主要解决以下问题: 1. 实验室化学品合规入库 2. 化学品领用与现场校验 3. 化学品归还、空瓶处理、废弃出库 4. 柜门/柜锁权限控制与开锁操作 5. 安全管控类化学品双人认证 6. 电子台账、MSDS、安全预警闭环 7. 一体机设备联网、心跳、升级、异常恢复 --- ## 3. 项目结构总览 ### 3.1 Gradle 模块 - 主应用模块:`app` - 串口模块:`serialport` 关键文件: - `settings.gradle:23` - `app/build.gradle:6` - `serialport/build.gradle:5` ### 3.2 主要包结构 #### 业务 UI - `app/src/main/java/xn/hxp/ui/login` 登录 - `app/src/main/java/xn/hxp/ui/verify` 双人认证/二次校验 - `app/src/main/java/xn/hxp/ui/plan` 入库计划、手动录入、待入库、开锁 - `app/src/main/java/xn/hxp/ui/uses` 领用、预警 - `app/src/main/java/xn/hxp/ui/still` 归还、MSDS、静态资料 - `app/src/main/java/xn/hxp/ui/discard` 废弃、电子台账 - `app/src/main/java/xn/hxp/ui/inquiry` 查询 - `app/src/main/java/xn/hxp/ui/warehousing` 标签、库存相关页面 - `app/src/main/java/xn/hxp/ui/fragments` 台账/查询子页面 - `app/src/main/java/xn/hxp/ui/adapter` 列表适配器 #### 网络层 - `app/src/main/java/com/rc/httpcore/client/retrofit/ApiService.java` - `app/src/main/java/com/rc/httpcore/client/retrofit/ChemicalRetrofit.kt` - `app/src/main/java/com/rc/httpcore/client/ApiRepository.kt` - `app/src/main/java/com/rc/httpcore/HttpClient.kt` - `app/src/main/java/com/rc/httpcore/client/HttpTool.java` #### 系统/硬件能力 - `app/src/main/java/xn/hxp/utils/Tool.java` - `app/src/main/java/xn/hxp/utils/bluetooth/SppTool.java` - `app/src/main/java/xn/hxp/receiver/PortScanService.kt` - `app/src/main/java/xn/hxp/receiver/UsbReceiver.kt` - `app/src/main/java/xn/hxp/receiver/PortScanHelper*` #### 本地数据 - `app/src/main/java/xn/hxp/ui/plan/room/**` - `app/src/main/java/xn/hxp/utils/SharedPreferencesHelper.kt` --- ## 4. 应用入口与运行模式 ### 4.1 Application 全局初始化 应用入口类: - `app/src/main/java/xn/hxp/app/ChemicalApp.kt:32` 核心职责: 1. 初始化全局状态 - `userData` - `subjectId` - `subjectName` - `confs` - `labInfo` - `subRoom` - `administrators` - `responsibles` 2. 初始化终端能力 - 蓝牙 SPP:`SppTool.init()` - FastBle:`BleManager` - DialogX - X5 WebView - Toaster - 日志系统 3. 异常恢复策略 - 使用 `ANRWatchDog` - 卡顿后先重启 App,多次卡顿后直接重启设备 - 见 `ChemicalApp.kt:64-81` ### 4.2 启动页逻辑 启动页: - `app/src/main/java/xn/hxp/ui/StartActivity.java:34` 启动流程: 1. 长按 logo 可进入设置页 2. 自动补齐关键权限 3. 从本地配置恢复服务地址与相机参数 4. 调 `HttpTool.getCheck()` 获取设备绑定实验室信息 5. 将实验室信息写入全局变量 6. 进入主页 `MainActivity` 关键点: - 权限不是常规弹窗申请,而是直接执行 `pm grant` - 说明系统运行于受控设备环境 - 见 `StartActivity.java:80-96` ### 4.3 主页职责 主页: - `app/src/main/java/xn/hxp/ui/MainActivity.java:87` 主页主要做三件事: 1. 加载实验室配置与当前柜体轮播 2. 提供所有主业务入口 3. 维护登录状态、自动登出、设备心跳 关键逻辑: - 拉基础配置:`basicConfig`,见 `MainActivity.java:295` - 拉柜体列表:`getCabinetIn`,见 `MainActivity.java:249` - 心跳上报:每 20 秒调用 `HttpTool.heartbeat()`,见 `MainActivity.java:194-217` - 自动登出:根据 `signOutTime` 计时,见 `MainActivity.java:394-418` --- ## 5. 业务功能模块 ## 5.1 登录与身份认证模块 ### 页面 - `ui/login/SwipeActivity.kt` 刷卡登录 - `ui/login/ScanLoginActivity.kt` 扫码登录 - `ui/login/FaceLoginActivity.java` 人脸登录 - `ui/login/FacialCardActivity.kt` 人脸+刷卡组合登录 ### 业务能力 支持多种登录方式,由实验室配置控制: - 人脸 - 刷卡 - 扫码 - 人脸+刷卡 - 人脸+扫码 - 刷卡+扫码 - 多方式混合 配置来源: - `ConfigBean.loginType`,见 `ConfigBean.kt:9` - 主页分流逻辑见 `MainActivity.java:325-384` - 查询页分流逻辑见 `InquiryActivity.java:623-678` ### 认证后权限判定 刷卡登录流程: 1. 刷卡获取 token:`auth/cardNum` 2. 校验当前人在当前实验室的身份:`userCardValidation` 3. 读取用户角色字段 4. 允许或拒绝进入系统 关键代码: - `SwipeActivity.kt:147-167` - `SwipeActivity.kt:164-205` - `ChemicalRetrofit.kt:100-111` 角色模型: - `UserValidationBean.kt:4-26` 可确认角色: - 校级管理员 `schoolLevelAdmin` - 院级管理员 `collegeAdmin` - 实验室负责人 `adminUser` - 安全负责人 `safeUser` - 柜锁管理员 `cabinetAdmin` - 化学品归属人 `belongUser` - 课题组成员 `toipcUser` - 实验室准入 `apply` - 白名单 `white` ### 业务结论 登录不是单纯账号体系,而是**与实验室、柜门、化学品权限模型深度耦合的身份校验入口**。 --- ## 5.2 双人认证模块 ### 页面 - `ui/verify/TwoVerificationActivity.kt` - 以及同类辅助页面:`TwoPersonActivity.kt`、`SwipeCodeTwoActivity.kt`、`ScanCodeTwoActivity.kt` ### 用途 双人认证被用于多个高风险业务节点: - 新增入库 - 领用 - 归还/废弃/空瓶等返回类操作 - 待入库确认 关键字段: - `mTag` 表示业务场景 - 注释可直接确认: - `0` 新增入库 - `1` 归还/废弃/空瓶等 - `2` 待入库 - `3` 领用认证 - 见 `TwoVerificationActivity.kt:83` ### 支持的认证方式 由 `ConfigBean.verifyType` 配置: - `1` 人脸 - `2` 刷卡 - `3` 扫码 - 组合形态:`1,2`、`1,3`、`2,3`、多方式组合 见: - `ConfigBean.kt:31` - `UseActivity.kt:233-320` - `ChemicalsAlsoActivity.kt:110-146, 414-429` - `WasteChemicalsActivity.kt:297-330` - `ChemicalLabelingActivity.kt:185-217` ### 认证实现方式 #### 人脸 - 摄像头采图 + `checkUserFaceByPic` - 登录与认证接口分离 - 认证接口可带 `subId/doorId/stockId/waitId` 关键代码: - `ApiService.java:337-340` - `ChemicalRetrofit.kt:860-885` - `TwoVerificationActivity.kt:514-516` #### 刷卡 - 通过 USB/串口输入卡号 - 调用 `useCardVerify` - 请求参数带 `doorId`、`chemicalLevel` 等业务上下文 关键代码: - `ChemicalRetrofit.kt:125-139` - `ChemicalRetrofit.kt:601-616` - `TwoVerificationActivity.kt:1336-1337` #### 扫码 - 终端本地生成二维码 - 小程序扫码后由后台回传登录/验证状态 - 轮询 `aioScanLogin` 关键代码: - `TwoVerificationActivity.kt:142-146` - `TwoVerificationActivity.kt:1658` - `ApiService.java:236-237` ### 认证结果存储 通过 `DoubleDialogBean` 记录两位认证人,并写入本地 SharedPreferences: - `TwoVerificationActivity.kt:464` - `SharedPreferencesHelper.kt:42-70` 后续开锁、归还、废弃等操作会读取这两位认证人的 `userId/name` 写入业务请求。 ### 业务结论 双人认证是本系统安全策略中心,认证不是独立动作,而是**带业务上下文的二次授权**。 --- ## 5.3 入库模块 入库分为两个层次: 1. 计划/待入库编排 2. 实际入库提交 ### 5.3.1 计划入库总控页 页面: - `ui/plan/PlanAddActivity.java` - 辅助类:`ui/plan/PlanAddActivityHelp.java` 职责: - 读取实验室及柜体信息 - 初始化本地 Room 临时表 - 展示待录入清单 - 手动录入或扫码录入化学品 - 在提交前判断哪些柜门需要开锁 - 跳转开锁页或直接提交入库 关键代码: - `PlanAddActivity.java:100-155` - `PlanAddActivity.java:157-255` - `PlanAddActivityHelp.java:61-144` - `PlanAddActivityHelp.java:317-391` ### 5.3.2 手动录入页 页面: - `ui/plan/add/AddActivity.java` - 辅助:`ui/plan/add/AddActivityHelp.java` 支持信息: - 化学品名称搜索 - CAS 搜索 - 类别选择 - 归属人搜索 - 课题组搜索 - 规格/单位/密度/净含量/数量 - 管控/非管控属性 - 存储柜层选择 关键代码: - `AddActivity.java:151-239` - `AddActivityHelp.java:96-191` - `AddActivityHelp.java:198-305` ### 5.3.3 扫码录入 `PlanAddActivityHelp` 中提供扫码监听: - 既兼容“18 位时间戳式码” - 也兼容 `code=xxx&type=9` 的 URL 型码 - 最终统一通过 `scanCodeChemical` 查询化学品信息 关键代码: - `PlanAddActivityHelp.java:254-315` - `PlanAddActivityHelp.java:181-252` ### 5.3.4 入库前校验与确认 录入时会: 1. 通过 `getControlConfigs(chemicalLevel)` 获取化学品控制策略 2. 调 `certitude` 做化学品确认/补全 3. 如需要,先打印标签 4. 如需要,走蓝牙称重 5. 最终写入本地待入库列表 关键代码: - `AddActivityHelp.java:372-451` - `AddActivityHelp.java:453-458` ### 5.3.5 实际入库提交 `PlanAddActivityHelp.save()` 会把本地待入库临时数据组装为后端要求的 `HxpChemicalVo` 列表,并调用: - `HttpTool.addChemical()` -> `chemical/aio/addStock` 关键代码: - `PlanAddActivityHelp.java:317-391` - `HttpTool.java:101-108` ### 5.3.6 已申领未入库 主页上“存储/新增入库”入口会先判断是否存在“已申领未入库”记录: - 有数据时弹出选择:进入 `AlreadyActivity` 或 `PlanAddActivity` - 无数据时直接进入 `PlanAddActivity` 关键代码: - `MainActivity.java:645-684` ### 业务结论 入库不是简单表单提交,而是**柜位选择 + 化学品确认 + 打印/RFID/称重 + 柜门开锁 + 最终提交**的复合流程。 --- ## 5.4 领用模块 页面: - `ui/uses/UseActivity.kt` ### 核心流程 1. 加载可领用库存列表 2. 选择柜体与柜门 3. 如柜门要求双人认证,则先走双人认证 4. 如是智能锁柜门,先开锁 5. 在开门后的弹窗里刷 RFID/扫码标签 6. 拉取当前化学品库存详情 7. 选择领用数量/方式 8. 如需要称重则读取蓝牙秤 9. 提交领用记录 ### 关键特征 #### 柜门选择与双人认证 - 柜门字段 `verify` 决定是否要求双人认证 - `isControl` 决定化学品是否为管控类 - 智能锁通过 `unlockingMethod == 2` 识别 见: - `UseActivity.kt:198-275` #### 领用方式 - `mJoinType = 1` 表示称重 - `mJoinType = 2` 表示手动录入 - 见 `UseActivity.kt:81` #### RFID 查询 - 通过 `getByRfid` 获取领用对象 - 见 `UseActivity.kt:426` - 对应接口:`ApiService.java:165-176` #### 蓝牙称重 - `weighData()`、`connectToDeviceWithTimeout()` 等函数负责接秤 - 使用 SPP 蓝牙读取称重值 - 见 `UseActivity.kt:475-585` #### 再次开门 - 领用弹窗支持“再次开门”,且代码明确说明再次开门**不再需要双人认证** - 见 `UseActivity.kt:351-362` #### 异常上报 - 只要开过智能锁却中途返回,就会调用 `outTimeWarn` 做异常数据上报 - 见 `UseActivity.kt:107-113` - `UseActivity.kt:1318` ### 业务结论 领用流程是该系统最典型的“人-柜-物”闭环流程:**选柜门 -> 授权 -> 开门 -> 识别化学品 -> 称重/录入 -> 提交使用记录**。 --- ## 5.5 归还模块 页面: - `ui/still/ChemicalsAlsoActivity.kt` ### 核心流程 1. 查询待归还列表 `useList` 2. 选择具体记录或扫描 RFID 3. 加载归还详情 `backDetail` 4. 如需要双人认证则先认证 5. 如是智能锁则开柜门 6. 根据业务选择: - 正常归还 - 空瓶处理 - 废弃出库 7. 如需要称重则接蓝牙秤 8. 调 `giveBack/returnGiveBack` 提交 ### 可确认能力 - 补打标签 - 更换 RFID / RFID 补打 - 正常归还 - 空瓶流程 - 废弃流程 - 再次开门 - 超时异常上报 关键代码: - `ChemicalsAlsoActivity.kt:105-170` - `ChemicalsAlsoActivity.kt:172-235` - `ChemicalsAlsoActivity.kt:248-320` - `ChemicalsAlsoActivity.kt:643-747` - `ChemicalsAlsoActivity.kt:959` - `ChemicalsAlsoActivity.kt:1488` ### 业务状态线索 从代码可推断: - `useStatus = 4`:归还相关状态 - `useStatus = 3`:废弃相关状态 - `returnType = mJoinType`:归还方式区分称重/录入 见: - `ChemicalsAlsoActivity.kt:530-531` - `ChemicalsAlsoActivity.kt:602-603` - `ChemicalsAlsoActivity.kt:822-828` ### 业务结论 归还页面不是单一“归还”,而是将**归还、空瓶、废弃、补标、换 RFID** 集中在一个化学品出库回流工作台中。 --- ## 5.6 废弃模块 页面: - `ui/discard/WasteChemicalsActivity.kt` ### 核心流程 1. 查询可废弃化学品列表 `stockDetailsList` 2. 选择对象或扫描标签/RFID 3. 加载详情 `discardDetail` 4. 如需要则双人认证 5. 录入废弃原因 6. 生成 `GiveBackBean` 7. 调 `giveBack` 完成废弃出库 8. 如果已开过门但未完成,则调用 `outTimeWarn` 关键代码: - `WasteChemicalsActivity.kt:93-168` - `WasteChemicalsActivity.kt:237-264` - `WasteChemicalsActivity.kt:297-330` - `WasteChemicalsActivity.kt:520` - `WasteChemicalsActivity.kt:940` - `WasteChemicalsActivity.kt:1237` ### 业务状态线索 - 废弃提交时 `useStatus = 3` - `returnType = 1` - `remark = "repeal"` - 带 `disuseReason` 见: - `WasteChemicalsActivity.kt:106-120` ### 业务结论 废弃复用了归还接口,但在业务上属于**单独的危险化学品废弃出库流程**,强调原因记录与后续回收提醒。 --- ## 5.7 查询模块 页面: - `ui/inquiry/InquiryActivity.java` - `ui/fragments/QueryOneFragment.kt` - `ui/fragments/QueryTwoFragment.kt` - `ui/inquiry/QueryDetailsActivity.kt` ### 核心流程 1. 进入查询页时可带登录态与预选柜门信息 2. 登录态下显示柜体/柜门列表 3. 左侧选柜,右侧选柜门 4. 切换查询 Fragment 5. 可通过扫描标签/RFID 查询详情 6. 某些情况下支持开柜门查看 关键代码: - `InquiryActivity.java:139-181` - `InquiryActivity.java:240-304` - `InquiryActivity.java:306-362` - `InquiryActivity.java:376-420` - `InquiryActivity.java:505-598` ### 业务特点 - 查询分登录态与未登录态 - 未登录时扫码可查基础详情 - 登录时扫码可查更细库存详情 - 查询结果与柜门上下文绑定较深 - 查询页也允许权限人员执行开门操作 ### 业务结论 查询并非纯浏览页面,而是**带柜门上下文的库存/标签/RFID 联动查询入口**。 --- ## 5.8 电子台账模块 页面: - `ui/discard/LedgerActivity.kt` - `ui/fragments/UseLedgerFragment.kt` - `ui/fragments/InventoryIedgerFragment.kt` ### 功能 电子台账分为两类: - 使用台账 - 库存台账 切换方式: - `LedgerActivity.kt:54-72` - `LedgerActivity.kt:103-110` 对应后端能力: - `useRecords` - `stockLedger` - `useReturnList` 见: - `ApiService.java:254-261` - `ApiRepository.kt:378-397` --- ## 5.9 预警事件模块 页面: - `ui/uses/WarningEventsActivity.kt` - `ui/uses/ProcessedActivity.kt` ### 功能 1. 获取预警总数 2. 分页查询预警列表 3. 支持按时间范围筛选 4. 支持按处理状态筛选 5. 进入详情页查看/处理 6. 提交处理说明 关键代码: - `WarningEventsActivity.kt:50-60` - `WarningEventsActivity.kt:81-145` - `WarningEventsActivity.kt:210-240` - `WarningEventsActivity.kt:563-576` 后端接口: - `warningNoticeList` - `warningNoticeDetail` - `handleMessage` - `warningNoticeCount` 见: - `ApiService.java:220-230` ### 业务结论 预警模块是完整闭环,不是单纯看板,支持**统计、筛选、详情、处置**。 --- ## 5.10 MSDS 模块 页面: - `ui/still/MsdsActivity.kt` - `ui/still/MsdsScreenActivity.kt` ### 功能 1. 查询 MSDS 列表 2. WebView 展示文档内容 3. 生成二维码用于分享/扫码查看 4. 全屏查看 关键代码: - `MsdsActivity.kt:46-73` - `MsdsActivity.kt:91-129` - `MsdsActivity.kt:154-180` 后端接口: - `getMsdsDetails` - `msdsDetails` ### 技术特点 - 使用 X5 WebView - 直接加载 HTML 内容 - 使用二维码地址 `type=1` --- ## 5.11 标签与 RFID 模块 页面: - `ui/warehousing/ChemicalLabelingActivity.kt` ### 功能 1. 查询标签列表 `tagDetailsList` 2. 查看标签对应化学品详情 3. 补打标签 4. 更换 RFID 5. 打开柜门定位化学品 6. 对需要认证的标签执行双人认证后开门 关键代码: - `ChemicalLabelingActivity.kt:70-107` - `ChemicalLabelingActivity.kt:108-161` - `ChemicalLabelingActivity.kt:165-219` - `ChemicalLabelingActivity.kt:436-469` - `ChemicalLabelingActivity.kt:492-513` ### 业务结论 该页面承担了**标签重打、RFID 维护、通过标签反查库存并定位开门**的现场维护职能。 --- ## 6. 业务路径说明 ## 6.1 启动到主页路径 `StartActivity` → 获取设备绑定实验室信息 → `MainActivity` 路径关键点: - 自动授权 - 读取本地服务地址 - 调 `iot/aio/report` - 写全局 `labInfo/subjectId/subjectName/subRoom` 源码: - `StartActivity.java:100-150` --- ## 6.2 登录路径 ### 刷卡登录 `MainActivity.basicConfLog()` → `SwipeActivity` → `cardNum` → `userCardValidation` → 登录成功 → 回主页 源码: - `MainActivity.java:325-384` - `SwipeActivity.kt:147-214` ### 人脸登录 `MainActivity.basicConfLog()` → `FaceLoginActivity` → `faceNewCompare` → 登录成功 ### 扫码登录 `MainActivity.basicConfLog()` → `ScanLoginActivity` → `auth/scanCode` 或扫码验证相关接口 → 登录成功 --- ## 6.3 新增入库路径 `MainActivity` → `PlanAddActivity` → `AddActivity` 手动录入/扫码录入 → 本地待入库列表 → `UnlockActivity`(如需要开门)→ `PlanAddActivityHelp.save()` → `SaveListActivity` 关键业务节点: 1. 选择柜层 2. 录入化学品信息 3. 归属人/课题组绑定 4. 打印标签 5. 蓝牙称重 6. 判断需要开哪些智能柜门 7. 提交入库 源码: - `MainActivity.java:645-684` - `PlanAddActivity.java:157-255` - `AddActivityHelp.java:372-451` - `PlanAddActivityHelp.java:317-391` --- ## 6.4 领用路径 `MainActivity` → `UseActivity` → 选柜/柜门 → 双人认证(如需)→ 开锁(如需)→ 扫标签/RFID → 称重/录入 → `addUseRecord` 源码: - `MainActivity.java:504-513` - `UseActivity.kt:178-321` - `UseActivity.kt:323-585` - `ApiService.java:165-176` --- ## 6.5 归还路径 `MainActivity` → `ChemicalsAlsoActivity` → 查询待归还记录或扫描 → 查看详情 → 双人认证(如需)→ 开锁(如需)→ 称重/录入 → `giveBack/returnGiveBack` 源码: - `MainActivity.java:515-524` - `ChemicalsAlsoActivity.kt:105-170` - `ChemicalsAlsoActivity.kt:643-747` --- ## 6.6 废弃路径 `MainActivity` → `WasteChemicalsActivity` → 查询待废弃记录或扫描 → 双人认证(如需)→ 输入废弃原因 → `giveBack(useStatus=3)` 源码: - `MainActivity.java:482-491` - `WasteChemicalsActivity.kt:93-168` --- ## 6.7 查询路径 `MainActivity` → `InquiryActivity` → 选柜/柜门 → 查询 Fragment 切换 → 扫描标签/RFID → 查看详情 → 可选开柜 源码: - `MainActivity.java:493-501` - `InquiryActivity.java:240-304` - `InquiryActivity.java:376-420` --- ## 6.8 台账路径 `MainActivity` → `LedgerActivity` → 使用台账 / 库存台账 Fragment 切换 源码: - `MainActivity.java:526-535` - `LedgerActivity.kt:54-72` --- ## 6.9 预警路径 `MainActivity` → `WarningEventsActivity` → 筛选列表 → `ProcessedActivity` → 查看/处理预警 源码: - `MainActivity.java:548-557` - `WarningEventsActivity.kt:61-72` --- ## 6.10 MSDS 路径 `MainActivity` → `MsdsActivity` → 搜索 MSDS → 查看 HTML 内容 → 全屏查看 源码: - `MainActivity.java:559-564` - `MsdsActivity.kt:46-129` --- ## 7. 业务规则与域模型 ## 7.1 核心业务对象 ### 化学品 模型: - `ChemicalSearchBean.kt` - `HxpChemicalVo.java` 关键字段: - `chemicalId` - `chemicalName` - `casNum` - `chemicalLevel`:1 管控,2 非管控 - `chemicalPurity` - `chemicalCategory` - `packNum` - `specNum` - `depositRequire` - `msdsId` 见: - `ChemicalSearchBean.kt:7-32` ### 柜体/柜门/柜锁 模型: - `RuleBean.kt` - `CabinetDoorVo.kt` - `LockVoListBean.kt` 关键字段: - `cabinetId` - `cabinetName` - `doorUniqueId` - `cabinetDoorVoList` - `lockNum` 见: - `RuleBean.kt:3-28` ### 用户权限 模型: - `UserValidationBean.kt` 决定: - 是否能登录 - 是否能开门 - 是否可操作管控类/非管控类 - 是否可作为双人认证参与者 ### 基础配置 模型: - `ConfigBean.kt` 关键字段: - `loginType` 登录方式 - `verifyType` 双人验证方式 - `operateTimeout` - `timeoutHour` - `useHour` - `backTime` - `signOutTime` - `offTime` - `vinVex` 称重容差率 见: - `ConfigBean.kt:5-32` ## 7.2 角色权限策略 根据 `ChemicalApp` 与 `UserValidationBean`,系统至少存在两层权限模型: ### 全局业务角色 - 校级管理员 - 院级管理员 - 实验室负责人 - 安全负责人 - 柜锁管理员 - 归属人 - 课题组成员 - 白名单/准入人员 ### 页面级快捷标识 `ChemicalApp` 中维护: - `administrators` - `responsibles` 注释说明: - 管控类化学品:仅校级/院级管理员可操作 - 实验室负责人/安全责任人/柜门管理员:仅能操作非管控 见: - `ChemicalApp.kt:56-59` ## 7.3 柜锁规则 代码中明确: - `unlockingMethod == 2` 表示智能锁 - 只有智能锁才进入轮询开锁状态判断 - 柜门已开/无智能锁时直接进入后续操作 见: - `InquiryActivity.java:95-103` - `UseActivity.kt:209-214` - `ChemicalsAlsoActivity.kt:154-159` - `ChemicalLabelingActivity.kt:165-219` ## 7.4 超时与回退规则 由配置驱动: - 自动返回:`backTime` - 自动注销:`signOutTime` - 弹窗关闭:`offTime` 同时,开锁后若未完成业务就返回,会调用: - `outTimeWarn` 用于记录异常或超时操作。 --- ## 8. 技术实现策略 ## 8.1 UI 与架构策略 ### 技术栈 - Java + Kotlin 混合 - 传统 Activity/Fragment 架构 - ViewBinding - RecyclerView + 自定义 Dialog - RxJava3 + Retrofit 见: - `app/build.gradle:37-45` - `app/build.gradle:85-105` ### 分层方式 - UI 页面:`xn.hxp.ui/**` - 接口仓储:`ApiRepository.kt` - Retrofit 包装:`ChemicalRetrofit.kt` - 原始 HTTP 工具:`HttpTool.java` - 全局状态:`ChemicalApp.kt` 特点: - 业务页面直接通过 `ApiRepository.INSTANCE.xxx()` 调接口 - 某些老流程仍保留 `HttpTool + OkHttpUtils` 直连方式 - 属于“仓储层 + 历史工具共存”的过渡架构 ## 8.2 网络层策略 ### Retrofit 主通路 关键文件: - `ApiService.java` - `ChemicalRetrofit.kt` - `ApiRepository.kt` - `HttpClient.kt` 网络特征: - `ApiService` 统一声明业务接口 - `ChemicalRetrofit` 做响应成功判断与请求体包装 - `ApiRepository` 统一调度线程:IO -> Main - `HttpClient` 负责 OkHttp/Retrofit 创建 ### 统一响应包装 后端返回统一结构: - `code` - `message` - `data` 在 `ChemicalRetrofit.kt` 中统一判断 `isSuccess()`,失败抛 `NetException`。 ### Token 策略 - 登录成功后将 token 写入 `HttpClient.token` - `TokenHeaderInterceptor` 自动加 `authorization` 头 - 解析响应判断 token 是否过期并广播 见: - `ChemicalRetrofit.kt:108-110` - `ChemicalRetrofit.kt:855-856` - `TokenHeaderInterceptor.kt:21-63` ### 旧接口补充通路 `HttpTool.java` 仍承担若干流程: - 启动设备上报 - 获取柜体信息 - 直接入库提交 - 退出登录 - 心跳上报 - 某些旧版双人认证接口 说明项目存在一定历史接口兼容层。 ## 8.3 本地数据策略 ### SharedPreferences 用途: - 服务端基础地址 - 图片地址 - 二维码地址 - 相机方向 - 管理员密码 - 双人认证缓存人员列表 见: - `SharedPreferencesHelper.kt:19-39` - `SharedPreferencesHelper.kt:42-70` ### Room 临时库 主要用于入库计划编排,不是全局核心数据库。 保存内容: - 柜体 - 柜门 - 柜层选择 - 实验室负责人/安全员 - 待入库清单 见: - `ui/plan/room/**` - `PlanAddActivity.java:100-113` ## 8.4 权限与受控终端策略 Manifest 中声明了大量普通权限与高权限: - 网络、存储、录音、摄像头、蓝牙、USB、定位 - `INSTALL_PACKAGES` - `WRITE_SECURE_SETTINGS` - `READ_PRIVILEGED_PHONE_STATE` - `READ_LOGS` - `MANAGE_USB` - `USES_POLICY_FORCE_LOCK` 见: - `AndroidManifest.xml:5-63` 这表明应用运行环境大概率是: - 定制 ROM - 系统签名应用 - 企业/工控专用设备 同时 `Tool.java` 直接调用: - `suExec` - `reboot` - `force-stop` - `pm set-home-activity` - `settings put global bluetooth_on` 见: - `Tool.java:24-99` 说明该 App 不只是普通应用,更像**设备侧受控终端软件**。 ## 8.5 升级与设备监控策略 ### 启动设备上报 - `iot/aio/report` - 获取实验室绑定信息与版本相关信息 ### 心跳 - 主页面每 20 秒调用 `terminal/machine/heartbeat` - 上报设备号、版本、前台展示状态、IP 等信息 见: - `MainActivity.java:194-217` - `HttpTool.java:220-248` ### 安装升级 Manifest 申请了安装权限,并配置 `FileProvider`: - `AndroidManifest.xml:249-262` 接口层也有: - `onepcApkUpdate` 说明系统具备 APK 升级状态回传能力。 --- ## 9. 硬件与外设接入策略 ## 9.1 摄像头 / 人脸识别 ### 方式 - Fotoapparat + FaceDetectorProcessor - ML Kit face detection - ArcSoft 相关 jar/aar 同时存在 依赖与文件: - `app/build.gradle:73, 139` - `app/libs/arcsoft_face.jar` - `app/libs/facedetector-1.0.0.aar` - `TwoVerificationActivity.kt:44-50` ### 用途 - 登录人脸识别 - 双人认证人脸校验 --- ## 9.2 刷卡 / 串口扫码 / 键盘式输入 ### 方式 - `PortScanHelper` 拦截按键流 - `UsbReceiver` 监听 USB 插拔 - `PortScanService` 设计为系统服务形式统一广播扫码结果 见: - `SwipeActivity.kt:118-145` - `InquiryActivity.java:117-137` - `PortScanService.kt:9-67` ### 用途 - 刷卡登录 - 查询页扫码 - 领用/归还/废弃/标签页扫描标签或 RFID 码 --- ## 9.3 蓝牙秤 ### 实现方式 #### 主通路 - `SppTool.java` 使用 Feasycom SPP SDK - 经典蓝牙串口协议 - 解析称重数据字符串 见: - `SppTool.java:16-91` #### 辅助旧实现 - `BluetoothHelper.kt` - 使用 RFCOMM UUID `00001101-0000-1000-8000-00805F9B34FB` 见: - `BluetoothHelper.kt:22-124` ### 用途 - 入库称重 - 领用称重 - 归还称重 ### 配置方式 设置页支持: - 扫描蓝牙设备 - 保存 `sppMac / sppName` 见: - `SettingActivity.java:78-89` ## 9.4 柜门/锁控 ### 方式 后端接口驱动为主: - `getCabinetLock` - `lockOperate` - `getLocks` - `outTimeWarn` 前端负责: - 选定柜门 - 组装上下文(实验室、柜门、开锁人) - 提交开锁请求 - 轮询锁状态 - 超时上报 见: - `ApiService.java:209-248` - `InquiryActivity.java:505-598` - `UseActivity.kt:1140-1318` - `ChemicalsAlsoActivity.kt:1488-1630` - `WasteChemicalsActivity.kt:1237-1368` - `ChemicalLabelingActivity.kt:904-1074` ## 9.5 标签打印 / RFID ### 已引入依赖 - `USBPrintSDK.jar` - `autoreplyprint.aar` - `whdrawlabel1.1.jar` - `sdkapi.jar` 见: - `app/libs/*` ### 业务动作 - 打印化学品标签 - 补打标签 - 更换 RFID - RFID 补打/写入 页面: - `ChemicalLabelingActivity.kt` - `ChemicalsAlsoActivity.kt` - 入库流程中的 `PrintLabelDialog` ## 9.6 WebView / 文档预览 - 使用腾讯 X5 内核 - 用于 MSDS HTML 展示与全屏浏览 见: - `ChemicalApp.kt:142-160` - `MsdsActivity.kt:91-117` --- ## 10. 关键后端接口能力边界 从 `ApiService.java` 可以明确后端提供的能力边界: ### 10.1 认证与身份 - `auth/cardNum` - `chemical/aio/verify/userCardValidation` - `chemical/aio/verify/useCardVerify` - `chemical/aio/verify/aioScanLogin` - `auth/faceByPic` - `chemical/aio/verify/checkUserFaceByPic` - `auth/logout` ### 10.2 实验室与柜体 - `laboratory/subRelInfo/getRelList` - `chemical/aio/getCabinetList` - `chemical/aio/getCabinetBySubId` - `chemical/aio/getCabinetLock` - `chemical/aio/lockOperate` - `chemical/aio/getLockStatus` ### 10.3 化学品主数据 - `chemical/aio/searchChemica` - `system/dict/item/option` - `chemical/aio/searchProducer` - `chemical/aio/searchSpec` - `chemical/aio/controlConfig` ### 10.4 入库与库存 - `chemical/aio/addStock` - `chemical/aio/addStockCheck` - `chemical/aio/getStockWaitDetails` - `chemical/aio/waitList` - `chemical/aio/stockList` - `chemical/aio/indexStockList` - `chemical/aio/tagDetailsList` - `chemical/aio/checkRfid` - `chemical/aio/updateRfid` ### 10.5 领用与归还 - `chemical/aio/byRfid` - `chemical/aio/indexDetailbyRfid` - `chemical/aio/getStockDetailsByCode` - `chemical/aio/addUserecord` - `chemical/aio/useList` - `chemical/aio/backDetail` - `chemical/aio/giveBack` - `chemical/aio/useReturnList` ### 10.6 废弃与处置 - `chemical/aio/discardDetail` - `chemical/aio/stockDetailsList` ### 10.7 台账与预警 - `chemical/aio/useRecords` - `chemical/aio/stockLedger` - `system/aioUnify/warningNoticeList` - `system/aioUnify/warningNoticeDetail` - `system/warningNotice/handleMessage` - `system/aioUnify/warningNoticeCount` - `chemical/aio/outTimeWarn` ### 10.8 MSDS 与配置 - `chemical/aio/msds` - `chemical/aio/msdsDetails` - `chemical/aio/basicConfig` - `system/logo/config/getConfInfo` ### 10.9 设备上报与升级 - `iot/aio/report` - `iot/aio/monitor` - `terminal/machine/heartbeat` - `laboratory/apkfile/onepcApkUpdate/{id}/{state}` --- ## 11. 第三方依赖与本地 SDK 策略 ## 11.1 Maven 依赖 主要依赖包括: - Retrofit 2.11 - OkHttp 4.12 - RxJava3 / RxAndroid - Gson - Glide - EventBus - BRVAH - XXPermissions - DialogX - CameraX - ML Kit Face Detection - FastBle - Fotoapparat - ZXing - XPopup - ANRWatchDog 见: - `app/build.gradle:55-153` ## 11.2 本地 jar/aar/so - `USBPrintSDK.jar` - `arcsoft_face.jar` - `arcsoft_image_util.jar` - `autoreplyprint.aar` - `facedetector-1.0.0.aar` - `feasyblue.jar` - `sdkapi.jar` - `tbs_sdk_v4.3.0.165_20210628_103707.jar` - `whdrawlabel1.1.jar` - `libserial_port_wh.so` - `libfacp.so` - `libota.so` - `libutil.so` 这些依赖说明系统同时整合了: - 打印 - 人脸 - WebView 内核 - 蓝牙串口 - 本地串口 - OTA / 设备能力扩展 --- ## 12. 当前源码体现出的设计特点 ## 12.1 优点 1. 业务域边界比较清晰 - 登录、认证、入库、领用、归还、废弃、查询、台账、MSDS、预警分包明确 2. 终端场景适配明显 - 自动恢复、心跳、管理员入口、设备设置、蓝牙配置、系统权限操作完善 3. 安全流程完整 - 登录权限、双人认证、智能锁、异常上报、预警处理形成闭环 4. 软硬件融合较深 - 柜门、蓝牙秤、标签、扫码、刷卡、人脸不是外挂,而是业务主链路的一部分 ## 12.2 需要注意的实现特征 1. 存在新旧接口栈并存 - `ApiRepository/ChemicalRetrofit` 与 `HttpTool` 并存 2. 全局状态较多依赖 `ChemicalApp` - 业务推进依赖全局单例状态 3. 页面逻辑较重 - 多个 Activity 承载了较多流程、硬件、弹窗和状态管理逻辑 4. 部分二维码地址为硬编码域名 - 例如 `https://labcontrol.nwafu.edu.cn/api/...` - 与 `API_BASE_QC_URL` 并存 --- ## 13. 总结 该仓库对应的是一个典型的**实验室化学品智能管理终端**,不是单纯的库存系统,而是一个把以下能力整合到统一设备端工作流里的应用: - 实验室化学品主数据管理 - 智能柜门/智能锁控制 - 多方式登录与双人认证 - 入库、领用、归还、空瓶、废弃全生命周期管理 - RFID/标签/扫码联动 - 蓝牙称重复核 - 电子台账、MSDS、预警闭环 - 受控终端运维、心跳、升级、异常恢复 从实现角度看,系统采用了**传统 Android 业务页面 + Repository/Retrofit + 一体机设备控制 + 本地临时缓存**的混合架构,强调“现场操作闭环”和“安全合规可追溯”。 如果后续需要继续深入,建议优先沿以下三个方向细读: 1. **领用/归还/废弃页面**:最能体现主业务闭环 2. **双人认证页面**:最能体现安全策略 3. **PlanAdd + Room 临时库**:最能体现入库编排和智能柜协同 --- ## 14. 源码导航版(适合开发接手) 本章节按“从哪里进、看哪些类、每个页面依赖哪些适配器/对话框/接口/模型”的方式整理,适合接手开发时快速建立代码地图。 ## 14.1 启动与全局 ### 1)应用全局入口 - `app/src/main/java/xn/hxp/app/ChemicalApp.kt:32` 建议先看: - 全局状态字段:`userData / subjectId / confs / labInfo / administrators / responsibles` - 初始化组件:`SppTool`、`BleManager`、`DialogX`、`QbSdk` - ANR 恢复策略:`ANRWatchDog` ### 2)启动页 - `app/src/main/java/xn/hxp/ui/StartActivity.java:34` 建议重点看: - `requestPermission()`:设备权限获取方式 - `unreasonableCode()`:本地地址/相机配置恢复 - `initView()`:设备校验与实验室绑定入口 关联类: - `xn.hxp.ui.SettingActivity` - `xn.hxp.utils.SharedPreferencesHelper` - `com.rc.httpcore.client.HttpTool` ### 3)主页 - `app/src/main/java/xn/hxp/ui/MainActivity.java:87` 建议重点看: - `basicConf()`:基础配置拉取 - `basicConfLog()`:登录方式分流 - `getCabinetIn()`:主页柜体轮播 - `getHxpStockWait()`:入库入口分流 - 自动登出 handler 与心跳 timer 关联适配器/弹窗: - `ui/adapter/CabinetBannerAdapter.java` - `weidith/PlanDialog.java` - `weidith/CustomDialog.kt` --- ## 14.2 登录与认证导航 ### 1)刷卡登录 - `app/src/main/java/xn/hxp/ui/login/SwipeActivity.kt:46` 建议先看: - `handleScanEvent()`:刷卡登录 - `authenticationInfo()`:登录后权限校验 依赖: - `receiver/PortScanHelper` - `receiver/UsbReceiver` - `ApiRepository.cardNum` - `ApiRepository.userCardValidation` - `weidith/AuthenticationDialog.kt` ### 2)扫码登录 - `app/src/main/java/xn/hxp/ui/login/ScanLoginActivity.kt` 用途:扫码方式登录或与其它登录方式组合切换。 ### 3)人脸登录 - `app/src/main/java/xn/hxp/ui/login/FaceLoginActivity.java` - `app/src/main/java/xn/hxp/ui/login/FacialCardActivity.kt` 用途:纯人脸登录、人脸+刷卡组合登录。 ### 4)双人认证总控 - `app/src/main/java/xn/hxp/ui/verify/TwoVerificationActivity.kt:64` 这是接手时必须精读的页面,建议重点关注: - `mTag`:当前认证服务于哪个业务场景 - `mVerTyps`:单认证方式 - `mCertificationType`:组合认证方式 - `mDoorId / mChemicalLevel`:认证上下文 - `SharedPreferencesHelper.saveList()`:认证通过后的双人缓存 - `when (mTag)`:不同业务场景的权限分支 当前可确认: - `mTag = 0`:新增入库 - `mTag = 1`:归还/废弃/标签管理等 - `mTag = 2`:待入库 - `mTag = 3`:领用 关键代码点: - `TwoVerificationActivity.kt:127-146` - `TwoVerificationActivity.kt:464` - `TwoVerificationActivity.kt:529-616` - `TwoVerificationActivity.kt:1353-1467` - `TwoVerificationActivity.kt:1658-1848` 关联类: - `ui/DoubleDialogBean` - `weidith/DoublePeopleDialog.kt` - `receiver/PortScanHelper` - `ApiRepository.useCardVerify` - `ApiRepository.aioScanLogin` - `ApiRepository.checkUserFaceByPic` --- ## 14.3 入库线源码导航 ### 1)计划入库页 - `app/src/main/java/xn/hxp/ui/plan/PlanAddActivity.java:59` 建议阅读顺序: 1. `onInit()`:初始化 Room 临时表、页面事件 2. `subAdd` 点击逻辑:决定是否需要先开柜门 3. `intentActivityResultLauncher`:接收手动录入返回 关联 DAO: - `ui/plan/room/dao/HxpCabinetDAO` - `ui/plan/room/dao/HxpDoorDAO` - `ui/plan/room/dao/HxpLayerDAO` - `ui/plan/room/dao/HxpInventoryDAO` - `ui/plan/room/dao/HxpLabDirectorDAO` - `ui/plan/room/dao/HxpLabSafeDAO` ### 2)计划入库辅助类 - `app/src/main/java/xn/hxp/ui/plan/PlanAddActivityHelp.java:53` 建议重点看: - `getLabInfo()`:实验室基础信息 - `getCabinetList()`:柜体/柜门落本地库 - `selectCabinetLayer()`:当前选中柜层 - `updateInventoryUi()`:待入库列表刷新 - `chemicalSearchByCode()`:扫码录入入口 - `startScanEventListener()`:扫码识别兼容逻辑 - `save()`:最终入库提交 该类是“计划入库编排中枢”。 ### 3)手动录入页 - `app/src/main/java/xn/hxp/ui/plan/add/AddActivity.java:58` 建议重点看: - 化学品搜索、CAS 搜索 - 归属人/课题组选择 - 规格、密度、净含量、数量 - 存储到本地待入库清单 ### 4)手动录入辅助类 - `app/src/main/java/xn/hxp/ui/plan/add/AddActivityHelp.java:38` 建议重点看: - `hxpSearch()`:化学品搜索 - `chemicalSearchResult()`:搜索结果回填 - `save(boolean isWeigh)`:录入校验与后续动作总控 - `startBluetoothWeigh()`:蓝牙称重入口 - `qrInit()`:扫码录入后的只读回填模式 ### 5)入库开锁页 - `app/src/main/java/xn/hxp/ui/plan/unlock/UnlockActivity.java` - `app/src/main/java/xn/hxp/ui/plan/unlock/UnlockActivityHelp.java` - `app/src/main/java/xn/hxp/ui/plan/unlock/UnlockAdapter.java` 用途: - 针对待入库清单需要开的智能柜门逐个开锁 - 管理上门/下门开锁状态 - 开锁完成后进入正式保存 ### 6)入库完成页 - `app/src/main/java/xn/hxp/ui/plan/save_list/SaveListActivity.java` 用途:提交完成后的结果展示。 ### 7)已申领未入库页 - `app/src/main/java/xn/hxp/ui/plan/already/AlreadyActivity.java` - `app/src/main/java/xn/hxp/ui/plan/already/AlreadyAdapter.java` 用途:处理“已申领未入库”业务分支。 --- ## 14.4 领用线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/uses/UseActivity.kt:58` 建议阅读顺序: 1. `onInit()`:列表、柜门、返回逻辑 2. `inAdapter()`:左柜/右门选择与认证分流 3. `verifyChecking()`:多认证方式组合 4. `usageLabelDialog()`:开门后的领用工作台 5. `getByRfid()`:按 RFID 查领用对象 6. `weighData()`:称重或录入重量 7. `getStockList()`:领用列表查询 8. `openLock()`:开锁请求 9. `outTimeWarnData()`:异常上报 关键依赖: #### 适配器 - `ui/adapter/CabinetDoorAdapter.kt` - `ui/adapter/CabinetDoorRighAdapter.kt` - `ui/adapter/UseListAdapter.kt` - `ui/adapter/UsageLabelDialogAdapter.java` #### 对话框 - `weidith/UsageLabelDialog.java` - `weidith/WeighDialog.kt` - `weidith/CustomDialog.kt` - `weidith/StorageDialog.kt` #### 相关接口 - `ApiRepository.getStockList` - `ApiRepository.getByRfid` - `ApiRepository.addUseRecord` - `ApiRepository.lockOperate` - `ApiRepository.getLocks` - `ApiRepository.outTimeWarn` #### 关键模型 - `UseBean` - `UsePostDataBean` - `ChemistryBean` - `LockVoListBean` - `TimeWarBean` --- ## 14.5 归还/空瓶/废弃线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/still/ChemicalsAlsoActivity.kt:59` 建议阅读顺序: 1. `onInit()`:页面操作入口 2. `useList()`:待归还列表 3. `handleScanEvent()`:扫码进入详情 4. `verifyChecking()`:归还类双人认证 5. `weighData()`:归还称重 6. `cabinetOpen()` / `openLock()`:开门 7. `updateRfid()`:标签更换 8. `discardDialogShow()` / `emptiesDialogsShow()`:废弃/空瓶 9. `throwableView()`:页面统一异常处理 关键依赖: #### 适配器 - `ui/adapter/ReturningChemicalsAdapter.kt` #### 对话框 - `weidith/DiscardDialog.kt` - `weidith/EmptiesDialog.kt` - `weidith/AirBottleDialog.kt` - `weidith/AirBottleNewDialog.kt` - `weidith/CabinetOpenDialog.kt` - `weidith/StorageDialog.kt` #### 相关接口 - `ApiRepository.useList` - `ApiRepository.backDetail` - `ApiRepository.giveBack` - `ApiRepository.returnGiveBack` - `ApiRepository.updateRfid` - `ApiRepository.lockOperate` - `ApiRepository.getLocks` #### 关键模型 - `ReturningChemicalsBean` - `ReturnDetailsBean` - `ReturnGiveBackBean` - `GiveBackBean` --- ## 14.6 废弃线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/discard/WasteChemicalsActivity.kt:45` 建议阅读顺序: 1. `onInit()`:页面入口与分页 2. `stockDetailsList()`:废弃列表 3. `handleScanEvent()` / `codeDateIn()`:扫描后定位化学品 4. `verifyChecking()`:废弃认证 5. `discardDialogShow()`:废弃原因录入 6. `openLock()`:开门 7. `outTimeWarnData()`:异常退出上报 关键依赖: - `ui/adapter/WasteChemicalsAdapter.kt` - `weidith/DiscardDialog.kt` - `weidith/StorageDialog.kt` - `ApiRepository.stockDetailsList` - `ApiRepository.discardDetail` - `ApiRepository.giveBack` --- ## 14.7 查询线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/inquiry/InquiryActivity.java:69` 建议阅读顺序: 1. `initData()`:登录态/预选柜门处理 2. `fragmentInView()`:查询页签初始化 3. `inAdapter()`:左柜右门联动 4. `getCabinet()`:柜门初始化逻辑 5. `handleScanEvent()`:扫码查询详情 6. `openLock()` / `getLocks()`:查询场景开门 关键依赖: #### Fragment - `ui/fragments/QueryOneFragment.kt` - `ui/fragments/QueryTwoFragment.kt` #### 适配器 - `ui/adapter/CabinetDoorAdapter.kt` - `ui/adapter/CabinetDoorRighAdapter.kt` #### 对话框 - `weidith/PromptDialog.java` - `weidith/ScanCodeDialog.kt` - `weidith/CustomDialog.kt` #### 接口 - `ApiRepository.getCabinetList` - `ApiRepository.indexDetailbyRfid` - `ApiRepository.getStockDetailsByCode` - `ApiRepository.lockOperate` - `ApiRepository.getLocks` --- ## 14.8 标签/RFID 维护线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/warehousing/ChemicalLabelingActivity.kt:43` 建议阅读顺序: 1. `onInit()`:列表、查询、补打、换标 2. `labelingData()`:标签列表查询 3. `getIdDate()` / `upView()`:点击记录加载详情 4. `verifyChecking()`:标签场景认证 5. `updateRfid()`:RFID 更换 6. `openLock()`:按标签定位开柜 关键依赖: #### 适配器 - `ui/adapter/ChemicalLabelingAdapter.kt` - `ui/adapter/CustomSpinnerTwoAdapter.kt` #### 对话框 - `weidith/AirBottleDialog.kt` - `weidith/AirBottleNewDialog.kt` - `weidith/StorageDialog.kt` #### 接口 - `ApiRepository.tagDetailsList` - `ApiRepository.getDetailsById` - `ApiRepository.updateRfid` - `ApiRepository.lockOperate` --- ## 14.9 台账线源码导航 ### 1)电子台账容器页 - `app/src/main/java/xn/hxp/ui/discard/LedgerActivity.kt:28` 职责: - 切换使用台账和库存台账两个 Fragment ### 2)使用台账 - `app/src/main/java/xn/hxp/ui/fragments/UseLedgerFragment.kt:33` 建议重点看: - 柜门过滤 n- 类别过滤 - 级别过滤 - 时间范围过滤 - `getLists()` -> `ApiRepository.useRecords` - `butReturned` -> `ChecklistsActivity` ### 3)库存台账 - `app/src/main/java/xn/hxp/ui/fragments/InventoryIedgerFragment.kt:30` 建议重点看: - 柜门过滤 - 类别过滤 - 级别过滤 - 出库方式过滤:在库/空瓶出库/废弃出库/整瓶领用 - `getLists()` -> `ApiRepository.stockLedger` 关联适配器: - `ui/adapter/UseLedgerAdapter.kt` - `ui/adapter/InventoryAdapter.kt` - `ui/adapter/InventoryListAdapter.kt` --- ## 14.10 预警线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/uses/WarningEventsActivity.kt:33` - `app/src/main/java/xn/hxp/ui/uses/ProcessedActivity.kt` 建议阅读顺序: 1. `warningNoticeCount()`:预警总数 2. `getLists()`:预警分页查询 3. 时间筛选、状态筛选 4. item child click -> `ProcessedActivity` 关键依赖: - `ui/adapter/WarningEventsAdapter.kt` - `ApiRepository.warningNoticeList` - `ApiRepository.warningNoticeCount` - `ApiRepository.warningNoticeDetail` - `ApiRepository.handleMessage` --- ## 14.11 MSDS 线源码导航 ### 核心页面 - `app/src/main/java/xn/hxp/ui/still/MsdsActivity.kt:32` - `app/src/main/java/xn/hxp/ui/still/MsdsScreenActivity.kt` 建议重点看: - `msdsDetails(searchValue)`:查询 - WebView 初始化与 HTML 渲染 - `screen` 按钮跳转全屏页 - MSDS 二维码生成 关联类: - `ui/adapter/MsdsListAdapter.kt` - `com.rc.core.util.WebViewHelper.kt` - `com.rc.core.util.VideoFullScreenWebChromeClient.kt` --- ## 14.12 设置、设备与基础工具导航 ### 1)设置页 - `app/src/main/java/xn/hxp/ui/SettingActivity.java:24` 建议重点看: - 服务地址配置 - 管理员密码配置 - 蓝牙秤配置 - 相机前后置配置 - 系统设置/重启/文件浏览器入口 ### 2)系统控制工具 - `app/src/main/java/xn/hxp/utils/Tool.java:16` 负责: - su 命令执行 - 重启设备 - 重启 App - 打开系统设置/文件浏览器 - 状态栏显示 - 获取设备序列号 ### 3)蓝牙 SPP - `app/src/main/java/xn/hxp/utils/bluetooth/SppTool.java:16` 负责: - 蓝牙秤扫描、连接、收包、断连 - 将字符串称重值回调给业务页 ### 4)称重弹窗 - `app/src/main/java/xn/hxp/weidith/ble/BluetoothWeighDialog.java:40` 建议重点看: - 蓝牙连接建立 - 称重值解析 - 净含量与规格、称重值关系校验 - `HttpTool.addStockCheck()` 的称重校验提交 ### 5)打印工具 - `app/src/main/java/xn/hxp/utils/PrintTool.java:16` 负责: - 打开 USB 打印机 - 根据 `PrintBean` 生成标签图像 - 打印并切纸 ### 6)扫码与 USB 接入 - `app/src/main/java/xn/hxp/receiver/PortScanService.kt:9` - `app/src/main/java/xn/hxp/receiver/UsbReceiver.kt` - `app/src/main/java/xn/hxp/receiver/PortScanHelper*` 负责: - 键盘式扫码输入 - USB 设备接入监听 - 统一分发扫码内容 --- ## 14.13 适配器与对话框总表 ### 常用适配器 - 柜体/柜门:`CabinetDoorAdapter.kt`、`CabinetDoorRighAdapter.kt`、`CabinetBannerAdapter.java` - 领用:`UseListAdapter.kt`、`UsageLabelDialogAdapter.java` - 归还:`ReturningChemicalsAdapter.kt` - 废弃:`WasteChemicalsAdapter.kt` - 标签:`ChemicalLabelingAdapter.kt` - 预警:`WarningEventsAdapter.kt` - 台账:`UseLedgerAdapter.kt`、`InventoryAdapter.kt` - MSDS:`MsdsListAdapter.kt` ### 常用对话框 - 通用提示:`CustomDialog.kt` - 双人认证结果:`DoublePeopleDialog.kt` - 领用工作台:`UsageLabelDialog.java` - 称重:`WeighDialog.kt`、`BluetoothWeighDialog.java` - 柜位选择:`StorageDialog.kt` - 废弃:`DiscardDialog.kt` - 空瓶:`EmptiesDialog.kt` - 标签/RFID:`AirBottleDialog.kt`、`AirBottleNewDialog.kt` - 标签打印确认:`PrintLabelDialog.java` - 化学品选择:`SelectChemicalDialog.java` - 归属人选择:`BelongingPersonDialog.kt` - 课题组选择:`SelectTopicDialog.kt` - 查询结果:`PromptDialog.java`、`ScanCodeDialog.kt` - 蓝牙秤设备选择:`BleSelectorDialog.java` --- ## 14.14 接手开发建议阅读顺序 如果是第一次接手这个项目,建议按下面顺序看源码: 1. `ChemicalApp.kt`、`StartActivity.java`、`MainActivity.java` 2. `ConfigBean.kt`、`UserValidationBean.kt`、`RuleBean.kt` 3. `ApiService.java`、`ChemicalRetrofit.kt`、`ApiRepository.kt` 4. `TwoVerificationActivity.kt` 5. `UseActivity.kt` 6. `ChemicalsAlsoActivity.kt` 7. `WasteChemicalsActivity.kt` 8. `PlanAddActivity.java` + `PlanAddActivityHelp.java` 9. `AddActivity.java` + `AddActivityHelp.java` 10. `ChemicalLabelingActivity.kt` 11. `InquiryActivity.java` 12. `LedgerActivity.kt` + 两个台账 Fragment 13. `WarningEventsActivity.kt`、`MsdsActivity.kt` 14. `Tool.java`、`SppTool.java`、`BluetoothWeighDialog.java`、`PrintTool.java` 如果目的是修业务 Bug,优先看对应页面 + 认证页 + 开锁逻辑; 如果目的是重构,优先梳理 `ApiRepository / HttpTool / ChemicalApp` 三条主线。