This commit is contained in:
2025-11-06 20:18:15 +08:00
parent b532aa1b84
commit e865220a50
6 changed files with 798 additions and 7 deletions

View File

@@ -0,0 +1,274 @@
# 智能状态同步机制 - 详细说明
## 📖 背景
在实际使用中,腾讯文档的物流链接可能通过多种方式填写:
1. **系统推送**:通过"推送物流"按钮自动填写
2. **手动填写**:用户直接在文档中手动填写
3. **外部导入**从Excel等外部文件导入
4. **协同编辑**:团队成员直接编辑文档
如果没有智能同步机制,会导致:
- ❌ 订单状态显示"未推送",但文档中已有值
- ❌ 批量同步时重复查询这些订单
- ❌ 增加数据库查询负担
- ❌ 状态不一致,影响业务判断
## ✨ 智能同步机制
### 核心思路
**以腾讯文档的实际状态为准,自动同步到订单系统**
```
文档是最终展示层(实际填写状态)
订单系统是管理层(推送状态记录)
文档有值 + 订单未标记 = 状态不一致
智能同步:自动更新订单状态
```
## 🔄 工作流程
### 场景1系统推送正常流程
```
用户点击"推送物流"
1. 检查订单状态:未推送 ✅
2. 检查文档物流列:无值 ✅
写入物流链接到文档
更新订单状态为"已推送"
记录操作日志SUCCESS
```
**结果**:订单状态 ✅ 已推送 | 文档状态 ✅ 有值
---
### 场景2手动填写后首次批量同步智能同步触发
```
某人手动在文档中填写物流链接
订单状态仍为"未推送"(因为是手动填写)
批量同步开始
1. 读取文档数据
2. 发现某行物流列已有值
3. 查询该单号对应的订单
检测到状态不一致:
- 订单状态:未推送 ❌
- 文档状态:有值 ✅
【智能同步触发】
自动更新订单状态为"已推送"
记录同步日志SKIPPED文档中已有值已同步订单状态
```
**结果**:订单状态 ✅ 已推送 | 文档状态 ✅ 有值
---
### 场景3手动填写后再次批量同步无需同步
```
批量同步开始
1. 读取文档数据
2. 发现某行物流列已有值
3. 查询该单号对应的订单
检测到状态一致:
- 订单状态:已推送 ✅(上次已同步)
- 文档状态:有值 ✅
直接跳过(无需同步)
```
**结果**:订单状态 ✅ 已推送 | 文档状态 ✅ 有值
---
### 场景4用户尝试重复推送拒绝
```
用户点击"推送物流"
1. 检查订单状态:已推送 ❌
拒绝推送
返回错误提示:
"该订单已推送到腾讯文档推送时间2025-11-06 12:30:00请勿重复操作"
```
**结果**:请求被拒绝,订单和文档状态保持不变
## 📊 状态同步矩阵
| 订单状态 | 文档物流列 | 用户操作 | 系统行为 | 最终状态 |
|---------|-----------|---------|---------|---------|
| 未推送 | 无值 | 单个推送 | ✅ 写入物流链接,更新订单状态 | 已推送 + 有值 |
| 未推送 | 无值 | 批量同步 | ✅ 写入物流链接,更新订单状态 | 已推送 + 有值 |
| 未推送 | **有值** | 单个推送 | ❌ 拒绝(文档已有值) | 未推送 + 有值 |
| 未推送 | **有值** | 批量同步 | ✅ **智能同步订单状态** | **已推送 + 有值** |
| 已推送 | 有值 | 单个推送 | ❌ 拒绝(订单已推送) | 已推送 + 有值 |
| 已推送 | 有值 | 批量同步 | ✅ 跳过(订单已推送) | 已推送 + 有值 |
| 已推送 | 无值 | 单个推送 | ❌ 拒绝(订单已推送) | 已推送 + 无值 |
| 已推送 | 无值 | 批量同步 | ✅ 跳过(订单已推送) | 已推送 + 无值 |
**重点场景**第4行 - 未推送 + 有值 + 批量同步 = **智能同步**
## 🎯 核心优势
### 1. 自动化
- ✅ 无需人工干预
- ✅ 批量同步时自动检测
- ✅ 自动修正状态不一致
### 2. 高效性
- ✅ 同步后下次批量同步会跳过
- ✅ 减少数据库查询
- ✅ 减少不必要的状态检查
### 3. 可追溯
- ✅ 记录同步操作日志
- ✅ 标记同步原因:"文档中已有物流链接(可能手动填写)"
- ✅ 便于审计和问题排查
### 4. 兼容性
- ✅ 兼容手动填写
- ✅ 兼容外部导入
- ✅ 兼容协同编辑
- ✅ 兼容各种数据来源
## 📝 代码实现(简化版)
```java
// 批量同步时,检查文档物流列
String existingLogisticsLink = row.getString(logisticsLinkColumn);
if (existingLogisticsLink != null && !existingLogisticsLink.trim().isEmpty()) {
// 文档中已有物流链接,检查订单状态
JDOrder existingOrder = jdOrderService.selectJDOrderByThirdPartyOrderNo(orderNo);
if (existingOrder != null &&
(existingOrder.getTencentDocPushed() == null ||
existingOrder.getTencentDocPushed() == 0)) {
// 状态不一致,触发智能同步
existingOrder.setTencentDocPushed(1);
existingOrder.setTencentDocPushTime(new Date());
jdOrderService.updateJDOrder(existingOrder);
log.info("✓ 同步订单状态 - 单号: {}, 行号: {}, 原因: 文档中已有物流链接(可能手动填写)",
orderNo, excelRow);
// 记录同步日志
logOperation(fileId, sheetId, "BATCH_SYNC", orderNo, excelRow,
existingLogisticsLink, "SKIPPED", "文档中已有物流链接,已同步订单状态");
}
skippedCount++; // 跳过写入
continue;
}
```
## 🔍 日志示例
### 智能同步触发
```
2025-11-06 14:30:15 INFO - 批量同步开始 - 范围第3-202行
2025-11-06 14:30:16 INFO - 发现物流列已有值 - 单号: JY2025110329041, 行号: 123
2025-11-06 14:30:16 INFO - 检测到状态不一致 - 订单状态: 未推送, 文档状态: 有值
2025-11-06 14:30:16 INFO - ✓ 同步订单状态 - 单号: JY2025110329041, 行号: 123, 原因: 文档中已有物流链接(可能手动填写)
2025-11-06 14:30:16 INFO - 记录同步日志 - 操作类型: BATCH_SYNC, 状态: SKIPPED
```
### 操作日志表记录
```sql
INSERT INTO tencent_doc_operation_log (
file_id, sheet_id, operation_type, order_no, target_row,
logistics_link, operation_status, error_message, operator, create_time
) VALUES (
'DUW50RUprWXh2TGJK', 'BB08J2', 'BATCH_SYNC', 'JY2025110329041', 123,
'https://3.cn/2ume-Ak1', 'SKIPPED', '文档中已有物流链接,已同步订单状态',
'admin', '2025-11-06 14:30:16'
);
```
## 🛠️ 排查与维护
### 查询智能同步记录
```sql
-- 查询所有智能同步操作
SELECT order_no, target_row, logistics_link, create_time, operator
FROM tencent_doc_operation_log
WHERE operation_status = 'SKIPPED'
AND error_message LIKE '%文档中已有物流链接,已同步订单状态%'
ORDER BY create_time DESC;
```
### 查询状态不一致的订单理论上应该为0
```sql
-- 如果有记录,说明智能同步未触发或失败
SELECT o.third_party_order_no, o.tencent_doc_pushed, o.logistics_link
FROM jd_order o
WHERE o.logistics_link IS NOT NULL
AND o.logistics_link != ''
AND (o.tencent_doc_pushed IS NULL OR o.tencent_doc_pushed = 0);
```
### 手动修正状态不一致
```sql
-- 如果发现状态不一致,可以手动修正
UPDATE jd_order
SET tencent_doc_pushed = 1,
tencent_doc_push_time = NOW()
WHERE logistics_link IS NOT NULL
AND logistics_link != ''
AND (tencent_doc_pushed IS NULL OR tencent_doc_pushed = 0);
```
## ✅ 最佳实践
1. **定期批量同步**
- 建议每天运行一次批量同步
- 自动修正所有状态不一致
2. **监控同步日志**
- 定期检查 `SKIPPED` 状态的日志
- 分析手动填写的频率和模式
3. **培训团队成员**
- 告知团队手动填写会被系统自动同步
- 建议优先使用系统推送功能
4. **备份重要数据**
- 定期备份腾讯文档
- 定期备份订单数据库
## 🎉 总结
智能状态同步机制确保了:
-**订单状态****文档实际状态** 始终保持一致
- ✅ 兼容多种数据来源(系统推送、手动填写、外部导入)
- ✅ 减少重复查询,提高系统效率
- ✅ 所有同步操作可追溯,便于审计
**这是一个真正智能的、自适应的状态管理机制!** 🚀