# 执行计划 — 元素映射表定位方案：前端 Key-Value 键值提升定位稳定性

> **文档版本**: v1.0  
> **创建日期**: 2026-08-11  
> **作者**: Claude Code  
> **关联PRD**: `_PRD_元素映射表定位方案_前端key-value键值_提升定位稳定性.md`  
> **状态**: 待确认

---

## 一、执行概览

### 1.1 目标

将前端提供的元素定位键值表转化为结构化 JSON 映射文件，作为 Playwright 执行器的最高优先级选择器来源，提升定位稳定性。以用例 `case_13650e0406e64779b66e6fa5de35c24a` 为实验验证目标，验证"登录→功能中心→对应分类下的模块点击"链路。

### 1.2 范围

- 后端新增 ElementMappingService
- 新增元素映射表 JSON 文件
- 改造 PlaywrightExecutor 选择器解析
- 目标用例实验验证

### 1.3 预估工时

| 阶段 | 工时 |
|------|------|
| Phase 1: 映射表 JSON 文件生成 | 1 小时 |
| Phase 2: ElementMappingService 实现 | 2 小时 |
| Phase 3: PlaywrightExecutor 集成 | 2 小时 |
| Phase 4: 目标用例实验验证 | 2 小时 |
| **总计** | **7 小时** |

---

## 二、Phase 1: 映射表 JSON 文件生成

### 2.1 任务清单

| # | 任务 | 文件 | 说明 |
|---|------|------|------|
| 1.1 | 解析前端文档 | `Docs/Doc_门户首页_首页元素获取键值_功能总结-新.md` | 提取全部键值对 |
| 1.2 | 生成映射表 JSON | `backend/app/data/elements_mapping.json` | 结构化存储元素映射 |
| 1.3 | 处理未开发功能 | JSON 中标记 | 排除 `publication_list.player` 等 3 个未开发功能 |

### 2.2 JSON 结构

```json
{
  "version": "1.0",
  "updated_at": "2026-08-11",
  "source": "门户首页+功能中心元素定位键值表",
  "elements": {
    "导航栏-功能中心抽屉开关": {
      "selector": ".home_nav_left",
      "type": "css",
      "description": "打开/关闭功能中心抽屉"
    },
    "全部功能-会议预约-创建会议": {
      "selector": "[data-id=\"reserve_list.create\"]",
      "type": "css",
      "description": "创建会议按钮"
    }
  }
}
```

### 2.3 验收标准

| 检查项 | 预期 |
|--------|------|
| JSON 合法 | `python -c "import json; json.load(open(...))"` 通过 |
| 键值对数量 | ≥ 100 个 |
| data-key / data-id / id / class 覆盖 | 全部含定位优先级 |

---

## 三、Phase 2: ElementMappingService 实现

### 3.1 任务清单

| # | 任务 | 文件 | 说明 |
|---|------|------|------|
| 2.1 | 创建 ElementMappingService 类 | `backend/app/services/element_mapping_service.py` | 加载 + 匹配 + 查询 |
| 2.2 | 实现加载逻辑 | 同上 | 启动时加载 JSON，支持热重载 |
| 2.3 | 实现匹配逻辑 | 同上 | 精确匹配 + jieba 模糊匹配 + 上下文辅助 |
| 2.4 | 实现查询接口 | 同上 | `get_selector(step_name, action, context)` |
| 2.5 | 容错处理 | 同上 | JSON 损坏自动禁用，日志告警 |

### 3.2 核心接口

```python
class ElementMappingService:
    def __init__(self, mapping_file: str = "elements_mapping.json"):
        ...
    
    def get_selector(self, step_name: str, action: str,
                     context: Optional[Dict] = None) -> Optional[Dict]:
        """根据步骤描述和上下文返回映射表选择器"""
    
    def get_all_keys(self) -> List[str]:
        """返回所有映射键列表"""
    
    def reload(self) -> bool:
        """热重载映射表文件"""
```

### 3.3 匹配策略

| 匹配方式 | 说明 |
|---------|------|
| 精确匹配 | 步骤描述包含映射键中的关键词（分词后比对） |
| 模糊匹配 | jieba 分词后计算相似度，取最高分（阈值 ≥ 0.7） |
| 上下文辅助 | 结合当前页面 URL、前序步骤判断所在功能分类，缩小范围 |

### 3.4 验收标准

| 检查项 | 预期 |
|--------|------|
| 单测通过 | 精确/模糊/上下文匹配均正确 |
| 容错 | JSON 不存在/损坏时不抛异常 |
| 性能 | 单次查询 ≤ 10ms |

---

## 四、Phase 3: PlaywrightExecutor 集成

### 4.1 任务清单

| # | 任务 | 文件 | 说明 |
|---|------|------|------|
| 3.1 | 集成 ElementMappingService | `backend/app/executors/playwright_executor.py` | 作为最高优先级选择器来源 |
| 3.2 | 更新 SelectorMapper | `backend/app/utils/selector_mapper.py` | 增加映射表优先级 |
| 3.3 | 日志记录 | 同上 | 记录映射表命中/未命中 |

### 4.2 集成位置

在 `execute_step` 方法的选择器解析阶段，插入映射表查询作为最高优先级：

```python
# 步骤1: 查询元素映射表（最高优先级）
mapping_selector = element_mapping_service.get_selector(step_name, action)
if mapping_selector:
    selector = mapping_selector["selector"]
    logger.info(f"[映射表] 命中: {step_name} → {selector}")
    # 直接使用映射表选择器执行

# 步骤2: 映射表未命中，回落 DB 选择器
# 步骤3: DB 选择器未命中，回落关键词匹配 + 智能定位
```

### 4.3 验收标准

| 检查项 | 预期 |
|--------|------|
| 集成无回归 | 原有用例执行不受影响 |
| 映射表命中优先 | 映射表覆盖的步骤优先使用映射表选择器 |
| 映射表未命中回退 | 自动回落原有策略 |

---

## 五、Phase 4: 目标用例实验验证

### 5.1 任务清单

| # | 任务 | 文件 | 说明 |
|---|------|------|------|
| 4.1 | 准备目标用例 | 服务器 MySQL | 从 `192.168.5.60:3307` 获取 `case_13650e0406e64779b66e6fa5de35c24a` |
| 4.2 | 执行实验 | `backend/scripts/` | 运行目标用例，验证步骤 1-9 |
| 4.3 | 分析结果 | 日志 | 检查步骤 7-9 是否命中映射表选择器 |

### 5.2 验证范围

| 步骤 | 描述 | 映射表预期命中 | 映射表选择器 |
|------|------|---------------|-------------|
| 1-6 | 登录操作 | ❌ | 使用原有登录模板 |
| 7 | 点击【功能中心】展开 | ✅ | `.home_nav_left` |
| 8 | 点击【会议预约】分类 | ✅ | `#reserve_enable` |
| 9 | 点击【新建会议】按钮 | ✅ | `[data-key="reserve_list.create"]` |

### 5.3 验收标准

| 指标 | 目标 |
|------|------|
| 步骤 7-9 映射表命中率 | 100% |
| 步骤 7-9 定位准确率 | 100% |
| 链路执行成功率 | 100%（登录→功能中心→模块点击） |
| 子页面操作 | 不考核（后续阶段） |

---

## 六、回退方案

| 场景 | 处理策略 |
|------|---------|
| 映射表 JSON 文件不存在 | 静默跳过，使用原有策略 |
| 映射表 JSON 解析失败 | 日志告警，使用原有策略 |
| 映射表查询无匹配 | 返回 None，继续下一优先级 |
| 映射表选择器执行失败 | 自动尝试下一优先级选择器 |

---

## 七、风险与缓解

| 风险 | 影响 | 缓解措施 |
|------|------|---------|
| data-key 随前端版本变化 | 映射表失效 | 与前端约定 data-key 稳定，版本同步 |
| 个性化菜单动态性 | 映射表与实际不一致 | 仅覆盖默认配置，实际以渲染为准 |
| 权限过滤导致元素不渲染 | 定位失败 | 确认测试账号权限 |

---

*本文档待确认后进入实现阶段。*