# 执行计划 — 平台版本号与操作日志子模块

> 版本：1.0 ｜ 日期：2026-07-29 ｜ 关联 PRD：`PRD_平台版本号与操作日志子模块.md`

---

## 执行概览

| 阶段 | 任务 | 预估工时 | 状态 |
|------|------|----------|------|
| 阶段一 | 后端 API 基础设施 | 2h | 待开始 |
| 阶段二 | 版本号功能 | 1h | 待开始 |
| 阶段三 | 问题排查模块操作日志 | 2h | 待开始 |
| 阶段四 | 服务监测模块操作日志 | 2h | 待开始 |
| 阶段五 | 服务管理模块操作日志 | 1h | 待开始 |
| 阶段六 | 集成测试与部署 | 1h | 待开始 |

---

## 阶段一：后端 API 基础设施

### 1.1 新增审计日志服务

**文件**：`skill/code/web/services/audit_service.py`

```python
# -*- coding: utf-8 -*-
"""
audit_service.py — 操作日志查询服务

提供日志分页查询、用户列表、模块操作类型定义等功能。
"""

import json
from pathlib import Path
from typing import Optional
from utils.paths import AUDIT_LOG_FILE

# 模块操作类型常量
MODULE_ACTIONS = {
    'troubleshoot': ['search', 'analyze', 'export', 'submit'],
    'monitor': ['create_target', 'edit_target', 'delete_target', 
                'run_check', 'export_report', 'create_schedule',
                'edit_schedule', 'delete_schedule', 'config_notification'],
    'manage': ['auth_change', 'upgrade', 'query_info']
}

def get_logs(module: str, page: int = 1, page_size: int = 20,
             start_time: Optional[str] = None, end_time: Optional[str] = None,
             action_type: Optional[str] = None, user: Optional[str] = None) -> dict:
    """分页查询操作日志"""
    # 实现：读取 audit.log → 过滤 → 分页 → 返回
    pass

def get_users_with_logs(module: Optional[str] = None) -> list:
    """获取有操作记录的用户列表"""
    pass

def enrich_audit_entry(entry: dict, module: str) -> dict:
    """为日志条目补充 module 字段（兼容旧日志）"""
    if 'module' not in entry:
        entry['module'] = module
    return entry
```

### 1.2 新增审计日志路由

**文件**：`skill/code/web/routes/audit.py`

```python
# -*- coding: utf-8 -*-
"""
audit.py — 操作日志查询路由
"""

from flask import Blueprint, request, jsonify, g
from decorators import login_required
from services.audit_service import get_logs, get_users_with_logs, MODULE_ACTIONS

bp = Blueprint('audit', __name__, url_prefix='/api/audit')

@bp.route('/logs', methods=['GET'])
@login_required
def list_logs():
    """分页查询操作日志"""
    module = request.args.get('module')
    # 参数校验 + 调用 service
    pass

@bp.route('/users', methods=['GET'])
@login_required
def list_users():
    """获取有操作记录的用户列表"""
    pass

@bp.route('/actions/<module>', methods=['GET'])
@login_required
def list_actions(module):
    """获取模块的操作类型列表"""
    pass
```

### 1.3 注册 Blueprint

**修改文件**：`skill/code/web/server.py`

```python
# 在 create_app() 中注册
from routes.audit import bp as audit_bp
app.register_blueprint(audit_bp)
```

### 1.4 修改现有 log_audit 调用

为现有 `log_audit()` 调用补充 `module` 和 `target` 字段。

**涉及文件**：
- `skill/code/web/routes/troubleshoot.py` — 补充 `module: 'troubleshoot'`
- `skill/code/web/routes/submit.py` — 补充 `module: 'troubleshoot'`
- `skill/code/web/routes/export.py` — 补充 `module` 根据导出类型
- `skill/code/web/routes/cache.py` — 补充 `module: 'troubleshoot'`
- `skill/code/web/routes/auth.py` — 补充 `module: 'auth'`（登录/退出）

---

## 阶段二：版本号功能

### 2.1 后端版本 API

**文件**：`skill/code/web/routes/version.py`

```python
# -*- coding: utf-8 -*-
"""
version.py — 版本信息接口
"""

from flask import Blueprint, jsonify
import os
from pathlib import Path
from datetime import datetime

bp = Blueprint('version', __name__, url_prefix='/api')

@bp.route('/version', methods=['GET'])
def get_version():
    """获取平台版本号"""
    # 读取前端 package.json 或环境变量
    return jsonify({
        'version': os.environ.get('APP_VERSION', '0.1.0'),
        'buildTime': os.environ.get('BUILD_TIME', ''),
        'name': 'troubleshoot-frontend'
    })
```

### 2.2 前端版本组件

**文件**：`frontend/src/components/common/AppVersion.vue`

```vue
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import api from '@/utils/api'

const version = ref('')

onMounted(async () => {
  try {
    const res = await api.get('/api/version')
    version.value = res.data.version
  } catch {
    version.value = ''
  }
})
</script>

<template>
  <span v-if="version" class="app-version">v{{ version }}</span>
</template>

<style scoped lang="scss">
.app-version {
  background: rgba(255,255,255,0.15);
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  color: rgba(255,255,255,0.85);
}
</style>
```

### 2.3 集成到导航栏

**修改文件**：`frontend/src/components/layout/AppNavbar.vue`

在用户名左侧插入 `<AppVersion />` 组件。

---

## 阶段三：问题排查模块操作日志

### 3.1 前端路由配置

**修改文件**：`frontend/src/router/index.ts`

```typescript
{
  path: '/troubleshoot/logs',
  name: 'TroubleshootLogs',
  component: () => import('@/views/troubleshoot/Logs.vue'),
  meta: { requiresAuth: true, activeMenu: 'troubleshoot-logs' }
}
```

### 3.2 操作日志页面组件

**文件**：`frontend/src/views/troubleshoot/Logs.vue`

```vue
<script setup lang="ts">
// 日志列表、筛选、分页、详情弹窗
</script>

<template>
  <div class="logs-page">
    <div class="logs-header">
      <h2>操作日志</h2>
      <div class="logs-actions">
        <el-date-picker v-model="dateRange" type="daterange" />
        <el-select v-model="actionType" placeholder="操作类型">
          <el-option label="全部" value="" />
          <el-option label="搜索" value="search" />
          <el-option label="分析" value="analyze" />
          <el-option label="导出" value="export" />
          <el-option label="入库" value="submit" />
        </el-select>
        <el-button @click="fetchLogs">刷新</el-button>
      </div>
    </div>
    <el-table :data="logs" stripe>
      <el-table-column prop="timestamp" label="操作时间" width="160" />
      <el-table-column prop="user" label="用户" width="100" />
      <el-table-column prop="action" label="操作类型" width="100" />
      <el-table-column prop="target" label="操作对象" />
      <el-table-column prop="ip" label="IP" width="130" />
      <el-table-column label="操作" width="80">
        <template #default="{ row }">
          <el-button link @click="showDetail(row)">详情</el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:current-page="page"
      :page-size="pageSize"
      :total="total"
      layout="total, prev, pager, next"
      @current-change="fetchLogs"
    />
    <!-- 详情弹窗 -->
  </div>
</template>
```

### 3.3 侧边栏菜单更新

**修改文件**：`frontend/src/views/troubleshoot/Index.vue` 或对应 Layout

添加侧边栏菜单项：
```
📊 问题排查 | 📋 操作日志
```

---

## 阶段四：服务监测模块操作日志

### 4.1 路由与页面

- 路由：`/service-monitor/logs`
- 组件：`frontend/src/views/service-monitor/Logs.vue`
- 操作类型：create_target, edit_target, delete_target, run_check, export_report, create_schedule, edit_schedule, delete_schedule, config_notification

### 4.2 侧边栏菜单

**修改文件**：`frontend/src/layouts/MonitorLayout.vue`

```typescript
const monitorMenus = computed(() => {
  const base = [
    { key: 'targets', ... },
    { key: 'reports', ... },
    { key: 'logs', icon: '📋', label: '操作日志', path: '/service-monitor/logs' },
    // ...
  ]
})
```

### 4.3 后端日志记录补充

**修改文件**：`skill/code/web/service_monitor/routes.py`

在目标创建/编辑/删除、巡检执行、定时任务配置等操作处调用 `log_audit()` 并补充 `module: 'monitor'`。

---

## 阶段五：服务管理模块操作日志

### 5.1 路由与页面

- 路由：`/service-manage/logs`
- 组件：`frontend/src/views/service-manage/Logs.vue`
- 操作类型：auth_change, upgrade, query_info

### 5.2 侧边栏菜单

**修改文件**：`frontend/src/layouts/ManageLayout.vue`

添加操作日志菜单项。

---

## 阶段六：集成测试与部署

### 6.1 单元测试

新增测试文件：`skill/code/tests/test_audit_service.py`

- 测试日志分页查询
- 测试筛选过滤
- 测试模块操作类型定义

### 6.2 API 测试

```bash
# 版本接口
curl http://localhost:8088/api/version

# 日志列表
curl "http://localhost:8088/api/audit/logs?module=troubleshoot&page=1"

# 用户列表
curl http://localhost:8088/api/audit/users
```

### 6.3 前端构建验证

```bash
cd frontend && npm run build
```

### 6.4 部署到 5.60

1. 更新 `deploy/upload_to_server.py` 上传清单
2. 重新构建 Docker 镜像
3. 更新容器

---

## 文件变更清单

### 新增文件

| 文件 | 说明 |
|------|------|
| `skill/code/web/services/audit_service.py` | 审计日志服务 |
| `skill/code/web/routes/audit.py` | 审计日志路由 |
| `skill/code/web/routes/version.py` | 版本接口 |
| `frontend/src/components/common/AppVersion.vue` | 版本号组件 |
| `frontend/src/views/troubleshoot/Logs.vue` | 问题排查操作日志页 |
| `frontend/src/views/service-monitor/Logs.vue` | 服务监测操作日志页 |
| `frontend/src/views/service-manage/Logs.vue` | 服务管理操作日志页 |
| `skill/code/tests/test_audit_service.py` | 单元测试 |

### 修改文件

| 文件 | 修改内容 |
|------|----------|
| `skill/code/web/server.py` | 注册 audit/version Blueprint |
| `skill/code/web/routes/troubleshoot.py` | log_audit 补充 module |
| `skill/code/web/routes/submit.py` | log_audit 补充 module |
| `skill/code/web/routes/export.py` | log_audit 补充 module |
| `skill/code/web/routes/cache.py` | log_audit 补充 module |
| `skill/code/web/routes/auth.py` | log_audit 补充 module |
| `skill/code/web/service_monitor/routes.py` | 新增 log_audit 调用 |
| `skill/code/web/utils/audit.py` | 补充 id、module、target 字段 |
| `frontend/src/router/index.ts` | 新增日志页路由 |
| `frontend/src/components/layout/AppNavbar.vue` | 集成版本号组件 |
| `frontend/src/layouts/MonitorLayout.vue` | 添加操作日志菜单 |
| `frontend/src/layouts/ManageLayout.vue` | 添加操作日志菜单 |
| `deploy/upload_to_server.py` | 更新上传清单 |

---

## 执行顺序

```
阶段一 → 阶段二 → 阶段三 → 阶段四 → 阶段五 → 阶段六
   │                    │
   └── 后端先行 ────────┴── 前端并行开发
```

**建议**：
1. 先完成后端 API（阶段一、二），再并行开发前端三个日志页面
2. 前端组件可复用，先完成问题排查模块的日志页面作为模板