Files
MobileModels/README.md
T
2026-04-14 18:43:19 +08:00

536 lines
13 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.
# 项目使用文档
## 1. 文档概览
### 1.1 文档目标
这份文档用于说明 MobileModels 的使用方式、数据接入方式、维护方式和排查方式。文档不再按“项目说明 / 使用说明 / 数据库说明”拆开,而是整理成一份统一文档,方便不同角色在同一份上下文里完成阅读。
### 1.2 适用角色
- 产品或业务使用者:需要查设备、看字段、理解页面入口
- 数据维护者:需要维护品牌、来源排序、同步数据、刷新索引
- 服务端接入方:需要接 MySQL、按统一规则查询设备数据
- 运维维护者:需要启动服务、检查配置、处理运行问题
### 1.3 建议阅读路径
- 只想先跑起来:先看 `2. 快速开始`
- 只想用页面:先看 `3. 页面使用`
- 只想接数据库:先看 `4. 数据接入`
- 负责维护和发布:重点看 `5. 数据维护``6. 配置与运行``7. 排查指南`
## 2. 快速开始
### 2.1 项目提供什么
MobileModels 将下面几类能力放在一个项目里统一交付:
- 设备查询页面
- 数据管理页面
- 文档查看页面
- 设备索引构建
- MySQL schema 与 seed 生成
- 原始数据同步与自动调度
使用时不需要分别启动多个服务,默认通过 Docker Compose 统一运行。
### 2.2 启动服务
在项目根目录执行:
```bash
docker compose up --build -d
```
如果需要同时启动本地测试 MySQL:
```bash
docker compose -f docker-compose.yml -f docker-compose.test.yml up --build -d
```
如果需要覆盖默认环境变量:
```bash
cp .env.example .env
```
### 2.3 页面入口
- `设备查询``http://127.0.0.1:8123/web/device_query.html`
- `数据管理``http://127.0.0.1:8123/web/brand_management.html`
- `使用文档``http://127.0.0.1:8123/web/device_query.html?view=docs`
### 2.4 停止与重置
停止服务:
```bash
docker compose down
```
清空运行期数据:
```bash
docker compose down -v
```
### 2.5 启动后会自动完成什么
默认启动后会按配置完成以下动作:
1. 加载原始数据工作区
2. 构建设备索引
3. 生成 `dist/device_index.json`
4. 生成 `dist/mobilemodels_mysql_seed.sql`
5. 按配置决定是否自动装载 MySQL
6. 启动 Web 页面与 API
7. 启动项目内部的自动同步调度
## 3. 页面使用
### 3.1 页面结构
项目包含两个主页面和一个文档入口:
- `设备查询`:面向日常查询、联调、设备归类
- `数据管理`:面向品牌维护、来源维护、同步维护、索引维护
- `使用文档`:面向统一查看项目使用文档
### 3.2 设备查询页
设备查询页分为三个 tab。
#### 设备标识
适用输入:
- Android 原始标识,如 `SM-G9980`
- iOS 原始标识,如 `iPhone14,2`
- HarmonyOS 原始标识,如 `NOH-AL00`
适合场景:
- 设备管理
- 登录设备展示
- 服务端设备归类
- 客户端上报值排查
结果字段使用方式:
- 设备名称:`device_name`
- 品牌展示:优先 `market_brand`,为空再取 `brand`
- 厂商归属:优先 `parent_brand`,为空再取 `manufacturer_brand`
- 设备类型:`device_type`
不建议直接用作主展示的字段:
- `alias_norm`
- `source_file`
- `source_rank`
- `source_weight`
- `code`
- `code_alias`
- `ver_name`
#### 设备名称
适用输入:
- `iPad mini 7`
- `iPhone SE 3`
- 其他人工可读设备名称
查询行为:
1. 先尝试设备名称别名映射
2. 未命中时再查 `device_name` / `ver_name`
适合场景:
- 运营核对
- 人工排查
- 已知设备名但不知道原始标识
#### 标识索引
适用输入:
- 设备标识
- 常见设备名称
适合场景:
- 联调
- 索引识别结果比对
- 与 MySQL 查询结果做交叉验证
### 3.3 数据管理页
数据管理页按左侧导航分为五部分。
#### 品牌列表
这里维护:
- 品牌数、厂商数
- 品牌列表
- 品牌与厂商关系
- 品牌同义词
适用场景:
- 品牌口径调整
- 厂商归属调整
- 品牌展示不符合预期时排查
#### 手动补录
这里维护本地覆盖库。
这里可做的事:
- 新增独立品牌
- 在品牌下补录设备
- 编辑或删除本地补录记录
适用场景:
- 上游暂未收录的新品牌
- 学习机、教育终端、定制设备
- 需要立即参与页面查询和 MySQL 查询的补录数据
使用说明:
1. 品牌先建在本地覆盖库
2. 设备标识填客户端真实上报值
3. 保存后自动重建索引和 MySQL seed
4. 如果开启 MySQL 自动装载,会继续自动刷新 MySQL
5. 本地覆盖库不会被“原始数据同步”覆盖
#### 数据来源
这里维护来源优先级。
使用方式:
1. 直接拖拽来源顺序
2. 越靠前优先级越高
3. 保存后影响结果排序
适用场景:
- 多来源结果排序不符合预期
- 新来源加入后需要重新排序
#### 原始数据同步
这里维护:
- MySQL 自动装载开关
- 外部 MySQL 初始化
- 每日自动同步时间
- 同步状态与任务日志
适用场景:
- 上游数据更新后刷新本地数据
- 外部 MySQL 需要重建
- 调整自动同步策略
#### 索引数据
这里用于查看当前索引状态并手动重新加载。
适用场景:
- 同步完成后确认索引是否已生效
- 页面结果与预期不一致时检查索引版本
### 3.4 页面调试建议
如果页面查询结果异常,建议按下面顺序判断:
1. 先看输入值是否符合页面预期
2. 再看页面中的调试信息
3. 再看返回 JSON 是否包含预期字段
4. 再检查索引或 MySQL 数据是否已刷新
## 4. 数据接入
### 4.1 推荐查询入口
推荐统一查询下面这张主表:
```sql
mobilemodels.mm_device_catalog
```
这张表已经整合了设备标识、设备名称、品牌、厂商、来源和归一化结果。业务侧如果需要查设备信息,优先直接使用这张表,而不是自己拼接多张表或从页面逻辑反推字段。
### 4.2 推荐查询方式
主用方式是按 `alias_norm` 等值查询。
推荐 SQL
```sql
SELECT
model,
record_id,
alias_norm,
device_name,
brand,
manufacturer_brand,
parent_brand,
market_brand,
device_type,
source_file,
section,
source_rank,
source_weight,
code,
code_alias,
ver_name
FROM mobilemodels.mm_device_catalog
WHERE alias_norm = ?
ORDER BY source_rank ASC, record_id ASC
LIMIT 20;
```
### 4.3 为什么主推 `alias_norm`
客户端上报的原始 `model_raw` 可能包含大小写、横线、空格、下划线、逗号等差异。为了让相同设备尽可能稳定命中,项目统一把输入值归一化到 `alias_norm`,然后按 `alias_norm` 查询主表。
这也是页面查询与数据库查询保持一致的关键。
### 4.4 查询前归一化规则
归一化规则如下:
- 先转小写
- 只保留数字、英文字母、中文
- 去掉空格、横线、下划线、逗号及其他标点
正则示例:
```text
/[^0-9a-z\u4e00-\u9fff]+/g
```
JavaScript 示例:
```js
text.toLowerCase().replace(/[^0-9a-z\u4e00-\u9fff]+/g, "")
```
样例:
```text
SM-G9980 -> smg9980
iPhone14,2 -> iphone142
NOH-AL00 -> nohal00
```
### 4.5 结果字段使用建议
面向设备管理场景,推荐按下面顺序取值:
- 设备名称:`device_name`
- 品牌展示:优先 `market_brand`,为空再取 `brand`
- 厂商归属:优先 `parent_brand`,为空再取 `manufacturer_brand`
- 设备类型:`device_type`
下面这些字段通常用于排查、排序或扩展匹配,不建议直接作为主展示字段:
- `alias_norm`
- `source_file`
- `source_rank`
- `source_weight`
- `code`
- `code_alias`
- `ver_name`
### 4.6 页面查询与数据库查询的关系
页面里的 `设备标识` 查询和 `设备名称` 查询,底层都依赖这张主表。因此:
- 页面结果和第三方直接查库结果应该保持同一口径
- 页面里的归一化规则应与服务端或业务接入侧保持一致
- 如果页面显示异常,先核对主表数据,再核对前端展示逻辑
## 5. 数据维护
### 5.1 数据来源
项目的数据来源分为两部分:
- 上游原始数据:`workspace/brands/*.md`
- 本地覆盖库:`workspace/local/manual_catalog.json`
上游原始数据用于同步官方或社区维护的数据,本地覆盖库用于补录当前业务需要但上游暂未收录的品牌和设备。
### 5.2 数据生成链路
完整链路如下:
1. 同步上游原始 markdown
2. 解析 `workspace/brands/*.md`
3. 合并 `workspace/local/manual_catalog.json`
4. 构建 `dist/device_index.json`
5. 导出 `dist/mobilemodels_mysql_seed.sql`
6. 按配置决定是否自动装载 MySQL
### 5.3 关键产物
- 索引文件:`dist/device_index.json`
- MySQL seed`dist/mobilemodels_mysql_seed.sql`
### 5.4 常见维护动作
#### 刷新原始数据
适用于上游数据已变化,需要重新生成索引和 MySQL 数据。
#### 调整品牌关系
适用于品牌展示或厂商归属不符合预期的情况。
#### 手动补录品牌或设备
适用于上游未收录,但业务需要立即支持的设备。
维护方式:
1.`数据管理 -> 手动补录` 中新增品牌或设备
2. 保存后自动刷新索引与 MySQL seed
3. 如关闭了 MySQL 自动装载,需按需手动初始化或刷新外部 MySQL
说明:
- 本地覆盖库不会被上游同步覆盖
- 本地补录来源默认优先级更高
- 适合维护学习机、教育设备、定制终端
#### 调整来源顺序
适用于多个来源的优先级需要重新定义的情况。
#### 重新加载索引
适用于索引已更新,但页面还没有使用到最新索引的情况。
## 6. 配置与运行
### 6.1 目录说明
```text
workspace/ 上游原始数据与补充资料
dist/ 索引产物与 MySQL seed
docs/ 文档入口与兼容说明
sql/ MySQL schema
tools/ 构建、同步、导入、服务脚本
web/ 页面与静态资源
```
### 6.2 常见环境变量
- `MYSQL_HOST`
- `MYSQL_PORT`
- `MYSQL_DATABASE`
- `MYSQL_ROOT_USER`
- `MYSQL_ROOT_PASSWORD`
- `MYSQL_READER_USER`
- `MYSQL_READER_PASSWORD`
- `MYSQL_AUTO_LOAD`
- `SYNC_SCHEDULE_ENABLED`
- `SYNC_SCHEDULE_TIME`
- `GITHUB_PROXY_PREFIX`
- `TZ`
### 6.3 运行期配置落盘位置
- MySQL 自动装载:`/data/state/mysql_settings.json`
- 自动同步计划:`/data/state/sync_schedule.json`
### 6.4 运行约定
- Compose 会优先读取 shell 环境变量和项目根目录 `.env`
- 容器启动后会完成索引构建、服务启动,以及按配置决定是否自动装载 MySQL
- 自动同步运行在项目容器内部,不依赖 GitHub Actions
- 生产环境应替换默认数据库密码
### 6.5 MySQL 使用建议
- 生产环境不要继续使用默认密码
- 如果接外部 MySQL,先确认 root 账号具备建库建表权限
- 如关闭自动装载,需通过数据管理页手动初始化外部 MySQL
## 7. 排查指南
### 7.1 查不到设备标识
按下面顺序排查:
1. 确认输入的是客户端原始 `model_raw`
2. 确认归一化结果是否符合规则
3. 查看 `设备标识` 页调试信息和返回 JSON
4. 检查主表里是否存在对应 `alias_norm`
### 7.2 品牌或厂商归属不对
建议排查:
1. 查看 `数据管理 -> 品牌列表`
2. 核对 `market_brand``parent_brand`
3. 确认是否存在品牌同义词或父级归属未维护的情况
### 7.3 结果排序不符合预期
建议排查:
1. 查看 `数据管理 -> 数据来源`
2. 核对 `source_rank`
3. 确认结果是否来自预期来源文件
### 7.4 MySQL 没有刷新
建议排查:
1. 查看 `数据管理 -> 原始数据同步`
2. 检查 MySQL 自动装载开关
3. 查看同步状态与任务日志
4. 必要时手动初始化外部 MySQL
### 7.5 索引结果不对
建议排查:
1. 查看 `数据管理 -> 索引数据`
2. 检查 `dist/device_index.json` 是否已更新
3. 确认页面是否已经重新加载了最新索引
## 8. 常见问题
### 8.1 为什么页面结果和数据库结果不一致
优先检查以下两点:
- 页面是否使用了最新索引
- 数据库是否使用了最新 seed 数据
如果索引和 MySQL 数据版本不一致,页面和数据库查询结果就可能不同步。
### 8.2 为什么品牌字段有多个
项目同时保留原始品牌、展示品牌和父级厂商字段,是为了兼顾原始数据保留、业务展示口径和厂商归属口径。业务展示通常取 `market_brand`,厂商归属通常取 `parent_brand`
### 8.3 什么时候用设备名称查询,什么时候用设备标识查询
- 主流程、服务端接入、设备管理:优先用设备标识查询
- 人工排查、运营核对、设备名反查:用设备名称查询
### 8.4 什么时候需要手动初始化外部 MySQL
当你使用的是外部 MySQL,且关闭了自动装载,或者数据库结构和数据需要重新初始化时,需要在数据管理页里手动执行初始化。