开始第四阶段开发
This commit is contained in:
@@ -6,97 +6,161 @@
|
||||
* 完善 API 文档。
|
||||
* 增强系统测试覆盖率。
|
||||
* 优化错误处理和日志记录。
|
||||
* 对移动端 App 进行 UI 细节打磨和体验优化。
|
||||
* 对前端应用进行 UI 细节打磨和体验优化(根据实际优先级调整)。
|
||||
|
||||
## 2. 后端开发详解
|
||||
|
||||
1. **数据库初始化**:
|
||||
* **创建 `activation_code` 表**: 执行 `development_plan.md` 中定义的 `activation_code` 表 DDL 语句。
|
||||
* **创建 `activation_code` 表**: 执行以下 DDL 语句创建激活码表。
|
||||
```sql
|
||||
CREATE TABLE `activation_code` (...) COMMENT='激活码表';
|
||||
CREATE TABLE `activation_code` (
|
||||
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
`code` VARCHAR(64) NOT NULL COMMENT '激活码字符串,确保全局唯一',
|
||||
`value` DECIMAL(10, 2) NOT NULL COMMENT '激活码对应的面值(金额)',
|
||||
`is_used` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否已使用:0-未使用,1-已使用',
|
||||
`user_id` BIGINT UNSIGNED NULL DEFAULT NULL COMMENT '使用者用户ID (如果已使用)',
|
||||
`use_time` DATETIME NULL DEFAULT NULL COMMENT '激活码使用时间 (如果已使用)',
|
||||
`expire_time` DATETIME NULL DEFAULT NULL COMMENT '激活码过期时间 (NULL表示永不过期)',
|
||||
`batch_id` VARCHAR(64) NULL DEFAULT NULL COMMENT '生成批次号,方便管理员追踪管理',
|
||||
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`is_delete` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '逻辑删除标志:0-未删除,1-已删除',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `uk_code` (`code`) COMMENT '激活码唯一索引',
|
||||
KEY `idx_user_id` (`user_id`) COMMENT '使用者用户ID索引',
|
||||
KEY `idx_expire_time` (`expire_time`) COMMENT '过期时间索引',
|
||||
KEY `idx_batch_id` (`batch_id`) COMMENT '批次号索引'
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='激活码表';
|
||||
```
|
||||
2. **激活码模块实现**:
|
||||
* **Entity**: 创建 `ActivationCode.java`。
|
||||
* **Mapper**: 创建 `ActivationCodeMapper.java`。
|
||||
* **Service**: 创建 `ActivationCodeService.java` 接口和实现类。
|
||||
* `generateCodes(int count, BigDecimal value, Date expireTime)`: (管理员) 批量生成激活码。生成逻辑可以使用 UUID 或自定义规则,确保唯一性。将生成的 Code 和 Value 存入数据库。
|
||||
* `redeemCode(String userId, String code)`: (用户) 兑换激活码。
|
||||
1. 查询 `code` 是否存在、是否未使用 (`is_used = 0`)、是否过期 (如果 `expire_time` 不为空)。
|
||||
2. 如果有效,获取其 `value`。
|
||||
3. 调用 `userService.addBalance(userId, value)` 增加用户余额 (注意并发)。
|
||||
4. 将激活码标记为已使用 (`is_used = 1`), 记录 `user_id`, `use_time`。
|
||||
5. 返回成功或失败信息。
|
||||
* (可选) `listCodes(Page page, ActivationCodeQuery query)`: (管理员) 查询激活码列表。
|
||||
* **Controller**: 创建 `ActivationCodeController.java`。
|
||||
* 实现 `POST /api/codes/redeem` 接口: 调用 `activationCodeService.redeemCode(...)`。
|
||||
* (可选) 实现 `POST /api/codes` 接口 (管理员): 调用 `activationCodeService.generateCodes(...)`。
|
||||
* (可选) 实现 `GET /api/codes` 接口 (管理员): 调用 `activationCodeService.listCodes(...)`。
|
||||
2. **激活码模块实现**:
|
||||
* **Entity (`ActivationCode.java`)**: 创建 `ActivationCode.java` 实体类,其字段应精确映射 `activation_code` 表的列,例如:
|
||||
* `Long id`
|
||||
* `String code`
|
||||
* `BigDecimal value`
|
||||
* `Integer isUsed` (或 `Boolean isUsed`,注意与数据库 `TINYINT` 映射)
|
||||
* `Long userId`
|
||||
* `LocalDateTime useTime` (或 `Date`)
|
||||
* `LocalDateTime expireTime` (或 `Date`)
|
||||
* `String batchId`
|
||||
* `LocalDateTime createTime`
|
||||
* `LocalDateTime updateTime`
|
||||
* `Integer isDelete` (或 `Boolean`)
|
||||
* **Mapper (`ActivationCodeMapper.java`)**: 创建 Mybatis Plus Mapper 接口。
|
||||
* **Service (`ActivationCodeService.java` 接口和 `ActivationCodeServiceImpl.java` 实现类)**:
|
||||
* `List<ActivationCode> generateCodes(int count, BigDecimal value, LocalDateTime expireTime, String batchId)`: (管理员) 批量生成激活码。
|
||||
* `batchId` 可由调用者传入或在Service中生成(如UUID)。
|
||||
* 生成逻辑需确保 `code` 的唯一性 (例如结合随机数、时间戳、序列号生成较长字符串,或使用 UUID)。
|
||||
* 将生成的 `code`, `value`, `expireTime`, `batchId`, 以及默认的 `is_used=0`, `is_delete=0` 等信息存入数据库。
|
||||
* 返回生成的激活码列表。
|
||||
* `boolean redeemCode(Long currentUserId, String code)`: (用户) 兑换激活码。
|
||||
1. 根据 `code` 查询激活码,需同时满足:`code` 存在、`is_used = 0`、`is_delete = 0`。
|
||||
2. 检查是否过期:如果 `expire_time` 不为 `NULL` 且当前时间已超过 `expire_time`,则视为过期。
|
||||
3. 如果激活码有效且未过期:
|
||||
a. 获取其 `value`。
|
||||
b. 调用 `userService.addBalance(currentUserId, value)` 为用户增加余额 (关键:此操作需保证事务性和并发安全)。
|
||||
c. 更新激活码记录:将 `is_used` 标记为 `1`, 设置 `user_id = currentUserId`, `use_time = NOW()`。
|
||||
d. 返回 `true` 表示成功。
|
||||
4. 如果激活码无效(不存在、已使用、已过期),返回 `false` 或抛出业务异常,明确告知原因。
|
||||
* `Page<ActivationCodeVO> listCodes(ActivationCodeQueryRequest queryRequest)`: (管理员) 分页查询激活码列表。
|
||||
* `ActivationCodeQueryRequest` DTO 应包含分页参数 (`current`, `pageSize`) 以及筛选条件,如 `code` (模糊查询), `is_used`, `batch_id`, `userId` (查询某个用户兑换的), `value` 范围, `expire_time` 范围, `create_time` 范围。
|
||||
* 返回结果 `ActivationCodeVO` 视图对象,可能包含用户信息(如果已兑换)。
|
||||
* **Controller (`ActivationCodeController.java`)**:
|
||||
* `POST /api/activation-code/redeem`: (用户) 兑换激活码。
|
||||
* 请求体:`{"code": "XXXX-XXXX-XXXX"}`。
|
||||
* 响应:成功时返回类似 `{"success": true, "message": "兑换成功,增加余额 XX 元", "redeemedValue": XX.XX}`;失败时返回 `{"success": false, "message": "错误信息"}`。
|
||||
* `POST /api/admin/activation-code/generate`: (管理员, 需权限校验) 批量生成激活码。
|
||||
* 请求体:`{"count": 100, "value": 50.00, "expireTime": "YYYY-MM-DDTHH:mm:ss", "batchId": "OPTIONAL_BATCH_ID"}`。
|
||||
* 响应:成功时可返回生成批次的信息或生成的码列表的摘要。
|
||||
* `GET /api/admin/activation-code/list`: (管理员, 需权限校验) 分页查询激活码。
|
||||
* 请求参数:对应 `ActivationCodeQueryRequest` 中的字段。
|
||||
* 响应:分页结果,包含 `ActivationCodeVO` 列表及分页信息。
|
||||
3. **API 文档完善 (Knife4j/Swagger)**:
|
||||
* 检查所有 Controller 类和方法,确保添加了 `@Api`, `@ApiOperation` 注解,描述清晰。
|
||||
* 检查所有请求 DTO 和响应 VO (视图对象),确保添加了 `@ApiModel`, `@ApiModelProperty` 注解,描述字段含义和是否必需。
|
||||
* 启动项目,访问 Knife4j 文档地址 (通常是 `/doc.html`),检查文档是否完整、准确。
|
||||
4. **测试增强**:
|
||||
* **单元测试**: 使用 JUnit 和 Mockito (或 PowerMock) 对 Service 层的核心业务逻辑进行测试,特别是计费、余额变更、激活码兑换、任务状态处理等。
|
||||
* **集成测试 (可选但推荐)**:
|
||||
* 使用 Spring Boot Test (`@SpringBootTest`) 测试 Service 层与数据库的交互。
|
||||
* **MQTT 集成测试**: 搭建本地 MQTT Broker (如 Docker 版 EMQX 或 Mosquitto),编写测试用例模拟机器人发送状态消息,验证 `MqttMessageHandler` 和后续业务逻辑是否正确处理。
|
||||
* **接口测试**: 使用 Postman 或 Apifox 等工具,对所有 API 进行测试,覆盖正常和异常场景。
|
||||
5. **错误处理与日志优化**:
|
||||
* **全局异常处理**: 检查 `GlobalExceptionHandler.java`,确保捕获了常见的业务异常 (`BusinessException`) 和系统异常,并返回统一格式的错误响应给前端。
|
||||
* **日志**: 使用 SLF4j + Logback (Spring Boot 默认)。
|
||||
* 在关键路径 (如用户登录、发起充电、收到 MQTT 消息、计费、余额变更、任务超时) 添加 `info` 级别的日志。
|
||||
* 在异常捕获处添加 `error` 级别的日志,包含堆栈信息。
|
||||
* 考虑异步记录日志 (如果性能要求高)。
|
||||
* 配置 `logback-spring.xml`,区分不同环境的日志级别和输出目的地(控制台、文件)。
|
||||
* 重点关注新增的 `ActivationCodeController` 的所有接口。
|
||||
* 确保 `ActivationCode.java` (作为响应的一部分或查询条件)、`ActivationCodeQueryRequest` (请求DTO)、`ActivationCodeVO` (响应VO) 等模型都添加了 `@ApiModel` 和 `@ApiModelProperty` 注解,清晰描述每个字段的含义、示例值、是否必需。
|
||||
* 更新所有受影响的现有API文档(例如,如果用户接口返回了余额,激活码兑换会影响此余额)。
|
||||
4. **测试增强**:
|
||||
* **单元测试 (JUnit/Mockito)**:
|
||||
* `ActivationCodeServiceImpl`:
|
||||
* `generateCodes`: 验证生成数量、值的正确性,`batchId` 的设置,`code` 的唯一性(可以通过mock Mapper的查询行为来模拟已存在的code)。
|
||||
* `redeemCode`:
|
||||
* 测试有效码的成功兑换流程(`userService.addBalance` 被正确调用,激活码状态被正确更新)。
|
||||
* 测试无效码(不存在、格式错误)。
|
||||
* 测试已使用码的兑换。
|
||||
* 测试已过期码的兑换。
|
||||
* 测试永不过期码的兑换。
|
||||
* 模拟 `userService.addBalance` 失败的情况。
|
||||
* `listCodes`: 验证查询条件拼接的正确性。
|
||||
* `UserServiceImpl`: 如果 `addBalance` 方法涉及复杂逻辑或并发控制,也需要单元测试。
|
||||
* **集成测试 (`@SpringBootTest`)**:
|
||||
* `ActivationCodeService` 与数据库的交互:测试 `generateCodes` 实际写入数据库,`redeemCode` 实际更新数据库,`listCodes` 实际查询数据。
|
||||
* 测试 `redeemCode` 中余额增加和激活码状态更新的事务性。
|
||||
* **接口测试 (Postman/Apifox)**:
|
||||
* 对 `/api/activation-code/redeem`, `/api/admin/activation-code/generate`, `/api/admin/activation-code/list` 三个核心接口进行全面测试,覆盖各种参数组合和业务场景。
|
||||
5. **错误处理与日志优化**:
|
||||
* **全局异常处理**: 确保 `GlobalExceptionHandler.java` 能处理与激活码相关的业务异常(如 `InvalidCodeException`, `CodeUsedException`, `CodeExpiredException`),并返回规范的错误响应。
|
||||
* **日志**:
|
||||
* `ActivationCodeServiceImpl`:
|
||||
* `generateCodes`: INFO 记录生成批次、数量、面值。
|
||||
* `redeemCode`: INFO 记录用户尝试兑换的 `code`,成功时记录兑换的 `userId`, `code`, `value`;失败时 WARN 或 ERROR 记录失败原因。
|
||||
* 在 `userService.addBalance` 关键步骤添加日志。
|
||||
|
||||
## 3. 前端 (移动端 App) 开发详解
|
||||
## 3. 前端 (Web 应用) 开发详解
|
||||
|
||||
* **目标**: 实现激活码兑换功能,优化用户体验和界面细节。
|
||||
* **目标**: 实现用户激活码兑换功能,管理员激活码管理功能,并根据优先级进行UI/UX优化。
|
||||
|
||||
* **页面设计与流程**:
|
||||
1. **激活码兑换页 (`RedeemCodeScreen.js`)**: (普通用户,通常在 "我的" 页面内入口)
|
||||
* **UI**: 简洁风格。一个输入框用于输入激活码,一个 "兑换" 按钮 (蓝色)。可以加一些提示文字说明。
|
||||
* **交互**: 输入激活码,点击兑换按钮,显示加载状态。
|
||||
* **API 调用**: 调用 `POST /api/codes/redeem`,参数 `{ code: enteredCode }`。
|
||||
* **响应处理**: 成功则提示 "兑换成功,增加余额 X 元",并更新本地用户余额显示;失败则提示错误原因(如无效码、已使用、已过期)。
|
||||
2. **用户中心/我的页面 (`ProfileScreen.js`)**:
|
||||
* **UI**: 优化布局,清晰展示用户名、角色、**账户余额**。
|
||||
* 提供 "充电历史"、"激活码兑换" 等功能的入口。
|
||||
* 提供 "退出登录" 按钮。
|
||||
* 整体风格保持蓝白科技感。
|
||||
3. **UI 细节打磨**:
|
||||
* 检查所有页面的 UI 元素对齐、间距、颜色、字体是否符合设计规范。
|
||||
* 优化加载状态的显示(如骨架屏、更平滑的加载动画)。
|
||||
* 优化错误提示方式,使其更友好、清晰。
|
||||
* 确保在不同尺寸和分辨率的手机屏幕上显示良好(响应式布局)。
|
||||
* 增加必要的过渡动画,提升操作流畅感和科技感。
|
||||
4. **管理员激活码管理页 (`AdminCodeManagementScreen.js`)**: (管理员)
|
||||
* **UI**:
|
||||
* 提供生成激活码的功能入口(输入数量、金额、过期时间)。
|
||||
* 列表展示已生成的激活码,包含码字、金额、状态(未使用/已使用/已过期)、使用者、使用时间等信息。
|
||||
* 支持搜索、筛选、分页。
|
||||
* **API 调用**: 调用 `/api/codes` (POST 生成, GET 查询)。
|
||||
1. **激活码兑换功能/组件 (用户)**: (可以是一个独立的页面,例如 `/redeem-code`,或集成到用户中心/我的账户页面)
|
||||
* **UI**:
|
||||
* 一个清晰的输入框供用户输入激活码。
|
||||
* 一个 "立即兑换" 或 "确认" 按钮。
|
||||
* 可以有简短的文字说明激活码的用途和注意事项。
|
||||
* **交互**:
|
||||
* 输入激活码时可以有格式校验提示(如果激活码有固定格式)。
|
||||
* 点击按钮后,显示加载状态(例如按钮禁用并显示Spinner)。
|
||||
* **API 调用**: 调用 `POST /api/activation-code/redeem`,请求体 `{ "code": "用户输入的激活码" }`。
|
||||
* **响应处理**:
|
||||
* 成功:显示成功提示(例如 "兑换成功!XX元已存入您的账户余额。"),并触发刷新用户余额显示(例如通过全局状态管理或重新获取用户信息)。
|
||||
* 失败:在输入框下方或页面顶部显示具体的错误信息(例如 "无效的激活码"、"此激活码已被使用"、"此激活码已过期")。
|
||||
2. **用户中心/我的页面 (`dashboard/page.tsx`) 增强**:
|
||||
* **UI**:
|
||||
* 在合适的位置(例如账户信息区域或操作列表区域)添加入口,如 "激活码兑换" 按钮或链接,导航到激活码兑换功能/页面。
|
||||
* 确保用户余额 (`user.balance`) 能够及时反映兑换后的最新金额。
|
||||
3. **管理员激活码管理页面/功能 (`admin/activation-codes/page.tsx` 或类似路径)**: (管理员)
|
||||
* **UI**:
|
||||
* **生成激活码区域**:
|
||||
* 表单包含输入字段:生成数量 (`count`)、单个面值 (`value`)、过期时间 (`expireTime` - 可使用日期选择器)、批次ID (`batchId` - 可选,或由系统生成后显示)。
|
||||
* "生成激活码" 按钮。
|
||||
* **激活码列表区域**:
|
||||
* 表格形式展示已生成的激活码。
|
||||
* 列:ID, 激活码 (`code`), 面值 (`value`), 状态 (例如 "未使用", "已使用", "已过期" - 前端根据 `is_used` 和 `expire_time` 计算得出), 使用者用户ID/用户名 (如果已使用,`user_id`), 使用时间 (`use_time`), 过期时间 (`expire_time`), 生成批次ID (`batch_id`), 创建时间 (`create_time`)。
|
||||
* 支持按 `code` (模糊)、`is_used` (下拉选择)、`batch_id`、`expire_time` 范围等条件进行搜索/筛选。
|
||||
* 支持分页。
|
||||
* **API 调用**:
|
||||
* 生成:调用 `POST /api/admin/activation-code/generate`。
|
||||
* 查询:调用 `GET /api/admin/activation-code/list`,并处理分页和筛选参数。
|
||||
4. **UI 细节打磨与体验优化 (根据优先级)**:
|
||||
* 同上一版本计划,关注对齐、间距、颜色、字体、加载状态、错误提示、响应式等。
|
||||
|
||||
* **代码优化**:
|
||||
* 检查代码结构,封装可复用组件。
|
||||
* 处理潜在的内存泄漏。
|
||||
* 优化性能,特别是列表渲染。
|
||||
* **代码优化**:
|
||||
* 封装可复用的UI组件(如输入框、按钮、提示框、表格)。
|
||||
* 优化API请求逻辑,处理加载和错误状态。
|
||||
|
||||
## 4. 本阶段交付物
|
||||
|
||||
* 包含 `activation_code` 表的数据库。
|
||||
* 包含 `activation_code` 表的数据库 schema 更新。
|
||||
* 实现激活码生成、查询、兑换功能的后端服务及 API。
|
||||
* 完善的 Knife4j API 文档。
|
||||
* 更高覆盖率的单元测试和集成测试报告。
|
||||
* 优化后的错误处理和日志配置。
|
||||
* 移动端 App 实现激活码兑换功能。
|
||||
* 移动端 App 整体 UI/UX 优化版本。
|
||||
* (可选) 移动端 App 实现管理员激活码管理界面。
|
||||
* 最终的接口测试报告。
|
||||
* 更新且完善的 Knife4j API 文档,包含激活码相关接口。
|
||||
* 更高覆盖率的单元测试和集成测试,特别是激活码和余额相关逻辑。
|
||||
* 优化后的后端错误处理和日志配置。
|
||||
* 前端Web应用实现用户激活码兑换功能。
|
||||
* (如果开发) 前端Web应用实现管理员激活码管理界面。
|
||||
* 针对上述新功能的接口测试报告。
|
||||
* (可选,根据进度) 前端Web应用整体 UI/UX 优化版本。
|
||||
|
||||
## 5. 注意事项
|
||||
|
||||
* 激活码生成要保证唯一性。
|
||||
* 激活码兑换和余额增加操作要保证原子性。
|
||||
* API 文档应与实际代码保持同步。
|
||||
* 测试应尽可能覆盖边界条件和异常情况。
|
||||
* 激活码生成务必保证 `code` 字段的全局唯一性。
|
||||
* 激活码兑换和余额增加操作必须保证**原子性**(事务管理)。
|
||||
* API 文档应与实际代码实现严格保持同步。
|
||||
* 测试用例需覆盖所有正常流程、边界条件和异常情况(例如并发兑换同一个码)。
|
||||
* 管理员操作需进行严格的权限校验。
|
||||
Reference in New Issue
Block a user