# 系统设置模块开发方案

## 1. 引言

### 1.1. 目的
本文档旨在为"MQTT智能充电桩管理系统"的"系统设置"模块提供详细的开发方案。该模块的目标是允许管理员通过用户界面方便地配置系统级的关键参数和业务规则，特别是充电费率。

### 1.2. 背景与依据
根据项目需求文档 (`requirements.md`) 和开发计划 (`development_plan.md`)，系统需要提供管理员配置充电费率及其他关键参数的功能。当前管理界面已预留"系统设置"入口，描述为"配置系统参数、费率等"。本方案将在现有项目结构和技术栈基础上进行设计。

### 1.3. 范围
本方案覆盖"系统设置"模块的后端和前端设计，包括：
*   充电费率管理
*   MQTT 相关参数配置
*   激活码默认参数配置
*   (可选) 系统维护模式配置

## 2. 功能需求

### 2.1. 充电费率管理
*   **FR2.1.1**: 管理员能够配置当前生效的充电费率。
    *   至少支持按电量计费，例如：X 元/kWh (度)。
    *   (可选扩展) 支持按时长计费，例如：Y 元/分钟，或阶梯计费、分时段计费。本期方案优先实现基础的单一电量费率。
*   **FR2.1.2**: 费率修改后，新发起的充电会话应按新费率计算。已在进行的会话按其开始时应用的费率计算（或根据最终业务决策调整）。
*   **FR2.1.3**: 系统界面应清晰展示当前的生效费率。
*   **FR2.1.4**: (可选扩展) 系统应能记录费率的变更历史。

### 2.2. 系统参数配置

#### 2.2.1. MQTT 相关参数
*   **FR2.2.1.1**: 管理员能够配置机器人任务的默认超时时间（单位：秒）。
    *   对应原 `application.yml` 中的 `mqtt.task.timeoutSeconds`。
*   **FR2.2.1.2**: 管理员能够启用或禁用MQTT通信日志的记录功能。
    *   对应原 `application.yml` 中的 `mqtt.logger.enabled`。
*   **FR2.2.1.3**: 管理员能够配置MQTT通信日志的保留天数。
    *   对应原 `application.yml` 中的 `mqtt.logger.retain-days`。

#### 2.2.2. 激活码默认参数
*   **FR2.2.2.1**: 管理员能够配置生成激活码时的默认有效天数（当批量生成未指定时使用）。
*   **FR2.2.2.2**: 管理员能够配置生成激活码时的默认面额（当批量生成未指定时使用）。

#### 2.2.3. (可选) 系统维护模式
*   **FR2.2.3.1**: 管理员能够开启或关闭系统维护模式。
*   **FR2.2.3.2**: 系统处于维护模式时，普通用户在前端应看到明确提示，并且核心业务功能（如发起充电请求）应受限。

## 3. 后端设计 (`springboot-init-main`)

### 3.1. 数据模型

#### 3.1.1. 系统配置表 (`system_config`)
用于存储各类可配置的系统参数。

```sql
CREATE TABLE `system_config` (
  `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
  `config_key` VARCHAR(100) NOT NULL UNIQUE COMMENT '配置键，例如: mqtt.task.timeoutSeconds',
  `config_value` VARCHAR(500) COMMENT '配置值',
  `config_name` VARCHAR(100) COMMENT '配置项名称/标签，用于UI显示',
  `description` VARCHAR(255) COMMENT '配置项描述',
  `data_type` VARCHAR(20) DEFAULT 'STRING' COMMENT '数据类型 (STRING, INTEGER, BOOLEAN, DECIMAL)',
  `config_group` VARCHAR(50) COMMENT '配置分组 (例如: MQTT, ACTIVATION_CODE, GENERAL)',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除标志 (0:未删除, 1:已删除)'
) COMMENT '系统配置表';
```
**预置数据/示例**:
*   `mqtt.task.timeoutSeconds`, `mqtt.logger.enabled`, `mqtt.logger.retain-days`
*   `activation_code.default.duration_days`, `activation_code.default.value`
*   `system.maintenance_mode` (value: '0' or '1')

#### 3.1.2. 充电费率表 (`charging_rate`)
用于管理充电费率。初期简化，只管理一个当前全局有效的电量费率。

```sql
CREATE TABLE `charging_rate` (
  `id` BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键ID',
  `rate_per_kwh` DECIMAL(10, 4) NOT NULL COMMENT '每度电的费率 (元/kWh)',
  `description` VARCHAR(255) COMMENT '费率描述',
  `is_active` TINYINT DEFAULT 1 COMMENT '是否当前生效 (1:是, 0:否) - 初期只有一个active的',
  `effective_from` DATETIME NOT NULL COMMENT '此费率生效起始时间',
  `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `is_deleted` TINYINT DEFAULT 0 COMMENT '逻辑删除标志'
) COMMENT '充电费率表';
```
**说明**: `is_active` 和 `effective_from` 字段用于管理费率版本。简单实现下，可以只允许一条 `is_active=1` 的记录。

### 3.2. Service 层

#### 3.2.1. `SystemConfigService`
*   `String getConfigValue(String key)`: 获取指定键的配置值。
*   `List<SystemConfig> getAllConfigs()`: 获取所有配置项。
*   `List<SystemConfig> getConfigsByGroup(String group)`: 按组获取配置。
*   `boolean updateConfigs(List<SystemConfigUpdateRequest> requests)`: 批量更新配置项。
*   **缓存**: 实现配置的读取缓存 (例如使用 Spring Cache)，更新时清除缓存。

#### 3.2.2. `ChargingRateService`
*   `ChargingRate getCurrentActiveRate()`: 获取当前生效的充电费率。
*   `ChargingRate setRate(ChargingRate newRate)`: 设置或更新充电费率。旧费率设为`is_active=0`，新费率`is_active=1`。
*   `List<ChargingRate> getRateHistory()`: (可选) 获取费率变更历史。

### 3.3. Controller 层

#### 3.3.1. `SystemConfigAdminController` (`/api/admin/config`)
*   `GET /`: 获取所有系统配置项，按组分类返回。
    *   响应: `BaseResponse<Map<String, List<SystemConfigVO>>>`
*   `PUT /`: 批量更新系统配置项。
    *   响应: `BaseResponse<Boolean>`
    *   参数: `List<SystemConfigUpdateRequest>` (包含 `configKey`, `configValue`)

#### 3.3.2. `ChargingRateAdminController` (`/api/admin/rate`)
*   `GET /current`: 获取当前生效的充电费率。
    *   响应: `BaseResponse<ChargingRateVO>`
*   `POST /`: 设置新的充电费率。
    *   请求: `ChargingRateUpdateRequest` (包含 `ratePerKwh`, `description`, `effectiveFrom`)
    *   响应: `BaseResponse<ChargingRateVO>`
*   `GET /history`: (可选) 获取费率变更历史。

### 3.4. 对现有模块的修改

*   **`ChargingSessionServiceImpl`**:
    *   在 `calculateAndSetFee` 或相关计费方法中，需从 `ChargingRateService.getCurrentActiveRate()` 获取费率，替换当前的计费逻辑。
*   **`MqttServiceImpl` / `TaskTimeoutHandler` / `MqttCommunicationLogServiceImpl`**:
    *   涉及 `mqtt.task.timeoutSeconds`, `mqtt.logger.enabled`, `mqtt.logger.retain-days` 的地方，应改为从 `SystemConfigService` 获取配置值。
    *   例如，通过 `@Value` 注入配置时，可以提供一个默认值，然后服务初始化时或每次使用时从 `SystemConfigService` 读取覆盖。
*   **`ActivationCodeServiceImpl`**:
    *   在 `generateCodes` 方法中，当请求未提供 `expireTime` 或 `value` 时，从 `SystemConfigService` 读取 `activation_code.default.duration_days` 和 `activation_code.default.value` 作为默认值。
*   **(可选) 权限/全局拦截器**:
    *   如果实现系统维护模式，可能需要在全局请求拦截器或权限校验处增加判断，如果维护模式开启，则对普通用户操作返回特定提示或状态码。

## 4. 前端设计 (`charging_web_app`)

### 4.1. 页面与路由
*   在管理员界面下创建新页面，例如: `/admin/settings`。
*   在 `src/app/(authenticated)/admin/settings/page.tsx` 实现。
*   在管理员导航栏 (`AuthenticatedLayout.tsx`) 中添加入口。

### 4.2. UI 结构
使用 Ant Design 的 `Tabs` 组件将不同类型的设置分组显示：
*   **Tab 1: "费率设置"**
*   **Tab 2: "MQTT 设置"**
*   **Tab 3: "激活码设置"**
*   **Tab 4: "其他设置" (例如：系统维护模式)**

#### 4.2.1. 费率设置 Tab
*   **显示当前费率**:
    *   只读文本展示当前 `ratePerKwh` 和描述。
*   **修改费率表单**:
    *   `Form` 包含：
        *   `InputNumber` 用于新的 `ratePerKwh` (元/度)。
        *   `Input.TextArea` 用于描述。
        *   `DatePicker` 用于 `effectiveFrom` (生效日期，默认为当前或次日)。
    *   "保存" 按钮，触发表单提交。
*   **(可选)** `Table` 展示费率历史。

#### 4.2.2. MQTT 设置 Tab
*   `Form` 包含：
    *   "机器人任务超时时间 (秒)": `InputNumber` (对应 `mqtt.task.timeoutSeconds`)。
    *   "启用MQTT通信日志": `Switch` (对应 `mqtt.logger.enabled`)。
    *   "MQTT日志保留天数": `InputNumber` (对应 `mqtt.logger.retain-days`)。
*   "保存设置" 按钮。

#### 4.2.3. 激活码设置 Tab
*   `Form` 包含：
    *   "默认有效天数": `InputNumber` (对应 `activation_code.default.duration_days`)。
    *   "默认面额 (元)": `InputNumber` (对应 `activation_code.default.value`)。
*   "保存设置" 按钮。

#### 4.2.4. 其他设置 Tab
*   `Form` 包含：
    *   "系统维护模式": `Switch` (对应 `system.maintenance_mode`)。
    *   旁边可有文字说明维护模式的影响。
*   "保存设置" 按钮。

### 4.3. 状态管理与API调用
*   使用 `useState` 和 `useEffect` 管理表单数据、加载状态和从API获取的配置数据。
*   页面加载时，调用后端API (`GET /api/admin/config` 和 `GET /api/admin/rate/current`) 获取所有配置的当前值并填充表单。
*   用户点击各Tab下的"保存"按钮时：
    *   调用对应的后端API (`PUT /api/admin/config` 或 `POST /api/admin/rate`)。
    *   成功后提示用户，并刷新显示的数据。
    *   统一处理API错误并向用户展示。

### 4.4. 类型定义 (`src/types/`)
*   `SystemConfig.ts`: 定义 `SystemConfigVO`, `SystemConfigUpdateRequest`。
*   `Rate.ts`: 定义 `ChargingRateVO`, `ChargingRateUpdateRequest`。

## 5. 开发步骤概要
1.  **后端**:
    1.  数据库设计与SQL脚本编写 (`system_config`, `charging_rate` 表)。
    2.  实体类、VO、DTO 定义。
    3.  Mapper 接口编写。
    4.  `SystemConfigService` 及 `SystemConfigServiceImpl` 实现。
    5.  `ChargingRateService` 及 `ChargingRateServiceImpl` 实现。
    6.  `SystemConfigAdminController` 和 `ChargingRateAdminController` 实现。
    7.  修改现有Service层代码，使其依赖新的配置服务。
    8.  编写单元测试和API接口测试。
2.  **前端**:
    1.  创建 `/admin/settings` 页面及路由。
    2.  实现各配置Tab的UI布局 (使用Ant Design组件)。
    3.  实现API服务调用逻辑，用于获取和更新配置。
    4.  实现表单数据绑定、提交和验证。
    5.  在管理员导航栏添加链接。
3.  **联调与测试**:
    1.  前后端联调，确保数据流正确。
    2.  全面测试各项配置的生效情况，特别是对现有功能的影响。
    3.  UI/UX 测试和调整。
4.  **文档**:
    1.  更新 `README.md` 或相关部署文档，说明新增的配置项。
    2.  更新API文档。

## 6. 风险与注意事项
*   **配置生效机制**: 部分系统参数（如日志开关）可能需要特定的机制使其在修改后能被应用动态感知，而不是仅在服务重启后生效。Service层中读取配置的逻辑需要考虑这一点，缓存机制是关键。
*   **数据一致性**: 费率等关键业务数据的修改需要保证事务性。
*   **权限控制**: 确保所有系统设置的API接口都受到严格的管理员权限保护。
*   **用户体验**: 配置项应有清晰的名称和描述，重要的修改操作最好有二次确认。
*   **向后兼容**: 如果某些配置项被移除或重命名，需要考虑旧数据的迁移或兼容。

## 7. 未来扩展
*   **分时段/阶梯费率**: `charging_rate` 表已为分时段费率预留 `start_time_segment`, `end_time_segment` 字段，未来可扩展。
*   **更细致的权限控制**: 例如，不同管理员角色管理不同的配置模块。
*   **操作日志**: 对系统设置的修改操作记录审计日志。

This concludes the development plan for the System Settings module. 