# 疑点甄别功能扩展至普通规则 - 页面改动说明

## 文档信息

- 文档名称：疑点甄别功能扩展至普通规则 - 页面改动说明
- 所属模块：全知平台 / 风控模块 / 风险疑点
- 关联PRD：`疑点甄别功能扩展至普通规则-PRD.md`
- 编写目的：逐页说明原型改动内容，为前端开发提供明确的改动指引
- 变更说明：
  - ~~F1（规则甄别开关）~~ 已取消，所有规则默认启用甄别，不设开关
  - F4（已排除疑点汇总页）由"仅运营方"改为"所有用户可访问，按角色控制数据范围"
  - 2026-05-11：F5 去除普通规则"可甄别"标签；F4 新增排除人单位列、视图切换、查看详情弹窗、恢复操作、场景/规则编号展示、搜索简化；F3 新增排除人/排除人单位列

---

## 涉及页面清单

| 序号 | 页面文件 | 改动类型 | 对应PRD功能 |
|------|----------|----------|-------------|
| 1 | ~~`规则详情.html`~~ | ~~修改~~ | ~~F1：规则甄别开关~~ **（已取消）** |
| 2 | `疑点派发-场景疑点.html` | 修改 | F2：场景疑点页标识 |
| 3 | `疑点派发-疑点详情.html` | 修改 | F3：派发环节甄别 |
| 4 | `疑点派发-疑点详情-已排除疑点.html` | 修改 | F3：普通规则已排除疑点页 |
| 5 | `已排除疑点汇总.html` | **新增** | F4：已排除疑点汇总页（全用户可见，按角色控数据） |

---

## ~~1. 规则详情页（F1：规则甄别开关）~~ — 已取消

> **决策说明**：所有规则（AI规则 + 普通规则）默认启用疑点甄别，不设置启用/关闭开关。规则详情页无需改动。

---

## 2. 场景疑点页（F2：场景疑点页标识）

### 对应文件

`疑点派发-场景疑点.html`

### 当前状态

- 已有AI标识展示逻辑：`${rule.isAI ? '<span class="ai-tag">AI规则</span>' : ''}`
- 规则数据结构中有`isAI`布尔字段
- 6条规则数据中3条为AI规则（CONTRACT_001, SECURITY_001, SECURITY_002）

### 改动内容

#### 2.1 标签展示逻辑修改

所有普通规则统一启用甄别，"可甄别"标签无实际区分意义，予以去除。仅保留 AI 规则标签。

**当前代码**：
```javascript
${rule.isAI ? '<span class="ai-tag">AI规则</span>' : '<span class="screening-tag">可甄别</span>'}
```

**修改为**：
```javascript
${rule.isAI ? '<span class="ai-tag">AI规则</span>' : ''}
```

> 普通规则不再显示任何标签。保留 AI 标签是因为 AI 规则是用户特别关注的类型。

#### 2.2 业务视图同步

业务视图（按规则分组展示）中同样去除普通规则的"可甄别"标签，逻辑与规则视图一致。

---

## 3. 疑点派发详情页（F3：派发环节甄别）

### 对应文件

`疑点派发-疑点详情.html`

### 当前状态

- 列表已有"甄别状态"列（第4列），展示`待甄别`/`已确认疑点`/`已排除`状态
- 甄别弹窗标题为"AI疑点甄别"，规则类型硬编码为"AI规则"
- 所有疑点行的`data-rule-type`均为`ai`
- "疑点甄别"操作按钮在所有行中都显示
- 甄别弹窗共用一个`#reviewModal`

### 改动内容

#### 3.1 行数据属性

在疑点行`<tr>`上使用`data-rule-type`区分规则类型。所有规则均启用甄别，无需`enableScreening`属性：

```html
<!-- 普通规则疑点行示例 -->
<tr data-id="YD20250101010"
    data-rule-type="ordinary"
    data-review-status="pending"
    data-rule-name="差旅费超标">
    ...
</tr>
```

#### 3.2 甄别弹窗适配

修改`#reviewModal`中的规则类型显示逻辑：

**当前代码**（硬编码）：
```html
<div class="detail-item">
    <span class="detail-label">规则类型</span>
    <span class="detail-value">AI规则</span>
</div>
```

**修改为**（动态读取）：
```html
<div class="detail-item">
    <span class="detail-label">规则类型</span>
    <span class="detail-value" id="reviewRuleType">AI规则</span>
</div>
```

弹窗标题根据规则类型动态调整：

```javascript
// openReviewModal 函数中
const ruleType = row.data('rule-type');

// 标题动态化
$('#reviewModal .modal-title').html(
    ruleType === 'ai'
        ? '<i class="fa fa-check-square-o me-2"></i>AI疑点甄别'
        : '<i class="fa fa-check-square-o me-2"></i>疑点甄别'
);

// 规则类型显示
$('#reviewRuleType').text(ruleType === 'ai' ? 'AI规则' : '普通规则');
```

#### 3.3 操作列菜单规范

操作列采用三点悬浮菜单样式，菜单项根据派发状态动态调整：

| 派发状态 | 菜单项（从上到下） |
|----------|-------------------|
| 未派发 | 疑点派发、放白名单、疑点甄别、查看链上记录、查看完整流程 |
| 已派发 | 放白名单、疑点甄别、查看链上记录、查看完整流程 |

> 已派发的疑点不显示"疑点派发"选项。所有规则均启用甄别，"疑点甄别"按钮对所有疑点行显示。

#### 3.4 "甄别状态"列显示逻辑

所有规则均启用甄别，所有疑点行统一显示甄别状态badge：

```javascript
function getReviewBadgeForRow(row) {
    const status = row.data('review-status') || 'pending';
    return getReviewBadge(status);
}
```

#### 3.5 已派发锁定逻辑（不变）

已派发的疑点无论AI还是普通规则，均不可再执行甄别。现有逻辑无需修改：

```javascript
// openReviewModal 中已有此判断
if (dispatchStatus.indexOf('已派发') !== -1) {
    alert('疑点已派发，不可再次甄别');
    return;
}
```

#### 3.6 疑点描述来源差异

| 规则类型 | 疑点描述来源 |
|----------|-------------|
| AI规则 | AI生成的描述（不变） |
| 普通规则 | 疑点描述模板生成 |

弹窗中`#reviewDescription`字段无需改动，数据来源由后端控制。

#### 3.7 批量甄别弹窗

在疑点派发详情页底部批量操作栏中新增"批量甄别"功能，与单个甄别保持操作语义一致。

**弹窗结构**：

```html
<!-- 批量甄别弹窗 -->
<div class="modal-overlay" id="batchReviewModal" style="display:none">
    <div class="modal-content" style="width: 500px;">
        <div class="modal-header">
            <h4 class="modal-title">批量甄别</h4>
            <button class="modal-close" onclick="closeBatchReviewModal()">&times;</button>
        </div>
        <div class="modal-body">
            <div style="background: #e6f7ff; ...">
                已选择 <span id="batchReviewCount">0</span> 条疑点，请选择甄别结果：
            </div>
            <div class="detail-item">
                <span class="detail-label">排除原因</span>
                <textarea id="batchReviewReason" placeholder="选填：若排除疑点，请输入排除原因"></textarea>
            </div>
        </div>
        <div class="modal-footer">
            <button class="btn btn-outline-secondary" onclick="closeBatchReviewModal()">取消</button>
            <button class="btn btn-success" onclick="confirmBatchDoubt()">确认疑点</button>
            <button class="btn btn-danger" onclick="batchExcludeDoubt()">排除疑点</button>
        </div>
    </div>
</div>
```

**与单个甄别弹窗的差异**：

| 差异点 | 单个甄别 | 批量甄别 |
|--------|----------|----------|
| 弹窗宽度 | 640px | 500px |
| 展示内容 | 疑点编号、触发规则、规则类型、疑点描述 | 选中数量提示、排除原因输入框 |
| 排除原因 | 选填 | 选填（共用） |
| 操作按钮 | 确认疑点 / 排除疑点 | 确认疑点 / 排除疑点（一致） |

**JavaScript 逻辑**：

```javascript
// 打开弹窗时重置排除原因
function openBatchReviewModal() {
    if (selectedDoubtIds.length === 0) { alert('请先选择疑点'); return; }
    document.getElementById('batchReviewCount').textContent = selectedDoubtIds.length;
    document.getElementById('batchReviewReason').value = '';
    document.getElementById('batchReviewModal').style.display = 'flex';
}

// 批量确认疑点
function confirmBatchDoubt() {
    const count = selectedDoubtIds.length;
    const states = readReviewStates();
    selectedDoubtIds.forEach(id => { states[id] = 'confirmed'; });
    saveReviewStates(states);
    selectedDoubtIds.forEach(id => {
        const row = document.querySelector(`tbody tr[data-id="${id}"]`);
        if (row) {
            row.dataset.reviewStatus = 'confirmed';
            const td = row.querySelector('td:nth-child(4)');
            if (td) td.innerHTML = getReviewBadge('confirmed');
        }
    });
    closeBatchReviewModal();
    alert(`成功确认 ${count} 条疑点`);
}

// 批量排除疑点
function batchExcludeDoubt() {
    const count = selectedDoubtIds.length;
    const states = readReviewStates();
    const excluded = readExcludedDoubts();
    selectedDoubtIds.forEach(id => {
        states[id] = 'excluded';
        const row = document.querySelector(`tbody tr[data-id="${id}"]`);
        if (row) {
            excluded.unshift(buildExcludedItem($(row)));
            row.remove();
        }
    });
    saveReviewStates(states);
    saveExcludedDoubts(excluded);
    closeBatchReviewModal();
    updateRecordCount();
    alert(`成功排除 ${count} 条疑点`);
}
```

**批量按钮显示条件**：与批量派发、批量加白名单同组（A组按钮），在 `updateBatchButtons()` 中统一管理。仅"需处置"类型场景、选中 A 组（未派发/派发驳回）时显示。

**验收要点**：
- [ ] 批量甄别弹窗同时包含"确认疑点"和"排除疑点"两个按钮
- [ ] 确认疑点后所选行甄别状态更新为"已确认疑点"
- [ ] 排除疑点后所选行从主列表移除并进入已排除列表
- [ ] 排除原因输入框在打开弹窗时清空

---

## 4. 已排除疑点页（F4：普通规则已排除疑点页）

### 对应文件

`疑点派发-疑点详情-已排除疑点.html`

### 当前状态

- 页面顶部说明文字写死为："本页面展示当前场景、当前规则下，被业务方在派发环节判定为"已排除"的 AI 疑点。"
- 规则信息卡片显示`AI规则`badge（硬编码）
- 列表字段包含疑点编号、排除时间、排除原因、疑点描述及业务字段
- 恢复操作调用`restoreDoubt()`，通过localStorage管理数据

### 改动内容

#### 4.1 新增"排除人"和"排除人单位"列

在列表"排除原因"列后新增两列：

| 新增列 | 说明 |
|--------|------|
| 排除人 | 执行排除操作的人员姓名 |
| 排除人单位 | 排除人所属单位/部门 |

**表头改动**（colspan 从 11 更新为 13）：
```html
<tr>
    <!-- 原有列... -->
    <th>排除原因</th>
    <th>排除人</th>
    <th>排除人单位</th>
    <th>疑点描述</th>
    <!-- 业务字段列... -->
    <th>操作</th>
</tr>
```

**Mock 数据新增字段**：
```javascript
{
    excludedBy: '张三',
    excludedByUnit: '财务管理部',
    // ...其他字段
}
```

#### 4.2 页面说明文字修改

**当前**：
```html
<div class="text-muted" style="font-size: 14px;">
    <i class="fa fa-info-circle me-1"></i>本页面展示当前场景、当前规则下，被业务方在派发环节判定为"已排除"的 AI 疑点。
</div>
```

**修改为**：
```html
<div class="text-muted" style="font-size: 14px;">
    <i class="fa fa-info-circle me-1"></i>本页面展示当前场景、当前规则下，被业务方在派发环节判定为"已排除"的疑点。
</div>
```

#### 4.3 规则类型badge动态化

**当前**（硬编码）：
```html
<span class="review-badge" style="margin-left: 8px;">AI规则</span>
```

**修改为**（根据URL参数动态显示）：
```html
<span class="review-badge" id="ruleTypeBadge" style="margin-left: 8px;">AI规则</span>
```

```javascript
// 在 getPageContext 或 renderExcludedTable 中
const urlParams = new URLSearchParams(window.location.search);
const ruleType = urlParams.get('ruleType') || 'ai';
document.getElementById('ruleTypeBadge').textContent =
    ruleType === 'ai' ? 'AI规则' : '普通规则';
```

#### 4.4 疑点描述字段适配

当前"疑点描述"列展示AI生成的描述。对于普通规则，描述来源为疑点描述模板。

无需前端改动——数据来源由后端控制，前端统一展示`item.description`字段。

#### 4.5 跳转入口适配

在`疑点派发-疑点详情.html`中，"查看已排除疑点"按钮跳转时需传递`ruleType`参数：

**当前代码**：
```javascript
window.open(`疑点派发-疑点详情-已排除疑点.html?sceneName=${sceneName}&sceneCode=${sceneCode}&ruleName=${ruleName}&ruleCode=${ruleCode}`, '_blank');
```

**修改为**：
```javascript
const ruleType = $('tbody tr').first().data('rule-type') || 'ai';
window.open(`疑点派发-疑点详情-已排除疑点.html?sceneName=${sceneName}&sceneCode=${sceneCode}&ruleName=${ruleName}&ruleCode=${ruleCode}&ruleType=${ruleType}`, '_blank');
```

---

## 5. 已排除疑点汇总页（F4：已排除疑点汇总页）- 新增

### 对应文件

`已排除疑点汇总.html`（**新页面**）

### 页面定位

所有用户均可访问的已排除疑点汇总页面。**管理员**可查看全部数据，**普通用户**仅可查看自己所属场景的数据。

### 入口

侧边菜单"风控运营管理"下新增子菜单项"已排除疑点汇总"。

### 数据权限模型

| 用户角色 | 数据范围 | 说明 |
|----------|----------|------|
| 管理员 | 全部场景 | 可查看所有场景、所有规则的已排除疑点 |
| 普通用户 | 所属场景 | 仅可查看自己被分配或负责的场景下的已排除疑点 |

> 后端根据当前登录用户的角色和场景归属自动过滤数据，前端无需额外处理权限逻辑，只需透传筛选条件。

### 页面结构

#### 5.1 侧边菜单改动

在"风控运营管理"节点下新增：

```html
<li class="tree-node level-3">
    <a href="已排除疑点汇总.html">已排除疑点汇总</a>
</li>
```

#### 5.2 视图切换

页面右上角提供视图切换按钮，支持管理员与普通用户视角切换：

```html
<div class="d-flex align-items-center gap-2">
    <span class="scope-indicator" id="scopeIndicator">
        <i class="fa fa-shield"></i>
        <span id="scopeText">管理员视图 - 全部场景</span>
    </span>
    <button class="btn btn-outline-primary btn-sm" id="toggleRoleBtn" title="切换视图">
        <i class="fa fa-exchange"></i> 切换
    </button>
</div>
```

```javascript
// 切换角色
$('#toggleRoleBtn').on('click', function() {
    currentUserRole = currentUserRole === 'admin' ? 'user' : 'admin';
    $('#sceneFilter').val('');
    $('#sceneFilter option').show();
    updateScopeUI();
    renderTable();
});
```

切换后同步更新：
- 页面提示文字（管理员提示 / 普通用户提示）
- 筛选区下拉选项范围（普通用户仅显示所属场景）
- 列表数据范围

#### 5.3 页面顶部提示

管理员与普通用户看到的提示不同：

```html
<div class="tip-box" id="scopeTipBox">
    <span id="adminTip">当前为管理员视图，展示所有场景下的已排除疑点。</span>
    <span id="userTip" style="display:none;">当前展示您所属场景下的已排除疑点。</span>
</div>
```

#### 5.4 顶部筛选区

| 筛选项 | 类型 | 说明 |
|--------|------|------|
| 业务域 | 下拉单选 | 管理员：全部业务域；普通用户：仅所属业务域 |
| 风险场景 | 下拉单选 | 选项展示"场景名称 (编号)"格式，宽度 280px |
| 规则类型 | 下拉单选 | 全部 / AI规则 / 普通规则 |
| 排除时间 | 日期范围 | 开始日期 + 结束日期 |
| 搜索 | 文本输入 | 不选字段，统一搜索规则名称、规则编号、疑点编号、排除人 |

搜索框实现要点：
- 移除搜索类型下拉框（`#searchType`），简化为单一输入框
- placeholder 设为"支持搜索规则名称、规则编号、疑点编号、排除人"
- 添加 `title` 属性，鼠标悬浮展示完整提示文字
- 输入框 `min-width: 320px` 确保提示文字完整显示
- JS 搜索逻辑同时匹配：`item.id`、`item.ruleName`、`item.ruleCode`、`item.excludedBy`、`item.sceneName`、`item.description`、`item.reason`

```html
<div class="filter-item" style="flex: 1; min-width: 300px;">
    <label>搜索：</label>
    <div class="search-group" style="flex: 1;">
        <input type="text" class="form-control form-control-sm" id="searchInput"
               style="min-width: 320px;"
               placeholder="支持搜索规则名称、规则编号、疑点编号、排除人"
               title="支持搜索规则名称、规则编号、疑点编号、排除人">
        <button class="btn btn-primary btn-sm" id="searchBtn"><i class="fa fa-search"></i></button>
    </div>
</div>
```

#### 5.5 列表区

| 列字段 | 宽度 | 说明 |
|--------|------|------|
| 疑点编号 | 130px | 疑点唯一标识 |
| 所属场景 | 250px | 场景名称 + 场景编号（`<br>` 换行，编号以等宽灰色小字显示） |
| 触发规则 | 220px | 规则名称 + 规则编号（`<br>` 换行，编号以等宽灰色小字显示） |
| 规则类型 | 100px | AI规则 / 普通规则 badge |
| 疑点描述 | 240px | 疑点的业务描述信息，两行省略 |
| 排除人 | 100px | 执行排除的人员 |
| 排除人单位 | 130px | 排除人所属单位/部门 |
| 排除时间 | 160px | 执行排除的时间 |
| 排除原因 | 300px | 排除原因，两行省略 |
| 操作 | 80px | 三点悬浮菜单（查看详情、恢复到疑点列表） |

场景和规则编号展示（编号使用等宽字体、灰色小字，悬浮提示显示完整"名称（编号）"）：
```javascript
// 场景列
<td class="cell-wrap" title="${item.sceneName}（${item.sceneCode || ''}）">
    ${item.sceneName}${item.sceneCode ? '<br><small class="text-muted" style="font-family:monospace;">' + item.sceneCode + '</small>' : ''}
</td>

// 规则列
<td class="cell-wrap" title="${item.ruleName}（${item.ruleCode || ''}）">
    ${item.ruleName}${item.ruleCode ? '<br><small class="text-muted" style="font-family:monospace;">' + item.ruleCode + '</small>' : ''}
</td>
```

> 优化要点：编号使用 `font-family:monospace` 等宽字体，与名称形成视觉区分；悬浮提示（`title`）展示"名称（编号）"完整格式；列宽适度加大以容纳双行内容；`cell-wrap` 类允许单元格内换行（`white-space:normal; line-height:1.6`）。

#### 5.6 操作列 - 三点悬浮菜单

操作列采用三点悬浮菜单样式，鼠标悬浮展开操作项：

```html
<div class="action-menu-container">
    <div class="action-dots">
        <span class="action-dot"></span>
        <span class="action-dot"></span>
        <span class="action-dot"></span>
    </div>
    <div class="action-dropdown">
        <a onclick="viewDetail('${item.id}')">查看详情</a>
        <a onclick="restoreDoubt('${item.id}')">恢复到疑点列表</a>
    </div>
</div>
```

```javascript
// 悬浮展开/收起
$(document).on('mouseenter', '.action-menu-container', function() {
    $(this).find('.action-dropdown').addClass('show');
}).on('mouseleave', '.action-menu-container', function() {
    $(this).find('.action-dropdown').removeClass('show');
});
```

CSS 关键点：
- `.table tbody tr:hover td:last-child { z-index:100; }` — 悬浮行的操作列 z-index 提升，避免被下一行遮挡
- `.action-dropdown { z-index:1000; }` — 下拉菜单高层级

#### 5.7 查看详情弹窗

弹窗使用 `modal-xl` 宽度，包含三个信息区块：

1. **疑点基本信息**：疑点编号、场景名称、规则名称、规则类型、排除时间
2. **业务信息**：横向表格展示，使用 `.table-responsive` 包裹支持水平滚动
3. **排除信息**：排除人、排除人单位、排除原因

业务信息横向表格：
```html
<div class="table-responsive">
    <table class="biz-table">
        <thead>
            <tr>
                <th>字段1</th><th>字段2</th><th>...</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>值1</td><td>值2</td><td>...</td>
            </tr>
        </tbody>
    </table>
</div>
```

根据业务域不同，展示不同的业务字段（合同管理、差旅管理、安全管理各有 11~13 个字段）。

#### 5.8 恢复到疑点列表

```javascript
function restoreDoubt(id) {
    if (!confirm('确定将此疑点恢复到疑点列表？')) return;
    // TODO: 调用后端接口
    // 成功后移除该行，更新统计
    $(`tr[data-id="${id}"]`).remove();
    renderTable();
}
```

#### 5.9 Mock 数据结构

```javascript
{
    id: 'YD20250101001',
    sceneName: '合同管理合规性场景',
    sceneCode: 'CJ-20250101-00001',
    ruleName: '合同签署合规性检查',
    ruleCode: 'RULE-20250101-001',
    ruleType: 'ordinary',
    description: '疑点描述内容...',
    excludedBy: '张三',
    excludedByUnit: '财务管理部',
    excludedAt: '2025-01-15 10:30:00',
    reason: '排除原因...',
    bizType: 'contract',
    bizData: { /* 业务字段 */ }
}
```

---

## 6. 新增样式汇总

以下样式在各页面`<style>`中按需添加：

```css
/* ~~可甄别标签 - 场景疑点页~~ （已去除，不再使用） */

/* 三点悬浮菜单 - 已排除汇总页 */
.action-menu-container { position:relative; display:inline-block; z-index:1; }
.action-menu-container:hover { z-index:100; }
.action-dots { cursor:pointer; padding:4px 8px; display:flex; flex-direction:column; align-items:center; gap:3px; }
.action-dot { width:4px; height:4px; background-color:currentColor; border-radius:50%; display:block; }
.action-dropdown { position:absolute; top:100%; right:0; background:#fff; border:1px solid #e4e7ed; border-radius:4px; box-shadow:0 2px 12px rgba(0,0,0,0.1); min-width:80px; padding:4px 0; z-index:1000; display:none; white-space:nowrap; }
.action-dropdown.show { display:block; }
.action-dropdown a { display:block; padding:8px 16px; color:#606266; text-decoration:none; font-size:13px; transition:all 0.2s ease; cursor:pointer; }
.action-dropdown a:hover { background:#F5F7FA; color:#409EFF; }

/* 操作列 sticky + 悬浮层级提升 */
.table thead th:last-child,
.table tbody td:last-child { position:sticky; right:0; background:#fff; z-index:10; box-shadow:-2px 0 4px rgba(0,0,0,0.05); }
.table tbody tr:hover td:last-child { z-index:100; }

/* 业务信息横向表格 - 查看详情弹窗 */
.biz-table { width:100%; border-collapse:collapse; font-size:13px; }
.biz-table th { background:#f5f7fa; color:#909399; font-weight:500; padding:8px 12px; border:1px solid #ebeef5; white-space:nowrap; text-align:left; }
.biz-table td { padding:8px 12px; border:1px solid #ebeef5; color:#303133; white-space:nowrap; }

/* 角色范围提示框 - 已排除汇总页 */
.tip-box {
    background: linear-gradient(135deg, #fff7e6 0%, #fff1d6 100%);
    border: 1px solid #ffd591;
    border-radius: 8px;
    padding: 12px 16px;
    margin-bottom: 16px;
    color: #8c6d1f;
    font-size: 13px;
}
```

---

## 7. 数据模型变更（前端视角）

### 7.1 规则数据

所有规则默认启用甄别，前端**无需** `enableScreening`字段。

### 7.2 疑点数据无新增字段

现有甄别相关字段（`SCREENING_STATUS`、`SCREENING_SOURCE`等）直接复用，前端无需感知新增列。

### 7.3 localStorage key 适配

当前已排除疑点使用`aiReviewedExcludedDoubts`作为localStorage key。扩展至普通规则后：

- 保持key不变，通过数据中的`ruleType`字段区分AI/普通规则

---

## 8. 改动优先级与依赖关系

```
F2（场景疑点标识）──→ F3（派发环节甄别）──→ F4（已排除疑点页）
                                                    │
                                                    ↓
                                            F5（汇总页，独立新增）
```

- F2/F3 可并行开发，均不依赖开关（所有规则默认启用甄别）
- F4 依赖 F3 的数据流（排除操作产生已排除数据）
- F5 相对独立，但需要后端提供跨规则的汇总查询接口，并按角色过滤数据范围

---

## 9. 验收检查清单

### ~~F1：规则甄别开关~~ （已取消）
- ~~普通规则详情页出现"启用疑点甄别"开关~~
- ~~AI规则详情页不展示该开关~~
- ~~仅管理员可操作~~
- ~~仅已上线规则可开启~~

### F2：场景疑点标识
- [x] 普通规则去除"可甄别"标签
- [x] AI规则仍显示"AI规则"标签

### F3：派发环节甄别
- [x] 所有规则（AI + 普通）的疑点均显示甄别状态列
- [x] 所有未派发疑点均可执行甄别操作
- [x] 甄别弹窗规则类型正确显示（AI规则 / 普通规则）
- [x] 已派发疑点不可甄别（不变）
- [x] 操作列菜单按派发状态区分：未派发含"疑点派发"，已派发不含
- [x] 批量甄别弹窗同时包含"确认疑点"和"排除疑点"两个按钮（与单个甄别一致）
- [x] 批量确认疑点后所选行甄别状态批量更新
- [x] 批量排除疑点后所选行从主列表批量移除并进入已排除列表
- [x] 批量甄别排除原因输入框在打开弹窗时清空

### F3：已排除疑点页
- [x] 页面说明文字不再写死"AI疑点"
- [x] 规则类型badge根据实际规则类型显示
- [x] 普通规则疑点描述为模板生成内容
- [x] 恢复功能正常
- [x] 新增"排除人"和"排除人单位"列

### F4：已排除疑点汇总页
- [x] 所有用户均可访问（非仅运营方）
- [x] 管理员可查看全部场景数据
- [x] 普通用户仅可查看自己所属场景数据
- [x] 右上角视图切换按钮可切换管理员/普通用户视角
- [x] 筛选区场景下拉显示"名称 (编号)"格式
- [x] 搜索框统一搜索规则名称、规则编号、疑点编号、排除人
- [x] 列表显示场景编号和规则编号
- [x] 列表新增"排除人单位"和"疑点描述"列
- [x] 操作列采用三点悬浮菜单样式
- [x] 支持"查看详情"弹窗（业务信息横向表格+水平滚动）
- [x] 支持"恢复到疑点列表"操作
