# 库位管理开发文档

## 概述

库位管理模块是VWED任务系统的核心组件之一，提供对库位（基于动作点分层）的全面管理功能。本文档详细介绍了库位管理的API接口、内部实现、数据模型以及开发指南。

## 架构概述

### 系统架构

```
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   API 层        │    │   服务层        │    │   数据层        │
│   (Routes)      │───▶│   (Services)    │───▶│   (Models)      │
│                 │    │                 │    │                 │
│ operate_point_  │    │ OperatePoint    │    │ OperatePoint    │
│ api.py          │    │ Service         │    │ Layer           │
└─────────────────┘    └─────────────────┘    └─────────────────┘
```

### 核心组件

1. **API路由层** (`routes/operate_point_api.py`): FastAPI路由定义
2. **服务层** (`services/operate_point_service.py`): 业务逻辑处理
3. **数据模型层** (`data/models/`): ORM模型定义
4. **请求/响应模型** (`routes/model/operate_point_model.py`): API数据模型

## 数据模型

### 主要数据表

#### OperatePointLayer (库位层表)
```sql
CREATE TABLE operate_point_layer (
    id VARCHAR(255) PRIMARY KEY,           -- 库位ID
    operate_point_id VARCHAR(255),         -- 动作点ID (外键)
    layer_index INTEGER,                   -- 层索引
    layer_name VARCHAR(255),               -- 库位名称
    is_occupied BOOLEAN DEFAULT FALSE,     -- 是否占用
    is_locked BOOLEAN DEFAULT FALSE,       -- 是否锁定
    is_disabled BOOLEAN DEFAULT FALSE,     -- 是否禁用
    is_empty_tray BOOLEAN DEFAULT FALSE,   -- 是否空托盘
    locked_by VARCHAR(255),                -- 锁定者
    goods_content TEXT,                    -- 货物内容
    goods_weight INTEGER,                  -- 货物重量(克)
    goods_volume INTEGER,                  -- 货物体积(立方厘米)
    max_weight INTEGER,                    -- 最大承重(克)
    max_volume INTEGER,                    -- 最大体积(立方厘米)
    layer_height INTEGER,                  -- 层高(毫米)
    tags TEXT,                             -- 标签
    description TEXT,                      -- 描述
    config_json JSONB,                     -- 扩展字段配置
    created_at TIMESTAMP,                  -- 创建时间
    updated_at TIMESTAMP,                  -- 更新时间
    is_deleted BOOLEAN DEFAULT FALSE       -- 软删除标记
);
```

#### OperatePoint (动作点表)
```sql
CREATE TABLE operate_point (
    id VARCHAR(255) PRIMARY KEY,           -- 动作点ID
    station_name VARCHAR(255),             -- 站点名称
    scene_id VARCHAR(255),                 -- 场景ID
    storage_area_id VARCHAR(255),          -- 库区ID
    max_layers INTEGER,                    -- 最大层数
    current_layers INTEGER,                -- 当前层数
    position_x DECIMAL(10,3),              -- X坐标
    position_y DECIMAL(10,3),              -- Y坐标
    position_z DECIMAL(10,3),              -- Z坐标
    description TEXT,                      -- 描述
    created_at TIMESTAMP,                  -- 创建时间
    updated_at TIMESTAMP,                  -- 更新时间
    is_deleted BOOLEAN DEFAULT FALSE       -- 软删除标记
);
```

#### ExtendedProperty (扩展属性表)
```sql
CREATE TABLE extended_property (
    id VARCHAR(255) PRIMARY KEY,           -- 属性ID
    property_key VARCHAR(255) UNIQUE,      -- 属性键名
    property_name VARCHAR(255),            -- 属性名称
    property_type VARCHAR(50),             -- 属性类型
    is_required BOOLEAN DEFAULT FALSE,     -- 是否必填
    is_enabled BOOLEAN DEFAULT TRUE,       -- 是否启用
    default_value TEXT,                    -- 默认值
    description TEXT,                      -- 描述
    category VARCHAR(100),                 -- 分类
    validation_rules JSONB,                -- 验证规则
    options JSONB,                         -- 选项(select类型使用)
    created_at TIMESTAMP,                  -- 创建时间
    updated_at TIMESTAMP,                  -- 更新时间
    is_deleted BOOLEAN DEFAULT FALSE       -- 软删除标记
);
```

#### StorageLocationLog (库位操作日志表)
```sql
CREATE TABLE storage_location_log (
    id VARCHAR(255) PRIMARY KEY,           -- 日志ID
    operation_time TIMESTAMP,              -- 操作时间
    operator VARCHAR(255),                 -- 操作人
    operation_type VARCHAR(100),           -- 操作类型
    affected_storage_locations JSONB,      -- 受影响的库位列表
    description TEXT,                      -- 操作描述
    request_data JSONB,                    -- 请求数据
    created_at TIMESTAMP                   -- 创建时间
);
```

## API接口详解

### 接口分类

库位管理API主要分为以下几类：

1. **库位查询接口** - 获取库位列表、详情、状态
2. **库位操作接口** - 更新库位状态、编辑库位信息
3. **扩展属性接口** - 管理自定义属性定义
4. **操作记录接口** - 查询操作历史记录

### 核心接口实现

#### 1. 获取库位列表 (`GET /api/vwed-operate-point/list`)

**实现流程：**

```python
@router.get("/list")
async def get_storage_location_list(
    # 查询参数
    scene_id: Optional[str] = None,
    storage_area_id: Optional[str] = None,
    # ... 其他参数
    db: Session = Depends(get_db)
):
    # 1. 参数验证和构建请求对象
    request = StorageLocationListRequest(...)
    
    # 2. 调用服务层方法
    result = OperatePointService.get_storage_location_list(db, request)
    
    # 3. 返回格式化响应
    return api_response(message="查询成功", data=result)
```

**服务层实现关键点：**

1. **动态查询构建**：根据请求参数动态构建SQLAlchemy查询
2. **关联查询优化**：只在需要时关联OperatePoint表
3. **自定义排序**：支持层名称和站点名称的智能排序
4. **分页处理**：内存中排序后再分页
5. **数据转换**：将ORM对象转换为响应模型

```python
def get_storage_location_list(db: Session, request: StorageLocationListRequest):
    # 构建基础查询
    query = db.query(OperatePointLayer).filter(
        OperatePointLayer.is_deleted == False
    )
    
    # 条件过滤
    if request.scene_id or request.storage_area_id:
        query = query.join(OperatePoint)
    
    # 应用自定义排序
    storage_locations = query.all()
    if request.layer_name_sort is not None:
        storage_locations = _apply_custom_sorting(
            storage_locations, request.layer_name_sort, request.station_name_sort
        )
    
    # 分页和数据转换
    # ...
```

#### 2. 更新库位状态 (`PUT /api/vwed-operate-point/status`)

**支持的操作类型：**

```python
class StorageLocationActionEnum(str, Enum):
    OCCUPY = "occupy"                    # 占用库位
    RELEASE = "release"                  # 释放库位
    LOCK = "lock"                       # 锁定库位
    UNLOCK = "unlock"                   # 解锁库位
    ENABLE = "enable"                   # 启用库位
    DISABLE = "disable"                 # 禁用库位
    SET_EMPTY_TRAY = "set_empty_tray"   # 设置为空托盘
    CLEAR_EMPTY_TRAY = "clear_empty_tray" # 清除空托盘状态
```

**实现流程：**

```python
def update_storage_location_status(db: Session, request: StorageLocationStatusUpdateRequest):
    # 1. 查找库位
    storage_location = db.query(OperatePointLayer).filter(
        OperatePointLayer.layer_name == request.layer_name,
        OperatePointLayer.is_deleted == False
    ).first()
    
    # 2. 验证操作合法性
    if not storage_location:
        raise ValueError("库位不存在")
    
    # 3. 执行状态更新
    old_status = _get_storage_location_status(storage_location)
    _apply_action(storage_location, request.action, request.locked_by)
    
    # 4. 记录操作日志
    _log_operation(request.layer_name, request.action, request.operator, request.reason)
    
    # 5. 提交事务
    db.commit()
    
    return StatusUpdateResult(...)
```

#### 3. 扩展属性管理

扩展属性系统允许用户为库位定义自定义字段，具有以下特点：

1. **动态属性定义**：支持多种数据类型
2. **全局同步**：创建/删除属性会同步到所有库位
3. **验证规则**：支持自定义验证逻辑
4. **UI友好**：支持显示格式和选项配置

**创建扩展属性流程：**

```python
def create_extended_property(db: Session, request: ExtendedPropertyCreateRequest):
    # 1. 验证属性名唯一性
    existing = db.query(ExtendedProperty).filter(
        ExtendedProperty.property_key == request.property_key
    ).first()
    if existing:
        raise ValueError("属性键名已存在")
    
    # 2. 创建属性定义
    property_obj = ExtendedProperty(...)
    db.add(property_obj)
    
    # 3. 同步到所有库位
    layers = db.query(OperatePointLayer).filter(
        OperatePointLayer.is_deleted == False
    ).all()
    
    for layer in layers:
        config = layer.config_json or {}
        config[request.property_key] = request.default_value
        layer.config_json = config
    
    # 4. 提交事务
    db.commit()
    
    return CreateResult(affected_layers_count=len(layers))
```

## 核心功能详解

### 1. 智能排序功能

系统支持对库位名称和站点名称进行智能排序，能够正确处理字母数字混合的名称：

```python
def _apply_custom_sorting(storage_locations, layer_name_sort, station_name_sort):
    """
    智能排序算法：
    1. 解析名称中的字母和数字部分
    2. 先按字母部分排序
    3. 字母相同时按数字部分逐位比较
    
    示例：AP1, AP2, AP10, AP11, B1, B2
    """
    import re
    
    def _parse_alphanumeric_name(name):
        parts = re.findall(r'([A-Za-z]+)|(\d+)', name)
        letters = ""
        numbers = []
        
        for letter_part, number_part in parts:
            if letter_part:
                letters += letter_part
            elif number_part:
                numbers.append(int(number_part))
        
        return (letters.upper(), numbers)
    
    # 实现排序比较逻辑
    # ...
```

### 2. 批量操作机制

批量状态更新支持以下特性：

1. **事务一致性**：所有操作在同一事务中执行
2. **部分成功处理**：记录每个库位的操作结果
3. **冲突检测**：检测并报告操作冲突
4. **性能优化**：批量查询和更新

```python
def batch_update_storage_location_status(db: Session, request: BatchStorageLocationStatusUpdateRequest):
    results = []
    
    # 批量查询所有库位
    storage_locations = db.query(OperatePointLayer).filter(
        OperatePointLayer.layer_name.in_(request.layer_names),
        OperatePointLayer.is_deleted == False
    ).all()
    
    # 创建名称到对象的映射
    location_map = {sl.layer_name: sl for sl in storage_locations}
    
    # 处理每个库位
    for layer_name in request.layer_names:
        try:
            if layer_name not in location_map:
                results.append(OperationResult(
                    layer_name=layer_name,
                    success=False,
                    message="库位不存在"
                ))
                continue
            
            # 执行操作
            storage_location = location_map[layer_name]
            result = _apply_single_action(storage_location, request.action, request.locked_by)
            results.append(result)
            
        except Exception as e:
            results.append(OperationResult(
                layer_name=layer_name,
                success=False,
                message=str(e)
            ))
    
    # 提交事务
    db.commit()
    
    return BatchUpdateResult(results=results)
```

### 3. 扩展字段管理

扩展字段系统的设计要点：

1. **存储机制**：使用JSONB字段存储扩展属性值
2. **类型系统**：支持string、integer、float、boolean、date等类型
3. **验证系统**：支持必填验证、格式验证、范围验证
4. **UI集成**：提供显示格式、宽度等UI配置

```python
# 扩展字段配置示例
{
    "temperature": {
        "value": 25.5,
        "type": "float",
        "display_format": "{{value}}°C",
        "validation": {
            "min": -50,
            "max": 100
        }
    },
    "product_category": {
        "value": "electronics",
        "type": "select",
        "options": [
            {"value": "electronics", "label": "电子产品"},
            {"value": "machinery", "label": "机械配件"}
        ]
    }
}
```

### 4. 操作日志系统

所有库位操作都会自动记录到操作日志中：

```python
def _log_storage_location_operation(
    layer_names: List[str], 
    operation_type: str, 
    operator: str, 
    description: str,
    request_data: Dict = None
):
    """记录库位操作日志"""
    log_entry = StorageLocationLog(
        id=generate_uuid(),
        operation_time=datetime.now(),
        operator=operator,
        operation_type=operation_type,
        affected_storage_locations=layer_names,
        description=description,
        request_data=request_data or {}
    )
    
    db.add(log_entry)
    # 注意：不在此处提交事务，由调用方统一提交
```

## 开发指南

### 1. 添加新的操作类型

要添加新的库位操作类型，需要：

1. **更新枚举定义**：
```python
class StorageLocationActionEnum(str, Enum):
    # 现有操作...
    NEW_ACTION = "new_action"  # 新操作
```

2. **实现操作逻辑**：
```python
def _apply_new_action(storage_location: OperatePointLayer, **kwargs):
    """实现新操作的具体逻辑"""
    # 验证前置条件
    if not _can_perform_new_action(storage_location):
        raise ValueError("无法执行新操作")
    
    # 执行状态更新
    storage_location.some_field = new_value
    storage_location.updated_at = datetime.now()
    
    return "新操作执行成功"
```

3. **更新操作描述**：
```python
def get_action_descriptions():
    descriptions = {
        # 现有描述...
        StorageLocationActionEnum.NEW_ACTION: "执行新操作"
    }
    return descriptions
```

### 2. 扩展字段类型支持

要添加新的扩展字段类型：

1. **更新类型枚举**：
```python
class ExtendedPropertyTypeEnum(str, Enum):
    # 现有类型...
    CUSTOM_TYPE = "custom_type"
```

2. **实现验证逻辑**：
```python
def _validate_custom_type_value(value, property_config):
    """验证自定义类型的值"""
    # 实现验证逻辑
    pass
```

3. **更新UI配置**：
```python
def _get_custom_type_ui_config(property_config):
    """返回自定义类型的UI配置"""
    return {
        "component": "CustomTypeInput",
        "props": {
            # UI组件属性
        }
    }
```

### 3. 性能优化建议

1. **查询优化**：
   - 合理使用数据库索引
   - 避免N+1查询问题
   - 使用批量查询替代循环查询

2. **内存管理**：
   - 大量数据查询时使用分页
   - 及时释放不需要的对象引用
   - 考虑使用数据流处理

3. **缓存策略**：
   - 缓存扩展属性配置
   - 缓存常用的库位状态查询
   - 使用Redis进行分布式缓存

### 4. 错误处理最佳实践

```python
# 统一错误处理模式
try:
    # 业务逻辑
    result = perform_operation()
    return success_response(result)
    
except ValueError as e:
    # 业务逻辑错误（客户端错误）
    logger.warning(f"业务逻辑错误: {str(e)}")
    return error_response(str(e), 400)
    
except PermissionError as e:
    # 权限错误
    logger.warning(f"权限不足: {str(e)}")
    return error_response("权限不足", 403)
    
except Exception as e:
    # 系统错误（服务器错误）
    logger.error(f"系统错误: {str(e)}", exc_info=True)
    return error_response("系统内部错误", 500)
```

### 5. 测试策略

1. **单元测试**：
```python
def test_update_storage_location_status():
    # 准备测试数据
    storage_location = create_test_storage_location()
    request = StorageLocationStatusUpdateRequest(
        layer_name="test-layer",
        action="occupy"
    )
    
    # 执行测试
    result = OperatePointService.update_storage_location_status(db, request)
    
    # 验证结果
    assert result.success == True
    assert storage_location.is_occupied == True
```

2. **集成测试**：
```python
def test_storage_location_api_integration():
    # 测试完整的API调用流程
    response = client.put("/api/vwed-operate-point/status", json={
        "layer_name": "test-layer",
        "action": "occupy"
    })
    
    assert response.status_code == 200
    assert response.json()["code"] == 200
```

## 部署和维护

### 1. 数据库迁移

当需要修改数据表结构时：

```python
# 创建迁移文件
python scripts/generate_migration.py

# 应用迁移
python scripts/run_migration.py
```

### 2. 监控和日志

关键指标监控：
- API响应时间
- 数据库查询性能
- 错误率统计
- 库位操作频率

日志配置：
```python
# 在utils/logger.py中配置
logger = get_logger("services.operate_point_service")
logger.info("库位状态更新", extra={
    "layer_name": layer_name,
    "action": action,
    "operator": operator
})
```

### 3. 性能调优

数据库优化：
```sql
-- 创建必要的索引
CREATE INDEX idx_operate_point_layer_name ON operate_point_layer(layer_name);
CREATE INDEX idx_operate_point_layer_status ON operate_point_layer(is_occupied, is_locked, is_disabled);
CREATE INDEX idx_storage_location_log_time ON storage_location_log(operation_time);
```

## 总结

库位管理模块是一个功能完整、设计良好的系统组件，提供了：

1. **完整的CRUD操作**：支持库位的查询、创建、更新、删除
2. **灵活的状态管理**：支持多种库位状态操作
3. **可扩展的属性系统**：允许用户定义自定义字段
4. **完整的操作审计**：记录所有操作历史
5. **高性能的查询**：支持复杂查询和智能排序
6. **良好的错误处理**：统一的错误处理和响应格式

该模块为AMR调度系统提供了可靠的库位管理基础，支持高并发、高可用的生产环境需求。