# 从Status字段提取手机号码功能说明

## 功能概述

在批量同步物流链接到腾讯文档时，系统会自动从订单的 `status` 字段中提取手机号码，并写入到腾讯文档的"下单电话"列。

> **注意：** 手机号码存储在 `status` 字段，不是 `remark` 字段。

## 实现原理

### 1. 列识别

系统在读取表头时，会自动识别以下列名：
- `下单电话`
- `电话`
- `手机`

任何包含以上关键词的列都会被识别为"下单电话"列。

### 2. 手机号码提取

从订单的 `status`（状态）字段中提取手机号码：

**提取规则：**
- 自动移除status字段中的空格、横线、括号等分隔符
- 使用正则表达式匹配11位手机号码（1开头的11位数字）
- 支持格式示例：
  ```
  138 0013 8000
  138-0013-8000
  (138)00138000
  13800138000
  ```

**正则表达式：** `1[3-9]\d{9}`

**匹配规则：**
- 第1位必须是 `1`
- 第2位必须是 `3-9`
- 后面9位是任意数字 `0-9`

### 3. 写入逻辑

在批量同步时，如果同时满足以下条件，会写入手机号码：
1. ✅ 表头中识别到了"下单电话"列
2. ✅ 从订单备注中成功提取到手机号码
3. ✅ 订单有物流链接需要同步

写入时使用 `batchUpdate` API，一次性更新多个字段：
1. 物流单号（超链接类型）
2. **下单电话（普通文本）** ← 新增
3. 是否安排（值为"2"）
4. 标记（当前日期，格式：251106）

## 代码实现

### 关键方法

#### `extractPhoneFromRemark(String remark)`

```java
/**
 * 从备注中提取手机号码
 * 支持11位手机号码，可能包含空格、横线等分隔符
 * 
 * @param remark 备注信息
 * @return 提取到的手机号码，如果没有则返回null
 */
private String extractPhoneFromRemark(String remark) {
    if (remark == null || remark.trim().isEmpty()) {
        return null;
    }

    // 移除所有空格、横线、括号等分隔符
    String cleanedRemark = remark.replaceAll("[\\s\\-\\(\\)\\[\\]（）\\【\\】]", "");

    // 匹配11位手机号码（1开头的11位数字）
    java.util.regex.Pattern pattern = java.util.regex.Pattern.compile("1[3-9]\\d{9}");
    java.util.regex.Matcher matcher = pattern.matcher(cleanedRemark);

    if (matcher.find()) {
        String phone = matcher.group();
        log.debug("从备注中提取到手机号码: {}", phone);
        return phone;
    }

    return null;
}
```

### 使用位置

**`TencentDocController.fillLogisticsByOrderNo`** - 批量同步方法

1. **列识别阶段**（第1003-1008行）：
```java
// 识别"下单电话"列（可选）
if (phoneColumn == null && (cellValueTrim.contains("下单电话") 
    || cellValueTrim.contains("电话") 
    || cellValueTrim.contains("手机"))) {
    phoneColumn = i;
    log.info("✓ 识别到 '下单电话' 列：第 {} 列（索引{}）", i + 1, i);
}
```

2. **数据处理阶段**（第1188-1195行）：
```java
// 从status字段中提取手机号码
String phone = null;
if (phoneColumn != null) {
    phone = extractPhoneFromRemark(order.getStatus());
    if (phone != null) {
        log.info("✓ 从status字段提取手机号码 - 单号: {}, 手机号: {}", orderNo, phone);
    }
}
```

3. **构建更新请求**（第1201-1205行）：
```java
// 如果找到手机号码，也添加到更新中
if (phone != null && phoneColumn != null) {
    update.put("phone", phone);
    update.put("phoneColumn", phoneColumn);
}
```

4. **写入腾讯文档**（第1294-1300行）：
```java
// 2. 更新"下单电话"列（如果存在且提取到了手机号码）
String phone = update.getString("phone");
Integer phoneCol = update.getInteger("phoneColumn");
if (phone != null && phoneCol != null) {
    requests.add(buildUpdateCellRequest(sheetId, row - 1, phoneCol, phone, false));
    log.info("✓ 准备写入手机号码 - 单号: {}, 手机号: {}, 行: {}, 列: {}", 
        expectedOrderNo, phone, row, phoneCol);
}
```

## 日志输出

### 成功提取手机号码

```
✓ 从status字段提取手机号码 - 单号: JY2025110601, 手机号: 13800138000
✓ 准备写入手机号码 - 单号: JY2025110601, 手机号: 13800138000, 行: 3, 列: 6
✓ 写入成功 - 行: 3, 单号: JY2025110601, 物流链接: https://3.cn/xxx, 手机号: 13800138000
```

### 未找到手机号码

```
找到订单物流链接 - 单号: JY2025110602, 物流链接: https://3.cn/xxx, 手机号: 无, 行号: 4, 已推送: 否
✓ 写入成功 - 行: 4, 单号: JY2025110602, 物流链接: https://3.cn/xxx
```

### 未识别到"下单电话"列

```
未找到'下单电话'列，将跳过该字段的更新
列位置识别完成 - 单号: 2, 物流单号: 12, 是否安排: null, 标记: 14, 下单电话: null
```

## 使用示例

### 订单Status字段示例

| Status内容 | 提取结果 | 说明 |
|---------|---------|------|
| `联系电话：138 0013 8000` | `13800138000` | ✅ 成功提取 |
| `手机号138-0013-8000` | `13800138000` | ✅ 成功提取 |
| `电话：(138)00138000` | `13800138000` | ✅ 成功提取 |
| `13800138000 张三` | `13800138000` | ✅ 成功提取 |
| `17703916233` | `17703916233` | ✅ 成功提取 |
| `无电话` | `null` | ❌ 未提取到 |
| `12345678901` | `null` | ❌ 不符合规则（不是1开头） |
| `1280013800` | `null` | ❌ 不符合规则（第2位不是3-9） |

### 腾讯文档表头示例

支持的表头名称（包含即可识别）：
- ✅ `下单电话`
- ✅ `电话`
- ✅ `手机`
- ✅ `手机号`
- ✅ `联系电话`
- ✅ `客户电话`

## 兼容性

### 向后兼容

- ✅ 如果表头中**没有**"下单电话"列，功能自动跳过，不影响其他字段的同步
- ✅ 如果订单status字段中**没有**手机号码，功能自动跳过，不影响其他字段的同步
- ✅ 不影响现有的物流链接、是否安排、标记字段的同步

### 可选性

此功能是**完全可选**的：
1. 不需要在表头中添加"下单电话"列
2. 订单status字段可以不包含手机号码
3. 功能会自动识别和适配

## 测试建议

### 测试场景

1. **正常场景**
   - 表头包含"下单电话"列
   - 订单status字段包含手机号码
   - 预期：手机号码正确写入

2. **无电话列场景**
   - 表头不包含"下单电话"列
   - 预期：其他字段正常同步，手机号码跳过

3. **无手机号场景**
   - 表头包含"下单电话"列
   - 订单status字段不包含手机号码
   - 预期：其他字段正常同步，手机号码列为空

4. **多种格式场景**
   - 测试不同格式的手机号码（带空格、横线、括号等）
   - 预期：都能正确提取

### 测试步骤

1. 在腾讯文档表头添加"下单电话"列（或"电话"、"手机"）
2. 确保订单的status字段包含手机号码（例如：17703916233）
3. 点击"批量同步物流"按钮
4. 查看后端日志，确认提取和写入成功
5. 查看腾讯文档，确认手机号码正确显示在"下单电话"列

## 未来优化建议

1. **支持更多手机号格式**
   - 国际号码（+86）
   - 固定电话（区号+号码）

2. **支持多个手机号**
   - 从备注中提取多个手机号码
   - 用逗号或分号分隔

3. **手机号验证**
   - 验证号码段有效性（如：135、138等）
   - 提示无效号码

4. **手机号脱敏**
   - 日志中对手机号进行脱敏显示
   - 如：138****8000

## 相关文件

- **Controller**: `TencentDocController.java`
- **方法**: `fillLogisticsByOrderNo()`, `extractPhoneFromRemark()`
- **API**: 腾讯文档 `batchUpdate` API

---

**最后更新时间**: 2025-11-06  
**版本**: v1.0

