# 2026-07-28 会话新增模式

## 顺丰轨迹 fine_status opCode 优先判断

**Bug**：`fine_status()` 先匹配 remark 文本中的"派送"，导致"已派送成功"（实际 opCode=80=已签收）被误判为 delivering。138 条错判。

**修复**（`sf_delivery_watchdog.py`）：
```python
def fine_status(routes, reason=''):
    if not routes: return ('no_data' if reason else 'unknown'), None
    last = routes[-1]
    op = last.get('opCode', '')
    remark = last.get('remark', '')

    # opCode 优先（最可靠）
    if op == '80':  return 'delivered', last   # 已签收
    if op == '204' or op == '30': return 'delivering', last  # 派送中
    if op == '54':  return 'picked_up', last   # 已揽收

    # 文本兜底
    if '签收' in remark or '派送成功' in remark: return 'delivered', last
    if '派送' in remark: return 'delivering', last
    if '揽收' in remark: return 'picked_up', last
    return 'in_transit', last
```

## 14→1 JSON 合并优化

**问题**：前端 `loadData()` 每次加载 14 个独立 JSON（14 次 HTTP 请求），每个切换 Tab 都要等全部就绪。

**方案**：`merge_workbench_data.py` 合并 14 个 JSON → 单一 `workbench_data.json`（2.3MB→4.2MB with H1）。

**实现**：
1. `合并脚本/merge_workbench_data.py`：读取 14 个源 JSON → 合并为单一对象 → 注入 H1 存档
2. 前端 `loadData()`：从 `Promise.all(14 fetches)` 改为 `fetch('workbench_data.json')`
3. `cb_sync.sh` 在末尾执行合并+上传

**H1 注入逻辑**：
```python
h1_all = os.path.join(DATA, 'h1_archive', 'h1_all.json')
h1_orders = json.load(open(h1_all)).get('orders', [])
h2_orders = result['shipments'].get('orders', [])
seen = set(o.get('orderId','') for o in h1_orders)  # H1在前
for o in h1_orders:
    if not o.get('shipment'):
        o['shipment'] = {'status': 'archived', 'statusLabel': 'H1 归档'}
merged = h1_orders + [o for o in h2_orders if o.get('orderId','') not in seen]
```

## H1 存档系统

**架构**：
```
数据/h1_archive/
  m01_orders.json ~ m06_orders.json   # 月度存档（一次性拉取，永久复用）
  h1_all.json                          # 合并全量
  h1_summary.json                      # 汇总统计
  reconcile_2026-07.md                 # 月度校对报告
```

**拉取脚本**：`数据/pull_h1_archive.py --m01 | --m02 | ... | --h1`
- 按月分批（避免季度超时），每批 ~750 条订单
- H1 存档用客户→销售员映射（不逐条查下单人角色，省时间）
- MCP curl 超时 60s（比 H2 拉取的 30s 宽松）

**月度校对 cron**：每月 3 号 9:00 运行 `reconcile_monthly.sh`
- 比较 H1 MCP 金额 vs KPI H1 实际
- 输出报告到 `h1_archive/reconcile_YYYY-MM.md`

## 合同编号搜索替代多选

**决策**：合同编号从多选筛选器改为搜索框模糊匹配。订单管理搜索框覆盖：`单号/客户/合同/物流`。

```javascript
// 搜索逻辑
if (orderState.filterText) {
  var t = orderState.filterText.toLowerCase();
  filtered = filtered.filter(function(o) {
    return (o.orderId||'').toLowerCase().indexOf(t)>=0 ||
           (o.customer||'').toLowerCase().indexOf(t)>=0 ||
           (o.trackingNo||'').toLowerCase().indexOf(t)>=0 ||
           (o.contractNo||'').toLowerCase().indexOf(t)>=0;
  });
}
```

## 订单管理 本年累计 数据源修正

**问题链**：
1. `yearTax` 声明了但未渲染 → 改为 `fmtW(ps.taxTotal)` → 值来自 shipment 订单（多为 0）
2. `ps.taxTotal` 是 period 内订单金额，全年数据不存在 → 改为 KPI `yearTax`
3. `yearTax` 卡片在周/月/季视图也显示全年 → 改为独立 bar（始终可见）+ 周期统计卡片

**终版布局**：
```
📊 本年累计  2,353.7万  （H1: 2,164.0万 + H2当月: 189.6万）
┌──────────┬──────────┬──────────┬──────────┬──────────┐
│ 本周发货  │ 运输中   │ 已签收   │ 🟢备货中  │ 🟡备货预警│ 🔴严重超期│
└──────────┴──────────┴──────────┴──────────┴──────────┘
```

**关键规则**：`yearTax = dash.total_h1 + prog.total`（KPI 数据），不依赖 shipment orders 的 taxTotal。

## CloudBase 部署路径陷阱

`cloudbase hosting deploy file.json` 默认部署到根目录。部署到子目录需显式传 cloudPath：
```bash
# ❌ 部署到根 /
cloudbase hosting deploy 数据/workbench_data.json

# ✅ 部署到 /数据/workbench_data.json  
cloudbase hosting deploy 数据/workbench_data.json 数据/workbench_data.json
```

## 统一硬编码登录 + 角色映射

CloudBase DB 认证已废弃。`doLogin()` 改为：
1. 密码统一 `biori2026`
2. `_personnel.json` 查角色/部门
3. 中文职衔 → 系统角色映射（销售总监→admin, 销售工程师→sales）

## Python 脚本 SCRIPT_DIR 未定义

在 `~/.hermes/scripts/` 下的 Python 脚本中引用同目录文件时，需显式定义：
```python
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
```
否则 `os.path.join(SCRIPT_DIR, ...)` 报 `NameError`。
