# HANDOFF 服务管理模块交接文档

> 文档生成时间：2026-08-13
> 分支：troubleshoot-ai-assistant
> 状态：后端代理转发开发完成（Vue SPA 前端 + Flask 后端 + 5.44 代理客户端）

---

## 一、任务概述

开发"服务管理"模块（service-manage），提供服务授权管理、服务升级管理、服务信息查看等功能。

**关键里程碑**：
1. 阶段一（2026-07-22）：静态页面 + 基础路由 ✅
2. 阶段二（2026-08-13）：后端业务层 + 5.44 代理转发 ✅
3. 阶段三（待部署）：部署到 5.60 生产环境

---

## 二、已完成项

### 2.1 PRD 文档

| 文档 | 路径 | 状态 |
|------|------|------|
| 需求文档（初始） | `Docs/服务管理/需求文档/PRD_需求文档_服务管理模块.md` | ✅ 完成 |
| 需求文档（功能升级） | `Docs/服务管理/需求文档/PRD_需求文档_服务管理功能升级.md` | ✅ 完成 |
| 需求文档（平台化改造） | `Docs/服务管理/需求文档/PRD_需求文档_平台化改造与模块切换.md` | ✅ 完成 |
| 需求文档（返回首页改造） | `Docs/服务管理/需求文档/PRD_需求文档_返回首页改造与新增模块.md` | ✅ 完成 |
| 计划执行（初始） | `Docs/服务管理/计划执行/PRD_计划执行_服务管理模块.md` | ✅ 完成 |
| 计划执行（功能升级） | `Docs/服务管理/计划执行/PRD_计划执行_服务管理功能升级.md` | ✅ 完成 |
| 计划执行（平台化改造） | `Docs/服务管理/计划执行/PRD_计划执行_平台化改造与模块切换.md` | ✅ 完成 |
| 计划执行（返回首页改造） | `Docs/服务管理/计划执行/PRD_计划执行_返回首页改造与新增模块.md` | ✅ 完成 |
| 交接文档 | `Docs/服务管理/HANDOFF_服务管理.md` | ✅ 当前 |

### 2.2 后端代码

| 文件 | 行数 | 说明 |
|------|------|------|
| `skill/code/web/services/service_manage.py` | 575 | 业务层：目标 CRUD、项目信息、授权文件操作、5.44 代理转发 |
| `skill/code/web/services/five44_client.py` | 401 | 5.44 统一管理平台代理客户端（认证 + 签名 + 6 个业务接口） |
| `skill/code/web/routes/service_manage.py` | 327 | 路由层：API `/api/service-manage/*`，管理员权限校验 |

### 2.3 前端代码（Vue SPA）

| 文件 | 说明 |
|------|------|
| `frontend/src/views/service-manage/Authorization.vue` | 服务授权页（4 步骤：下载激活、上传授权、部署视图、自检文档） |
| `frontend/src/views/service-manage/Upgrade.vue` | 服务升级页（Tab 切换：服务重启 + 服务回滚） |
| `frontend/src/views/service-manage/Info.vue` | 服务信息页（CPU/内存/硬盘监控卡片） |
| `frontend/src/views/service-manage/Targets.vue` | 目标配置页（管理对接的 5.44 服务器） |
| `frontend/src/views/service-manage/Logs.vue` | 操作日志页 |
| `frontend/src/api/service-manage/index.ts` | API 接口层 |
| `frontend/src/types/service-manage.ts` | TypeScript 类型定义 |

### 2.4 后端 API 清单

| 路由 | 方法 | 功能 | 代理状态 |
|------|------|------|----------|
| `/api/service-manage/targets` | GET | 目标列表 | 本地 |
| `/api/service-manage/targets` | POST | 新增目标 | 本地 |
| `/api/service-manage/targets/<id>` | PUT | 更新目标 | 本地 |
| `/api/service-manage/targets/<id>` | DELETE | 删除目标 | 本地 |
| `/api/service-manage/targets/test` | POST | 测试连接 | 本地 |
| `/api/service-manage/license/download` | GET | 下载激活文件 | ✅ 代理 5.44 |
| `/api/service-manage/license/upload` | POST | 上传授权文件 | ✅ 代理 5.44 |
| `/api/service-manage/license/task-status` | GET | 查询授权任务状态 | ✅ 代理 5.44 |
| `/api/service-manage/project` | GET/POST | 项目信息读写 | ✅ 代理 5.44（保存） |
| `/api/service-manage/deploy-view/download` | GET | 下载部署视图 | ✅ 代理 5.44 |
| `/api/service-manage/deploy-view/upload` | POST | 上传部署视图 | ✅ 代理 5.44 |
| `/api/service-manage/self-check/download` | GET | 下载自检文档 | ✅ 代理 5.44 |
| `/api/service-manage/self-check/upload` | POST | 上传自检文档 | ✅ 代理 5.44 |

### 2.5 目标配置 CRUD

`service_manage.py` 实现了完整的目标服务器 CRUD（与 `service_monitor` 的目标数据完全独立）：

| 功能 | 说明 |
|------|------|
| 新增目标 | name / host / port / protocol / auth_type / username / password（Fernet 加密存储） |
| 列表 | 脱敏输出（密码→has_password 布尔） |
| 更新 | 支持部分字段更新 |
| 删除 | 按 ID 删除 |
| 测试连接 | HTTP(S) GET 根路径，超时 10s |

### 2.6 单元测试

```
238 passed in 8.65s
```

- 全部 238 个测试通过（含核心模块 106 用例 + 服务监测模块 132 用例）
- 服务管理模块暂未单独编写测试（功能依赖 5.44 真实服务器）

---

## 三、架构设计

### 3.1 分层架构

```
路由层（routes/service_manage.py）
  → 业务层（services/service_manage.py）
    → 代理客户端（services/five44_client.py）→ HTTP → 5.44 目标服务器
    → 加密工具（service_monitor/utils/crypto.py）→ Fernet 加密
    → 本地存储（JSON 文件）
```

### 3.2 5.44 代理客户端（five44_client.py）

**认证机制**（从 5.44 的 `http_client.py` 逆向移植）：

| 层 | 算法 | 说明 |
|----|------|------|
| 密码加密 | SHA256 摘要 | 登录前 `hashlib.sha256(password).hexdigest()` |
| 请求签名 | SHA256 + AES-CBC(PKCS7) | sign_str = timestamp + JSON(body) + random → SHA256 → AES-CBC |
| AES 密钥派生 | SHA256(Bearer token) | 有 token 时：密钥源 = SHA256("Bearer {token}") |
| AES 密钥派生 | SHA256(60位随机串) | 无 token 时：密钥源 = SHA256(random_code)，随 RandomCode 头发送 |
| AES 密钥/IV | 取密钥源字符串子串 | 密钥 = source[16:32]，IV = source[0:8] + source[-8:]（UTF-8 字节，非 hex） |

**业务接口（6 个）**：

| 方法 | 5.44 端点 | 说明 |
|------|-----------|------|
| `download_activation()` | GET `/exapi/system/downLincenceFile?category=java_python` | 下载激活文件 |
| `upload_license()` | POST `/backstage/exapi/system/uploadLincenceFile` | 上传授权文件（multipart） |
| `check_task_status()` | GET `/backstage/exapi/system/licenceTaskStatus?taskId=` | 查询授权任务状态 |
| `save_project()` | POST `/exapi/system/setOtherInfo` | 保存项目信息 |
| `download_deploy_view()` | GET `/exapi/system/exportDeployView` | 导出部署视图 |
| `download_self_check()` | GET `/exapi/system/exportServiceDetect` | 导出自检文档 |
| `upload_deploy_view()` | POST `/exapi/uploader/uploadDeployView` | 上传部署视图 |
| `upload_self_check()` | POST `/exapi/uploader/uploadServiceDetect` | 上传自检文档 |

**自动重试**：遇到 401/403 自动清除 token、重新登录、重试请求一次。

### 3.3 降级策略

未配置目标服务器时，所有授权操作降级为本地占位模式：

| 操作 | 本地降级行为 |
|------|-------------|
| 下载激活文件 | 生成 `licences.zip` 占位文件 |
| 下载部署视图 | 生成 `deploymentView{ts}.xlsx` 占位文件 |
| 下载自检文档 | 生成 `checkList{ts}.xlsx` 占位文件 |
| 上传授权文件 | 本地暂存到 `uploads/` 目录，返回 `taskId: "local-{filename}"` |
| 上传部署视图/自检文档 | 本地暂存到 `uploads/` 子目录 |
| 查询任务状态 | 直接返回 `status: "completed"` |

### 3.4 数据存储

| 文件 | 路径 | 说明 |
|------|------|------|
| `targets.json` | `service_manage_data/targets.json` | 目标服务器配置（密码 Fernet 加密） |
| `projects.json` | `service_manage_data/projects.json` | 项目信息（密码加密存储，读取脱敏） |
| `uploads/` | `service_manage_data/uploads/` | 上传文件暂存目录 |

路径常量通过 `utils/paths.py` 的 `SERVICE_MANAGE_DATA_DIR` / `MANAGE_TARGETS_FILE` / `MANAGE_PROJECTS_FILE` / `MANAGE_UPLOADS_DIR` 定义。

---

## 四、配置说明

### 4.1 5.44 目标服务器凭据

在服务管理页面 → 目标配置中添加：

| 字段 | 值 |
|------|-----|
| 名称 | 5.44 统一管理平台（或自定义） |
| 主机 | 192.168.5.44 |
| 端口 | 443 |
| 协议 | https |
| 认证方式 | password |
| 用户名 | `admin@xty` |
| 密码 | 见 `server-credentials` 记忆 |

### 4.2 依赖

| 库 | 用途 | 是否已安装 |
|----|------|-----------|
| `requests` | HTTP 请求 | ✅ 已安装 |
| `pycryptodome` | AES-CBC 加密签名 | ✅ 已安装 |
| `cryptography` | Fernet 密码加密（复用 `service_monitor`） | ✅ 已安装 |

---

## 五、已知问题

### 5.1 代理转发依赖目标配置

- 所有授权操作的代理转发要求先配置目标服务器（targets 中至少有一条有效记录）
- 未配置目标时自动降级本地占位，不影响页面功能验证

### 5.2 下载激活文件端点

`downLincenceFile` 在 PRD 中标注为 POST，但 5.44 实际实现使用 GET——已按 GET 实现。

### 5.3 上传文件大小限制

- 授权文件上传到 5.44 经 multipart 转发，需注意 5.44 侧的上传大小限制
- 本地暂存模式无大小限制

---

## 六、待办项

### 6.1 部署到 5.60 生产环境

1. 更新 `deploy/upload_to_server.py` 的上传清单：
   - 新增 `skill/code/web/services/five44_client.py`
   - 确认 `skill/code/web/services/service_manage.py` 已在清单
   - 确认 `skill/code/web/routes/service_manage.py` 已在清单
   - 确认 `skill/code/web/utils/paths.py` 中的服务管理路径常量已同步
   - 确认前端 Vue 构建后的 dist 文件已包含

2. 部署命令：
```bash
! cd deploy && SSH_PASSWORD='***' python upload_to_server.py
```

3. 部署后验证：
   - 在浏览器中访问 `/service-manage/authorization` 确认页面正常
   - 配置目标服务器（5.44）
   - 测试授权文件下载/上传流程，使用 `F12` 网络面板确认请求转发到 5.44

### 6.2 编写单元测试

- 为 `service_manage.py` 的业务函数编写测试（目标 CRUD、项目信息读写）
- 为 `five44_client.py` 编写 mock 测试（签名算法、登录流程、业务接口）
- 目标：核心函数覆盖率 > 80%

### 6.3 前端页面完善

- 服务升级页（Upgrade.vue）的后端 API 尚未实现
- 服务信息页（Info.vue）的实时监控数据获取尚未实现
- 操作日志页（Logs.vue）的后端 API 尚未实现

### 6.4 服务升级与回滚

- 服务重启/回滚的后端 API 需要开发
- 下载配置、备份数据库、上传更新服务的功能需要实现

---

## 七、踩坑警示

### 7.1 5.44 签名算法

- AES 密钥和 IV 按 UTF-8 字符串字节解析（与 CryptoJS 行为一致），**不是 hex 解码**
- 无 token 时签名使用 `RandomCode` 头发送 60 位随机串，不能省略
- login 接口的 captcha 验证码固定为 `"csba"`（安全测试已知项）

### 7.2 密码加密复用

- 目标配置的密码加密复用 `service_monitor.utils.crypto` 的 Fernet 加密
- 如果 `crypto` 模块不可用，会静默降级为明文存储（仅开发环境）
- 生产环境必须确保 `crypto` 模块可用

### 7.3 数据隔离

- 服务管理模块的目标数据与 `service_monitor` 模块完全独立（两套 `targets.json`）
- 服务管理数据存储在 `service_manage_data/` 目录下

### 7.4 代码分层

- 新增功能按 `routes/services/` 分层，纯工具放 `utils/`
- 路径常量从 `utils/paths.py` 取，不要在各文件重算
- 依赖方向单向：routes → services → utils，禁止反向导入

---

## 八、相关文档

- [[PRD_需求文档_服务管理功能升级]] — 5.44 代理转发需求
- [[PRD_计划执行_服务管理功能升级]] — 5.44 代理转发执行计划
- [[PRD_需求文档_服务管理模块]] — 初始模块需求
- [[PRD_计划执行_服务管理模块]] — 初始模块执行计划
- [[PRD_需求文档_平台化改造与模块切换]] — 平台化改造需求
- [[PRD_计划执行_平台化改造与模块切换]] — 平台化改造计划
- [[PRD_需求文档_返回首页改造与新增模块]] — 首页改造需求
- [[PRD_计划执行_返回首页改造与新增模块]] — 首页改造计划