# 运维监控看板功能实现方案

## 需求概述

在现有 `batch_query.html` 数据看板中新增一个「运维监控」Tab，调用后端新增的 `sp_GetOperationsMonitor()` 存储过程，以表格形式展示每日运营监控数据。

**约束：不影响、不修改任何现有模块代码。**

---

## 整体架构图

```
前端 batch_query.html
   └─ 新增 Tab：📈 运维监控
         └─ JSONP 调用: GET /api/dashboard/ops-monitor
               └─ DashboardController（新增一个 Action，不改现有 Action）
                     └─ ILabelReplaceService（新增接口方法声明）
                           └─ LabelReplaceService（新增实现方法）
                                 └─ ILabelReplaceRepository（新增接口方法声明）
                                       └─ LabelReplaceRepository（新增实现方法，调用存储过程）
                                             └─ MySQL: CALL sp_GetOperationsMonitor()
```

---

## 数据字段对应关系

存储过程输出字段 → DTO 属性 → 前端列名：

| 存储过程字段         | DTO 属性                  | 前端列名         |
|-----------------|-------------------------|--------------|
| 日期              | Date                    | 日期           |
| 当天新增换单数         | DailyNewReplaceCount    | 当天新增换单数      |
| 累计要换的总单数        | CumulativeTotalCount    | 累计要换的总单数     |
| 当天应该换单数         | ShouldReplaceCount      | 当天应该换单数      |
| 当日换单完成数         | DailySuccessCount       | 当日换单完成数      |
| 当日换单失败数         | DailyFailureCount       | 当日换单失败数      |
| 当日STOP数         | DailyStopCount          | 当日STOP数      |
| 24小时换单成功数       | Rate24HourCount         | 24H换单成功数     |
| 当日标签推送数         | DailyLabelPushCount     | 当日标签推送数      |
| 当日扫描数           | DailyScanCount          | 当日扫描数        |
| 当天换单完成率         | DailyCompletionRate     | 当天换单完成率      |
| 24小时换单率         | Rate24Hour              | 24H换单率       |
| 数据拉取时间（UTC_5）   | DataFetchTime           | 数据拉取时间(UTC-5) |

---

## 实施步骤

### 步骤 1：新增 DTO 类

**文件**：`src/MDL/DTOs/OpsMonitorDto.cs`（新建文件）

定义 `OpsMonitorDto` 类，包含上表中所有属性，与存储过程输出字段一一对应。

### 步骤 2：Repository 层新增方法

**文件**：`src/DAL/repositories/LabelReplaceRepository.cs`（仅追加，不修改现有代码）

新增方法 `GetOpsMonitorDataAsync()`，实现逻辑：
1. 使用与 `GetDailyLabelStatsChineseAsync` **完全相同的** `MySqlConnection` 方式（硬编码连接字符串、`MySqlCommand`、`ExecuteReaderAsync`）
2. SQL 语句改为 `CALL sp_GetOperationsMonitor();`（调用已部署的存储过程）
3. 通过 `DataReader` 映射字段到 `OpsMonitorDto`
4. 返回 `List<OpsMonitorDto>`

同步在接口文件 `src/DAL/Interfaces/ILabelReplaceRepository.cs` 中追加方法声明：
```csharp
Task<List<OpsMonitorDto>> GetOpsMonitorDataAsync();
```

### 步骤 3：Service 层新增方法

**文件**：`src/BLL/Services/LabelReplaceService.cs`（仅追加）

新增方法 `GetOpsMonitorDataAsync()`，直接透传调用 Repository 方法。

同步在接口文件 `src/BLL/Interfaces/ILabelReplaceService.cs` 中追加方法声明：
```csharp
Task<List<OpsMonitorDto>> GetOpsMonitorDataAsync();
```

### 步骤 4：Controller 层新增 Action

**文件**：`src/CONTROLLER/Controllers/DashboardController.cs`（仅追加）

新增 Action：`GET /api/dashboard/ops-monitor`

实现逻辑（与 `GetDailyLabelStatsChinese` 完全对称）：
1. 接收可选 `callback` 参数（JSONP 支持）
2. 调用 `_labelReplaceService.GetOpsMonitorDataAsync()`
3. 统一返回格式 `{ code: 0, message: "success", data: [...] }`
4. 支持 JSONP 包装

### 步骤 5：前端 batch_query.html 新增 Tab

**文件**：`batch_query.html`（新增内容，不修改现有 Tab）

#### 5.1 在 `<ul class="nav nav-tabs">` 末尾追加 Tab 按钮

```html
<li class="nav-item" role="presentation">
    <button class="nav-link" id="ops-monitor-tab"
        data-bs-toggle="tab" data-bs-target="#ops-monitor"
        type="button" role="tab" aria-controls="ops-monitor" aria-selected="false">
        📈 运维监控
    </button>
</li>
```

#### 5.2 在 `<div class="tab-content">` 末尾追加 Tab 面板

面板结构：
- **顶部操作栏**：刷新按钮、导出 Excel 按钮、数据拉取时间显示
- **汇总指标卡片行**（4个）：今日应换单数 / 今日换单完成数 / 今日24H完成数 / 今日完成率
- **数据表格**：展示全量历史数据，包含存储过程输出的所有列，支持完成率颜色高亮

表格列定义：
日期 | 当天新增换单数 | 累计要换的总单数 | 当天应该换单数 | 当日换单完成数 | 当日换单失败数 | 当日STOP数 | 24H换单成功数 | 当日标签推送数 | 当日扫描数 | 当天换单完成率 | 24H换单率 | 数据拉取时间

#### 5.3 追加 JavaScript 函数（在文件末尾 `</script>` 之前追加）

新增以下函数（均使用与现有代码相同的 JSONP + `getBaseUrl()` 模式）：
- `loadOpsMonitorData()`：调用 `/api/dashboard/ops-monitor`，渲染表格
- `displayOpsMonitorTable(data)`：渲染表格行，完成率 ≥ 80% 显示绿色，< 50% 显示红色
- `exportOpsMonitorToExcel()`：使用 `xlsx.js` 将当前表格数据导出为 Excel（复用现有 `XLSX` 库）
- Tab 激活事件：首次切换到运维监控 Tab 时自动调用 `loadOpsMonitorData()`

---

## 文件变更清单

| 操作 | 文件路径 | 修改方式 |
|------|--------|--------|
| 新建 | `src/MDL/DTOs/OpsMonitorDto.cs` | 新文件 |
| 追加 | `src/DAL/Interfaces/ILabelReplaceRepository.cs` | 追加接口方法声明 |
| 追加 | `src/DAL/repositories/LabelReplaceRepository.cs` | 追加实现方法 |
| 追加 | `src/BLL/Interfaces/ILabelReplaceService.cs` | 追加接口方法声明 |
| 追加 | `src/BLL/Services/LabelReplaceService.cs` | 追加实现方法 |
| 追加 | `src/CONTROLLER/Controllers/DashboardController.cs` | 追加 Action |
| 追加 | `batch_query.html` | 追加 Tab 按钮 + Tab 面板 + JS 函数 |

**所有修改均为"仅追加"，不触碰任何现有代码行。**

---

## 注意事项

1. 存储过程 `sp_GetOperationsMonitor()` 需要已提前执行 `004_create_sp_operations_monitor.sql` 部署到数据库
2. 连接字符串沿用 `GetDailyLabelStatsChineseAsync` 中的硬编码连接字符串，保持一致
3. 前端使用 `JSONP` 方式调用，与现有所有 API 调用方式保持一致
4. Excel 导出使用已引入的 `xlsx.js` 库，无需新增依赖
5. 不注册新的 DI 服务（`OpsMonitorDto` 是 DTO，无需注册；新方法追加到现有接口/实现中）
