# 品牌编辑页面

> 最后更新：2026-04-25
> 状态：已设计

---

### 1. 基本信息

| 项 | 值 |
|----|-----|
| 路由 | /brand/create 或 /brand/{id}/edit |
| 权限 | admin |
| 入口 | 品牌列表页点击"新增品牌"或"编辑" |
| 面包屑 | 首页 / 品牌模板管理 / 新增品牌 或 编辑FANUC |

### 2. 界面布局

┌──────────────────────────────────────────────────────────┐
│ [面包屑] 首页 / 品牌模板管理 / 编辑FANUC                    │
├──────────────────────────────────────────────────────────┤
│ [基本信息区]                                              │
│ < 返回    编辑品牌模板：FANUC                              │
│ 品牌名称：[FANUC]                                        │
│ device字段名：[device]                                    │
│ tags路径：[tags]                                          │
├──────────────────────────────────────────────────────────┤
│ [字段映射配置区]                     [+ 添加映射]          │
│ 标准字段          | 匹配方式 | 匹配值     | 类型   | 必须 | 操作 │
│ program_name     | 按id    | Tag5      | string | 是  | [删除] │
│ part_count       | 按id    | Tag8      | number | 是  | [删除] │
│ device_status    | 按id    | _io_status| number | 是  | [删除] │
│ ...                                                      │
├──────────────────────────────────────────────────────────┤
│ ⚠ 修改映射配置仅影响后续新采集数据，历史数据不受影响         │
│                                    [取消]    [保存]        │
└──────────────────────────────────────────────────────────┘

### 3. 查询条件

无。

### 4. 操作按钮

| 名称 | 位置 | 显示条件 | 点击行为 |
|------|------|---------|---------|
| 添加映射 | 映射表头上方 | 始终 | 新增一行空映射 |
| 删除 | 映射行操作 | 始终 | 移除该行(不弹确认) |
| 保存 | 页脚 | 始终 | 校验->保存->返回列表 |
| 取消 | 页脚 | 始终 | 脏数据检测->返回列表 |

### 5. 弹窗规格

添加映射行：使用el-select选标准字段+输入匹配值+选择类型，直接在表格行内编辑，不弹窗。

### 6. 状态机

品牌is_enabled：
- 1(启用): el-tag success
- 0(停用): el-tag danger

### 7. 交互流程

- 加载(编辑)：请求品牌详情+映射列表->渲染
- 加载(新增)：空表单
- 添加映射：表格新增一行空行(标准字段下拉+匹配值输入+类型选择+必填勾选)
- 删除映射：直接移除该行
- 保存：确认弹窗"修改映射配置仅影响后续新采集数据，历史数据不受影响，确定保存？"->调API->成功返回列表
- 取消：脏数据检测->返回

### 8. 脏数据检测（本模块特殊规则）

品牌名称/device字段/tags路径/映射列表任一变更则isDirty=true。

### 9. 接口引用与数据结构

> Mock/正式API的URL、HTTP方法均定义在 `03-API接口设计.md` §3.4 端点清单，本节仅引用编号并定义返回数据结构。

#### 接口引用

| 接口名称 | 端点编号 | 界面用途 |
|---------|---------|---------|
| 品牌详情（含映射） | §3.4 #2 | 页面加载时获取品牌信息+字段映射列表 |
| 编辑品牌 | §3.4 #4 | 保存按钮提交 |
| 标准字段列表 | §3.4 #8 | 映射表格的标准字段下拉 |

#### 数据结构

**品牌详情（§3.4 #2）：**

Response：
```json
{ "code": 0, "data": {
  "id": 1, "brandName": "FANUC", "deviceField": "device", "tagsPath": "tags",
  "mappings": [
    { "id": 1, "standardField": "program_name", "fieldName": "Tag5", "matchBy": "id", "dataType": "string", "isRequired": 1 },
    { "id": 2, "standardField": "part_count", "fieldName": "Tag8", "matchBy": "id", "dataType": "number", "isRequired": 1 },
    { "id": 3, "standardField": "device_status", "fieldName": "_io_status", "matchBy": "id", "dataType": "number", "isRequired": 1 },
    { "id": 4, "standardField": "run_status", "fieldName": "Tag9", "matchBy": "id", "dataType": "number", "isRequired": 1 },
    { "id": 5, "standardField": "operate_mode", "fieldName": "Tag10", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 6, "standardField": "spindle_speed_set", "fieldName": "Tag11", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 7, "standardField": "feed_speed_set", "fieldName": "Tag12", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 8, "standardField": "spindle_speed_actual", "fieldName": "Tag13", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 9, "standardField": "feed_speed_actual", "fieldName": "Tag14", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 10, "standardField": "spindle_load", "fieldName": "Tag15", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 11, "standardField": "spindle_override", "fieldName": "Tag16", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 12, "standardField": "power_on_time", "fieldName": "Tag17", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 13, "standardField": "run_time", "fieldName": "Tag18", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 14, "standardField": "cutting_time", "fieldName": "Tag19", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 15, "standardField": "cycle_time", "fieldName": "Tag20", "matchBy": "id", "dataType": "number", "isRequired": 0 },
    { "id": 16, "standardField": "machining_status", "fieldName": "Tag21", "matchBy": "id", "dataType": "string", "isRequired": 0 }
  ]
}}
```

**编辑品牌（§3.4 #4）：**

Response：
```json
{ "code": 0, "message": "success", "data": null }
```

### 9. 数据需求

> 以下为本页面需要的数据，数据库设计定稿时需覆盖。参考 `01-数据库设计.md` 草案。

| 数据需求 | 草案对应 | 说明 |
|---------|---------|------|
| 品牌基本信息 | cnc_brand | brand_name/device_field/tags_path |
| 字段映射列表 | cnc_brand_field_mapping | 按brand_id查询，含standard_field/field_name/match_by/data_type/is_required |
| 标准字段枚举 | 代码层面约定（不建表） | program_name/part_count等16个标准字段 |
