# 批量风险处置功能 - 页面改动说明

## 1. 改动概述

| 页面 | 使用角色 | 改动类型 | 说明 |
|------|----------|----------|------|
| 疑点处置-疑点详情.html | 处置人 | 修改 | 新增复选框列、批量已读按钮（提示类型规则）、批量提交处理结果和批量退回重新分派按钮（需处置类型规则）、"处置反馈"改名为"提交处理结果"。同一规则下疑点处置方式一致 |
| 疑点派发-疑点详情.html | 派发人 | 修改 | 新增处置类型切换功能、处置情况列固定显示、新增处置情况筛选器、新增审核处理情况菜单、新增批量派发/甄别/加白名单/审核通过/审核驳回功能（分组控制） |

---

## 2. 疑点处置-疑点详情.html

### 2.0 处置类型切换功能

**功能描述：** 面包屑行最右侧新增处置类型标签和切换按钮，支持在"需处置"和"提示"两种类型之间切换。

**不同处置类型的处置状态和操作菜单：**

| 处置类型 | 处置状态 | 操作菜单 |
|----------|----------|----------|
| 【需处置】 | 已派发待处置 | 提交处理结果、查看完整流程、查看链上记录 |
| 【需处置】 | 已处置待审核 | 查看完整流程、查看链上记录 |
| 【提示】 | 已派发未读 | 确认已读、查看链上记录 |

**实现方式：**
- 页面包含两个 `<tbody>`：`id="needHandleBody"`（需处置数据）和 `id="tipBody"`（提示数据）
- 切换时通过 show/hide 控制显隐，同时更新标签文字、面包屑、筛选器选项
- 提示类型筛选器选项：全部、已派发未读、已读完毕
- 需处置类型筛选器选项：全部、已派发待处置、已处置待审核

---

### 2.1 表格头部改动

**改动位置：** `<thead>` 标签内

**改动内容：** 在第一列新增复选框列

**改动前：**
```html
<thead>
    <tr>
        <th width="100">处置状态</th>
        <th width="130">疑点编号</th>
        <th width="100">上链状态</th>
        <!-- 其他列 -->
    </tr>
</thead>
```

**改动后：**
```html
<thead>
    <tr>
        <th width="40"><input type="checkbox" id="selectAll" title="全选当前页"></th>
        <th width="100">处置状态</th>
        <th width="130">疑点编号</th>
        <th width="100">上链状态</th>
        <!-- 其他列 -->
    </tr>
</thead>
```

---

### 2.2 表格行改动

**改动位置：** `<tbody>` 内每行 `<tr>` 标签

**改动内容：** 在每行第一列新增复选框

**改动前：**
```html
<tr data-id="YD20250101001" data-handler="" data-unit="" data-complete="no" data-void="no">
    <td><span class="status-badge status-pending">已派发待处置</span></td>
    <td>YD20250101001</td>
    <!-- 其他列 -->
</tr>
```

**改动后：**
```html
<tr data-id="YD20250101001" data-handler="" data-unit="" data-complete="no" data-void="no" data-status="pending_disposal">
    <td><input type="checkbox" class="doubt-checkbox" data-id="YD20250101001"></td>
    <td><span class="status-badge status-pending">已派发待处置</span></td>
    <td>YD20250101001</td>
    <!-- 其他列 -->
</tr>
```

**说明：**
- 新增 `data-status` 属性，用于判断是否可勾选
- 新增复选框列，`data-id` 存储疑点ID

---

### 2.3 底部批量操作栏

**改动位置：** 表格下方、分页上方

**改动内容：** 新增悬浮底部操作栏（初始隐藏），包含批量操作按钮

**按钮说明：**
| 按钮 | 显示条件 | 说明 |
|------|----------|------|
| 批量确认已读 | 处置类型为"提示" | 勾选"已派发未读"疑点后显示 |
| 批量提交处理结果 | 处置类型为"需处置" | 勾选"已派发待处置"疑点后显示 |
| 批量退回重新分派 | 处置类型为"需处置" | 勾选"已派发待处置"疑点后显示 |

**新增代码：**
```html
<div class="batch-action-bar" id="batchActionBar" style="display:none;">
    <div class="d-flex justify-content-between align-items-center">
        <div class="selected-info">
            已选 <span id="selectedCount" class="fw-bold text-primary">0</span> 条
        </div>
        <div class="action-buttons d-flex gap-2">
            <button class="btn btn-primary btn-sm" id="batchConfirmReadBtnBottom" onclick="openBatchReadModal()" style="display:none">
                <i class="fa fa-check"></i> 批量确认已读
            </button>
            <button class="btn btn-primary btn-sm" id="batchDisposeBtnBottom" onclick="openBatchDisposeModal()" style="display:none">
                <i class="fa fa-send"></i> 批量提交处理结果
            </button>
            <button class="btn btn-warning btn-sm" id="batchReturnBtnBottom" onclick="openBatchReturnModal()" style="display:none">
                <i class="fa fa-undo"></i> 批量退回重新分派
            </button>
        </div>
    </div>
</div>
```

---

### 2.4 新增底部操作栏

**改动位置：** 表格下方、分页上方

**改动内容：** 新增悬浮底部操作栏（初始隐藏）

**新增代码：**
```html
<div class="batch-action-bar" id="batchActionBar" style="display:none; position: sticky; bottom: 0; background: #fff; padding: 12px 20px; border-top: 1px solid #e4e7ed; box-shadow: 0 -2px 8px rgba(0,0,0,0.05); z-index: 100;">
    <div class="d-flex justify-content-between align-items-center">
        <div class="selected-info">
            已选 <span id="selectedCount" class="fw-bold text-primary">0</span> 条
        </div>
        <div class="action-buttons d-flex gap-2">
            <!-- 提示方式显示 -->
            <button class="btn btn-primary btn-sm" id="batchReadBtnBottom" onclick="openBatchReadModal()" style="display:none">
                <i class="fa fa-check"></i> 批量已读
            </button>
            <!-- 需处置方式（处置人）显示 -->
            <button class="btn btn-primary btn-sm" id="batchDisposeBtnBottom" onclick="openBatchDisposeModal()" style="display:none">
                <i class="fa fa-send"></i> 批量处置
            </button>
            <!-- 需处置方式（分派人）显示 -->
            <button class="btn btn-success btn-sm" id="batchApproveBtnBottom" onclick="openBatchApproveModal()" style="display:none">
                <i class="fa fa-check-circle"></i> 批量通过
            </button>
            <button class="btn btn-danger btn-sm" id="batchRejectBtnBottom" onclick="openBatchRejectModal()" style="display:none">
                <i class="fa fa-times-circle"></i> 批量驳回
            </button>
        </div>
    </div>
</div>
```

---

### 2.5 新增弹窗

#### 2.5.1 批量标记已读弹窗

**新增位置：** 页面底部 `</body>` 前

**新增代码：**
```html
<!-- 批量标记已读弹窗 -->
<div class="modal-overlay" id="batchReadModal" style="display:none">
    <div class="modal-content" style="width: 400px;">
        <div class="modal-header">
            <h4 class="modal-title">批量标记已读</h4>
            <button class="modal-close" onclick="closeBatchReadModal()">&times;</button>
        </div>
        <div class="modal-body">
            <p>确定将 <span id="batchReadCount" class="fw-bold text-primary">0</span> 条疑点标记为已读？</p>
        </div>
        <div class="modal-footer" style="padding: 16px 24px; border-top: 1px solid #e4e7ed; text-align: right;">
            <button class="btn btn-outline-secondary btn-sm me-2" onclick="closeBatchReadModal()">取消</button>
            <button class="btn btn-primary btn-sm" onclick="confirmBatchRead()">确定</button>
        </div>
    </div>
</div>
```

#### 2.5.2 批量处置弹窗

**新增代码：**
```html
<!-- 批量处置弹窗 -->
<div class="modal-overlay" id="batchDisposeModal" style="display:none">
    <div class="modal-content" style="width: 500px;">
        <div class="modal-header">
            <h4 class="modal-title">批量处置</h4>
            <button class="modal-close" onclick="closeBatchDisposeModal()">&times;</button>
        </div>
        <div class="modal-body">
            <div style="background: #e6f7ff; border: 1px solid #91d5ff; border-radius: 6px; padding: 12px 16px; margin-bottom: 16px;">
                <i class="fa fa-info-circle text-primary me-2"></i>
                您已选择 <span id="batchDisposeCount" class="fw-bold text-primary">0</span> 条疑点，请填写处置说明后提交审核
            </div>
            <div class="mb-3">
                <label class="form-label">处置说明 <span class="text-danger">*</span></label>
                <textarea class="form-control" id="disposeOpinion" rows="4" placeholder="请描述疑点处理过程及结果"></textarea>
            </div>
        </div>
        <div class="modal-footer" style="padding: 16px 24px; border-top: 1px solid #e4e7ed; text-align: right;">
            <button class="btn btn-outline-secondary btn-sm me-2" onclick="closeBatchDisposeModal()">取消</button>
            <button class="btn btn-primary btn-sm" onclick="confirmBatchDispose()">确定提交</button>
        </div>
    </div>
</div>
```

#### 2.5.3 批量退回重新分派弹窗

**新增代码：**
```html
<!-- 批量退回重新分派弹窗 -->
<div class="modal-overlay" id="batchReturnModal" style="display:none">
    <div class="modal-content" style="width: 500px;">
        <div class="modal-header">
            <h4 class="modal-title">批量退回重新分派</h4>
            <button class="modal-close" onclick="closeBatchReturnModal()">&times;</button>
        </div>
        <div class="modal-body">
            <div style="background: #fff7e6; border: 1px solid #ffd591; border-radius: 6px; padding: 12px 16px; margin-bottom: 16px;">
                <i class="fa fa-exclamation-circle text-warning me-2"></i>
                您已选择 <span id="batchReturnCount" class="fw-bold text-primary">0</span> 条疑点，请填写退回原因后确认退回
            </div>
            <div class="mb-3">
                <label class="form-label">退回原因 <span class="text-danger">*</span></label>
                <textarea class="form-control" id="returnReason" rows="4" placeholder="请说明退回理由"></textarea>
            </div>
        </div>
        <div class="modal-footer" style="padding: 16px 24px; border-top: 1px solid #e4e7ed; text-align: right;">
            <button class="btn btn-outline-secondary btn-sm me-2" onclick="closeBatchReturnModal()">取消</button>
            <button class="btn btn-warning btn-sm" onclick="confirmBatchReturn()">确定退回</button>
        </div>
    </div>
</div>
```

#### 2.5.4 批量审核通过弹窗

**新增代码：**
```html
<!-- 批量审核通过弹窗 -->
<div class="modal-overlay" id="batchApproveModal" style="display:none">
    <div class="modal-content" style="width: 500px;">
        <div class="modal-header">
            <h4 class="modal-title">批量审核通过</h4>
            <button class="modal-close" onclick="closeBatchApproveModal()">&times;</button>
        </div>
        <div class="modal-body">
            <div style="background: #f0f9eb; border: 1px solid #c2e7b0; border-radius: 6px; padding: 12px 16px; margin-bottom: 16px;">
                <i class="fa fa-check-circle text-success me-2"></i>
                您已选择 <span id="batchApproveCount" class="fw-bold text-primary">0</span> 条疑点，请填写审核意见后确认通过
            </div>
            <div class="mb-3">
                <label class="form-label">审核意见 <span class="text-danger">*</span></label>
                <textarea class="form-control" id="approveOpinion" rows="4" placeholder="请填写审核通过说明（如无特殊说明可写"同意通过"）"></textarea>
            </div>
        </div>
        <div class="modal-footer" style="padding: 16px 24px; border-top: 1px solid #e4e7ed; text-align: right;">
            <button class="btn btn-outline-secondary btn-sm me-2" onclick="closeBatchApproveModal()">取消</button>
            <button class="btn btn-success btn-sm" onclick="confirmBatchApprove()">确定通过</button>
        </div>
    </div>
</div>
```

#### 2.5.4 批量审核驳回弹窗

**新增代码：**
```html
<!-- 批量审核驳回弹窗 -->
<div class="modal-overlay" id="batchRejectModal" style="display:none">
    <div class="modal-content" style="width: 500px;">
        <div class="modal-header">
            <h4 class="modal-title">批量审核驳回</h4>
            <button class="modal-close" onclick="closeBatchRejectModal()">&times;</button>
        </div>
        <div class="modal-body">
            <div style="background: #fff7e6; border: 1px solid #ffd591; border-radius: 6px; padding: 12px 16px; margin-bottom: 16px;">
                <i class="fa fa-exclamation-circle text-warning me-2"></i>
                您已选择 <span id="batchRejectCount" class="fw-bold text-primary">0</span> 条疑点，请填写驳回意见后确认驳回
            </div>
            <div class="mb-3">
                <label class="form-label">驳回意见 <span class="text-danger">*</span></label>
                <textarea class="form-control" id="rejectOpinion" rows="4" placeholder="请说明驳回原因及需补充完善的内容"></textarea>
            </div>
        </div>
        <div class="modal-footer" style="padding: 16px 24px; border-top: 1px solid #e4e7ed; text-align: right;">
            <button class="btn btn-outline-secondary btn-sm me-2" onclick="closeBatchRejectModal()">取消</button>
            <button class="btn btn-danger btn-sm" onclick="confirmBatchReject()">确定驳回</button>
        </div>
    </div>
</div>
```

---

### 2.6 新增CSS样式

**改动位置：** `<style>` 标签内

**新增代码：**
```css
/* 批量操作栏样式 */
.batch-action-bar {
    background: #fff;
    padding: 12px 20px;
    border-top: 1px solid #e4e7ed;
    box-shadow: 0 -2px 8px rgba(0,0,0,0.05);
}

.batch-action-bar .selected-info {
    font-size: 14px;
    color: #606266;
}

.batch-action-bar .action-buttons {
    display: flex;
    gap: 8px;
}

/* 复选框列样式 */
.table thead th:first-child,
.table tbody td:first-child {
    text-align: center;
    width: 40px;
}

/* 禁用状态复选框 */
.doubt-checkbox:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}
```

---

### 2.7 新增JavaScript代码

**改动位置：** `<script>` 标签内

**新增代码：**
```javascript
// ========== 批量操作相关 ==========

// 全局变量
let selectedDoubtIds = [];
let currentRuleType = 'need-handle'; // 规则类型：tip-提示，need-handle-需处置
let currentUserRole = 'handler'; // 用户角色：handler-处置人，dispatcher-分派人

// 初始化批量操作按钮
function initBatchButtons() {
    if (currentRuleType === 'tip') {
        // 提示方式
        document.getElementById('batchReadBtn').style.display = 'inline-block';
        document.getElementById('batchReadBtnBottom').style.display = 'inline-block';
    } else if (currentRuleType === 'need-handle') {
        if (currentUserRole === 'handler') {
            // 处置人
            document.getElementById('batchDisposeBtn').style.display = 'inline-block';
            document.getElementById('batchDisposeBtnBottom').style.display = 'inline-block';
        } else if (currentUserRole === 'dispatcher') {
            // 分派人
            document.getElementById('batchApproveBtn').style.display = 'inline-block';
            document.getElementById('batchApproveBtnBottom').style.display = 'inline-block';
            document.getElementById('batchRejectBtn').style.display = 'inline-block';
            document.getElementById('batchRejectBtnBottom').style.display = 'inline-block';
        }
    }
}

// 全选/取消全选
document.getElementById('selectAll').addEventListener('change', function() {
    const checkboxes = document.querySelectorAll('.doubt-checkbox:not(:disabled)');
    checkboxes.forEach(cb => cb.checked = this.checked);
    updateSelectedCount();
});

// 单选复选框事件
document.querySelectorAll('.doubt-checkbox').forEach(cb => {
    cb.addEventListener('change', updateSelectedCount);
});

// 更新已选数量
function updateSelectedCount() {
    const checked = document.querySelectorAll('.doubt-checkbox:checked');
    selectedDoubtIds = Array.from(checked).map(cb => cb.dataset.id);
    const count = selectedDoubtIds.length;

    // 更新底部操作栏
    document.getElementById('batchActionBar').style.display = count > 0 ? 'block' : 'none';
    document.getElementById('selectedCount').textContent = count;

    // 更新全选状态
    const allCheckboxes = document.querySelectorAll('.doubt-checkbox:not(:disabled)');
    const allChecked = allCheckboxes.length > 0 && allCheckboxes.length === checked.length;
    document.getElementById('selectAll').checked = allChecked;
}

// 根据状态判断是否可勾选
function updateCheckboxState() {
    document.querySelectorAll('.doubt-checkbox').forEach(cb => {
        const row = cb.closest('tr');
        const status = row.dataset.status;

        let canCheck = false;
        if (currentRuleType === 'tip') {
            // 提示方式：只有"未读"状态可勾选
            canCheck = status === 'unread';
        } else if (currentRuleType === 'need-handle') {
            if (currentUserRole === 'handler') {
                // 处置人：只有"已派发待处置"状态可勾选
                canCheck = status === 'pending_disposal';
            } else if (currentUserRole === 'dispatcher') {
                // 分派人：只有"已处置待审核"状态可勾选
                canCheck = status === 'pending_review';
            }
        }

        cb.disabled = !canCheck;
        if (!canCheck) {
            cb.checked = false;
        }
    });
    updateSelectedCount();
}

// ========== 批量已读 ==========

function openBatchReadModal() {
    if (selectedDoubtIds.length === 0) {
        alert('请先选择疑点');
        return;
    }
    document.getElementById('batchReadCount').textContent = selectedDoubtIds.length;
    document.getElementById('batchReadModal').style.display = 'flex';
}

function closeBatchReadModal() {
    document.getElementById('batchReadModal').style.display = 'none';
}

function confirmBatchRead() {
    fetch('/core/riskRuleFiledConfig/batchRead', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ doubtIds: selectedDoubtIds })
    })
    .then(response => response.json())
    .then(data => {
        if (data.code === 200) {
            alert(`成功标记 ${data.data.successCount} 条疑点为已读`);
            closeBatchReadModal();
            location.reload();
        } else {
            alert('操作失败：' + data.message);
        }
    })
    .catch(error => {
        alert('请求失败：' + error.message);
    });
}

// ========== 批量处置 ==========

function openBatchDisposeModal() {
    if (selectedDoubtIds.length === 0) {
        alert('请先选择疑点');
        return;
    }
    document.getElementById('batchDisposeCount').textContent = selectedDoubtIds.length;
    document.getElementById('disposeOpinion').value = '';
    document.getElementById('batchDisposeModal').style.display = 'flex';
}

function closeBatchDisposeModal() {
    document.getElementById('batchDisposeModal').style.display = 'none';
}

function confirmBatchDispose() {
    const opinion = document.getElementById('disposeOpinion').value.trim();
    if (!opinion) {
        alert('请填写处置说明');
        return;
    }

    fetch('/core/riskRuleFiledConfig/batchDispose', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            doubtIds: selectedDoubtIds,
            disposeOpinion: opinion
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.code === 200) {
            alert(`成功处置 ${data.data.successCount} 条疑点`);
            closeBatchDisposeModal();
            location.reload();
        } else {
            alert('操作失败：' + data.message);
        }
    })
    .catch(error => {
        alert('请求失败：' + error.message);
    });
}

// ========== 批量审核通过 ==========

function openBatchApproveModal() {
    if (selectedDoubtIds.length === 0) {
        alert('请先选择疑点');
        return;
    }
    document.getElementById('batchApproveCount').textContent = selectedDoubtIds.length;
    document.getElementById('approveOpinion').value = '';
    document.getElementById('batchApproveModal').style.display = 'flex';
}

function closeBatchApproveModal() {
    document.getElementById('batchApproveModal').style.display = 'none';
}

function confirmBatchApprove() {
    const opinion = document.getElementById('approveOpinion').value.trim();
    if (!opinion) {
        alert('请填写审核意见');
        return;
    }

    fetch('/core/riskRuleFiledConfig/batchAudit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            doubtIds: selectedDoubtIds,
            auditType: 'PASS',
            auditOpinion: opinion
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.code === 200) {
            alert(`成功审核通过 ${data.data.successCount} 条疑点`);
            closeBatchApproveModal();
            location.reload();
        } else {
            alert('操作失败：' + data.message);
        }
    })
    .catch(error => {
        alert('请求失败：' + error.message);
    });
}

// ========== 批量审核驳回 ==========

function openBatchRejectModal() {
    if (selectedDoubtIds.length === 0) {
        alert('请先选择疑点');
        return;
    }
    document.getElementById('batchRejectCount').textContent = selectedDoubtIds.length;
    document.getElementById('rejectOpinion').value = '';
    document.getElementById('batchRejectModal').style.display = 'flex';
}

function closeBatchRejectModal() {
    document.getElementById('batchRejectModal').style.display = 'none';
}

function confirmBatchReject() {
    const opinion = document.getElementById('rejectOpinion').value.trim();
    if (!opinion) {
        alert('请填写驳回意见');
        return;
    }

    fetch('/core/riskRuleFiledConfig/batchAudit', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            doubtIds: selectedDoubtIds,
            auditType: 'REJECT',
            auditOpinion: opinion
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.code === 200) {
            alert(`成功驳回 ${data.data.successCount} 条疑点`);
            closeBatchRejectModal();
            location.reload();
        } else {
            alert('操作失败：' + data.message);
        }
    })
    .catch(error => {
        alert('请求失败：' + error.message);
    });
}

// 页面加载完成后初始化
$(document).ready(function() {
    // 初始化批量操作按钮
    initBatchButtons();
    // 初始化复选框状态
    updateCheckboxState();
});
```

---

## 3. 改动汇总

### 3.1 新增HTML元素
| 元素 | 类型 | 位置 | 说明 |
|------|------|------|------|
| 全选复选框 | `<input>` | 表头第一列 | 支持全选当前页 |
| 行复选框 | `<input>` | 每行第一列 | 单选功能 |
| 处置类型标签 | `<span>` | 面包屑行右侧 | 显示当前处置类型（需处置/提示） |
| 切换按钮 | `<button>` | 面包屑行右侧 | 切换处置类型 |
| 需处置数据区 | `<tbody>` | 表格内 | id="needHandleBody"，默认显示 |
| 提示数据区 | `<tbody>` | 表格内 | id="tipBody"，默认隐藏 |
| 批量确认已读按钮 | `<button>` | 底部操作栏 | 提示类型显示 |
| 批量处置按钮 | `<button>` | 底部操作栏 | 需处置类型显示 |
| 批量通过按钮 | `<button>` | 筛选区下方 | 需处置方式（分派人）显示 |
| 批量驳回按钮 | `<button>` | 筛选区下方 | 需处置方式（分派人）显示 |
| 底部操作栏 | `<div>` | 表格下方 | 勾选后显示 |
| 批量已读弹窗 | `<div>` | 页面底部 | 确认弹窗 |
| 批量处置弹窗 | `<div>` | 页面底部 | 填写处置说明 |
| 批量通过弹窗 | `<div>` | 页面底部 | 填写审核意见 |
| 批量驳回弹窗 | `<div>` | 页面底部 | 填写驳回意见 |

### 3.2 新增CSS样式
| 样式名 | 说明 |
|--------|------|
| `.batch-action-bar` | 底部操作栏样式 |
| `.doubt-checkbox:disabled` | 禁用状态复选框样式 |

### 3.3 新增JavaScript函数
| 函数名 | 说明 |
|--------|------|
| `initBatchButtons()` | 初始化批量操作按钮 |
| `updateSelectedCount()` | 更新已选数量 |
| `updateCheckboxState()` | 更新复选框状态 |
| `openBatchReadModal()` | 打开批量已读弹窗 |
| `closeBatchReadModal()` | 关闭批量已读弹窗 |
| `confirmBatchRead()` | 确认批量已读 |
| `openBatchDisposeModal()` | 打开批量处置弹窗 |
| `closeBatchDisposeModal()` | 关闭批量处置弹窗 |
| `confirmBatchDispose()` | 确认批量处置 |
| `openBatchApproveModal()` | 打开批量通过弹窗 |
| `closeBatchApproveModal()` | 关闭批量通过弹窗 |
| `confirmBatchApprove()` | 确认批量通过 |
| `openBatchRejectModal()` | 打开批量驳回弹窗 |
| `closeBatchRejectModal()` | 关闭批量驳回弹窗 |
| `confirmBatchReject()` | 确认批量驳回 |

---

## 3. 疑点派发-疑点详情.html（派发人页面）

### 3.0 处置类型切换功能

**功能描述：** 面包屑行最右侧新增处置类型标签和切换按钮，支持在"需处置"和"提示"两种类型之间切换。

**不同处置类型的筛选器选项：**

| 处置类型 | 派发状态筛选器 | 处置情况筛选器 |
|----------|----------------|----------------|
| 【需处置】 | 全部、未派发、已派发、派发驳回 | 全部、待派发、已分派待处置、已处置待审核 |
| 【提示】 | 全部、未派发、已派发 | 全部、已派发未读 |

**不同处置类型的操作菜单：**

| 处置类型 | 派发状态 | 操作菜单 |
|----------|----------|----------|
| 【需处置】 | 未派发 | 疑点派发、放白名单、疑点甄别、查看链上记录 |
| 【需处置】 | 已派发 | 审核处理情况、查看完整流程、查看链上记录 |
| 【需处置】 | 派发驳回 | 重新派发、查看完整流程、查看链上记录 |
| 【需处置】 | 已处置待审核 | 审核处理情况、查看链上记录、查看完整流程 |
| 【提示】 | 未派发 | 疑点派发、放白名单、疑点甄别、查看链上记录 |
| 【提示】 | 已派发（已派发未读） | 查看链上记录 |

**复选框勾选规则：**
- 需处置类型：未派发、派发驳回、已处置待审核可勾选
- 提示类型：仅未派发可勾选

**实现方式：**
- 页面包含两个 `<tbody>`：`id="needHandleBody"`（需处置数据）和 `id="tipBody"`（提示数据）
- 切换时通过 show/hide 控制显隐，同时更新标签文字、筛选器选项
- 提示类型无批量操作按钮

**新增CSS样式：**
```css
.scope-indicator { display:inline-flex; align-items:center; gap:6px; padding:4px 12px; border-radius:12px; font-size:12px; font-weight:500; }
.scope-disposal { background:#ecf5ff; color:#409EFF; }
.scope-tip { background:#f0f9eb; color:#67c23a; }
.disposal-unread { background-color: #fff7e6; color: #E6A23C; border: 1px solid #ffd591; }
```

**新增HTML（面包屑区域）：**
```html
<div class="d-flex align-items-center gap-2">
    <span class="scope-indicator scope-disposal" id="scopeIndicator">
        <i class="fa fa-tasks"></i>
        <span id="scopeText">需处置</span>
    </span>
    <button class="btn btn-outline-primary btn-sm" id="toggleTypeBtn" title="切换处置类型" onclick="toggleDisposalType()">
        <i class="fa fa-exchange"></i> 切换
    </button>
</div>
```

---

### 3.1 处置情况列固定显示

**改动位置：** `<thead>` 和 `<tbody>` 内

**改动内容：** 将"处置情况"从折叠列移为固定列，位于"上链状态"之后

**改动前：**
```html
<th style="min-width: 90px;">上链状态</th>
<th style="min-width: 100px;" class="collapsible-column hidden">处置情况</th>
```

**改动后：**
```html
<th style="min-width: 90px;">上链状态</th>
<th style="min-width: 100px;">处置情况</th>
```

**处置情况状态样式：**
| 状态 | 样式类 | 说明 |
|------|--------|------|
| - (未派发/派发驳回时) | `disposal-pending` | 灰色 |
| 待派发 | `disposal-pending-dispatch` | 橙色 |
| 已分派待处置 | `disposal-pending-disposal` | 绿色 |
| 已处置待审核 | `disposal-review` | 蓝色 |

**派发状态新增样式：**
| 状态 | 样式类 | 说明 |
|------|--------|------|
| 派发驳回 | `status-rejected` | 红色 |

---

### 3.2 新增处置情况筛选器

**改动位置：** 筛选区（`.filter-row`）

**新增代码：**
```html
<div class="filter-item">
    <label>处置情况：</label>
    <select class="form-select form-select-sm" id="disposalStatusFilter" style="width: 140px;">
        <option value="">全部</option>
        <option value="待派发">待派发</option>
        <option value="已分派待处置">已分派待处置</option>
        <option value="已处置待审核">已处置待审核</option>
    </select>
</div>
```

**派发状态筛选器增强：**
```html
<select class="form-select form-select-sm" id="dispatchStatusFilter" style="width: 120px;">
    <option value="">全部</option>
    <option value="pending">未派发</option>
    <option value="assigned">已派发</option>
    <option value="rejected">派发驳回</option>
</select>
```

---

### 3.3 操作菜单项显示规则

**改动位置：** 操作下拉菜单（`.action-menu`）

#### 3.3.1 "审核处理情况"菜单项

**适用条件：** 仅"已处置待审核"状态的疑点

**菜单项：**
```html
<a class="action-menu-item" href="#" onclick="location.href='风险处置任务单.html'; return false;">
    <i class="fa fa-clipboard"></i> 审核处理情况
</a>
```

#### 3.3.2 "疑点甄别"和"放白名单"菜单项

**适用条件：** 仅"未派发"状态的疑点

**业务规则：**
- 只有当派发状态为"未派发"时，才能做"疑点甄别"和"放白名单"
- "已派发"、"派发驳回"、"已处置待审核"等状态的疑点不显示这两个菜单项

**菜单项：**
```html
<a class="action-menu-item" href="#" onclick="ignoreItem(this); return false;">
    <i class="fa fa-ban"></i> 放白名单
</a>
<a class="action-menu-item" href="#" onclick="openReviewModal(this); return false;">
    <i class="fa fa-check-square-o"></i> 疑点甄别
</a>
```

---

### 3.4 新增批量操作栏

**改动位置：** 表格下方、分页上方

**新增代码：**
```html
<div class="batch-action-bar" id="batchActionBar" style="display:none;">
    <div class="d-flex justify-content-between align-items-center">
        <div class="selected-info">
            已选 <span id="selectedCount" class="fw-bold text-primary">0</span> 条
        </div>
        <div class="action-buttons d-flex gap-2">
            <button class="btn btn-primary btn-sm" id="batchDispatchBtnBottom" onclick="openBatchDispatchModal()" style="display:none">
                <i class="fa fa-paper-plane"></i> 批量派发
            </button>
            <button class="btn btn-info btn-sm" id="batchReviewBtnBottom" onclick="openBatchReviewModal()" style="display:none">
                <i class="fa fa-check-square-o"></i> 批量甄别
            </button>
            <button class="btn btn-warning btn-sm" id="batchWhitelistBtnBottom" onclick="openBatchWhitelistModal()" style="display:none">
                <i class="fa fa-ban"></i> 批量加白名单
            </button>
            <button class="btn btn-success btn-sm" id="batchApproveBtnBottom" onclick="openBatchApproveModal()" style="display:none">
                <i class="fa fa-check-circle"></i> 批量审核通过
            </button>
            <button class="btn btn-danger btn-sm" id="batchRejectBtnBottom" onclick="openBatchRejectModal()" style="display:none">
                <i class="fa fa-times-circle"></i> 批量审核驳回
            </button>
        </div>
    </div>
</div>
```

**按钮显示逻辑（按选中组别）：**

| 选中组 | 派发状态 | 显示按钮 |
|--------|----------|----------|
| A组 | 未派发、派发驳回 | 批量派发、批量甄别、批量加白名单 |
| B组 | 已派发（处置情况=已处置待审核） | 批量审核通过、批量审核驳回 |

---

### 3.5 新增弹窗

#### 3.5.1 批量派发弹窗
- 标题：批量派发
- 提示信息：您已选择 X 条疑点，请确认派发
- 按钮：确定派发、取消

#### 3.5.2 批量甄别弹窗
- 标题：批量甄别
- 提示信息：确定对 X 条疑点进行甄别确认？
- 按钮：确定甄别、取消

#### 3.5.3 批量加白名单弹窗
- 标题：批量加白名单
- 提示信息：确定将 X 条疑点加入白名单？
- 按钮：确定加入、取消

#### 3.5.4 批量审核通过弹窗
- 标题：批量审核通过
- 提示信息：您已选择 X 条疑点，请填写审核意见后确认通过
- 审核意见：多行文本框（必填）
- 按钮：确定通过、取消

#### 3.5.5 批量审核驳回弹窗
- 标题：批量审核驳回
- 提示信息：您已选择 X 条疑点，请填写驳回意见后确认驳回
- 驳回意见：多行文本框（必填）
- 按钮：确定驳回、取消

---

### 3.6 复选框控制逻辑（分组控制）

**需处置类型分组：**

| 组别 | 派发状态 | 可执行的批量操作 |
|------|----------|------------------|
| A组 | 未派发、派发驳回 | 批量派发、批量甄别、批量加白名单 |
| B组 | 已派发（处置情况=已处置待审核） | 批量审核通过、批量审核驳回 |

**分组互斥规则：**
- 选中A组行 → B组行复选框置灰不可选
- 选中B组行 → A组行复选框置灰不可选
- 清空选中 → 恢复全部可勾选

**提示类型：** 仅未派发可勾选

---

## 4. 版本历史

| 版本 | 日期 | 更新内容 |
|------|------|----------|
| v1.0.0 | 2026-05-14 | 初始版本，新增批量处置功能页面改动说明 |
| v1.1.0 | 2026-05-15 | 明确页面职责划分；处置人页面移除批量审核功能；新增派发人页面改动说明 |
| v1.2.0 | 2026-05-15 | 修正状态值：派发状态新增"派发驳回"；处置情况改为"待派发/已分派待处置/已处置待审核"；更新筛选器、样式类、复选框控制逻辑 |
| v1.3.0 | 2026-05-15 | 处置人页面代码支持"提示"类型规则的批量已读功能（同一规则下疑点处置方式一致） |
| v1.4.0 | 2026-05-15 | 新增操作菜单显示规则："疑点甄别"和"放白名单"仅在派发状态为"未派发"时显示 |
| v1.5.0 | 2026-05-15 | 处置人页面新增处置类型切换功能；不同处置类型下处置状态和操作菜单不同；提示类型支持单条/批量确认已读 |
| v1.6.0 | 2026-05-15 | 批量按钮改名："批量已读"→"批量确认已读"，"批量处置"→"批量提交处理结果"；修复批量按钮点击弹窗功能 |
| v1.7.0 | 2026-05-15 | 弹窗文案优化："处置意见"→"处置说明"，placeholder改为"请描述疑点处理过程及结果" |
| v1.8.0 | 2026-05-15 | 派发人页面新增处置类型切换功能（需处置/提示）；不同处置类型下筛选器和操作菜单不同；提示类型仅"未派发"可勾选；新增"已派发未读"处置情况样式 |
| v1.9.0 | 2026-05-15 | 派发人页面批量操作重构：新增批量甄别、批量加白名单按钮和弹窗；复选框改为分组控制（A组：未派发/派发驳回，B组：已处置待审核）；批量按钮改名"批量通过"→"批量审核通过"、"批量驳回"→"批量审核驳回" |
| v2.0.0 | 2026-05-15 | 处置人页面新增"批量退回重新分派"按钮和弹窗，针对"已派发待处置"状态 |
