# 库位处理接口文档

## 批量设置库位 (BatchSettingSiteBp)

本接口用于批量设置库位的占用状态和内容。当库位 IDs 和库区集同时提供时，会对这些库位进行批量设置操作。

### 描述

本块在需要批量设置库位内容和占用状态时使用，可同时设置多个库位或多个库区的库位的占用状态。当库位 Ids 和库区集参数均填入时，则表示可同时对满足这两个参数的库位进行设置。

### 输入参数

| 参数名      | 中文名称 | 是否必填 | 类型         | 描述                     |
| ---------- | -------- | -------- | ------------ | ------------------------ |
| siteIds    | 库位IDs  | 非必填   | String[]     | 多个库位 id 的集合       |
| groupNames | 库区集   | 非必填   | String[]     | 多个库区的集合           |
| filled     | 占用     | 必填     | Boolean      | 库位是否占用状态，选择 true 或 false |
| content    | 货物     | 非必填   | String       | 填写库位中具体的货物     |
| type       | 是否物理库位	 | 非必填   |   Boolean     | 勾选设置的库位是否是物理库位或是逻辑库位。物理库位指地图上实际存在的库位，逻辑库位指因业务逻辑创建的虚拟库位，不实际存在于地图中。 |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteIds": ["site001", "site002", "site003"],
  "groupNames": [],
  "filled": true,
  "content": "产品A",
  "type": "physical"
}

// 成功响应示例
{
  "success": true,
  "message": "批量设置库位成功，共设置 3 个库位",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "批量设置库位失败: 库位ID不存在",
  "code": 404
}
```

## 获取密集库位 (GetIdleCrowdedSiteBp)

本接口用于获取密集库位，支持根据库区、占用状态等条件查找适合的库位。

### 描述

本块用于在一组密集库位中获取符合条件的空闲库位，支持重试机制。

### 输入参数

| 参数名      | 中文名称 | 是否必填 | 类型         | 描述                     |
| ---------- | -------- | -------- | ------------ | ------------------------ |
| groupName  | 库区集   | 必填     | String[]     | 库区数组           |
| filled     | 取/放     | 必填     | Boolean      | 选出库位用来取货还是放货 |
| content    | 货物(取)     | 非必填   | String       | 取货库位的货物内容，在放货此字段忽略         |
| lock       | 获取库位后是否锁定     | 非必填   | Boolean      | 选出库位后是否立即锁定 |
| retry      | 是否重试     | 必填   | Boolean      | 是否启用重试 |
| retryPeriod | 重试时间间隔(ms) | 非必填  | Long       | 重试周期（毫秒）         |
| retryNum   | 重试次数 | 非必填   | Long       | 重试次数                 |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |
| data      | 数据     | Object  | 返回数据对象        |
| data.siteId | 选出的库位 | String  | 获取到的库位ID      |

### 调用示例

```json
// 输入参数示例
{
  "groupName": ["density_area_1", "density_area_2"],
  "filled": false,
  "content": "",
  "lock": true,
  "retry": true,
  "retryPeriod": 1000,
  "retryNum": 3
}

// 成功响应示例
{
  "success": true,
  "message": "获取密集库位成功，库位ID: site001",
  "code": 200,
  "data": {
    "siteId": "site001"
  }
}

// 失败响应示例
{
  "success": false,
  "message": "获取密集库位失败: 未找到合适的库位",
  "code": 404
}
```

## 获取库位 (GetIdleSiteBp)

本接口用于获取符合条件的库位，支持按多种条件过滤和查询。

### 描述

本块用于获取符合特定条件的库位，可以指定多种查询参数，并支持自动无限重试机制直到找到合适的库位。

### 输入参数

| 参数名       | 中文名称 | 是否必填 | 类型          | 描述                      |
| ------------ | -------- | -------- | ------------- | ------------------------- |
| siteId       | 库位ID   | 非必填   | String        | 库位ID                    |
| content      | 货物     | 非必填   | String        | 获取该货物名称的库位                  |
| filled       | 是否有货物     | 非必填   | Boolean       | true: 获取有货物的库位; false: 获取无货物的库位                |
| locked       | 是否已锁定     | 必填     | Boolean       | true: 获取已锁定的库位; false: 获取未锁定的库位                |
| type         | 是否物理库位 | 非必填   | Boolean        | 是否是物理库位                  |
| groupName    | 库区名     | 非必填   | String        | 库区名称                  |
| lock         | 获取库位后是否锁定 | 非必填   | Boolean       | 选出库位后是否立即锁定 |
| retryPeriod  | 重试时间间隔(ms) | 非必填   | Long        | 重试间隔时间（毫秒），默认为1000毫秒。系统会不断重试直到获取到库位。 |
| ifFair       | 是否为公平锁 | 非必填   | Boolean       | 任务先尝试加锁库位，优先这个任务加锁此库位  |
| orderDesc    | 是否为降序 | 非必填   | Boolean       | true: 优先获取库位id大的; false: 优先获取库位id小的; 默认true  |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息，包含重试次数信息        |
| code      | 返回代码 | Number  | 操作结果代码        |
| data      | 数据     | Object  | 返回数据对象        |
| data.siteId | 选出的库位 | String  | 获取到的库位ID      |

### 调用示例

```json
// 输入参数示例
{
  "locked": false,
  "filled": false,
  "groupName": "storage_area_A",
  "lock": true,
  "retryPeriod": 2000,
  "ifFair": true,
  "orderDesc": true
}

// 成功响应示例
{
  "success": true,
  "message": "获取库位成功，库位ID: site123",
  "code": 200,
  "data": {
    "siteId": "site123"
  }
}

// 重试成功响应示例
{
  "success": true,
  "message": "第3次重试获取库位成功，库位ID: site123",
  "code": 200,
  "data": {
    "siteId": "site123"
  }
}
```

### 注意事项

1. 该接口实现了无限重试机制，会一直尝试获取库位直到成功
2. 每次重试之间会等待retryPeriod指定的时间（毫秒）
3. 如果长时间无法获取到库位，建议检查查询条件是否合理

## 根据任务实例ID获取所有枷锁库位 (GetLockedSitesByTaskRecordIdBp)

本接口用于获取某个任务实例已锁定的所有库位。

### 描述

本块用于查询指定任务实例ID锁定的所有库位，方便后续对这些库位进行操作。

### 输入参数

| 参数名        | 中文名称   | 是否必填 | 类型          | 描述           |
| ------------- | ---------- | -------- | ------------- | -------------- |
| taskRecordId  | 任务实例ID | 必填     | String        | 任务实例ID     |

### 输出参数

| 参数名           | 中文名称       | 类型      | 描述                    |
| ---------------- | -------------- | --------- | ----------------------- |
| success          | 成功标志       | Boolean   | 操作是否成功            |
| message          | 消息           | String    | 操作结果消息            |
| code             | 返回代码       | Number    | 操作结果代码            |
| data      | 数据     | Object  | 返回数据对象        |
| lockedSiteIdList | 已锁定库位列表 | String[]  | 已锁定的库位ID列表      |

### 调用示例

```json
// 输入参数示例
{
  "taskRecordId": "task123456"
}

// 成功响应示例
{
  "success": true,
  "message": "获取任务锁定库位成功，共 3 个库位",
  "code": 200,
  "data": {
    "lockedSiteIdList": ["site001", "site002", "site003"]
  }
}

// 失败响应示例
{
  "success": false,
  "message": "获取任务锁定库位失败: 任务实例不存在",
  "code": 404
}
```

## 获取库位扩展属性 (GetSiteAttrBp)

本接口用于获取库位的扩展属性值。

### 描述

本块用于获取指定库位ID的特定扩展属性值，支持获取自定义属性。

### 输入参数

| 参数名    | 中文名称 | 是否必填 | 类型          | 描述           |
| --------- | -------- | -------- | ------------- | -------------- |
| siteId    | 库位ID   | 必填     | String        | 指定的库位 Id  |
| attrName  | 属性名称 | 必填     | String        | 指定的库位扩展属性名称|

### 输出参数

| 参数名     | 中文名称 | 类型    | 描述                |
| ---------- | -------- | ------- | ------------------- |
| success    | 成功标志 | Boolean | 操作是否成功        |
| message    | 消息     | String  | 操作结果消息        |
| code       | 返回代码 | Number  | 操作结果代码        |
| data      | 数据     | Object  | 返回数据对象        |
| attrValue  | 属性值   | Any     | 属性值              |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "attrName": "temperature"
}

// 成功响应示例
{
  "success": true,
  "message": "获取库位属性值成功，temperature: 25",
  "code": 200,
  "data": {
    "attrValue": "25"
  }
}

// 失败响应示例
{
  "success": false,
  "message": "获取库位属性值失败: 属性不存在",
  "code": 404
}
```

## 查询库位 (QueryIdleSiteBp)

本接口用于查询符合条件的库位详细信息。

### 描述

本块用于根据指定条件查询库位的详细信息，与获取库位接口不同，此接口会返回库位的完整信息，而不会锁定库位。

### 输入参数

| 参数名       | 中文名称 | 是否必填 | 类型          | 描述                      |
| ------------ | -------- | -------- | ------------- | ------------------------- |
| siteId       | 库位ID   | 非必填   | String        | 库位ID                    |
| content      | 货物     | 非必填   | String        | 获取该货物名称的库位      |
| filled       | 是否有货物 | 非必填   | Boolean       | true: 获取有货物的库位; false: 获取无货物的库位 |
| locked       | 是否已锁定 | 非必填   | Boolean       | true: 获取已锁定的库位; false: 获取未锁定的库位 |
| type         | 是否物理库位 | 非必填   | Boolean      | 勾选 True 或者 False     |
| groupName    | 库区名   | 非必填   | String        | 填入库区名称              |
| orderDesc    | 是否为降序 | 非必填   | Boolean       | true: 优先获取库位id大的; false: 优先获取库位id小的; 默认为false |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |
| data      | 数据     | Object  | 返回数据对象        |
| site      | 库位信息 | Object  | 库位详细信息对象    |

### 库位对象属性（不确定）

| 属性名      | 中文名称 | 类型      | 描述                |
| ----------- | -------- | --------- | ------------------- |
| id          | 库位ID   | String    | 库位ID              |
| groupName   | 库区名称 | String    | 库区名称            |
| type        | 类型     | Number    | 库位类型            |
| filled      | 占用     | Boolean   | 是否已占用          |
| locked      | 锁定     | Boolean   | 是否已锁定          |
| content     | 货物内容 | String    | 库位内容            |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "filled": false,
  "locked": false
}

// 成功响应示例
{
  "success": true,
  "message": "查询库位成功，库位ID: site001",
  "code": 200,
  "data": {
    "site": {
      "id": "site001",
      "groupName": "storage_area_A",
      "type": 0,
      "filled": false,
      "locked": false,
      "content": ""
    }
  }
}

// 失败响应示例
{
  "success": false,
  "message": "查询库位失败: 未找到符合条件的库位",
  "code": 404
}
```

## 设置库位扩展属性 (SetSiteAttrBp)

本接口用于设置库位的扩展属性值。

### 描述

本块用于设置指定库位ID的特定扩展属性值，支持设置自定义属性。

### 输入参数

| 参数名     | 中文名称 | 是否必填 | 类型          | 描述          |
| ---------- | -------- | -------- | ------------- | ------------- |
| siteId     | 库位ID   | 必填     | String        | 库位ID        |
| attrName   | 属性名称 | 必填     | String        | 指定的库位扩展属性名称|
| attrValue  | 属性值   | 非必填   | Any           | 属性值        |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "attrName": "temperature",
  "attrValue": 25
}

// 成功响应示例
{
  "success": true,
  "message": "设置库位属性值成功，site001.temperature = 25",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "设置库位属性值失败: 库位不存在",
  "code": 404
}
```

## 设置库位货物 (SetSiteContentBp)

本接口用于设置库位的货物内容。

### 描述

本块用于设置指定库位ID的货物内容，通常用于标记库位中存放的具体物品。

### 输入参数

| 参数名    | 是否必填 | 类型          | 描述          |
| --------- | -------- | ------------- | ------------- |
| siteId    | 必填     | String        | 库位ID        |
| content   | 必填     | String        | 货物内容      |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "content": "产品A-批次123"
}

// 成功响应示例
{
  "success": true,
  "message": "设置库位货物成功，site001 货物: 产品A-批次123",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "设置库位货物失败: 库位不存在",
  "code": 404
}
```

## 设置库位为空 (SetSiteEmptyBp)

本接口用于将库位设置为空闲状态。

### 描述

该块可以将指定库位设置为未占用状态，同时清空货物字段。

### 输入参数

| 参数名    | 中文名称 | 是否必填 | 类型          | 描述          |
| --------- | -------- | -------- | ------------- | ------------- |
| siteId    | 库位ID   | 必填     | String        | 库位ID        |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001"
}

// 成功响应示例
{
  "success": true,
  "message": "设置库位为空成功，库位ID: site001",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "设置库位为空失败: 库位不存在",
  "code": 404
}
```

## 设置库位为占用 (SetSiteFilledBp)

本接口用于将库位设置为占用状态。

### 描述

该块可以将指定库位设置为占用状态，但不操作货物字符串。


### 输入参数

| 参数名    | 中文名称 | 是否必填 | 类型          | 描述          |
| --------- | -------- | -------- | ------------- | ------------- |
| siteId    | 库位ID   | 必填     | String        | 库位ID        |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001"
}

// 成功响应示例
{
  "success": true,
  "message": "设置库位为占用成功，库位ID: site001",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "设置库位为占用失败: 库位不存在",
  "code": 404
}
```

## 锁定库位 (SetSiteLockedBp)

本接口用于锁定库位，防止其他任务操作该库位。

### 描述

该块可以将指定定的库位锁定，前提是该库位位已经在库存中设置或者在当前节点任务实例中被当前节点加锁。如果不满足条件，这个块将阻塞，直到该库位可交为解锁状态，然后进行锁定。

### 输入参数

| 参数名      | 是否必填 | 类型         | 描述                     |
| ---------- | -------- | ------------ | ------------------------ |
| 库位 Id    | 必填     | String       | 指定的库位 Id            |
| 是否为公平锁 | 非必填   | boolean      | 任务先发出加锁库位，优先这个任务加锁此库位 |
| 加锁者     | 非必填   | String       | 指定加锁该库位的加锁者，默认为当前任务实例id |
| 重试次数   | 非必填   | Integer      | 重试次数                 |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "ifFair": true,
  "locker": "task123456",
  "retryNum": 3
}

// 成功响应示例
{
  "success": true,
  "message": "锁定库位成功，库位ID: site001",
  "code": 200,
  "data": {
    "success": true
  }
}

// 失败响应示例
{
  "success": false,
  "message": "锁定库位失败，库位ID: site001，可能已被其他任务锁定",
  "code": 409,
  "data": {
    "success": false
  }
}
```

## 解锁库位 (SetSiteUnlockedBp)

本接口用于解锁库位，允许其他任务操作该库位。

### 描述

本块用于解锁特定的库位ID，解除其与特定任务的关联，允许其他任务操作该库位。

### 输入参数

| 参数名      | 中文名称 | 是否必填 | 类型          | 描述                  |
| ---------- | -------- | -------- | ------------- | --------------------- |
| siteId     | 库位ID   | 必填     | String        | 指定的库位ID          |
| unLockedId | 解锁者   | 非必填   | String        | 指定解锁该库位的解锁者，默认为当前任务实例id |

### 输出参数

| 参数名    | 中文名称  | 类型    | 描述                |
| --------- | --------- | ------- | ------------------- |
| success   | 成功标志  | Boolean | 操作是否成功        |
| message   | 消息      | String  | 操作结果消息        |
| code      | 返回代码  | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "unLockedId": "task123456"
}

// 成功响应示例
{
  "success": true,
  "message": "解锁库位成功，库位ID: site001",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "解锁库位失败: 库位不存在",
  "code": 404
}
```

## 设置库位标签 (SetSiteTagsBp)

本接口用于设置库位的标签信息。

### 描述

本块用于为指定库位设置标签，可用于标记库位的特殊属性或分类，便于后续查询和管理。

### 输入参数

| 参数名    | 中文名称 | 是否必填 | 类型          | 描述          |
| --------- | -------- | -------- | ------------- | ------------- |
| siteId    | 库位ID   | 必填     | String        | 指定的库位ID  |
| tags      | 标签     | 非必填   | String        | 库位标签，多个标签可用逗号分隔 |

### 输出参数

| 参数名    | 中文名称 | 类型    | 描述                |
| --------- | -------- | ------- | ------------------- |
| success   | 成功标志 | Boolean | 操作是否成功        |
| message   | 消息     | String  | 操作结果消息        |
| code      | 返回代码 | Number  | 操作结果代码        |

### 调用示例

```json
// 输入参数示例
{
  "siteId": "site001",
  "tags": "临时存储,高优先级,易碎品"
}

// 成功响应示例
{
  "success": true,
  "message": "设置库位标签成功，库位ID: site001，标签: 临时存储,高优先级,易碎品",
  "code": 200
}

// 失败响应示例
{
  "success": false,
  "message": "设置库位标签失败: 库位不存在",
  "code": 404
}
```

## 获取库位详情 (GetStorageLocationDetail)

本接口用于获取指定库位的详细信息。

### 描述

本接口用于获取指定库位的完整详情信息，包括库位基本信息、动作点信息、扩展字段定义和值、状态变更历史等。适用于需要全面了解库位信息的场景。

### 接口信息

- **URL**: `/api/vwed-operate-point/{storage_location_id}`
- **方法**: GET
- **认证**: 需要

### 输入参数

| 参数名              | 中文名称 | 是否必填 | 类型   | 描述                           |
| ------------------ | -------- | -------- | ------ | ------------------------------ |
| storage_location_id | 库位ID   | 必填     | String | 要获取详情的库位ID              |

### 输出参数

| 参数名                      | 中文名称         | 类型    | 描述                           |
| -------------------------- | --------------- | ------- | ------------------------------ |
| code                       | 返回代码         | Number  | 操作结果代码                    |
| message                    | 消息            | String  | 操作结果消息                    |
| data                       | 数据            | Object  | 返回数据对象                    |
| data.storage_location      | 库位信息         | Object  | 库位基本信息                    |
| data.operate_point_info    | 动作点信息       | Object  | 所属动作点的详细信息             |
| data.extended_fields_definitions | 扩展字段定义 | Array   | 扩展字段的定义信息               |
| data.status_history        | 状态变更历史     | Array   | 库位状态变更历史记录             |

### 调用示例

```json
// 请求URL
GET /api/vwed-operate-point/layer-001

// 成功响应示例
{
  "code": 200,
  "message": "获取库位详情成功",
  "data": {
    "storage_location": {
      "id": "layer-001",
      "layer_index": 1,
      "layer_name": "第一层",
      "is_occupied": false,
      "is_locked": false,
      "is_disabled": false,
      "is_empty_tray": false,
      "locked_by": null,
      "goods_content": "",
      "goods_weight": null,
      "goods_volume": null,
      "goods_stored_at": null,
      "goods_retrieved_at": null,
      "last_access_at": null,
      "max_weight": 5000,
      "max_volume": 1000,
      "layer_height": 300,
      "tags": "高架库,密集存储",
      "description": "密集存储区第一层",
      "created_at": "2024-01-01T00:00:00",
      "updated_at": "2024-01-01T00:00:00",
      "extended_fields": {
        "产品类别": "电子产品",
        "存储温度": "常温"
      },
      "operate_point_id": "point-001",
      "station_name": "存储站点A",
      "storage_location_name": "A1库位",
      "scene_id": "scene-001",
      "storage_area_id": "area-001"
    },
    "operate_point_info": {
      "id": "point-001",
      "station_name": "存储站点A",
      "storage_location_name": "A1库位",
      "scene_id": "scene-001",
      "storage_area_id": "area-001",
      "storage_area_type": "dense",
      "area_name": "密集存储区",
      "max_layers": 10,
      "current_layers": 5,
      "position_x": 100,
      "position_y": 200,
      "position_z": 0,
      "description": "密集存储区的动作点",
      "created_at": "2024-01-01T00:00:00",
      "updated_at": "2024-01-01T00:00:00",
      "is_deleted": false
    },
    "extended_fields_definitions": [
      {
        "id": "ext-001",
        "property_name": "产品类别",
        "property_type": "select",
        "is_required": true,
        "is_enabled": true,
        "description": "产品分类",
        "options": [
          {"value": "电子产品", "label": "电子产品"},
          {"value": "机械配件", "label": "机械配件"}
        ]
      },
      {
        "id": "ext-002",
        "property_name": "存储温度",
        "property_type": "string",
        "is_required": false,
        "is_enabled": true,
        "description": "存储温度要求"
      }
    ],
    "status_history": []
  }
}

// 失败响应示例
{
  "code": 404,
  "message": "库位 layer-001 不存在",
  "data": null
}
```

## 编辑库位信息 (EditStorageLocation)

本接口用于编辑和更新库位的各种属性信息。

### 描述

本接口用于编辑库位的各种属性，包括货物信息、库位规格、状态字段、扩展字段等。支持部分更新，只有传入的字段且值发生变化时才会被更新。扩展字段必须在系统中已定义且已启用。

### 接口信息

- **URL**: `/api/vwed-operate-point/{storage_location_id}`
- **方法**: PUT
- **认证**: 需要

### 输入参数

| 参数名              | 中文名称      | 是否必填 | 类型    | 描述                           |
| ------------------ | ------------ | -------- | ------- | ------------------------------ |
| storage_location_id | 库位ID       | 必填     | String  | 要编辑的库位ID                  |
| goods_content      | 货物内容      | 非必填   | String  | 货物内容描述                    |
| goods_weight       | 货物重量      | 非必填   | Integer | 货物重量（克）                  |
| goods_volume       | 货物体积      | 非必填   | Integer | 货物体积（立方厘米）            |
| max_weight         | 最大承重      | 非必填   | Integer | 最大承重（克）                  |
| max_volume         | 最大体积      | 非必填   | Integer | 最大体积（立方厘米）            |
| layer_height       | 层高          | 非必填   | Integer | 层高（毫米）                    |
| is_locked          | 是否锁定      | 非必填   | Boolean | 库位是否锁定                    |
| is_disabled        | 是否禁用      | 非必填   | Boolean | 库位是否禁用                    |
| is_empty_tray      | 是否空托盘    | 非必填   | Boolean | 库位是否为空托盘状态            |
| tags               | 标签          | 非必填   | String  | 库位标签                        |
| description        | 描述          | 非必填   | String  | 库位描述                        |
| extended_fields    | 扩展字段      | 非必填   | Object  | 扩展字段的键值对                |

### 输出参数

| 参数名                      | 中文名称         | 类型    | 描述                           |
| -------------------------- | --------------- | ------- | ------------------------------ |
| code                       | 返回代码         | Number  | 操作结果代码                    |
| message                    | 消息            | String  | 操作结果消息                    |
| data                       | 数据            | Object  | 返回数据对象                    |
| data.storage_location_id   | 库位ID          | String  | 被编辑的库位ID                  |
| data.success               | 成功标志         | Boolean | 编辑是否成功                    |
| data.message               | 操作消息         | String  | 详细的操作结果消息               |
| data.updated_fields        | 更新字段列表     | Array   | 已更新的字段名称列表             |
| data.updated_storage_location | 更新后库位信息 | Object  | 更新后的库位完整信息             |

### 调用示例

```json
// 请求URL
PUT /api/vwed-operate-point/layer-001

// 请求体示例
{
  "goods_content": "电子产品A",
  "goods_weight": 500,
  "goods_volume": 200,
  "max_weight": 6000,
  "is_locked": false,
  "is_disabled": false,
  "is_empty_tray": true,
  "tags": "高架库,密集存储,已更新",
  "description": "密集存储区第一层 - 已更新",
  "extended_fields": {
    "产品类别": "机械配件",
    "存储温度": "常温",
    "保质期": "12个月"
  }
}

// 成功响应示例
{
  "code": 200,
  "message": "库位信息编辑成功",
  "data": {
    "storage_location_id": "layer-001",
    "success": true,
    "message": "库位信息更新成功，共更新 8 个字段",
    "updated_fields": [
      "goods_content",
      "goods_weight",
      "goods_volume",
      "max_weight",
      "is_locked",
      "is_disabled",
      "is_empty_tray",
      "tags",
      "description",
      "extended_fields.产品类别",
      "extended_fields.存储温度",
      "extended_fields.保质期",
      "updated_at"
    ],
    "updated_storage_location": {
      "id": "layer-001",
      "layer_index": 1,
      "layer_name": "第一层",
      "is_occupied": false,
      "is_locked": false,
      "is_disabled": false,
      "is_empty_tray": true,
      "locked_by": null,
      "goods_content": "电子产品A",
      "goods_weight": 500,
      "goods_volume": 200,
      "goods_stored_at": null,
      "goods_retrieved_at": null,
      "last_access_at": null,
      "max_weight": 6000,
      "max_volume": 1000,
      "layer_height": 300,
      "tags": "高架库,密集存储,已更新",
      "description": "密集存储区第一层 - 已更新",
      "created_at": "2024-01-01T00:00:00",
      "updated_at": "2024-01-02T10:30:00",
      "extended_fields": {
        "产品类别": "机械配件",
        "存储温度": "常温",
        "保质期": "12个月"
      },
      "operate_point_id": "point-001",
      "station_name": "存储站点A",
      "storage_location_name": "A1库位",
      "scene_id": "scene-001",
      "storage_area_id": "area-001"
    }
  }
}

// 失败响应示例
{
  "code": 404,
  "message": "库位 layer-001 不存在",
  "data": null
}

// 没有字段变化的响应示例
{
  "code": 200,
  "message": "库位信息编辑成功",
  "data": {
    "storage_location_id": "layer-001",
    "success": true,
    "message": "没有字段发生变化，数据保持不变",
    "updated_fields": [],
    "updated_storage_location": {
      "id": "layer-001",
      "layer_index": 1,
      "layer_name": "第一层",
      "is_occupied": false,
      "is_locked": false,
      "is_disabled": false,
      "is_empty_tray": false,
      "locked_by": null,
      "goods_content": "电子产品A",
      "goods_weight": 500,
      "goods_volume": 200,
      "goods_stored_at": null,
      "goods_retrieved_at": null,
      "last_access_at": null,
      "max_weight": 6000,
      "max_volume": 1000,
      "layer_height": 300,
      "tags": "高架库,密集存储",
      "description": "密集存储区第一层",
      "created_at": "2024-01-01T00:00:00",
      "updated_at": "2024-01-01T00:00:00",
      "extended_fields": {
        "产品类别": "电子产品",
        "存储温度": "常温"
      },
      "operate_point_id": "point-001",
      "station_name": "存储站点A",
      "storage_location_name": "A1库位",
      "scene_id": "scene-001",
      "storage_area_id": "area-001"
    }
  }
}

// 部分字段更新失败示例
{
  "code": 400,
  "message": "更新扩展字段失败: 扩展字段 未定义字段 不存在或已禁用",
  "data": null
}
```

### 注意事项

1. **部分更新**: 只有传入的字段且值发生变化时才会被更新，未传入的字段保持原值
2. **层名称限制**: 层名称（layer_name）不能通过此接口修改，请使用其他方式
3. **状态字段支持**: 支持修改 `is_locked`、`is_disabled`、`is_empty_tray` 三个状态字段
4. **扩展字段验证**: 扩展字段必须在系统中已定义且已启用，否则会跳过更新
5. **数据变更校验**: 如果所有字段都没有发生变化，会返回相应提示信息
6. **字段验证**: 数值类型字段会进行范围验证，字符串类型字段会进行长度验证
7. **事务处理**: 所有更新操作在同一个事务中进行，确保数据一致性

## 获取库位操作记录 (GetStorageLocationOperationLogs)

本接口用于获取库位相关的操作记录，支持多种筛选条件和分页查询。

### 描述

本接口用于查询库位相关的操作记录，包括状态更新操作、信息编辑操作等。所有对库位的操作都会自动记录到操作日志中，方便后续审计和追踪。

### 接口信息

- **URL**: `/api/vwed-operate-point/operation-logs`
- **方法**: GET
- **认证**: 需要

### 输入参数

| 参数名              | 中文名称      | 是否必填 | 类型    | 描述                           |
| ------------------ | ------------ | -------- | ------- | ------------------------------ |
| storage_location_id | 库位ID       | 非必填   | String  | 查询特定库位的操作记录           |
| operator           | 操作人        | 非必填   | String  | 操作人姓名（支持模糊搜索）       |
| operation_type     | 操作类型      | 非必填   | String  | 操作类型（如：occupy、release等）|
| start_time         | 开始时间      | 非必填   | String  | 开始时间（格式：YYYY-MM-DD HH:MM:SS）|
| end_time           | 结束时间      | 非必填   | String  | 结束时间（格式：YYYY-MM-DD HH:MM:SS）|
| page               | 页码          | 非必填   | Integer | 页码，默认为1                   |
| page_size          | 每页数量      | 非必填   | Integer | 每页数量，默认为20，最大100      |

### 输出参数

| 参数名                      | 中文名称         | 类型    | 描述                           |
| -------------------------- | --------------- | ------- | ------------------------------ |
| code                       | 返回代码         | Number  | 操作结果代码                    |
| message                    | 消息            | String  | 操作结果消息                    |
| data                       | 数据            | Object  | 返回数据对象                    |
| data.total                 | 总数量          | Number  | 符合条件的记录总数               |
| data.page                  | 当前页码        | Number  | 当前页码                        |
| data.page_size             | 每页数量        | Number  | 每页数量                        |
| data.total_pages           | 总页数          | Number  | 总页数                          |
| data.logs                  | 操作记录列表    | Array   | 操作记录数组                    |
| data.logs[].id             | 记录ID          | String  | 操作记录的唯一标识               |
| data.logs[].operation_time | 操作时间        | String  | 操作发生的时间                   |
| data.logs[].operator       | 操作人          | String  | 执行操作的人员                   |
| data.logs[].operation_type | 操作类型        | String  | 操作类型                        |
| data.logs[].affected_storage_locations | 影响的库位列表 | Array | 受影响的库位ID列表            |
| data.logs[].description    | 操作描述        | String  | 操作的详细描述                   |
| data.logs[].created_at     | 创建时间        | String  | 记录创建时间                     |

### 支持的操作类型

| 操作类型      | 中文名称     | 描述                           |
| ------------ | ----------- | ------------------------------ |
| occupy       | 占用库位     | 将库位设置为占用状态             |
| release      | 释放库位     | 将库位设置为空闲状态             |
| lock         | 锁定库位     | 锁定库位防止其他操作             |
| unlock       | 解锁库位     | 解锁库位允许其他操作             |
| enable       | 启用库位     | 启用库位使其可用                 |
| disable      | 禁用库位     | 禁用库位使其不可用               |
| set_empty_tray | 设置空托盘   | 将库位设置为空托盘状态           |
| clear_empty_tray | 清除空托盘 | 清除库位的空托盘状态             |
| 编辑库位     | 编辑库位     | 编辑库位的信息                   |

### 调用示例

```json
// 请求URL示例
GET /api/vwed-operate-point/operation-logs?storage_location_id=layer-001&page=1&page_size=10

// 带时间范围的请求示例
GET /api/vwed-operate-point/operation-logs?start_time=2024-01-01 00:00:00&end_time=2024-01-02 23:59:59&operator=admin&page=1&page_size=20

// 成功响应示例
{
  "code": 200,
  "message": "查询操作记录成功",
  "data": {
    "total": 25,
    "page": 1,
    "page_size": 10,
    "total_pages": 3,
    "logs": [
      {
        "id": "log-001",
        "operation_time": "2024-01-02T10:30:00",
        "operator": "admin",
        "operation_type": "编辑库位",
        "affected_storage_locations": ["layer-001"],
        "description": "编辑库位信息，更新字段: goods_content, goods_weight, is_locked",
        "created_at": "2024-01-02T10:30:00"
      },
      {
        "id": "log-002",
        "operation_time": "2024-01-02T09:15:00",
        "operator": "系统",
        "operation_type": "occupy",
        "affected_storage_locations": ["layer-001"],
        "description": "占用库位操作",
        "created_at": "2024-01-02T09:15:00"
      },
      {
        "id": "log-003",
        "operation_time": "2024-01-02T08:45:00",
        "operator": "user001",
        "operation_type": "lock",
        "affected_storage_locations": ["layer-001", "layer-002"],
        "description": "锁定库位操作",
        "created_at": "2024-01-02T08:45:00"
      }
    ]
  }
}

// 空结果响应示例
{
  "code": 200,
  "message": "查询操作记录成功",
  "data": {
    "total": 0,
    "page": 1,
    "page_size": 10,
    "total_pages": 0,
    "logs": []
  }
}

// 时间格式错误示例
{
  "code": 400,
  "message": "开始时间格式错误，请使用格式：YYYY-MM-DD HH:MM:SS",
  "data": null
}

// 参数错误示例
{
  "code": 400,
  "message": "开始时间不能大于结束时间",
  "data": null
}
```

### 注意事项

1. **时间格式**: 时间参数必须使用格式 `YYYY-MM-DD HH:MM:SS`，例如 `2024-01-01 12:00:00`
2. **时间范围**: 如果同时提供开始时间和结束时间，开始时间不能大于结束时间
3. **模糊搜索**: 操作人字段支持模糊搜索，会匹配包含关键词的记录
4. **排序方式**: 操作记录按操作时间倒序排列，最新的操作记录在前面
5. **自动记录**: 所有对库位的操作都会自动记录，无需手动创建记录
6. **分页限制**: 每页最多返回100条记录
7. **数据完整性**: 操作记录一旦创建就不能修改或删除，确保审计追踪的完整性