# OCR订单处理系统

这是一个基于OCR技术的订单处理系统，用于自动识别和处理Excel格式的订单文件。系统支持多种格式的订单处理，包括普通订单和赠品订单的处理。

## 主要功能

1. **OCR识别**
   - 支持图片和PDF文件的文字识别
   - 支持表格结构识别
   - 支持多种格式的订单识别

2. **Excel处理**
   - 自动处理订单数据
   - 支持赠品订单处理
   - 自动提取商品规格和数量信息
   - 从商品名称智能推断规格信息
   - 从数量字段提取单位信息
   - 支持多种格式的订单合并

3. **日志管理**
   - 自动记录处理过程
   - 支持日志文件压缩
   - 自动清理过期日志
   - 日志文件自动重建
   - 支持日志大小限制
   - 活跃日志文件保护机制

4. **文件管理**
   - 自动备份清理的文件
   - 支持按时间和模式清理文件
   - 文件统计和状态查看
   - 支持输入输出目录的独立管理

## 系统要求

- Python 3.8+
- Windows 10/11

## 安装说明

1. 克隆项目到本地：
```bash
git clone [项目地址]
cd orc-order
```

2. 安装依赖：
```bash
pip install -r requirements.txt
```

3. 配置百度OCR API：
   - 在[百度AI开放平台](https://ai.baidu.com/)注册账号
   - 创建OCR应用并获取API Key和Secret Key
   - 将密钥信息填入`config.ini`文件

## 使用说明

### 1. OCR处理流程

1. 运行OCR识别：
```bash
python run_ocr.py [输入文件路径]
```

2. 使用百度OCR API：
```bash
python baidu_ocr.py [输入文件路径]
```

3. 处理表格OCR：
```bash
python baidu_table_ocr.py [输入文件路径]
```

### 2. Excel处理

```bash
python excel_processor_step2.py [输入Excel文件路径]
```

或者不指定输入文件，自动处理output目录中最新的Excel文件：
```bash
python excel_processor_step2.py
```

#### 2.1 Excel处理逻辑说明

1. **列名识别与映射**：
   - 系统首先检查是否存在直接匹配的列（如"商品条码"列）
   - 如果没有，系统会尝试将多种可能的列名映射到标准列名
   - 支持特殊表头格式处理（如基本条码、仓库全名等）

2. **条码识别与处理**：
   - 验证条码格式（确保长度在8-13位之间）
   - 对特定的错误条码进行修正（如5开头改为6开头）
   - 识别特殊条码（如"5321545613"）
   - 跳过条码为"仓库"或"仓库全名"的行

3. **智能规格推断**：
   - 当规格信息为空时，从商品名称自动推断规格
   - 支持多种商品命名模式：
     - 445水溶C血橙15入纸箱 → 规格推断为 1*15
     - 500-东方树叶-绿茶1*15-纸箱装 → 规格推断为 1*15
     - 12.9L桶装水 → 规格推断为 12.9L*1
     - 900树叶茉莉花茶12入纸箱 → 规格推断为 1*12
     - 500茶π蜜桃乌龙15纸箱 → 规格推断为 1*15

4. **单位自动提取**：
   - 当单位信息为空时，从数量字段中自动提取单位
   - 支持格式：2箱、5桶、3件、10瓶等
   - 自动分离数字和单位部分

5. **赠品识别**：
   - 通过以下条件识别赠品：
     - 商品单价为0或为空
     - 商品金额为0或为空
     - 单价非有效数字

6. **数据合并与处理**：
   - 对同一条码的多个正常商品记录，累加数量
   - 对同一条码的多个赠品记录，累加赠品数量
   - 如果同一条码有不同单价，取平均值

### 3. 订单合并

`merge_purchase_orders.py`是专门用来合并多个采购单Excel文件的工具，可以高效处理多份采购单并去重。

#### 3.1 基本用法

自动合并output目录下的所有采购单文件（以"采购单_"开头的Excel文件）：
```bash
python merge_purchase_orders.py
```

指定要合并的特定文件：
```bash
python merge_purchase_orders.py --input "output/采购单_1.xls,output/采购单_2.xls"
```

#### 3.2 合并逻辑说明

1. **数据识别与映射**：
   - 自动识别Excel文件中的列名（支持多种表头格式）
   - 将不同格式的列名映射到标准列名（如"条码"、"条码（必填）"等）
   - 支持特殊表头结构的处理（如表头在第3行的情况）

2. **相同商品的处理**：
   - 自动检测相同条码和单价的商品
   - 对相同商品进行数量累加处理
   - 保持商品名称、条码和单价不变

3. **赠送量的处理**：
   - 自动检测和处理赠送量
   - 对相同商品的赠送量进行累加
   - 当原始文件中赠送量为空时，合并后保持为空（不显示为0）

4. **数据格式保持**：
   - 保持条码的原始格式（不转换为小数）
   - 单价保持四位小数格式
   - 避免"nan"值的显示，空值保持为空

### 4. 单位处理规则（核心规则）

系统支持多种单位的智能处理，能够自动识别和转换不同的计量单位。所有开发必须严格遵循以下规则处理单位转换。

#### 4.1 标准单位处理

| 单位 | 处理规则 | 示例 |
|------|----------|------|
| 件 | 数量×包装数量<br>单价÷包装数量<br>单位转换为"瓶" | 1件(规格1*12) → 12瓶<br>单价108元/件 → 9元/瓶 |
| 箱 | 数量×包装数量<br>单价÷包装数量<br>单位转换为"瓶" | 2箱(规格1*24) → 48瓶<br>单价120元/箱 → 5元/瓶 |
| 包 | 保持原数量和单位不变 | 3包 → 3包 |
| 其他单位 | 保持原数量和单位不变 | 5瓶 → 5瓶 |

#### 4.2 提和盒单位特殊处理

系统对"提"和"盒"单位有特殊的处理逻辑：

1. 当规格是三级格式（如1*5*12）时：
   - 按照件的计算方式处理
   - 数量 = 原始数量 × 包装数量
   - 单位转换为"瓶"
   - 单价 = 原始单价 ÷ 包装数量
   
   示例：3提(规格1*5*12) → 36瓶

2. 当规格是二级格式（如1*16）时：
   - **保持原数量不变**
   - **保持原单位不变**
   
   示例：3提(规格1*16) → 仍然是3提

#### 4.3 特殊条码处理

系统支持对特定条码进行特殊处理，这些条码的处理规则会覆盖上述的标准单位处理规则：

1. 特殊条码配置：
   ```python
   special_barcodes = {
       '6925019900087': {
           'multiplier': 10,  # 数量乘以10
           'target_unit': '瓶',  # 目标单位
           'description': '特殊处理：数量*10，单位转换为瓶'
       }
       # 可以添加更多特殊条码的配置
   }
   ```

2. 处理规则：
   - 当遇到特殊条码时，无论规格是二级还是三级
   - 无论单位是提还是盒还是件
   - 都按照特殊条码配置进行处理
   - 数量乘以配置的倍数
   - 单位转换为配置的目标单位
   - 如果有单价，单价除以配置的倍数

3. 添加新的特殊条码的正确方法：
   - 在`ExcelProcessorStep2`类的`__init__`方法中的`special_barcodes`字典中添加新的配置
   - 每个特殊条码需要配置：
     - `multiplier`: 数量乘以的倍数
     - `target_unit`: 转换后的目标单位
     - `description`: 处理规则的描述

4. 注意事项：
   - 特殊条码处理优先级高于标准单位处理
   - 添加新的特殊条码前，需要确认该条码是否真的需要特殊处理，或者可以使用现有的标准规则
   - 如果商品单位是"件"且有规格信息，应首先考虑使用标准的"件"单位处理规则

5. 示例：
   - 条码6925019900087，单位为"副"，原始数量为2：
     - 无论规格如何
     - 最终数量 = 2 * 10 = 20，单位为"瓶"
     - 如原单价为50元/副，则转换后为5元/瓶

### 5. 开发注意事项

1. **遵循原有处理逻辑**：
   - 在进行任何修改前，必须理解并遵循现有的单位处理逻辑
   - 对于"件"单位，必须按照"数量×包装数量"进行处理
   - 对于"提"和"盒"单位，必须检查规格是二级还是三级格式，按相应规则处理

2. **添加特殊条码处理**：
   - 只有在明确确认某条码无法使用现有规则处理的情况下，才添加特殊处理规则
   - 添加特殊条码处理前，先咨询相关负责人确认处理逻辑

3. **代码更改原则**：
   - 任何代码修改都不应破坏现有的处理逻辑
   - 添加新功能时，先确保理解并保留现有功能
   - 如需修改核心处理逻辑，必须详细记录变更并更新本文档

4. **文档同步更新**：
   - 当修改代码逻辑时，必须同步更新README文档
   - 确保文档准确反映当前系统的处理逻辑
   - 记录所有特殊处理规则和条码

## 注意事项

1. 确保输入文件格式正确
2. 定期检查日志文件大小
3. 及时更新百度OCR API密钥
4. 建议定期备份重要数据
5. 清理文件前先查看统计信息
6. 重要文件建议手动备份后再清理
7. 日志文件会自动重建，可以放心清理
8. 规格推断功能适用于特定命名格式的商品
9. 单位提取功能依赖于数量字段的格式

## 常见问题

1. **OCR识别失败**
   - 检查图片质量
   - 确认API密钥配置正确
   - 查看日志文件了解详细错误信息

2. **Excel处理错误**
   - 确认Excel文件格式正确
   - 检查商品信息是否完整
   - 查看处理日志了解具体错误

3. **规格推断失败**
   - 检查商品名称是否符合支持的格式
   - 尝试手动在Excel中填写规格信息
   - 查看日志中的推断过程信息

4. **单位提取失败**
   - 检查数量字段格式是否为"数字+单位"格式
   - 确认数量字段没有额外的空格或特殊字符
   - 尝试手动在Excel中填写单位信息

5. **文件清理问题**
   - 清理前使用`--test`参数预览要删除的文件
   - 清理前检查文件统计信息`--stats`
   - 对于重要文件，先使用`--test`确认后再实际删除
   - 对于被占用的文件，尝试关闭占用的程序后再清理
   - Windows下某些文件无法删除时，可以使用`--force`参数
   - 日志文件清理时可以使用`--clean-all-logs`参数

## 更新日志

### v1.2.1 (2024-05-04)
- 新增日志文件活跃标记保护机制
- 修复OCR处理器日志文件被意外删除的问题
- 改进日志清理工具，避免删除活跃日志
- 优化文件清理逻辑
- 更新README文档

### v1.2.0 (2024-05-03)
- 新增对"提"单位的支持（1提=10袋）
- 新增对三级规格格式（1*5*10）的解析支持
- 优化单位转换逻辑
- 改进规格解析能力

### v1.1.0 (2024-05-02)
- 新增从商品名称智能推断规格功能
- 新增从数量字段提取单位功能
- 优化赠品处理逻辑
- 修复缩进错误和代码问题
- 改进日志记录内容

### v1.0.0 (2024-05-01)
- 初始版本发布
- 支持基本的OCR识别功能
- 支持Excel订单处理
- 支持日志管理功能
- 添加文件清理工具
- 优化文件命名和目录结构
- 完善日志自动重建功能

## 许可证

MIT License 