# 机器人管理 — 业务使用指南

> **module**: robot-manager
> **doc_type**: UserGuide
> **status**: Active
> **owner**: FFOA Team
> **audience**: 业务方（销售/供应链/财务/售后/管理员）+ 工程师
> **last_verified**: 2026-04-18

---

## 目录

1. [系统概览](#1-系统概览)
2. [角色与职责](#2-角色与职责)
3. [Part 1 — 初始化与基础数据维护](#3-part-1--初始化与基础数据维护)
4. [Part 2 — 机器人生命周期（核心业务）](#4-part-2--机器人生命周期核心业务)
5. [Part 3 — 监控分析与日常操作](#5-part-3--监控分析与日常操作)
6. [常见问题（FAQ）](#6-常见问题-faq)

---

## 1. 系统概览

机器人管理模块以**单台机器人（RobotUnit）为核心**，管理从采购下单到交付维修的全生命周期。

**核心对象**：
- **RobotUnit**：一台具体的机器人，有唯一 FFSN 序列号，带 10 个状态
- **业务实体**：Model（型号）、SKU、Supplier（供应商）、Customer（客户）、Location（位置）
- **动态字段**：所有业务字段（采购价、销售价、合同状态、保修状态等）通过 `FieldDef` 配置，业务方可自助增删

**设计原则**：
- 骨架 + 动态（字段可配置，不需要工程师改代码）
- 状态机驱动（每个阶段有 Guard 校验 + 自动副作用）
- 字段级权限（每个 section 单独授权）

---

## 2. 角色与职责

本模块定义了 **5 个角色**，code 全部以 `RobotManager` 为前缀（`Administrator` 是全局角色，不加前缀）。

| Code | 名称 | 业务定位 |
|------|------|---------|
| `Administrator` | 系统管理员 | 全局权限，跨模块 |
| `RobotManagerRLE` | 机器人全生命周期工程师 | 对机器人全链路负责，可做所有操作 |
| `RobotManagerSupplyChain` | 供应链 | 采购下单、进口清关、收货入库 |
| `RobotManagerSales` | 销售 | 客户绑定、合同签订、交付跟进 |
| `RobotManagerFinance` | 财务 | 成本核算、发票、回款 |

### 2.1 权限矩阵

| 能力 | Administrator | RLE | SupplyChain | Sales | Finance |
|------|---------------|-----|-------------|-------|---------|
| 查看设备列表/详情 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 新建设备 | ✅ | ✅ | ✅ | — | — |
| 全量编辑 | ✅ | ✅ | — | — | — |
| 软删除 | ✅ | ✅ | — | — | — |
| 状态变更 | ✅ | ✅ | ✅ | ✅ | — |
| 编辑身份信息（identity） | ✅ | ✅ | ✅ | — | — |
| 编辑供应链（supply-chain） | ✅ | ✅ | ✅ | — | — |
| 编辑销售（sales） | ✅ | ✅ | — | ✅ | — |
| 编辑财务（finance） | ✅ | ✅ | — | — | ✅ |
| 编辑售后（after-sales） | ✅ | ✅ | — | — | — |
| 编辑合规（compliance） | ✅ | ✅ | — | — | — |
| Excel 导入 | ✅ | ✅ | ✅ | — | — |
| Excel 导出 | ✅ | ✅ | ✅ | ✅ | ✅ |
| 管理字段定义 / 系统配置 | ✅ | ✅ | — | — | — |
| 管理型号 / SKU | ✅ | ✅ | — | — | — |
| 管理供应商 | ✅ | ✅ | ✅ | — | — |
| 管理客户 | ✅ | ✅ | — | ✅ | — |
| 管理位置 | ✅ | ✅ | ✅ | ✅ | — |

**权限命名规则**：
- `write:{section}` — 字段级编辑（section 指 identity/supply-chain/sales/finance/after-sales/compliance）
- `manage:{entity}` — 基础数据管理（entity 指 fields/models/suppliers/customers/locations）
- `read` — 全局读权限，所有角色拥有

---

## 3. Part 1 — 初始化与基础数据维护

机器人生命周期运作前，系统需要准备好**基础数据**。按"谁最懂就谁维护"的原则，不同基础数据由不同角色维护：

| 基础数据 | 维护责任人 | 权限码 |
|---------|----------|--------|
| 字段定义 / 系统字典 / 系统配置 | Admin / RLE | `manage:fields` |
| 型号 / SKU | Admin / RLE | `manage:models` |
| **供应商** | **SupplyChain** + Admin / RLE | `manage:suppliers` |
| **客户** | **Sales** + Admin / RLE | `manage:customers` |
| 位置（仓库/保税） | SupplyChain + Admin / RLE | `manage:locations` |
| 位置（客户站点） | Sales + Admin / RLE | `manage:locations` |

基础数据的层级依赖关系：

```
系统配置（FFSN 规则 / 默认位置 / 货币）
    │
    ├─ 字段定义（决定机器人能填哪些字段）
    │    └─ 系统字典（服务类型 / 位置类型）
    │
    └─ 基础数据
         ├─ 型号 Model
         │    └─ SKU（挂在 Model 下）
         ├─ 供应商 Supplier
         ├─ 客户 Customer
         │    └─ 位置 Location（可选绑定到 Customer）
         └─ 位置 Location
```

### 3.1 系统设置

| 项 | 入口 | 内容 | 频率 |
|---|---|---|---|
| FFSN 生成规则 | 管理 → 系统配置 | 前缀（FF）、日期格式（YYYYMM）、序号长度（5）、重置周期（每月） | 首次配置，极少改 |
| 状态默认位置 | 管理 → 系统配置 | 每个状态对应的默认 location.code（如 IN_STOCK → HQ_FZ） | 首次配置 + 新增位置时调整 |
| 默认货币 | 字段定义 → currency 字段 → defaultValue | 新建设备的默认货币（USD） | 按公司主要业务调整 |
| 维修自动服务类型 | 管理 → 系统配置 → repair_auto_service_type | 进 REPAIR 状态时自动创建的 ServiceRecord 类型 | 可选调整 |

### 3.2 字段定义（Admin 自助）

| 场景 | 操作 |
|---|---|
| 新增业务字段（如"发货箱号"） | 管理 → 字段定义 → 自定义字段 Tab → 新建 → 选 type/group/是否必填 |
| 修改字段默认值 | 字段详情 → Default Value |
| 修改下拉选项 | 字段详情 → Options 编辑器 → 增删行 |
| 停用字段（不删，保留历史数据） | 字段详情 → 关闭 enabled |
| 管理系统字典（服务类型 / 位置类型） | 字段定义 → 系统字段 Tab → 选择对应字典 → 编辑 Options |

**重点**：字段是**动态的**，业务方不需要找工程师加字段。但 key（code）**自动生成**，业务方只填中英文 label 即可。

### 3.3 型号 Model + SKU 管理

| 操作 | 入口 | 要点 |
|---|---|---|
| 新建型号 | 基础数据 → 型号管理 → 新建 | 填 code（如 `TITAN`）+ 中英文名 + 品牌 |
| 新建 SKU | 基础数据 → SKU 管理 → 新建 | 必须关联 Model；填 variant（如 `Standard`）+ 默认采购价/销售价 |
| 停用旧型号 | 型号详情 → enabled 关闭 | 不删除，保持历史机器人数据引用完整 |
| 查看下游机器人数量 | 列表页 `_count.robotUnits` 字段 | 决定能否安全停用 |

### 3.4 供应商维护（**由 SupplyChain 自助**）

供应链团队最懂自己打交道的供应商，权限下放到 SupplyChain 角色，不再依赖 Admin。

| 操作 | 要点 |
|---|---|
| 新建供应商 | 填 code（自动生成可留空）、中英文名、联系方式、付款条款（paymentTerms）、预计交期（leadTimeDays） |
| 维护联系方式 | contactName / contactPhone / contactEmail — 供应链用于沟通采购 |
| 停用供应商 | 不删除，旧机器人仍能显示原供应商；新建时不再出现在下拉 |

### 3.5 客户维护（**由 Sales 自助**）

销售团队直接对接客户，维护客户档案和站点 Location 的权限下放到 Sales 角色。

| 操作 | 要点 |
|---|---|
| 新建客户 | 填 code、中英文名、行业、信用额度（creditLimit） |
| 关联位置 | 客户详情 → 位置管理 → 新建 → 选 typeCode='CUSTOMER_SITE' + 关联该客户 |
| 维护多个客户站点 | 同一客户可有多个 Location（总部 / 分公司 / 不同项目现场） |

### 3.6 位置维护

| 类型（typeCode） | 典型用途 |
|---|---|
| INTERNAL | 内部仓库（HQ_FZ 等） |
| CUSTOMER_SITE | 客户站点 |
| SUPPLIER | 供应商处（采购中） |
| BONDED | 保税区 |
| THIRD_PARTY | 第三方寄存 |

**系统默认位置映射**（system_config.status_default_location）：
- IN_STOCK → HQ_FZ
- RESERVED → HQ_FZ
- SOLD → HQ_FZ（已售未发）
- REPAIR / REPAIRED → HQ_FZ（返厂维修）
- DELIVERED → null（由 Sales 显式指定客户站点）

---

## 4. Part 2 — 机器人生命周期（核心业务）

> 这是**日常高频**的业务操作。基础数据准备好后，所有人都在这里工作。

### 4.1 机器人状态全览

机器人的 10 个状态贯穿采购到维修的完整链路。每个阶段都有**明确的责任人和交接点**。

### 4.2 单台新建全链路

#### 阶段 1：采购下单（Ordered）

| 项 | 详情 |
|---|---|
| **状态** | `ORDERED` |
| **责任人** | SupplyChain / RLE |
| **操作** | 新建设备 → 选择 Model + SKU + Supplier → 填 PO 号、采购日期、采购价、ETA |
| **Guard** | 必填 modelId、skuId |
| **下一步** | → IN_TRANSIT（供应商发货）<br>→ CANCELLED（取消采购，必须填 remark） |

**截止前必须填**：
- `poNumber`（采购订单号，设后不可改）
- `purchasePrice`
- `eta`（预计到货日期）

#### 阶段 2：在途运输（In Transit）

| 项 | 详情 |
|---|---|
| **状态** | `IN_TRANSIT` |
| **责任人** | SupplyChain |
| **操作** | 更新 trackingId（物流单号）、logisticsStatus |
| **下一步** | → BONDED（到保税仓）<br>→ IN_STOCK（直接入库，无需保税）<br>→ CANCELLED（物流异常） |

#### 阶段 3：保税仓（Bonded）

| 项 | 详情 |
|---|---|
| **状态** | `BONDED` |
| **责任人** | SupplyChain |
| **操作** | 清关 → 入库 |
| **下一步** | → IN_STOCK（清关完成）<br>→ CANCELLED（海关扣押） |

#### 阶段 4：在库（In Stock）

| 项 | 详情 |
|---|---|
| **状态** | `IN_STOCK` |
| **责任人** | SupplyChain（入库）/ Sales（出库到客户）/ RLE（故障检修） |
| **操作** | 等待分配；可发现故障进维修 |
| **自动** | locationId 默认设为 `HQ_FZ`（总部仓库） |
| **下一步** | → RESERVED（Sales 分配给客户）<br>→ REPAIR（RLE 库存故障检修） |

#### 阶段 5：预留（Reserved）

| 项 | 详情 |
|---|---|
| **状态** | `RESERVED` |
| **责任人** | Sales / RLE |
| **Guard** | 必须已绑定 customerId |
| **操作** | 选择客户、填合同信息、谈价 |
| **下一步** | → SOLD（合同签 + 款到位）<br>→ IN_STOCK（取消预留，自动解绑客户） |

#### 阶段 6：已售（Sold）

| 项 | 详情 |
|---|---|
| **状态** | `SOLD` |
| **责任人** | Sales |
| **Guard** | 必须设置 salesPriceHardware 或 salesPriceSoftware（至少其一） |
| **操作** | 收款跟进 → 安排发货交付 |
| **下一步** | → DELIVERED（物理交付；自动填 deliveredDate）<br>→ CANCELLED（撤销销售，必须填 remark） |

#### 阶段 7：已交付（Delivered）

| 项 | 详情 |
|---|---|
| **状态** | `DELIVERED` |
| **责任人** | Sales（交付确认）/ Finance（财务对账） |
| **自动** | `metadata.deliveredDate` 设为当前日期 |
| **下一步** | → REPAIR（客户报修） |

#### 阶段 8：维修中（Repair）

| 项 | 详情 |
|---|---|
| **状态** | `REPAIR` |
| **责任人** | RLE |
| **自动** | - locationId 设为 `HQ_FZ`（返厂）<br>- 创建一条 `ServiceRecord`（类型从 `system_config.repair_auto_service_type` 读取，默认 `REPAIR`） |
| **下一步** | → REPAIRED（维修完成，自动填 completedDate）<br>→ CANCELLED（无法修复，设备报废） |

> **智元换货**（Zhiyuan Exchange）流程：在 `ServiceRecord.serviceTypeCode` 字段选 `ZHIYUAN_EXCHANGE`，其他流程同常规维修。业务方可在"字段定义 → 系统字段"里自助增删该字典。

#### 阶段 9：维修完成（Repaired）

| 项 | 详情 |
|---|---|
| **状态** | `REPAIRED` |
| **责任人** | RLE |
| **操作** | 等待归还客户或重新入库 |
| **Guard**（REPAIRED → DELIVERED） | 必须有 customerId + salesPrice |
| **下一步** | → DELIVERED（归还原客户，自动填 deliveredDate）<br>→ IN_STOCK（自动解绑客户，回到可再分配状态）<br>→ CANCELLED（修好后仍报废） |

#### 阶段 10：已取消（Cancelled）

| 项 | 详情 |
|---|---|
| **状态** | `CANCELLED` |
| **终态** | 不可再转出 |
| **入口** | ORDERED / IN_TRANSIT / BONDED / SOLD / REPAIR / REPAIRED 都可进入 |
| **必填** | `remark`（取消原因） |

### 4.3 跨角色协作场景

#### 场景 A：新机销售全链路（最常见）

```
SupplyChain              RLE/Sales           Sales             Sales
    ↓                        ↓                  ↓                 ↓
  新建设备 → IN_TRANSIT → 入库 IN_STOCK → 分配客户 RESERVED → 签合同收款 SOLD → 发货 DELIVERED
  (ORDERED)                                                                        ↓
                                                                             Finance 对账
```

**交接点**：
1. SupplyChain 推 `IN_TRANSIT → IN_STOCK`（系统通知 RLE 库存可用）
2. Sales 选到合适设备 → `IN_STOCK → RESERVED`
3. Sales 拿到客户签字合同 + Finance 确认款到 → `RESERVED → SOLD`
4. SupplyChain 安排物流发货 → Sales 确认送达 → `SOLD → DELIVERED`

#### 场景 B：库存故障检修

```
RLE 巡检发现故障 → REPAIR → 维修完成 REPAIRED → 重新入库 IN_STOCK
```

- 不涉及客户，完全是 RLE 内部流程
- 故障标签（issueTagCode）必填

#### 场景 C：客户报修 → 维修 → 归还

```
客户报修 (DELIVERED) → REPAIR → 维修 REPAIRED → 归还 DELIVERED
```

- **保留 customerId**：整个维修流程不清客户，归还时系统验证 customerId 仍存在
- **自动创建 ServiceRecord**：进 REPAIR 时自动建一条服务记录，进 REPAIRED 时自动填 completedDate
- **智元换货特殊**：serviceTypeCode 选 `ZHIYUAN_EXCHANGE`，走同样流程但售后报表可筛出

#### 场景 D：采购取消 / 物流异常

```
ORDERED → CANCELLED（供应商违约 / 取消订单）
IN_TRANSIT → CANCELLED（物流丢失）
BONDED → CANCELLED（海关扣押）
```

所有 CANCELLED 操作必须填 remark 说明原因，便于审计。

#### 场景 E：销售撤销（已签合同但退款）

```
SOLD → CANCELLED（退款场景，填 remark）
```

不支持 `SOLD → RESERVED` 回退；如果客户改签必须走新设备。

---

---

## 5. Part 3 — 监控分析与日常操作

> 基础数据维护完 + 生命周期跑起来后，这部分是**运维态**操作：看数据、批量处理、分析趋势。

### 5.1 列表筛选与搜索

| 操作 | 路径 | 要点 |
|---|---|---|
| 快速搜索 | 列表页顶部搜索框 | 按 FFSN / 备注模糊匹配 |
| 按状态筛选 | 顶部下拉 "按状态筛选" | 可多选，直接 URL query 共享 |
| 多维筛选 | 顶部 "更多筛选" | 按型号 / 供应商 / 客户 / 位置 / SKU 组合 |
| 列配置 | 顶部 "配置列" | 勾选要显示的动态字段（localStorage 记忆） |
| 清除所有筛选 | "清除筛选" 按钮 | |

### 5.2 报表查看

| 报表 | 核心指标 | 可点击下钻 |
|---|---|---|
| 库存报表 | 总数、按状态分布、可分配数、在途数 | 点 StatCard 跳列表（带状态 filter） |
| 销售报表 | 累计交付数、总收入、按客户分布 | 客户分布表格可导出 |
| 财务报表 | 设备数、总收入、总成本、总毛利 | 数据按 metadata.cost / salesPrice 求和 |

**注意**：报表目前按**系统默认货币（USD）聚合**，多币种场景见 Roadmap Phase 4。

### 5.3 批量状态变更

| 场景 | 操作 |
|---|---|
| 批量选择设备 | 列表页勾选多行（顶部"全选当前页"） |
| 批量变更状态 | "批量变更" 按钮 → 选目标状态 → 必要时填 remark |
| 单台失败处理 | 成功 N 台，失败 M 台 → toast 显示，失败原因按行列出（如"未绑定客户"） |

**限制**：每台设备独立校验 Guard，不会因为一台失败就全部回滚。

### 5.4 Excel 导入导出

| 操作 | 路径 | 要点 |
|---|---|---|
| 导出当前视图 | 列表页 → 导出按钮 | 按当前筛选条件导出，文件名带日期 |
| 下载模板 | 导入导出页 → 下载模板 | 包含 FFSN / Model Code / SKU Code / Current Status + 所有 FieldDef 的英文 label 列 |
| 导入 | 导入导出页 → 上传 .xlsx | 每行对应一台机器人 |

**导入规则**：
- FFSN 必填、文件内唯一、组织内唯一
- ModelCode / SkuCode 必须已存在
- `currentStatus` 不允许是 `REPAIR` / `CANCELLED`（这些状态要通过状态机流程走）
- 无效的字典 code 会整行报错
- 报错行会在结果页列出（行号、字段、原因）

### 5.5 设备操作（详情页）

| 操作 | 路径 |
|---|---|
| 查看状态变更日志 | 详情页底部 → "状态变更日志" |
| 查看维修记录 | 详情页底部 → "服务记录"（进 REPAIR 自动创建，进 REPAIRED 自动补 completedDate） |
| 复制新建 | 详情页右上角下拉 → "复制新建"（源字段自动预填，不复制 FFSN / PO / 销售订单号） |
| 软删除 | 详情页右上角下拉 → "删除"（设置 deletedAt，列表不可见但 DB 保留） |
| 上/下一台导航 | 列表页进入的设备保留导航 session，可直接切换相邻设备 |
| 附件管理 | 详情页 "附件" 区域 — 上传合同扫描件、发货单、维修报告等 |

### 5.6 全局搜索（`/` 或 Cmd+K）

快捷键：在任何页面按 `/` 或 `Cmd+K` 打开全局搜索，按 FFSN / 型号 / 客户名 快速跳转。

### 5.7 快捷键

| 快捷键 | 功能 |
|---|---|
| `/` | 打开全局搜索 |
| `Cmd+K` / `Ctrl+K` | 同上 |
| `c` | 创建新设备（从任何页面跳转到创建页） |
| `?` | 打开本使用说明页 |

---

## 6. 常见问题（FAQ）

### Q1：为什么我看不到某个 Tab / 按钮？

A：字段级权限决定。你的角色没有对应 `write:xxx` 权限。联系管理员调整。

### Q2：poNumber/salesOrderId 为什么改不了？

A：这些字段**一旦设置就不可修改**（业务上是外部单据号，应保持稳定）。如果确实需要改，联系 Administrator / RLE 删除设备重建。

### Q3：交付后想改销售价怎么办？

A：DELIVERED 状态下可以继续改 `salesPriceHardware` / `salesPriceSoftware`（Sales / Finance 根据权限），只要字段不是 `immutable` 就能改。修改会 bump version（乐观锁防并发）。

### Q4：一次导入几百台机器怎么做？

A：管理 → 导入导出 → 下载模板 → 填好上传。系统按 FFSN 去重，冲突报错。**不允许导入 REPAIR / CANCELLED 状态的机器**（需要先正常入库再做状态变更）。

### Q5：货币怎么切换？

A：每台机器人在 Identity Tab 有 `currency` 字段（默认 USD），支持 USD / CNY / EUR / GBP / JPY / HKD / SGD。所有价格字段按此货币展示（`Intl.NumberFormat` 会自动处理符号和千分位）。

### Q6：状态机的合法转换是硬编码还是可配置？

A：当前**硬编码**在 `robot-status.service.ts`。转换规则、Guard 条件、副作用都在代码层。**不支持**业务方自助改状态机（状态机 == 业务契约，改动必须工程评审）。字典、字段、默认值这些 **"数据层配置"** 业务方可以自助改。

### Q7：字段级权限和 Role 是什么关系？

A：Role 是用户身份（如 Sales）。权限（permissions）是具体操作能力（如 `robot-manager:write:sales`）。Role 持有一组权限。例如 Sales 角色持有 `write:sales`，所以能编辑销售 Tab，但没有 `write:finance`，所以财务 Tab 只读。

### Q8：想看历史状态变更怎么办？

A：设备详情页底部有"状态变更日志"，记录了每次 from→to、操作人、时间、remark。同时维修记录（ServiceRecord）单独列表展示。

### Q9：怎么给销售配置默认货币？

A：管理 → 字段定义 → Identity Tab → currency 字段 → 编辑 → "Default Value" 填 `USD` / `CNY` 等。新建设备时自动填入该值。

### Q10：客户跨境支付，要记多币种怎么办？

A：当前**每台机器一个主货币**。如果客户跨境（如人民币采购 + 美元销售），当前设计只能保留其中一个货币显示。**多币种拆分（purchaseCurrency + salesCurrency）在未来规划中**，见 [12-roadmap.md](./12-roadmap.md)。

---

## 6. 关联文档

- [01-prd.md](./01-prd.md) — 产品需求
- [04-state-machine.md](./04-state-machine.md) — 状态机详细规格（合法转换表、Guard、副作用）
- [06-data-model.md](./06-data-model.md) — 数据模型（RobotUnit / FieldDef / 业务实体）
- [07-api.md](./07-api.md) — API 接口
- [12-roadmap.md](./12-roadmap.md) — 未来规划
