根据 project.md,这个 App 的核心不是电商展示,而是一个偏离线、偏仓储的小型物料管理工具,首期重点是:
- 扫描立创二维码完成入库。
- 根据二维码中的
pc编号或用户输入的关键词,到立创商城检索器件信息。 - 将器件基础信息、数量、库位等数据保存到本地。
- 支持本地库存搜索。
- 支持 CSV 导入导出。
因此技术路线应该优先保证以下几点:
- 本地离线可用。
- 结构化数据可检索、可更新、可导出。
- 后续能平滑增加批次、流水、盘点、同步等能力。
- 尽量贴合当前原生 Android Kotlin 工程,不引入过重的跨端方案。
- 平台:Android 原生
- 语言:Kotlin
- UI:Jetpack Compose + Material 3
- 架构:MVVM + Repository
- 异步:Kotlin Coroutines + Flow
- 依赖注入:Hilt
- 本地数据库:Room + SQLite
- 轻量配置存储:DataStore
- 条码扫描:CameraX + ML Kit Barcode Scanning
- 网络访问:Retrofit + OkHttp
- HTML 解析兜底:Jsoup
- 序列化:kotlinx.serialization
- CSV 导入导出:Apache Commons CSV 或等价 Kotlin CSV 库
当前仓库已经是标准 Android Kotlin + Compose 工程,继续沿用原生技术栈成本最低。这个项目的数据以“器件主数据 + 库存记录 + 入库流水 + 库位”这类结构化关系数据为主,明显更适合关系型本地存储,而不是文档型或 KV 型存储。
本地数据库建议使用:Room + SQLite
轻量配置建议使用:DataStore
-
数据模型天然是关系型。 器件信息、库存记录、库位、入库流水、导入批次之间存在明确关联,适合表结构和外键约束。
-
查询能力足够强。 需要按料号、名称、封装、库位、品牌、批次做组合查询,SQLite 非常适合这类条件过滤、排序、分页和聚合统计。
-
Android 官方生态最稳。 Room 是 Android 官方推荐方案,和 Kotlin、Flow、协程、分页、迁移、测试都能自然配合。
-
后续扩展成本低。 未来如果增加盘点、库存调整、出入库流水、低库存预警、全文搜索,SQLite 仍然能承接,不需要中途换库。
-
导入导出更直接。 CSV 导入、本地备份、字段映射、数据迁移都更容易做,调试也更透明。
-
不建议只用
DataStoreDataStore 适合保存用户设置、最近搜索条件、默认仓库等轻量配置,不适合库存明细这种可筛选、可关联、可批量更新的数据。 -
不建议直接裸用
SQLiteOpenHelper虽然可行,但 SQL、迁移、实体映射、线程处理都要手工维护,开发和维护成本明显高于 Room。 -
不建议首期使用 Realm/ObjectBox 一类第三方对象数据库 这类库上手可能快,但对本项目没有决定性收益,反而会增加生态依赖、迁移心智负担和后续可控性风险。
-
Room负责库存核心业务数据。 -
Proto DataStore负责设置项,例如默认仓库、默认搜索方式、最近导出路径、UI 偏好。 -
如后续需要更强搜索能力 优先在 SQLite 上增加索引,必要时使用 SQLite FTS5 做本地全文检索,而不是单独引入另一套搜索数据库。
建议先保持单 app 模块,按包分层;功能稳定后再考虑拆模块。
app/src/main/java/com/example/lcsc_android_erp/
core/
common/
network/
database/
datastore/
data/
repository/
remote/
local/
mapper/
domain/
model/
usecase/
feature/
inbound/
search/
inventory/
importexport/
settings/
ui/
theme/
component/
-
feature页面、ViewModel、UI 状态管理。 -
domain业务模型和用例,例如扫码入库、按料号搜索、CSV 导入匹配。 -
dataRepository 聚合本地库、远程接口、HTML 抓取等数据源。 -
core通用基础设施,例如数据库、网络、日志、配置。
器件主数据表,保存从立创获取到的标准器件信息。
建议字段:
idpart_number对应pc,如C17710mpnnamebrandpackage_namecategoryspec_jsondescriptionsource_urlupdated_at
库位表。
建议字段:
idcode如A1、C13remarkcreated_at
当前库存表,表示某个器件在某个库位上的现存量。
建议字段:
idcomponent_idlocation_idquantitylast_inbound_atupdated_at
建议唯一索引:
component_id + location_id
库存流水表,记录每次入库、调整、导入。
建议字段:
idcomponent_idlocation_idtxn_type如INBOUND、ADJUST、IMPORTquantity_deltasource_type如QRCODE、MANUAL、CSVsource_refraw_payloadcreated_at
CSV 导入批次表,便于回溯导入来源和错误处理。
建议字段:
idfile_namestatustotal_countsuccess_countfailed_countcreated_at
- 一个
component_master可以对应多个inventory_item - 一个
storage_location可以对应多个inventory_item - 每次库存变化都写入
inventory_txn inventory_item是当前态,inventory_txn是历史态
这个模型后续扩展出库、盘点、回滚都比较顺。
采用“接口优先,HTML 解析兜底”的双层方案:
- 优先调研立创是否存在稳定、可公开访问的搜索接口。
- 如果没有稳定接口,再使用搜索页和详情页 HTML 解析。
- 所有远端返回统一映射为内部
ComponentDetail模型。
- 网络层:Retrofit + OkHttp
- 如果返回 JSON:
kotlinx.serialization - 如果只能抓页面:
Jsoup - Repository 对上层屏蔽“接口/HTML”差异
立创网页结构未来可能变化,因此不能把页面字段结构直接散落在 UI 层。应集中封装在 remote 和 mapper 层,保证后续只改一处。
- CameraX 打开相机预览。
- ML Kit 识别二维码。
- 解析原始内容,如:
{on:SO2507139288,pc:C17710,pm:0805W8F4700T5E,qty:100,mc:,cc:1,pdi:166537429,hp:11}
- 提取
pc、pm、qty等字段。 - 根据
pc拉取器件详情。 - 用户确认数量、库位后提交入库。
- 写入
inventory_txn,同步更新inventory_item。
不要直接依赖字符串切分硬编码到页面中,建议单独提供 QrPayloadParser,输出稳定的数据结构:
data class InboundQrPayload(
val orderNo: String?,
val partNumber: String,
val manufacturerPartNo: String?,
val quantity: Int,
val rawText: String
)- 用户输入关键字或料号。
- 请求立创搜索结果。
- 用户选择具体器件。
- 输入数量和库位。
- 提交入库。
支持以下搜索维度:
- 料号
C17710 - 型号/MPN
- 名称
- 品牌
- 封装
- 库位
数据库层应优先加索引:
component_master.part_numbercomponent_master.mpncomponent_master.brandcomponent_master.package_namestorage_location.code
推荐导入流程:
- 使用 Android Storage Access Framework 选择文件。
- 解析 CSV。
- 进行字段映射与格式校验。
- 先写入
import_batch和临时内存结果。 - 校验通过后再事务性写入
inventory_txn和inventory_item。 - 输出失败行和失败原因。
推荐导出内容:
- 当前库存表
- 器件主数据表
- 库存流水表
导出格式建议首期统一为 UTF-8 CSV,后续再补 Excel。
目标:把工程从模板项目变成可扩展业务项目。
建议完成:
- 引入 Hilt、Room、DataStore、Retrofit、OkHttp、CameraX、ML Kit
- 建立分层目录
- 定义数据库实体、DAO、Repository 接口
- 建立首页导航与基础状态管理
目标:完成最核心的“扫码 -> 拉取器件 -> 选择库位 -> 入库”。
建议完成:
- 二维码扫描页
- 二维码解析器
- 器件详情拉取
- 入库确认页
- 写入库存和流水
目标:没有二维码时也能完成入库。
建议完成:
- 搜索页
- 搜索结果列表
- 器件选择和入库确认
目标:把“能录入”升级成“能管理”。
建议完成:
- 库存列表
- 条件筛选
- 库位维度查看
- 库存详情页
- 库存调整记录
目标:和外部表格工作流打通。
建议完成:
- CSV 模板定义
- 导入校验
- 失败报告
- 当前库存导出
- 流水导出
目标:为后续长期使用做准备。
建议完成:
- Room Migration
- 网络失败重试
- 离线缓存策略
- UI 测试与 Repository 测试
- 日志与错误上报
建议新增以下依赖方向:
androidx.roomandroidx.datastoreandroidx.hiltcom.google.dagger:hilt-androidandroidx.cameracom.google.mlkit:barcode-scanningcom.squareup.retrofit2com.squareup.okhttp3org.jsoup:jsouporg.jetbrains.kotlinx:kotlinx-serialization-json
至少应覆盖以下测试:
- 二维码解析单元测试
- 器件搜索结果映射测试
- Room DAO 测试
- 入库流程 ViewModel 测试
- CSV 导入解析测试
重点不是追求测试数量,而是先锁住最容易出错的规则解析和库存写入逻辑。
这个项目建议采用以下明确路线:
- 继续使用当前
Android + Kotlin + Compose原生方案 - 架构采用
MVVM + Repository - 本地业务数据库采用
Room + SQLite - 轻量设置存储采用
DataStore - 扫码采用
CameraX + ML Kit - 远程检索采用
Retrofit + OkHttp,必要时用Jsoup兜底解析页面
其中,本地存储数据库的结论不要摇摆,首选就是 Room + SQLite。这套方案最符合该项目“离线库存管理 + 结构化检索 + CSV 导入导出 + 后续可扩展流水”的核心需求。