# Stateflow API 文档

## 概述

Stateflow API 提供了状态节点和流程的 CRUD 操作接口。

## 基础 URL

```
/api/v1/
```

## 认证

所有 API 都需要 JWT 认证。在请求头中添加：

# Stateflow API 文档 (v2)

## 概述

Stateflow API 提供了状态节点、流程模板以及流程实例（业务对象）的完整生命周期管理，包括创建、查询、更新、删除以及核心的状态流转操作。

## 基础 URL

所有 Stateflow 相关 API 都在以下基础路径下：

```
/api/v1/stateflow/
```

## 认证

所有 API 都需要 JWT 认证。在请求头中添加：

```
Authorization: Bearer <access_token>
```

## 分页

列表接口默认使用 `LimitOffset` 分页：

- `limit`: 返回结果数量。
- `offset`: 偏移量。

---

## 1. State API (状态节点)

**基础路径**: `/api/v1/stateflow/states/`

管理流程中的基础单元：状态。

### 1.1. 列表查询

- **GET** `/api/v1/stateflow/states/`
- **描述**: 获取状态节点列表。
- **查询参数**:
    - `name`: 按名称精确查询。
    - `search`: 按名称和描述进行模糊搜索。
    - `ordering`: 排序字段 (`id`, `name`, `created_at`, `updated_at`)。

### 1.2. 详情查询

- **GET** `/api/v1/stateflow/states/{id}/`
- **描述**: 获取单个状态节点的详细信息，包含其关联的参数模板。

### 1.3. 创建状态

- **POST** `/api/v1/stateflow/states/`
- **描述**: 创建一个新的状态节点。
- **请求体**:
  ```json
  {
    "name": "待质检",
    "description": "等待品质检验",
    "parameters": [
      {
        "key": "inspector",
        "value": "",
        "is_required": true,
        "description": "质检员"
      }
    ]
  }
  ```

### 1.4. 更新状态

- **PUT/PATCH** `/api/v1/stateflow/states/{id}/`
- **描述**: 完全或部分更新一个状态节点。`PUT` 请求会替换所有字段，`PATCH` 只更新提供的字段。`parameters` 数组在 `PUT` 时会完全替换。

### 1.5. 删除状态

- **DELETE** `/api/v1/stateflow/states/{id}/`
- **描述**: 删除一个状态节点。

### 1.6. 获取状态参数

- **GET** `/api/v1/stateflow/states/{id}/parameters/`
- **描述**: 获取指定状态的参数列表。
- **查询参数**:
    - `required_only`: `true` 或 `false`，是否只返回必填参数。

---

## 2. Process API (流程模板)

**基础路径**: `/api/v1/stateflow/processes/`

管理可复用的流程模板。

### 2.1. 列表查询

- **GET** `/api/v1/stateflow/processes/`
- **描述**: 获取流程模板列表。
- **查询参数**:
    - `name`: 按名称精确查询。
    - `search`: 按名称和描述进行模糊搜索。
    - `ordering`: 排序字段 (`id`, `name`, `node_count`, `created_at`, `updated_at`)。

### 2.2. 详情查询

- **GET** `/api/v1/stateflow/processes/{id}/`
- **描述**: 获取单个流程模板的详细信息，包含其所有节点（`nodes`）。

### 2.3. 创建流程

- **POST** `/api/v1/stateflow/processes/`
- **描述**: 创建一个新的流程模板，并定义其节点顺序。
- **请求体**:
  ```json
  {
    "name": "生产流程",
    "description": "从下单到发货的标准流程",
    "nodes": [
      { "state_id": 1, "order": 0 },
      { "state_id": 2, "order": 1 },
      { "state_id": 5, "order": 2 }
    ]
  }
  ```

### 2.4. 更新流程

- **PUT/PATCH** `/api/v1/stateflow/processes/{id}/`
- **描述**: 更新流程模板。`nodes` 数组在 `PUT` 时会完全替换。

### 2.5. 删除流程

- **DELETE** `/api/v1/stateflow/processes/{id}/`
- **描述**: 删除一个流程模板。

---

## 3. Business Object API (流程实例)

**基础路径**: `/api/v1/stateflow/business-objects/`

管理流程的具体实例，这是状态流转的核心。

### 3.1. 列表查询

- **GET** `/api/v1/stateflow/business-objects/`
- **描述**: 获取流程实例列表。
- **查询参数**:
    - `name`: 按名称模糊查询。
    - `process`: 按流程模板 ID 过滤。
    - `process_name`: 按流程模板名称模糊查询。
    - `overall_status`: 按整体状态过滤 (`not_started`, `in_progress`, `completed`)。
    - `content_type_str`: 按关联的业务模型过滤，格式: `app_label.model` (例如 `printing.plateorder`)。
    - `has_content_object`: `true` 或 `false`，过滤是否有关联的业务模型。
    - `search`: 按名称和描述进行模糊搜索。
    - `ordering`: 排序字段 (`id`, `name`, `created_at`, `updated_at`)。

### 3.2. 详情查询

- **GET** `/api/v1/stateflow/business-objects/{id}/`
- **描述**: 获取单个流程实例的详细信息，包含当前状态、进度、时间线等。

### 3.3. 创建流程实例

- **POST** `/api/v1/stateflow/business-objects/`
- **描述**: 创建一个新的流程实例。
- **请求体**:
  ```json
  {
    "name": "订单 #123 的生产流程",
    "process": 1,
    "description": "客户A的加急订单"
  }
  ```

### 3.4. 更新流程实例

- **PUT/PATCH** `/api/v1/stateflow/business-objects/{id}/`
- **描述**: 更新流程实例的基本信息（如名称、描述）。

### 3.5. 删除流程实例

- **DELETE** `/api/v1/stateflow/business-objects/{id}/`
- **描述**: 删除一个流程实例及其所有相关日志。

### 3.6. 核心流转操作 (Custom Actions)

#### 3.6.1. 推进到下一状态

- **POST** `/api/v1/stateflow/business-objects/{id}/advance/`
- **描述**: 将流程实例从当前状态推进到下一个状态。
- **请求体** (可选):
  ```json
  {
    "parameters": {
      "temperature": "25.5",
      "humidity": "60%"
    }
  }
  ```
- **成功响应**: `200 OK`，包含成功信息和更新后的业务对象。
- **失败响应**: `400 Bad Request`，如果缺少必填参数或流程已完成。
  ```json
  {
    "success": false,
    "message": "流程已完成，无法继续推进"
  }
  ```

#### 3.6.2. 回退一步

- **POST** `/api/v1/stateflow/business-objects/{id}/step_back/`
- **描述**: 撤销最后一次完成的状态，使流程回退一步。
- **成功响应**: `200 OK`。
- **失败响应**: `400 Bad Request`，如果从未开始过。
  ```json
  {
    "success": false,
    "message": "没有任何状态流转记录，无法回退"
  }
  ```

#### 3.6.3. 重置进度

- **POST** `/api/v1/stateflow/business-objects/{id}/reset/`
- **描述**: 撤销所有已完成的状态，将流程实例重置到未开始状态。

### 3.7. 状态查询接口 (Custom Actions)

#### 3.7.1. 获取状态时间线

- **GET** `/api/v1/stateflow/business-objects/{id}/timeline/`
- **描述**: 获取一个包含所有节点及其当前状态（`not_started`, `in_progress`, `completed`, `cancelled`）的时间线。

#### 3.7.2. 获取下一个待执行节点

- **GET** `/api/v1/stateflow/business-objects/{id}/next_pending_state/`
- **描述**: 获取下一个待执行的节点信息。
- **查询参数**:
    - `include_parameters`: `true` 或 `false`，是否包含节点的参数模板。

#### 3.7.3. 获取所有待执行节点

- **GET** `/api/v1/stateflow/business-objects/{id}/pending_states/`
- **描述**: 获取所有未完成的节点列表。

#### 3.7.4. 获取当前状态的参数

- **GET** `/api/v1/stateflow/business-objects/{id}/current_state_parameters/`
- **描述**: 获取当前待执行节点（`current_state`）的参数模板。
- **注意**: `current_state` 指的是下一个待执行的节点。如果流程已完成，则返回空。

#### 3.7.5. 获取流程的所有节点

- **GET** `/api/v1/stateflow/business-objects/{id}/process-nodes/`
- **描述**: 获取业务对象所属流程的所有状态节点列表，按顺序排列。
- **响应示例**:
  ```json
  {
    "count": 3,
    "nodes": [
      {
        "id": 1,
        "state_id": 10,
        "state_name": "质检",
        "order": 0
      },
      {
        "id": 2,
        "state_id": 11,
        "state_name": "包装",
        "order": 1
      },
      {
        "id": 3,
        "state_id": 12,
        "state_name": "发货",
        "order": 2
      }
    ]
  }
  ```

### 3.8. 参数与日志接口 (Custom Actions)

#### 3.8.1. 获取状态流转记录列表

- **GET** `/api/v1/stateflow/business-objects/{id}/state-logs/`
- **描述**: 获取业务对象的所有状态流转记录列表。
- **查询参数**:
    - `include_parameters`: `true` 或 `false`，是否包含工艺参数，默认 `true`。
    - `include_cancelled`: `true` 或 `false`，是否包含已撤销的记录，默认 `true`。
- **响应示例**:
  ```json
  {
    "count": 2,
    "state_logs": [
      {
        "id": 123,
        "state": 1,
        "state_name": "质检",
        "completed_at": "2025-11-15T10:30:00Z",
        "completed_by": 5,
        "completed_by_username": "inspector1",
        "is_cancelled": false,
        "cancelled_at": null,
        "parameters_summary": {
          "temperature": "25.5",
          "humidity": "60%"
        }
      },
      {
        "id": 124,
        "state": 2,
        "state_name": "包装",
        "completed_at": "2025-11-15T14:20:00Z",
        "completed_by": 6,
        "completed_by_username": "packer1",
        "is_cancelled": false,
        "cancelled_at": null,
        "parameters_summary": {}
      }
    ]
  }
  ```
- **注意**: 
    - 当 `include_parameters=false` 时，返回的记录不包含 `parameters_summary` 字段。
    - 当 `include_cancelled=false` 时，只返回未撤销的记录。
    - 记录按 `completed_at` 时间正序排列。

#### 3.8.2. 为日志补充参数

- **POST** `/api/v1/stateflow/business-objects/{id}/state-logs/{log_id}/add-parameters/`
- **描述**: 为某一次具体的状态流转记录（`StateFlowRecord`）补充额外的参数。
- **请求体**:
  ```json
  {
    "parameters": {
      "inspector_comment": "发现轻微划痕"
    },
    "remark": "质检员补充"
  }
  ```
- **成功响应**: `200 OK`
  ```json
  {
    "success": true,
    "parameter_record": {
      "id": 456,
      "parameters": {
        "inspector_comment": "发现轻微划痕"
      },
      "remark": "质检员补充",
      "created_at": "2025-11-15T15:00:00Z"
    }
  }
  ```
- **失败响应**: 
    - `400 Bad Request`: 参数为空
    - `404 Not Found`: 状态流转记录不存在

#### 3.8.3. 获取单个日志的参数

- **GET** `/api/v1/stateflow/business-objects/{id}/state-logs/{log_id}/parameters/`
- **描述**: 获取某一次流转记录的所有参数记录或指定参数的历史。
- **查询参数**:
    - `key`: （可选）如果提供，则只返回该 `key` 的所有历史值。
    - `include_cancelled`: `true` 或 `false`，是否包含已撤销状态的参数，默认 `false`。
- **响应示例**（获取所有参数）:
  ```json
  {
    "state_log_id": 123,
    "is_cancelled": false,
    "count": 2,
    "summary": {
      "temperature": "26.5",
      "humidity": "60%"
    },
    "records": [
      {
        "id": 1,
        "parameters": {
          "temperature": "25.5",
          "humidity": "60%"
        },
        "remark": "",
        "created_at": "2025-11-15T10:30:00Z"
      },
      {
        "id": 2,
        "parameters": {
          "temperature": "26.5"
        },
        "remark": "重新测量",
        "created_at": "2025-11-15T11:00:00Z"
      }
    ]
  }
  ```
- **响应示例**（按 key 查询历史）:
  ```json
  {
    "state_log_id": 123,
    "key": "temperature",
    "is_cancelled": false,
    "history": [
      {
        "value": "25.5",
        "remark": "",
        "created_at": "2025-11-15T10:30:00Z"
      },
      {
        "value": "26.5",
        "remark": "重新测量",
        "created_at": "2025-11-15T11:00:00Z"
      }
    ]
  }
  ```


## 分页

使用 LimitOffset 分页：

- `limit`: 返回结果数量（默认无限制）
- `offset`: 偏移量（默认0）

示例：
```
GET /api/v1/states/?limit=10&offset=0
```

响应格式：
```json
{
  "count": 100,
  "next": "http://example.com/api/v1/states/?limit=10&offset=10",
  "previous": null,
  "results": [...]
}
```

---

## State API (状态节点)

### 1. 列表查询

**GET** `/api/v1/states/`

查询参数：
- `limit`: 分页限制
- `offset`: 分页偏移
- `name`: 按名称精确查询
- `search`: 全文搜索（名称和描述）
- `ordering`: 排序字段（id, name, created_at, updated_at）

示例：
```bash
curl -X GET "http://localhost:8000/api/v1/states/?search=审核&limit=10&offset=0" \
  -H "Authorization: Bearer <token>"
```

响应：
```json
{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "待审核",
      "description": "等待审核",
      "created_at": "2025-01-01T00:00:00Z",
      "updated_at": "2025-01-01T00:00:00Z"
    }
  ]
}
```

### 2. 详情查询

**GET** `/api/v1/states/{id}/`

响应：
```json
{
  "id": 1,
  "name": "待审核",
  "description": "等待审核",
  "parameters": [
    {
      "id": 1,
      "key": "timeout",
      "value": "24h",
      "description": "超时时间"
    }
  ],
  "created_at": "2025-01-01T00:00:00Z",
  "updated_at": "2025-01-01T00:00:00Z"
}
```

### 3. 创建状态

**POST** `/api/v1/states/`

请求体：
```json
{
  "name": "待审核",
  "description": "等待审核",
  "parameters": [
    {
      "key": "timeout",
      "value": "24h",
      "description": "超时时间"
    }
  ]
}
```

响应：`201 Created`
```json
{
  "name": "待审核",
  "description": "等待审核",
  "parameters": [...]
}
```

### 4. 更新状态

**PUT** `/api/v1/states/{id}/`

请求体：
```json
{
  "name": "已审核",
  "description": "审核通过",
  "parameters": [
    {
      "key": "approver",
      "value": "admin",
      "description": "审核人"
    }
  ]
}
```

注意：`parameters` 数组会完全替换原有参数。

**PATCH** `/api/v1/states/{id}/`

部分更新，可以只更新某些字段：
```json
{
  "description": "新的描述"
}
```

### 5. 删除状态

**DELETE** `/api/v1/states/{id}/`

响应：`204 No Content`

---

## Process API (流程)

### 1. 列表查询

**GET** `/api/v1/processes/`

查询参数：
- `limit`: 分页限制
- `offset`: 分页偏移
- `name`: 按名称精确查询
- `search`: 全文搜索（名称和描述）
- `ordering`: 排序字段（id, name, node_count, created_at, updated_at）

响应：
```json
{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 1,
      "name": "订单流程",
      "description": "标准订单处理流程",
      "node_count": 3,
      "created_at": "2025-01-01T00:00:00Z",
      "updated_at": "2025-01-01T00:00:00Z"
    }
  ]
}
```

### 2. 详情查询

**GET** `/api/v1/processes/{id}/`

响应：
```json
{
  "id": 1,
  "name": "订单流程",
  "description": "标准订单处理流程",
  "nodes": [
    {
      "id": 1,
      "state_id": 1,
      "state_name": "待审核",
      "order": 0
    },
    {
      "id": 2,
      "state_id": 2,
      "state_name": "已审核",
      "order": 1
    },
    {
      "id": 3,
      "state_id": 3,
      "state_name": "已发货",
      "order": 2
    }
  ],
  "created_at": "2025-01-01T00:00:00Z",
  "updated_at": "2025-01-01T00:00:00Z"
}
```

### 3. 创建流程

**POST** `/api/v1/processes/`

请求体：
```json
{
  "name": "订单流程",
  "description": "标准订单处理流程",
  "nodes": [
    {
      "state_id": 1,
      "order": 0
    },
    {
      "state_id": 2,
      "order": 1
    },
    {
      "state_id": 3,
      "order": 2
    }
  ]
}
```

响应：`201 Created`

### 4. 更新流程

**PUT** `/api/v1/processes/{id}/`

请求体：
```json
{
  "name": "更新后的流程",
  "description": "新的描述",
  "nodes": [
    {
      "state_id": 2,
      "order": 0
    },
    {
      "state_id": 3,
      "order": 1
    }
  ]
}
```

注意：`nodes` 数组会完全替换原有节点。

**PATCH** `/api/v1/processes/{id}/`

部分更新。

### 5. 删除流程

**DELETE** `/api/v1/processes/{id}/`

响应：`204 No Content`

---

## 错误响应

所有 API 遵循统一的错误响应格式：

```json
{
  "detail": "错误描述"
}
```

或字段级错误：

```json
{
  "name": ["该字段不能为空"],
  "nodes": [
    {
      "state_id": ["状态ID 999 不存在"]
    }
  ]
}
```

常见状态码：
- `200 OK`: 成功
- `201 Created`: 创建成功
- `204 No Content`: 删除成功
- `400 Bad Request`: 请求参数错误
- `401 Unauthorized`: 未认证
- `403 Forbidden`: 无权限
- `404 Not Found`: 资源不存在
- `500 Internal Server Error`: 服务器错误

## 示例代码

### Python (requests)

```python
import requests

# 获取 token
response = requests.post('http://localhost:8000/api/token/', {
    'username': 'admin',
    'password': 'password'
})
token = response.json()['access']

# 创建状态
headers = {'Authorization': f'Bearer {token}'}
response = requests.post(
    'http://localhost:8000/api/v1/stateflow/states/',
    json={
        'name': '待审核',
        'description': '等待审核'
    },
    headers=headers
)
state = response.json()

# 获取业务对象的流程节点
business_object_id = 1
response = requests.get(
    f'http://localhost:8000/api/v1/stateflow/business-objects/{business_object_id}/process-nodes/',
    headers=headers
)
nodes_data = response.json()
print(f"流程共有 {nodes_data['count']} 个节点")
for node in nodes_data['nodes']:
    print(f"  节点 {node['order']}: {node['state_name']}")
```

### JavaScript (fetch)

```javascript
// 获取状态列表
const response = await fetch('/api/v1/stateflow/states/?limit=10&offset=0', {
  headers: {
    'Authorization': `Bearer ${token}`
  }
});
const data = await response.json();
console.log(data.results);

// 获取业务对象的流程节点
const businessObjectId = 1;
const nodesResponse = await fetch(
  `/api/v1/stateflow/business-objects/${businessObjectId}/process-nodes/`,
  {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  }
);
const nodesData = await nodesResponse.json();
console.log(`流程共有 ${nodesData.count} 个节点:`, nodesData.nodes);
```

### curl

```bash
# 创建流程
curl -X POST "http://localhost:8000/api/v1/stateflow/processes/" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "订单流程",
    "description": "标准订单处理流程",
    "nodes": [
      {"state_id": 1, "order": 0},
      {"state_id": 2, "order": 1}
    ]
  }'

# 获取业务对象的流程节点
curl -X GET "http://localhost:8000/api/v1/stateflow/business-objects/1/process-nodes/" \
  -H "Authorization: Bearer <token>"
```
