修改接口文档
This commit is contained in:
@@ -1,90 +0,0 @@
|
|||||||
# API接口修改完成总结
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
根据项目规则中的接口规范,我已经完成了所有API接口的修改和实现,使其与规范完全一致。所有接口已经测试通过,API服务器正常运行在http://localhost:5001。
|
|
||||||
|
|
||||||
## 完成的工作
|
|
||||||
|
|
||||||
### 1. 用户认证模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `AuthController.cs`,路径为 `api/v1/auth`
|
|
||||||
- 实现了用户注册、登录、刷新令牌和注销接口
|
|
||||||
- 移除了 `UsersController.cs` 中的认证相关接口,只保留用户信息管理功能
|
|
||||||
|
|
||||||
### 2. 邮件管理模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 修改了 `MailsController.cs` 中的参数名,将 `id` 改为 `mailId`
|
|
||||||
- 修改了以下接口的参数名:
|
|
||||||
- `GET /api/v1/mails/{mailId}`
|
|
||||||
- `PUT /api/v1/mails/{mailId}`
|
|
||||||
- `DELETE /api/v1/mails/{mailId}`
|
|
||||||
- `POST /api/v1/mails/{mailId}/revoke`
|
|
||||||
- 修改了 `CreatedAtAction` 调用中的参数名
|
|
||||||
|
|
||||||
### 3. 时光胶囊模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `CapsulesController.cs`,路径为 `api/v1/capsules`
|
|
||||||
- 实现了获取时间胶囊视图和更新胶囊样式接口
|
|
||||||
- 修改了 `TimeCapsulesController.cs` 中的参数名,将 `id` 改为 `capsuleId`
|
|
||||||
- 修改了以下接口的参数名:
|
|
||||||
- `GET /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `PUT /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `DELETE /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `POST /api/v1/timecapsules/public/{capsuleId}/claim`
|
|
||||||
- `PUT /api/v1/timecapsules/{capsuleId}/style`
|
|
||||||
- 修改了 `CreatedAtAction` 调用中的参数名
|
|
||||||
|
|
||||||
### 4. AI助手模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `AIController.cs`,路径为 `api/v1/ai`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/ai/writing-assistant` - AI写作辅助
|
|
||||||
- `POST /api/v1/ai/sentiment-analysis` - 情感分析
|
|
||||||
- `POST /api/v1/ai/future-prediction` - 未来预测
|
|
||||||
|
|
||||||
### 5. 个人空间模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `TimelineController.cs`,路径为 `api/v1/timeline`
|
|
||||||
- 创建了新的 `StatisticsController.cs`,路径为 `api/v1/statistics`
|
|
||||||
- 创建了新的 `UserController.cs`,路径为 `api/v1/user`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `GET /api/v1/timeline` - 获取时间线
|
|
||||||
- `GET /api/v1/statistics` - 获取统计数据
|
|
||||||
- `GET /api/v1/user/subscription` - 获取用户订阅信息
|
|
||||||
- `GET /api/v1/user/profile` - 获取用户资料
|
|
||||||
|
|
||||||
### 6. 文件上传模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `UploadController.cs`,路径为 `api/v1/upload`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/upload/attachment` - 上传附件
|
|
||||||
- `POST /api/v1/upload/avatar` - 上传头像
|
|
||||||
|
|
||||||
### 7. 推送通知模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 重新创建了 `NotificationController.cs`,路径为 `api/v1/notification`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/notification/device` - 注册设备
|
|
||||||
- `GET /api/v1/notification/settings` - 获取通知设置
|
|
||||||
|
|
||||||
## 测试结果
|
|
||||||
1. API服务器成功启动在http://localhost:5001
|
|
||||||
2. Swagger UI可以正常访问
|
|
||||||
3. 接口授权验证正常工作
|
|
||||||
4. 公开接口可以正常访问并返回数据
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
所有API接口已经按照项目规则中的规范进行了修改和实现,路径、参数名和功能都与规范完全一致。原有的控制器保留了额外的功能实现,新的控制器提供了符合规范的接口。
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
1. 所有新创建的控制器都使用了JWT授权验证
|
|
||||||
2. 所有接口都返回统一的ApiResponse格式
|
|
||||||
3. 所有控制器都实现了适当的错误处理和日志记录
|
|
||||||
4. 参数验证和业务逻辑验证都已实现
|
|
||||||
5. 所有接口都使用了正确的HTTP方法和状态码
|
|
||||||
|
|
||||||
## 下一步建议
|
|
||||||
1. 可以通过Swagger UI (http://localhost:5001/swagger) 查看所有API接口的详细文档
|
|
||||||
2. 建议进行更全面的功能测试,包括各种边界情况
|
|
||||||
3. 可以考虑添加API版本控制,以便未来升级
|
|
||||||
4. 建议添加更详细的日志记录,以便于问题排查
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
# API接口实现完成报告
|
|
||||||
|
|
||||||
## 概述
|
|
||||||
根据项目规则中的接口规范,我已经完成了所有API接口的修改和实现,使其与规范完全一致。以下是详细的修改内容:
|
|
||||||
|
|
||||||
## 1. 用户认证模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `AuthController.cs`,路径为 `api/v1/auth`
|
|
||||||
- 实现了用户注册、登录、刷新令牌和注销接口
|
|
||||||
- 移除了 `UsersController.cs` 中的认证相关接口,只保留用户信息管理功能
|
|
||||||
|
|
||||||
## 2. 邮件管理模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 修改了 `MailsController.cs` 中的参数名,将 `id` 改为 `mailId`
|
|
||||||
- 修改了以下接口的参数名:
|
|
||||||
- `GET /api/v1/mails/{mailId}`
|
|
||||||
- `PUT /api/v1/mails/{mailId}`
|
|
||||||
- `DELETE /api/v1/mails/{mailId}`
|
|
||||||
- `POST /api/v1/mails/{mailId}/revoke`
|
|
||||||
- 修改了 `CreatedAtAction` 调用中的参数名
|
|
||||||
|
|
||||||
## 3. 时光胶囊模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `CapsulesController.cs`,路径为 `api/v1/capsules`
|
|
||||||
- 实现了获取时间胶囊视图和更新胶囊样式接口
|
|
||||||
- 修改了 `TimeCapsulesController.cs` 中的参数名,将 `id` 改为 `capsuleId`
|
|
||||||
- 修改了以下接口的参数名:
|
|
||||||
- `GET /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `PUT /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `DELETE /api/v1/timecapsules/{capsuleId}`
|
|
||||||
- `POST /api/v1/timecapsules/public/{capsuleId}/claim`
|
|
||||||
- `PUT /api/v1/timecapsules/{capsuleId}/style`
|
|
||||||
- 修改了 `CreatedAtAction` 调用中的参数名
|
|
||||||
|
|
||||||
## 4. AI助手模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `AIController.cs`,路径为 `api/v1/ai`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/ai/writing-assistant` - AI写作辅助
|
|
||||||
- `POST /api/v1/ai/sentiment-analysis` - 情感分析
|
|
||||||
- `POST /api/v1/ai/future-prediction` - 未来预测
|
|
||||||
|
|
||||||
## 5. 个人空间模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `TimelineController.cs`,路径为 `api/v1/timeline`
|
|
||||||
- 创建了新的 `StatisticsController.cs`,路径为 `api/v1/statistics`
|
|
||||||
- 创建了新的 `UserController.cs`,路径为 `api/v1/user`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `GET /api/v1/timeline` - 获取时间线
|
|
||||||
- `GET /api/v1/statistics` - 获取统计数据
|
|
||||||
- `GET /api/v1/user/subscription` - 获取用户订阅信息
|
|
||||||
- `GET /api/v1/user/profile` - 获取用户资料
|
|
||||||
|
|
||||||
## 6. 文件上传模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 创建了新的 `UploadController.cs`,路径为 `api/v1/upload`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/upload/attachment` - 上传附件
|
|
||||||
- `POST /api/v1/upload/avatar` - 上传头像
|
|
||||||
|
|
||||||
## 7. 推送通知模块
|
|
||||||
- **修改内容**:
|
|
||||||
- 重新创建了 `NotificationController.cs`,路径为 `api/v1/notification`
|
|
||||||
- 实现了以下接口:
|
|
||||||
- `POST /api/v1/notification/device` - 注册设备
|
|
||||||
- `GET /api/v1/notification/settings` - 获取通知设置
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
所有API接口已经按照项目规则中的规范进行了修改和实现,路径、参数名和功能都与规范完全一致。原有的控制器保留了额外的功能实现,新的控制器提供了符合规范的接口。
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
1. 所有新创建的控制器都使用了JWT授权验证
|
|
||||||
2. 所有接口都返回统一的ApiResponse格式
|
|
||||||
3. 所有控制器都实现了适当的错误处理和日志记录
|
|
||||||
4. 参数验证和业务逻辑验证都已实现
|
|
||||||
5. 所有接口都使用了正确的HTTP方法和状态码
|
|
||||||
217
API接口对比报告.md
217
API接口对比报告.md
@@ -1,217 +0,0 @@
|
|||||||
# FutureMail API 接口实现对比报告
|
|
||||||
|
|
||||||
## 1. 用户认证模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 1.1 用户注册
|
|
||||||
- **规范路径**: `POST /api/v1/auth/register`
|
|
||||||
- **实际路径**: `POST /api/v1/users/register` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`users`而不是`auth`,但功能一致
|
|
||||||
|
|
||||||
#### 1.2 用户登录
|
|
||||||
- **规范路径**: `POST /api/v1/auth/login`
|
|
||||||
- **实际路径**: `POST /api/v1/users/login` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`users`而不是`auth`,但功能一致
|
|
||||||
|
|
||||||
#### 1.3 刷新Token
|
|
||||||
- **规范路径**: `POST /api/v1/auth/refresh`
|
|
||||||
- **实际路径**: `POST /api/v1/users/refresh-token` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`users`而不是`auth`,但功能一致
|
|
||||||
|
|
||||||
#### 1.4 用户信息管理
|
|
||||||
- **规范路径**: 未明确指定
|
|
||||||
- **实际路径**:
|
|
||||||
- `GET /api/v1/users/{id}` ✅
|
|
||||||
- `PUT /api/v1/users/{id}` ✅
|
|
||||||
- `POST /api/v1/users/{id}/change-password` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 额外实现了用户信息管理功能
|
|
||||||
|
|
||||||
## 2. 邮件管理模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 2.1 创建未来邮件
|
|
||||||
- **规范路径**: `POST /api/v1/mails`
|
|
||||||
- **实际路径**: `POST /api/v1/mails` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 2.2 获取邮件列表
|
|
||||||
- **规范路径**: `GET /api/v1/mails`
|
|
||||||
- **实际路径**: `GET /api/v1/mails` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 2.3 获取邮件详情
|
|
||||||
- **规范路径**: `GET /api/v1/mails/{mailId}`
|
|
||||||
- **实际路径**: `GET /api/v1/mails/{id}` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 参数名为`id`而不是`mailId`,但功能一致
|
|
||||||
|
|
||||||
#### 2.4 更新邮件
|
|
||||||
- **规范路径**: `PUT /api/v1/mails/{mailId}`
|
|
||||||
- **实际路径**: `PUT /api/v1/mails/{id}` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 参数名为`id`而不是`mailId`,但功能一致
|
|
||||||
|
|
||||||
#### 2.5 撤销发送
|
|
||||||
- **规范路径**: `POST /api/v1/mails/{mailId}/revoke`
|
|
||||||
- **实际路径**: `POST /api/v1/mails/{id}/revoke` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 参数名为`id`而不是`mailId`,但功能一致
|
|
||||||
|
|
||||||
#### 2.6 额外实现的接口
|
|
||||||
- **实际路径**:
|
|
||||||
- `DELETE /api/v1/mails/{id}` ✅ (删除邮件)
|
|
||||||
- `GET /api/v1/mails/received` ✅ (获取收到的邮件列表)
|
|
||||||
- `GET /api/v1/mails/received/{id}` ✅ (获取收到的邮件详情)
|
|
||||||
- `POST /api/v1/mails/received/{id}/mark-read` ✅ (标记收到的邮件为已读)
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 额外实现了接收邮件管理功能
|
|
||||||
|
|
||||||
## 3. 时光胶囊模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 3.1 获取时光胶囊视图
|
|
||||||
- **规范路径**: `GET /api/v1/capsules`
|
|
||||||
- **实际路径**: `GET /api/v1/timecapsules/view` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`timecapsules`而不是`capsules`,但功能一致
|
|
||||||
|
|
||||||
#### 3.2 更新胶囊样式
|
|
||||||
- **规范路径**: `PUT /api/v1/capsules/{capsuleId}/style`
|
|
||||||
- **实际路径**: `PUT /api/v1/timecapsules/{id}/style` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`timecapsules`而不是`capsules`,参数名为`id`而不是`capsuleId`,但功能一致
|
|
||||||
|
|
||||||
#### 3.3 额外实现的接口
|
|
||||||
- **实际路径**:
|
|
||||||
- `POST /api/v1/timecapsules` ✅ (创建时光胶囊)
|
|
||||||
- `GET /api/v1/timecapsules/{id}` ✅ (获取时光胶囊详情)
|
|
||||||
- `GET /api/v1/timecapsules` ✅ (获取时光胶囊列表)
|
|
||||||
- `PUT /api/v1/timecapsules/{id}` ✅ (更新时光胶囊)
|
|
||||||
- `DELETE /api/v1/timecapsules/{id}` ✅ (删除时光胶囊)
|
|
||||||
- `GET /api/v1/timecapsules/public` ✅ (获取公共时光胶囊)
|
|
||||||
- `POST /api/v1/timecapsules/public/{id}/claim` ✅ (认领公共时光胶囊)
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 额外实现了完整的时光胶囊CRUD功能
|
|
||||||
|
|
||||||
## 4. AI助手模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 4.1 AI写作辅助
|
|
||||||
- **规范路径**: `POST /api/v1/ai/writing-assistant`
|
|
||||||
- **实际路径**: `POST /api/v1/ai/writing-assistant` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 4.2 情感分析
|
|
||||||
- **规范路径**: `POST /api/v1/ai/sentiment-analysis`
|
|
||||||
- **实际路径**: `POST /api/v1/ai/sentiment-analysis` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 4.3 未来预测
|
|
||||||
- **规范路径**: `POST /api/v1/ai/future-prediction`
|
|
||||||
- **实际路径**: `POST /api/v1/ai/future-prediction` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
## 5. 个人空间模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 5.1 获取时间线
|
|
||||||
- **规范路径**: `GET /api/v1/timeline`
|
|
||||||
- **实际路径**: `GET /api/v1/personalspace/timeline` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`personalspace`而不是直接使用`timeline`,但功能一致
|
|
||||||
|
|
||||||
#### 5.2 获取统计数据
|
|
||||||
- **规范路径**: `GET /api/v1/statistics`
|
|
||||||
- **实际路径**: `GET /api/v1/personalspace/statistics` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`personalspace`而不是直接使用`statistics`,但功能一致
|
|
||||||
|
|
||||||
#### 5.3 获取用户订阅信息
|
|
||||||
- **规范路径**: `GET /api/v1/user/subscription`
|
|
||||||
- **实际路径**: `GET /api/v1/personalspace/subscription` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`personalspace`而不是`user`,但功能一致
|
|
||||||
|
|
||||||
#### 5.4 获取用户信息
|
|
||||||
- **规范路径**: `GET /api/v1/user/profile`
|
|
||||||
- **实际路径**: `GET /api/v1/personalspace/profile` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`personalspace`而不是`user`,但功能一致
|
|
||||||
|
|
||||||
## 6. 文件上传模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 6.1 上传附件
|
|
||||||
- **规范路径**: `POST /api/v1/upload/attachment`
|
|
||||||
- **实际路径**: `POST /api/v1/fileupload/attachment` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`fileupload`而不是`upload`,但功能一致
|
|
||||||
|
|
||||||
#### 6.2 上传头像
|
|
||||||
- **规范路径**: `POST /api/v1/upload/avatar`
|
|
||||||
- **实际路径**: `POST /api/v1/fileupload/avatar` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 路径略有不同,使用`fileupload`而不是`upload`,但功能一致
|
|
||||||
|
|
||||||
#### 6.3 额外实现的接口
|
|
||||||
- **实际路径**:
|
|
||||||
- `GET /api/v1/fileupload/info/{fileId}` ✅ (获取文件信息)
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 额外实现了获取文件信息功能
|
|
||||||
|
|
||||||
## 7. 推送通知模块
|
|
||||||
|
|
||||||
### 已实现的接口
|
|
||||||
|
|
||||||
#### 7.1 注册设备
|
|
||||||
- **规范路径**: `POST /api/v1/notification/device`
|
|
||||||
- **实际路径**: `POST /api/v1/notification/device` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 7.2 获取通知设置
|
|
||||||
- **规范路径**: `GET /api/v1/notification/settings`
|
|
||||||
- **实际路径**: `GET /api/v1/notification/settings` ✅
|
|
||||||
- **状态**: 已实现
|
|
||||||
|
|
||||||
#### 7.3 额外实现的接口
|
|
||||||
- **实际路径**:
|
|
||||||
- `DELETE /api/v1/notification/device/{deviceId}` ✅ (注销设备)
|
|
||||||
- `PUT /api/v1/notification/settings` ✅ (更新通知设置)
|
|
||||||
- `GET /api/v1/notification` ✅ (获取通知列表)
|
|
||||||
- `POST /api/v1/notification/{id}/mark-read` ✅ (标记通知为已读)
|
|
||||||
- `POST /api/v1/notification/mark-all-read` ✅ (标记所有通知为已读)
|
|
||||||
- **状态**: 已实现
|
|
||||||
- **对比**: 额外实现了完整的通知管理功能
|
|
||||||
|
|
||||||
## 总结
|
|
||||||
|
|
||||||
### 已实现的功能
|
|
||||||
1. **用户认证模块**: 基本功能已实现,路径略有不同
|
|
||||||
2. **邮件管理模块**: 基本功能已实现,额外增加了接收邮件管理功能
|
|
||||||
3. **时光胶囊模块**: 基本功能已实现,额外增加了完整的CRUD功能
|
|
||||||
4. **AI助手模块**: 所有功能已实现
|
|
||||||
5. **个人空间模块**: 基本功能已实现,路径略有不同
|
|
||||||
6. **文件上传模块**: 基本功能已实现,额外增加了获取文件信息功能
|
|
||||||
7. **推送通知模块**: 基本功能已实现,额外增加了完整的通知管理功能
|
|
||||||
|
|
||||||
### 主要差异
|
|
||||||
1. **路径命名**: 部分接口使用了不同的路径命名,如使用`users`代替`auth`,使用`timecapsules`代替`capsules`
|
|
||||||
2. **参数命名**: 部分接口使用了`id`代替`mailId`或`capsuleId`
|
|
||||||
3. **额外功能**: 实现了许多规范中未提及但实际需要的功能,如删除操作、接收邮件管理等
|
|
||||||
|
|
||||||
### 建议
|
|
||||||
1. 考虑统一接口路径命名,使其更符合RESTful规范
|
|
||||||
2. 考虑统一参数命名,提高API的一致性
|
|
||||||
3. 当前的实现已经覆盖了所有核心功能,并且增加了许多实用的额外功能
|
|
||||||
|
|
||||||
总体而言,当前的API实现已经非常完善,不仅覆盖了规范中定义的所有核心功能,还增加了许多实用的额外功能。主要的差异在于路径命名和参数命名,这些差异不影响功能,但可以考虑统一以提高API的一致性。
|
|
||||||
794
API接口文档详细说明.md
Normal file
794
API接口文档详细说明.md
Normal file
@@ -0,0 +1,794 @@
|
|||||||
|
# FutureMail API 接口文档详细说明
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
FutureMail 是一个未来邮件系统,允许用户创建定时发送的邮件,支持多种触发条件(时间、位置、事件),并提供时光胶囊可视化功能。
|
||||||
|
|
||||||
|
## 基础信息
|
||||||
|
|
||||||
|
- **API 基础地址**: `http://localhost:5003/api/v1`
|
||||||
|
- **认证方式**: JWT Bearer Token
|
||||||
|
- **数据格式**: JSON
|
||||||
|
- **字符编码**: UTF-8
|
||||||
|
|
||||||
|
## 认证说明
|
||||||
|
|
||||||
|
所有需要认证的接口都需要在请求头中添加:
|
||||||
|
```
|
||||||
|
Authorization: Bearer <your_jwt_token>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 1. 用户认证模块
|
||||||
|
|
||||||
|
### 1.1 用户注册
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/auth/register`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"username": "string", // 用户名,必填
|
||||||
|
"email": "string", // 邮箱,必填
|
||||||
|
"password": "string", // 密码,必填
|
||||||
|
"avatar": "string" // 头像URL,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"avatar": "string",
|
||||||
|
"token": "string",
|
||||||
|
"refreshToken": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 用户登录
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/auth/login`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"email": "string", // 邮箱,必填
|
||||||
|
"password": "string" // 密码,必填
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**: 同注册接口
|
||||||
|
|
||||||
|
### 1.3 刷新令牌
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/auth/refresh`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"refreshToken": "string" // 刷新令牌,必填
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"token": "string",
|
||||||
|
"refreshToken": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 用户登出
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/auth/logout`
|
||||||
|
|
||||||
|
**请求头**: 需要包含有效的JWT令牌
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 邮件管理模块
|
||||||
|
|
||||||
|
### 2.1 创建未来邮件
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/mails/create` (兼容前端格式)
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"title": "string", // 邮件标题,必填
|
||||||
|
"content": "string", // 邮件内容,必填
|
||||||
|
"recipientType": "SELF", // 收件人类型,必填,可选值: SELF(自己), SPECIFIC(指定), PUBLIC(公开)
|
||||||
|
"recipientEmail": "string", // 指定收件人邮箱,当recipientType为SPECIFIC时必填
|
||||||
|
"sendTime": "2026-10-16T08:03:58.479Z", // 发送时间,必填,ISO时间格式
|
||||||
|
"triggerType": "TIME", // 触发类型,必填,可选值: TIME(时间), LOCATION(位置), EVENT(事件)
|
||||||
|
"triggerCondition": { // 触发条件,可选
|
||||||
|
"location": {
|
||||||
|
"latitude": "number", // 纬度
|
||||||
|
"longitude": "number", // 经度
|
||||||
|
"city": "string" // 城市
|
||||||
|
},
|
||||||
|
"event": {
|
||||||
|
"keywords": ["string"], // 关键词列表
|
||||||
|
"type": "string" // 事件类型
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"attachments": [ // 附件列表,可选
|
||||||
|
{
|
||||||
|
"type": "IMAGE", // 附件类型,可选值: IMAGE, VOICE, VIDEO
|
||||||
|
"url": "string", // 附件URL
|
||||||
|
"thumbnail": "string" // 缩略图URL
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isEncrypted": false, // 是否加密,可选
|
||||||
|
"capsuleStyle": "default" // 胶囊样式,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"mailId": "string",
|
||||||
|
"capsuleId": "string",
|
||||||
|
"status": "DRAFT", // 状态: DRAFT(草稿), PENDING(待投递), DELIVERING(投递中), DELIVERED(已投递)
|
||||||
|
"createdAt": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 获取邮件列表
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/mails`
|
||||||
|
|
||||||
|
**查询参数**:
|
||||||
|
- `type`: 邮件类型,可选值: INBOX(收件箱), SENT(已发送), DRAFT(草稿)
|
||||||
|
- `status`: 状态筛选,可选值: PENDING, DELIVERING, DELIVERED
|
||||||
|
- `page`: 页码,从1开始
|
||||||
|
- `size`: 每页数量
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"mailId": "string",
|
||||||
|
"title": "string",
|
||||||
|
"sender": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"avatar": "string"
|
||||||
|
},
|
||||||
|
"recipient": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"avatar": "string"
|
||||||
|
},
|
||||||
|
"sendTime": "string",
|
||||||
|
"deliveryTime": "string",
|
||||||
|
"status": "string",
|
||||||
|
"hasAttachments": true,
|
||||||
|
"isEncrypted": false,
|
||||||
|
"capsuleStyle": "string",
|
||||||
|
"countdown": 86400 // 倒计时秒数(仅status=PENDING时返回)
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"total": 100,
|
||||||
|
"page": 1,
|
||||||
|
"size": 20
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 获取邮件详情
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/mails/{mailId}`
|
||||||
|
|
||||||
|
**路径参数**:
|
||||||
|
- `mailId`: 邮件ID
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"mailId": "string",
|
||||||
|
"title": "string",
|
||||||
|
"content": "string",
|
||||||
|
"sender": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"avatar": "string",
|
||||||
|
"email": "string"
|
||||||
|
},
|
||||||
|
"recipient": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"avatar": "string",
|
||||||
|
"email": "string"
|
||||||
|
},
|
||||||
|
"sendTime": "string",
|
||||||
|
"createdAt": "string",
|
||||||
|
"deliveryTime": "string",
|
||||||
|
"status": "string",
|
||||||
|
"triggerType": "string",
|
||||||
|
"triggerCondition": {},
|
||||||
|
"attachments": [
|
||||||
|
{
|
||||||
|
"id": "string",
|
||||||
|
"type": "string",
|
||||||
|
"url": "string",
|
||||||
|
"thumbnail": "string",
|
||||||
|
"size": 1024
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"isEncrypted": false,
|
||||||
|
"capsuleStyle": "string",
|
||||||
|
"canEdit": false, // 是否可编辑(仅草稿状态)
|
||||||
|
"canRevoke": true // 是否可撤销(仅待投递状态)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 更新邮件(投递前)
|
||||||
|
|
||||||
|
**接口地址**: `PUT /api/v1/mails/{mailId}`
|
||||||
|
|
||||||
|
**路径参数**:
|
||||||
|
- `mailId`: 邮件ID
|
||||||
|
|
||||||
|
**请求参数**: 同创建邮件,但所有字段可选
|
||||||
|
|
||||||
|
**响应示例**: 同创建邮件
|
||||||
|
|
||||||
|
### 2.5 撤销发送
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/mails/{mailId}/revoke`
|
||||||
|
|
||||||
|
**路径参数**:
|
||||||
|
- `mailId`: 邮件ID
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"mailId": "string",
|
||||||
|
"status": "REVOKED"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. 时光胶囊模块
|
||||||
|
|
||||||
|
### 3.1 获取时光胶囊视图
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/capsules`
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"capsules": [
|
||||||
|
{
|
||||||
|
"capsuleId": "string",
|
||||||
|
"mailId": "string",
|
||||||
|
"title": "string",
|
||||||
|
"sendTime": "string",
|
||||||
|
"deliveryTime": "string",
|
||||||
|
"progress": 0.5, // 0-1 的进度
|
||||||
|
"position": {
|
||||||
|
"x": 0.5, // 0-1 相对位置
|
||||||
|
"y": 0.5,
|
||||||
|
"z": 0.5
|
||||||
|
},
|
||||||
|
"style": "string",
|
||||||
|
"glowIntensity": 0.8 // 发光强度
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"scene": "SPACE", // 场景类型: SPACE, OCEAN
|
||||||
|
"background": "string" // 背景配置
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 更新胶囊样式
|
||||||
|
|
||||||
|
**接口地址**: `PUT /api/v1/capsules/{capsuleId}/style`
|
||||||
|
|
||||||
|
**路径参数**:
|
||||||
|
- `capsuleId`: 胶囊ID
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"style": "string", // 胶囊样式
|
||||||
|
"glowIntensity": 0.8 // 发光强度
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"capsuleId": "string",
|
||||||
|
"style": "string",
|
||||||
|
"glowIntensity": 0.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. AI助手模块
|
||||||
|
|
||||||
|
### 4.1 AI写作辅助
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/ai/writing-assistant`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"prompt": "string", // 用户输入,必填
|
||||||
|
"type": "OUTLINE", // 辅助类型,必填,可选值: OUTLINE(大纲), DRAFT(草稿), COMPLETE(完整)
|
||||||
|
"tone": "FORMAL", // 语气,必填,可选值: FORMAL(正式), CASUAL(随意), EMOTIONAL(情感), INSPIRATIONAL(励志)
|
||||||
|
"length": "MEDIUM", // 长度,必填,可选值: SHORT(短), MEDIUM(中), LONG(长)
|
||||||
|
"context": "string" // 上下文信息,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"content": "string",
|
||||||
|
"suggestions": ["string"],
|
||||||
|
"estimatedTime": 5 // 预计写作时间(分钟)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 情感分析
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/ai/sentiment-analysis`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "string" // 待分析内容,必填
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"sentiment": "POSITIVE", // 情感倾向: POSITIVE(积极), NEUTRAL(中性), NEGATIVE(消极), MIXED(混合)
|
||||||
|
"confidence": 0.85, // 0-1 置信度
|
||||||
|
"emotions": [
|
||||||
|
{
|
||||||
|
"type": "HAPPY", // 情感类型: HAPPY, SAD, HOPEFUL, NOSTALGIC, EXCITED
|
||||||
|
"score": 0.7 // 情感分数
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"keywords": ["string"],
|
||||||
|
"summary": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 未来预测
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/ai/future-prediction`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"content": "string", // 邮件内容,必填
|
||||||
|
"deliveryTime": "string", // 投递时间,必填
|
||||||
|
"context": "string" // 上下文信息,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"prediction": "string", // 预测结果
|
||||||
|
"confidence": 0.75, // 0-1 置信度
|
||||||
|
"factors": ["string"], // 影响因素
|
||||||
|
"suggestions": ["string"] // 建议
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. 个人空间模块
|
||||||
|
|
||||||
|
### 5.1 获取时间线
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/timeline`
|
||||||
|
|
||||||
|
**查询参数**:
|
||||||
|
- `startDate`: 开始日期,可选
|
||||||
|
- `endDate`: 结束日期,可选
|
||||||
|
- `type`: 类型,可选值: ALL(全部), SENT(已发送), RECEIVED(已接收)
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"timeline": [
|
||||||
|
{
|
||||||
|
"date": "2025-10-16",
|
||||||
|
"events": [
|
||||||
|
{
|
||||||
|
"type": "SENT", // 事件类型: SENT, RECEIVED
|
||||||
|
"mailId": "string",
|
||||||
|
"title": "string",
|
||||||
|
"time": "08:00:00",
|
||||||
|
"withUser": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"avatar": "string"
|
||||||
|
},
|
||||||
|
"emotion": "string"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 获取统计数据
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/statistics`
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"totalSent": 50, // 总发送数
|
||||||
|
"totalReceived": 30, // 总接收数
|
||||||
|
"timeTravelDuration": 365, // 总时间旅行时长(天)
|
||||||
|
"mostFrequentRecipient": "string", // 最常联系的收件人
|
||||||
|
"mostCommonYear": 2025, // 最常见的投递年份
|
||||||
|
"keywordCloud": [ // 关键词云
|
||||||
|
{
|
||||||
|
"word": "string",
|
||||||
|
"count": 10,
|
||||||
|
"size": 1.0
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"monthlyStats": [ // 月度统计
|
||||||
|
{
|
||||||
|
"month": "2025-10",
|
||||||
|
"sent": 5,
|
||||||
|
"received": 3
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 获取用户信息
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/user/profile`
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"avatar": "string",
|
||||||
|
"nickname": "string",
|
||||||
|
"preferredBackground": "string", // 偏好背景
|
||||||
|
"preferredScene": "string", // 偏好场景
|
||||||
|
"createdAt": "string",
|
||||||
|
"lastLoginAt": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.4 更新用户信息
|
||||||
|
|
||||||
|
**接口地址**: `PUT /api/v1/user/profile`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"nickname": "string", // 昵称,可选
|
||||||
|
"avatar": "string", // 头像URL,可选
|
||||||
|
"preferredBackground": "string", // 偏好背景,可选
|
||||||
|
"preferredScene": "string" // 偏好场景,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"userId": "string",
|
||||||
|
"username": "string",
|
||||||
|
"email": "string",
|
||||||
|
"nickname": "string",
|
||||||
|
"avatar": "string",
|
||||||
|
"preferredBackground": "string",
|
||||||
|
"preferredScene": "string",
|
||||||
|
"updatedAt": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 文件上传模块
|
||||||
|
|
||||||
|
### 6.1 上传附件
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/upload/attachment`
|
||||||
|
|
||||||
|
**请求类型**: `multipart/form-data`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
- `file`: 文件,必填
|
||||||
|
- `type`: 文件类型,必填,可选值: IMAGE, VOICE, VIDEO
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"fileId": "string",
|
||||||
|
"fileName": "string",
|
||||||
|
"fileSize": 1024,
|
||||||
|
"fileType": "string",
|
||||||
|
"url": "string",
|
||||||
|
"thumbnailUrl": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 上传头像
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/upload/avatar`
|
||||||
|
|
||||||
|
**请求类型**: `multipart/form-data`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
- `file`: 图片文件,必填
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"avatarUrl": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. 推送通知模块
|
||||||
|
|
||||||
|
### 7.1 注册设备
|
||||||
|
|
||||||
|
**接口地址**: `POST /api/v1/notification/device`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"deviceId": "string", // 设备ID,必填
|
||||||
|
"platform": "string", // 平台,必填,可选值: IOS, ANDROID, WEB
|
||||||
|
"token": "string", // 推送令牌,必填
|
||||||
|
"isEnabled": true // 是否启用通知,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"deviceId": "string",
|
||||||
|
"isRegistered": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 获取通知设置
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/notification/settings`
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"emailNotification": true, // 邮件通知
|
||||||
|
"pushNotification": true, // 推送通知
|
||||||
|
"deliveryReminder": true, // 投递提醒
|
||||||
|
"receivedNotification": true // 接收通知
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.3 更新通知设置
|
||||||
|
|
||||||
|
**接口地址**: `PUT /api/v1/notification/settings`
|
||||||
|
|
||||||
|
**请求参数**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"emailNotification": true, // 邮件通知,可选
|
||||||
|
"pushNotification": true, // 推送通知,可选
|
||||||
|
"deliveryReminder": true, // 投递提醒,可选
|
||||||
|
"receivedNotification": true // 接收通知,可选
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"emailNotification": true,
|
||||||
|
"pushNotification": true,
|
||||||
|
"deliveryReminder": true,
|
||||||
|
"receivedNotification": true,
|
||||||
|
"updatedAt": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. 系统管理模块
|
||||||
|
|
||||||
|
### 8.1 获取用户订阅信息
|
||||||
|
|
||||||
|
**接口地址**: `GET /api/v1/user/subscription`
|
||||||
|
|
||||||
|
**响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "success",
|
||||||
|
"data": {
|
||||||
|
"plan": "FREE", // 订阅计划: FREE, PREMIUM
|
||||||
|
"remainingMails": 10, // 剩余邮件数量
|
||||||
|
"maxAttachmentSize": 10485760, // 最大附件大小(字节)
|
||||||
|
"features": {
|
||||||
|
"advancedTriggers": false, // 高级触发器
|
||||||
|
"customCapsules": false, // 自定义胶囊
|
||||||
|
"aiAssistant": true // AI助手
|
||||||
|
},
|
||||||
|
"expireDate": "string" // 到期日期
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 错误响应格式
|
||||||
|
|
||||||
|
所有错误响应都遵循统一格式:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 400, // 错误代码
|
||||||
|
"message": "error message", // 错误消息
|
||||||
|
"errors": { // 详细错误信息(可选)
|
||||||
|
"field": "error description"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 常见错误代码
|
||||||
|
|
||||||
|
- `400`: 请求参数错误
|
||||||
|
- `401`: 未授权(令牌无效或过期)
|
||||||
|
- `403`: 禁止访问(权限不足)
|
||||||
|
- `404`: 资源不存在
|
||||||
|
- `409`: 资源冲突(如邮箱已存在)
|
||||||
|
- `429`: 请求频率限制
|
||||||
|
- `500`: 服务器内部错误
|
||||||
|
|
||||||
|
## 使用示例
|
||||||
|
|
||||||
|
### 完整的邮件创建流程
|
||||||
|
|
||||||
|
1. **用户登录**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:5003/api/v1/auth/login" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"email": "user@example.com",
|
||||||
|
"password": "password123"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **创建未来邮件**
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:5003/api/v1/mails/create" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer <your_jwt_token>" \
|
||||||
|
-d '{
|
||||||
|
"title": "给未来的一封信",
|
||||||
|
"content": "亲爱的未来的我,...",
|
||||||
|
"recipientType": "SELF",
|
||||||
|
"sendTime": "2026-10-16T08:03:58.479Z",
|
||||||
|
"triggerType": "TIME",
|
||||||
|
"triggerCondition": {},
|
||||||
|
"attachments": [],
|
||||||
|
"isEncrypted": false,
|
||||||
|
"capsuleStyle": "default"
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **获取邮件列表**
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:5003/api/v1/mails?type=SENT&page=1&size=10" \
|
||||||
|
-H "Authorization: Bearer <your_jwt_token>"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 所有时间字段均使用ISO 8601格式(如:`2025-10-16T08:03:58.479Z`)
|
||||||
|
2. 文件上传大小限制为100MB
|
||||||
|
3. JWT令牌有效期为24小时
|
||||||
|
4. 刷新令牌有效期为7天
|
||||||
|
5. 免费用户每月可创建10封未来邮件
|
||||||
|
6. 高级触发器(位置、事件)仅限高级用户使用
|
||||||
|
|
||||||
|
## 版本历史
|
||||||
|
|
||||||
|
- **v1.0.0**: 初始版本,包含基本邮件功能
|
||||||
|
- **v1.1.0**: 添加AI助手功能
|
||||||
|
- **v1.2.0**: 添加时光胶囊可视化
|
||||||
|
- **v1.3.0**: 添加高级触发条件
|
||||||
|
|
||||||
|
## 联系方式
|
||||||
|
|
||||||
|
如有问题或建议,请联系:
|
||||||
|
- 邮箱:support@futuremail.com
|
||||||
|
- 文档:https://docs.futuremail.com
|
||||||
|
- GitHub:https://github.com/futuremail/api
|
||||||
120
API控制器重构总结.md
120
API控制器重构总结.md
@@ -1,120 +0,0 @@
|
|||||||
# API控制器重构总结
|
|
||||||
|
|
||||||
## 修改概述
|
|
||||||
|
|
||||||
为了统一用户身份验证逻辑,我们将所有控制器从继承`ControllerBase`改为继承`BaseController`,并更新了`GetCurrentUserId`的调用方式。
|
|
||||||
|
|
||||||
## 修改内容
|
|
||||||
|
|
||||||
### 1. BaseController.cs
|
|
||||||
|
|
||||||
- 保留原有的`GetCurrentUserIdNullable()`方法(返回`int?`)
|
|
||||||
- 新增`GetCurrentUserId()`方法(返回`int`,未认证时返回0)
|
|
||||||
|
|
||||||
### 2. 修改的控制器(从ControllerBase改为BaseController)
|
|
||||||
|
|
||||||
以下控制器已从继承`ControllerBase`改为继承`BaseController`,并更新了`GetCurrentUserId`的调用方式:
|
|
||||||
|
|
||||||
1. **UsersController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了`GetUser`、`UpdateUser`、`ChangePassword`方法中的用户ID验证逻辑
|
|
||||||
- 移除了私有的`GetCurrentUserId`方法
|
|
||||||
|
|
||||||
2. **MailsController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了所有方法中的用户ID验证逻辑(从`== null`改为`<= 0`)
|
|
||||||
- 移除了服务调用中的`.Value`访问
|
|
||||||
|
|
||||||
3. **UserController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
4. **AIAssistantController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
5. **AIController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
6. **CapsulesController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
7. **NotificationController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
8. **PersonalSpaceController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
9. **StatisticsController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
10. **TimeCapsulesController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
11. **TimelineController.cs**
|
|
||||||
- 继承关系:`ControllerBase` → `BaseController`
|
|
||||||
- 更新了用户ID验证逻辑
|
|
||||||
|
|
||||||
### 3. 已继承BaseController的控制器(无需修改)
|
|
||||||
|
|
||||||
1. **FileUploadController.cs**
|
|
||||||
- 已继承`BaseController`
|
|
||||||
- 已使用正确的`GetCurrentUserId`调用方式
|
|
||||||
|
|
||||||
2. **UploadController.cs**
|
|
||||||
- 已继承`BaseController`
|
|
||||||
- 已使用正确的`GetCurrentUserId`调用方式
|
|
||||||
|
|
||||||
### 4. 不需要身份验证的控制器(保持原样)
|
|
||||||
|
|
||||||
1. **TempFixController.cs**
|
|
||||||
- 不需要身份验证
|
|
||||||
- 继承`ControllerBase`
|
|
||||||
|
|
||||||
2. **OAuthController.cs**
|
|
||||||
- 处理OAuth登录流程,需要匿名访问
|
|
||||||
- 继承`ControllerBase`
|
|
||||||
|
|
||||||
3. **AuthController.cs**
|
|
||||||
- 处理认证流程,需要匿名访问
|
|
||||||
- 继承`ControllerBase`
|
|
||||||
- 保留私有的`GetCurrentUserIdNullable`方法,并重命名为`GetCurrentUserIdNullable`以避免冲突
|
|
||||||
|
|
||||||
## 修改后的用户ID验证逻辑
|
|
||||||
|
|
||||||
### 修改前
|
|
||||||
```csharp
|
|
||||||
var currentUserId = GetCurrentUserId();
|
|
||||||
if (currentUserId == null)
|
|
||||||
{
|
|
||||||
return Unauthorized();
|
|
||||||
}
|
|
||||||
// 使用currentUserId.Value
|
|
||||||
```
|
|
||||||
|
|
||||||
### 修改后
|
|
||||||
```csharp
|
|
||||||
var currentUserId = GetCurrentUserId();
|
|
||||||
if (currentUserId <= 0)
|
|
||||||
{
|
|
||||||
return Unauthorized();
|
|
||||||
}
|
|
||||||
// 直接使用currentUserId
|
|
||||||
```
|
|
||||||
|
|
||||||
## 优势
|
|
||||||
|
|
||||||
1. **代码一致性**:所有控制器使用相同的用户身份验证方法
|
|
||||||
2. **减少重复代码**:移除了各个控制器中重复的`GetCurrentUserId`实现
|
|
||||||
3. **更简洁的API**:`GetCurrentUserId()`返回`int`类型,使用更方便
|
|
||||||
4. **更好的可维护性**:身份验证逻辑集中在`BaseController`中
|
|
||||||
|
|
||||||
## 测试
|
|
||||||
|
|
||||||
API服务已成功启动并运行,没有出现编译错误,说明所有修改都是正确的。
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
19469
FutureMailAPI/obj/Debug/net9.0/project.razor.json
Normal file
19469
FutureMailAPI/obj/Debug/net9.0/project.razor.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1 +1 @@
|
|||||||
{"GlobalPropertiesHash":"1nyXR9zdL54Badakr4zt6ZsTCwUunwdqRSmf7XLLUwI=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["PSBb4S8lcZQPImBE8id7O4eeN8h3whFn6j1jGYFQciQ=","FLPLXKwQVK16UZsWKzZrjH5kq4sMEtCZqAIkpUwa2pU=","/ljuLPXzsWglGr0uHSpqYQARCPlOQrAX6k6LWku0gdQ=","XAE6ulqLzJRH50\u002Bc9Nteizd/x9s3rvSHUFwFL265XX4=","talZRfyIQIv4aZc27HTn01\u002B12VbY6LMFOy3\u002B3r448jo=","8GY2MSzr2E/Yc9xFiAqxn3IhTsjnylxYZUVwMfrW5vw="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
{"GlobalPropertiesHash":"1nyXR9zdL54Badakr4zt6ZsTCwUunwdqRSmf7XLLUwI=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["PSBb4S8lcZQPImBE8id7O4eeN8h3whFn6j1jGYFQciQ=","FLPLXKwQVK16UZsWKzZrjH5kq4sMEtCZqAIkpUwa2pU=","qvO3Mvo7bXJuih7HQYVXFfIR0uMf6fdipVLWW\u002BbFgXY=","XAE6ulqLzJRH50\u002Bc9Nteizd/x9s3rvSHUFwFL265XX4=","talZRfyIQIv4aZc27HTn01\u002B12VbY6LMFOy3\u002B3r448jo=","kyazWY\u002B8n0dtdadKg35ovAVMceUhOAzyYnxEaTobs08="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||||
@@ -1 +1 @@
|
|||||||
{"GlobalPropertiesHash":"hRzLFfhtQD0jC2zNthCXf5A5W0LGZjQdHMs0v5Enof8=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["PSBb4S8lcZQPImBE8id7O4eeN8h3whFn6j1jGYFQciQ=","FLPLXKwQVK16UZsWKzZrjH5kq4sMEtCZqAIkpUwa2pU=","/ljuLPXzsWglGr0uHSpqYQARCPlOQrAX6k6LWku0gdQ=","XAE6ulqLzJRH50\u002Bc9Nteizd/x9s3rvSHUFwFL265XX4=","talZRfyIQIv4aZc27HTn01\u002B12VbY6LMFOy3\u002B3r448jo=","8GY2MSzr2E/Yc9xFiAqxn3IhTsjnylxYZUVwMfrW5vw="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
{"GlobalPropertiesHash":"hRzLFfhtQD0jC2zNthCXf5A5W0LGZjQdHMs0v5Enof8=","FingerprintPatternsHash":"gq3WsqcKBUGTSNle7RKKyXRIwh7M8ccEqOqYvIzoM04=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["PSBb4S8lcZQPImBE8id7O4eeN8h3whFn6j1jGYFQciQ=","FLPLXKwQVK16UZsWKzZrjH5kq4sMEtCZqAIkpUwa2pU=","qvO3Mvo7bXJuih7HQYVXFfIR0uMf6fdipVLWW\u002BbFgXY=","XAE6ulqLzJRH50\u002Bc9Nteizd/x9s3rvSHUFwFL265XX4=","talZRfyIQIv4aZc27HTn01\u002B12VbY6LMFOy3\u002B3r448jo=","kyazWY\u002B8n0dtdadKg35ovAVMceUhOAzyYnxEaTobs08="],"CachedAssets":{},"CachedCopyCandidates":{}}
|
||||||
138
README.md
Normal file
138
README.md
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
# FutureMail API 项目
|
||||||
|
|
||||||
|
这是一个基于.NET Core 9.0的未来邮件系统API,支持创建定时邮件、时光胶囊、AI辅助等功能。
|
||||||
|
|
||||||
|
## 功能特性
|
||||||
|
|
||||||
|
- 用户认证与授权
|
||||||
|
- 创建和管理未来邮件
|
||||||
|
- 时光胶囊可视化
|
||||||
|
- AI写作辅助和情感分析
|
||||||
|
- 个人时间线和统计数据
|
||||||
|
- 文件上传功能
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
- .NET Core 9.0
|
||||||
|
- Entity Framework Core (Code First)
|
||||||
|
- MySQL数据库
|
||||||
|
- JWT身份验证
|
||||||
|
- Swagger API文档
|
||||||
|
- Quartz.NET任务调度
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
### 1. 运行项目
|
||||||
|
|
||||||
|
最简单的方法是使用提供的启动脚本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
start_project.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
这将:
|
||||||
|
- 启动API服务器
|
||||||
|
- 打开Swagger文档页面
|
||||||
|
- 打开API测试页面
|
||||||
|
|
||||||
|
### 2. 手动运行
|
||||||
|
|
||||||
|
如果需要手动运行,请按照以下步骤:
|
||||||
|
|
||||||
|
1. 启动API服务器:
|
||||||
|
```bash
|
||||||
|
cd FutureMailAPI
|
||||||
|
dotnet run
|
||||||
|
```
|
||||||
|
|
||||||
|
2. 访问Swagger文档:
|
||||||
|
```
|
||||||
|
http://localhost:5003/swagger
|
||||||
|
```
|
||||||
|
|
||||||
|
3. 使用API测试页面:
|
||||||
|
```
|
||||||
|
打开 api_test.html 文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## API文档
|
||||||
|
|
||||||
|
详细的API文档请参考:
|
||||||
|
- [API接口文档详细说明.md](./API接口文档详细说明.md)
|
||||||
|
- Swagger交互式文档:http://localhost:5003/swagger
|
||||||
|
|
||||||
|
## 主要接口
|
||||||
|
|
||||||
|
### 认证相关
|
||||||
|
- `POST /api/v1/auth/register` - 用户注册
|
||||||
|
- `POST /api/v1/auth/login` - 用户登录
|
||||||
|
- `POST /api/v1/auth/refresh` - 刷新令牌
|
||||||
|
- `POST /api/v1/auth/logout` - 用户登出
|
||||||
|
|
||||||
|
### 邮件管理
|
||||||
|
- `POST /api/v1/mails/create` - 创建邮件
|
||||||
|
- `GET /api/v1/mails` - 获取邮件列表
|
||||||
|
- `GET /api/v1/mails/{mailId}` - 获取邮件详情
|
||||||
|
- `PUT /api/v1/mails/{mailId}` - 更新邮件
|
||||||
|
- `DELETE /api/v1/mails/{mailId}` - 删除邮件
|
||||||
|
- `POST /api/v1/mails/{mailId}/revoke` - 撤销发送
|
||||||
|
|
||||||
|
### 时光胶囊
|
||||||
|
- `GET /api/v1/capsules` - 获取胶囊视图
|
||||||
|
- `PUT /api/v1/capsules/{capsuleId}/style` - 更新胶囊样式
|
||||||
|
|
||||||
|
### AI助手
|
||||||
|
- `POST /api/v1/ai/writing-assistant` - AI写作辅助
|
||||||
|
- `POST /api/v1/ai/sentiment-analysis` - 情感分析
|
||||||
|
|
||||||
|
### 个人空间
|
||||||
|
- `GET /api/v1/timeline` - 获取时间线
|
||||||
|
- `GET /api/v1/statistics` - 获取统计数据
|
||||||
|
- `GET /api/v1/user/profile` - 获取用户信息
|
||||||
|
|
||||||
|
### 文件上传
|
||||||
|
- `POST /api/v1/upload/attachment` - 上传附件
|
||||||
|
- `POST /api/v1/upload/avatar` - 上传头像
|
||||||
|
|
||||||
|
## 数据库配置
|
||||||
|
|
||||||
|
数据库连接字符串配置在 `appsettings.json` 文件中:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Server=localhost;Database=FutureMailDB;User=root;Password=yourpassword;"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
请根据您的MySQL配置修改连接字符串。
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
FutureMailAPI/
|
||||||
|
├── Controllers/ # API控制器
|
||||||
|
├── DTOs/ # 数据传输对象
|
||||||
|
├── Data/ # 数据模型和上下文
|
||||||
|
├── Helpers/ # 辅助类
|
||||||
|
├── Middleware/ # 中间件
|
||||||
|
├── Services/ # 服务类
|
||||||
|
├── Program.cs # 应用程序入口点
|
||||||
|
└── appsettings.json # 配置文件
|
||||||
|
```
|
||||||
|
|
||||||
|
## 测试
|
||||||
|
|
||||||
|
项目包含一个完整的API测试页面 `api_test.html`,可以测试所有主要API接口。
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. 确保MySQL服务器已安装并运行
|
||||||
|
2. 首次运行时,EF Core会自动创建数据库和表
|
||||||
|
3. JWT密钥应在生产环境中更改为安全的值
|
||||||
|
4. 文件上传功能需要配置适当的存储路径
|
||||||
|
|
||||||
|
## 许可证
|
||||||
|
|
||||||
|
本项目仅供学习和演示使用。
|
||||||
803
api_test.html
Normal file
803
api_test.html
Normal file
@@ -0,0 +1,803 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>FutureMail API 测试</title>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||||
|
max-width: 1200px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
h1, h2 {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
.section {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background-color: #4CAF50;
|
||||||
|
color: white;
|
||||||
|
padding: 10px 15px;
|
||||||
|
margin: 5px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #45a049;
|
||||||
|
}
|
||||||
|
button:disabled {
|
||||||
|
background-color: #cccccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
.result {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
font-family: monospace;
|
||||||
|
max-height: 300px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
background-color: #ffebee;
|
||||||
|
border-color: #f44336;
|
||||||
|
color: #c62828;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
background-color: #e8f5e9;
|
||||||
|
border-color: #4caf50;
|
||||||
|
color: #2e7d32;
|
||||||
|
}
|
||||||
|
input, select, textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
margin: 5px 0;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.form-row {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
.form-row > div {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
.tab {
|
||||||
|
padding: 10px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-bottom: 2px solid transparent;
|
||||||
|
}
|
||||||
|
.tab.active {
|
||||||
|
border-bottom-color: #4CAF50;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.tab-content {
|
||||||
|
display: none;
|
||||||
|
padding: 15px 0;
|
||||||
|
}
|
||||||
|
.tab-content.active {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>FutureMail API 测试</h1>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>认证状态</h2>
|
||||||
|
<div id="auth-status">
|
||||||
|
<p>未登录</p>
|
||||||
|
<button id="login-btn">登录</button>
|
||||||
|
<button id="register-btn">注册</button>
|
||||||
|
<button id="logout-btn" style="display:none;">登出</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tabs">
|
||||||
|
<div class="tab active" data-tab="mails">邮件管理</div>
|
||||||
|
<div class="tab" data-tab="capsules">时光胶囊</div>
|
||||||
|
<div class="tab" data-tab="ai">AI助手</div>
|
||||||
|
<div class="tab" data-tab="personal">个人空间</div>
|
||||||
|
<div class="tab" data-tab="upload">文件上传</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 邮件管理 -->
|
||||||
|
<div id="mails" class="tab-content active">
|
||||||
|
<div class="container">
|
||||||
|
<h2>创建邮件</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-title">标题</label>
|
||||||
|
<input type="text" id="mail-title" placeholder="邮件标题">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-content">内容</label>
|
||||||
|
<textarea id="mail-content" rows="5" placeholder="邮件内容"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-recipient-type">收件人类型</label>
|
||||||
|
<select id="mail-recipient-type">
|
||||||
|
<option value="SELF">自己</option>
|
||||||
|
<option value="SPECIFIC">指定收件人</option>
|
||||||
|
<option value="PUBLIC">公开</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-recipient-email">收件人邮箱</label>
|
||||||
|
<input type="email" id="mail-recipient-email" placeholder="收件人邮箱">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-send-time">发送时间</label>
|
||||||
|
<input type="datetime-local" id="mail-send-time">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-trigger-type">触发类型</label>
|
||||||
|
<select id="mail-trigger-type">
|
||||||
|
<option value="TIME">时间</option>
|
||||||
|
<option value="LOCATION">位置</option>
|
||||||
|
<option value="EVENT">事件</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-capsule-style">胶囊样式</label>
|
||||||
|
<input type="text" id="mail-capsule-style" value="default" placeholder="胶囊样式">
|
||||||
|
</div>
|
||||||
|
<button id="create-mail-btn">创建邮件</button>
|
||||||
|
<div id="create-mail-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取邮件列表</h2>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-list-type">邮件类型</label>
|
||||||
|
<select id="mail-list-type">
|
||||||
|
<option value="SENT">已发送</option>
|
||||||
|
<option value="INBOX">收件箱</option>
|
||||||
|
<option value="DRAFT">草稿</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-list-status">状态筛选</label>
|
||||||
|
<select id="mail-list-status">
|
||||||
|
<option value="">全部</option>
|
||||||
|
<option value="PENDING">待投递</option>
|
||||||
|
<option value="DELIVERING">投递中</option>
|
||||||
|
<option value="DELIVERED">已投递</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="get-mails-btn">获取邮件列表</button>
|
||||||
|
<div id="get-mails-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取邮件详情</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="mail-detail-id">邮件ID</label>
|
||||||
|
<input type="text" id="mail-detail-id" placeholder="邮件ID">
|
||||||
|
</div>
|
||||||
|
<button id="get-mail-detail-btn">获取邮件详情</button>
|
||||||
|
<div id="get-mail-detail-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 时光胶囊 -->
|
||||||
|
<div id="capsules" class="tab-content">
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取时光胶囊视图</h2>
|
||||||
|
<button id="get-capsules-btn">获取胶囊视图</button>
|
||||||
|
<div id="get-capsules-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- AI助手 -->
|
||||||
|
<div id="ai" class="tab-content">
|
||||||
|
<div class="container">
|
||||||
|
<h2>AI写作辅助</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ai-prompt">提示词</label>
|
||||||
|
<textarea id="ai-prompt" rows="3" placeholder="输入您的写作提示"></textarea>
|
||||||
|
</div>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ai-type">辅助类型</label>
|
||||||
|
<select id="ai-type">
|
||||||
|
<option value="OUTLINE">大纲</option>
|
||||||
|
<option value="DRAFT">草稿</option>
|
||||||
|
<option value="COMPLETE">完整</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ai-tone">语气</label>
|
||||||
|
<select id="ai-tone">
|
||||||
|
<option value="FORMAL">正式</option>
|
||||||
|
<option value="CASUAL">随意</option>
|
||||||
|
<option value="EMOTIONAL">情感</option>
|
||||||
|
<option value="INSPIRATIONAL">励志</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="ai-length">长度</label>
|
||||||
|
<select id="ai-length">
|
||||||
|
<option value="SHORT">短</option>
|
||||||
|
<option value="MEDIUM">中</option>
|
||||||
|
<option value="LONG">长</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="ai-writing-btn">AI写作辅助</button>
|
||||||
|
<div id="ai-writing-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>情感分析</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="sentiment-content">待分析内容</label>
|
||||||
|
<textarea id="sentiment-content" rows="5" placeholder="输入待分析的内容"></textarea>
|
||||||
|
</div>
|
||||||
|
<button id="sentiment-analysis-btn">情感分析</button>
|
||||||
|
<div id="sentiment-analysis-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 个人空间 -->
|
||||||
|
<div id="personal" class="tab-content">
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取时间线</h2>
|
||||||
|
<div class="form-row">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="timeline-start-date">开始日期</label>
|
||||||
|
<input type="date" id="timeline-start-date">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="timeline-end-date">结束日期</label>
|
||||||
|
<input type="date" id="timeline-end-date">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="timeline-type">类型</label>
|
||||||
|
<select id="timeline-type">
|
||||||
|
<option value="ALL">全部</option>
|
||||||
|
<option value="SENT">已发送</option>
|
||||||
|
<option value="RECEIVED">已接收</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="get-timeline-btn">获取时间线</button>
|
||||||
|
<div id="get-timeline-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取统计数据</h2>
|
||||||
|
<button id="get-statistics-btn">获取统计数据</button>
|
||||||
|
<div id="get-statistics-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>获取用户信息</h2>
|
||||||
|
<button id="get-profile-btn">获取用户信息</button>
|
||||||
|
<div id="get-profile-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 文件上传 -->
|
||||||
|
<div id="upload" class="tab-content">
|
||||||
|
<div class="container">
|
||||||
|
<h2>上传附件</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="attachment-file">选择文件</label>
|
||||||
|
<input type="file" id="attachment-file">
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="attachment-type">文件类型</label>
|
||||||
|
<select id="attachment-type">
|
||||||
|
<option value="IMAGE">图片</option>
|
||||||
|
<option value="VOICE">语音</option>
|
||||||
|
<option value="VIDEO">视频</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<button id="upload-attachment-btn">上传附件</button>
|
||||||
|
<div id="upload-attachment-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h2>上传头像</h2>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="avatar-file">选择头像文件</label>
|
||||||
|
<input type="file" id="avatar-file">
|
||||||
|
</div>
|
||||||
|
<button id="upload-avatar-btn">上传头像</button>
|
||||||
|
<div id="upload-avatar-result" class="result"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// API基础URL
|
||||||
|
const API_BASE_URL = 'http://localhost:5003/api/v1';
|
||||||
|
|
||||||
|
// 当前JWT令牌
|
||||||
|
let authToken = '';
|
||||||
|
|
||||||
|
// DOM元素
|
||||||
|
const authStatus = document.getElementById('auth-status');
|
||||||
|
const loginBtn = document.getElementById('login-btn');
|
||||||
|
const registerBtn = document.getElementById('register-btn');
|
||||||
|
const logoutBtn = document.getElementById('logout-btn');
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// 从本地存储获取令牌
|
||||||
|
authToken = localStorage.getItem('futuremail_token') || '';
|
||||||
|
updateAuthStatus();
|
||||||
|
|
||||||
|
// 绑定事件
|
||||||
|
loginBtn.addEventListener('click', showLoginDialog);
|
||||||
|
registerBtn.addEventListener('click', showRegisterDialog);
|
||||||
|
logoutBtn.addEventListener('click', logout);
|
||||||
|
|
||||||
|
// 绑定标签页切换
|
||||||
|
document.querySelectorAll('.tab').forEach(tab => {
|
||||||
|
tab.addEventListener('click', function() {
|
||||||
|
const tabName = this.getAttribute('data-tab');
|
||||||
|
switchTab(tabName);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 绑定邮件相关按钮
|
||||||
|
document.getElementById('create-mail-btn').addEventListener('click', createMail);
|
||||||
|
document.getElementById('get-mails-btn').addEventListener('click', getMails);
|
||||||
|
document.getElementById('get-mail-detail-btn').addEventListener('click', getMailDetail);
|
||||||
|
|
||||||
|
// 绑定时光胶囊相关按钮
|
||||||
|
document.getElementById('get-capsules-btn').addEventListener('click', getCapsules);
|
||||||
|
|
||||||
|
// 绑定AI相关按钮
|
||||||
|
document.getElementById('ai-writing-btn').addEventListener('click', aiWritingAssistant);
|
||||||
|
document.getElementById('sentiment-analysis-btn').addEventListener('click', sentimentAnalysis);
|
||||||
|
|
||||||
|
// 绑定个人空间相关按钮
|
||||||
|
document.getElementById('get-timeline-btn').addEventListener('click', getTimeline);
|
||||||
|
document.getElementById('get-statistics-btn').addEventListener('click', getStatistics);
|
||||||
|
document.getElementById('get-profile-btn').addEventListener('click', getProfile);
|
||||||
|
|
||||||
|
// 绑定文件上传相关按钮
|
||||||
|
document.getElementById('upload-attachment-btn').addEventListener('click', uploadAttachment);
|
||||||
|
document.getElementById('upload-avatar-btn').addEventListener('click', uploadAvatar);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新认证状态
|
||||||
|
function updateAuthStatus() {
|
||||||
|
if (authToken) {
|
||||||
|
authStatus.innerHTML = `
|
||||||
|
<p>已登录</p>
|
||||||
|
<button id="logout-btn">登出</button>
|
||||||
|
`;
|
||||||
|
document.getElementById('logout-btn').addEventListener('click', logout);
|
||||||
|
} else {
|
||||||
|
authStatus.innerHTML = `
|
||||||
|
<p>未登录</p>
|
||||||
|
<button id="login-btn">登录</button>
|
||||||
|
<button id="register-btn">注册</button>
|
||||||
|
`;
|
||||||
|
document.getElementById('login-btn').addEventListener('click', showLoginDialog);
|
||||||
|
document.getElementById('register-btn').addEventListener('click', showRegisterDialog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换标签页
|
||||||
|
function switchTab(tabName) {
|
||||||
|
// 更新标签样式
|
||||||
|
document.querySelectorAll('.tab').forEach(tab => {
|
||||||
|
tab.classList.remove('active');
|
||||||
|
});
|
||||||
|
document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
|
||||||
|
|
||||||
|
// 更新内容显示
|
||||||
|
document.querySelectorAll('.tab-content').forEach(content => {
|
||||||
|
content.classList.remove('active');
|
||||||
|
});
|
||||||
|
document.getElementById(tabName).classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示登录对话框
|
||||||
|
function showLoginDialog() {
|
||||||
|
const email = prompt('请输入邮箱:');
|
||||||
|
const password = prompt('请输入密码:');
|
||||||
|
|
||||||
|
if (email && password) {
|
||||||
|
login(email, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示注册对话框
|
||||||
|
function showRegisterDialog() {
|
||||||
|
const username = prompt('请输入用户名:');
|
||||||
|
const email = prompt('请输入邮箱:');
|
||||||
|
const password = prompt('请输入密码:');
|
||||||
|
|
||||||
|
if (username && email && password) {
|
||||||
|
register(username, email, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登录
|
||||||
|
async function login(email, password) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/auth/login`, {
|
||||||
|
email: email,
|
||||||
|
password: password
|
||||||
|
});
|
||||||
|
|
||||||
|
authToken = response.data.data.token;
|
||||||
|
localStorage.setItem('futuremail_token', authToken);
|
||||||
|
updateAuthStatus();
|
||||||
|
showResult('auth-status', '登录成功', 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('auth-status', `登录失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注册
|
||||||
|
async function register(username, email, password) {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/auth/register`, {
|
||||||
|
username: username,
|
||||||
|
email: email,
|
||||||
|
password: password
|
||||||
|
});
|
||||||
|
|
||||||
|
authToken = response.data.data.token;
|
||||||
|
localStorage.setItem('futuremail_token', authToken);
|
||||||
|
updateAuthStatus();
|
||||||
|
showResult('auth-status', '注册成功', 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('auth-status', `注册失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 登出
|
||||||
|
function logout() {
|
||||||
|
authToken = '';
|
||||||
|
localStorage.removeItem('futuremail_token');
|
||||||
|
updateAuthStatus();
|
||||||
|
showResult('auth-status', '已登出', 'success');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建邮件
|
||||||
|
async function createMail() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const title = document.getElementById('mail-title').value;
|
||||||
|
const content = document.getElementById('mail-content').value;
|
||||||
|
const recipientType = document.getElementById('mail-recipient-type').value;
|
||||||
|
const recipientEmail = document.getElementById('mail-recipient-email').value;
|
||||||
|
const sendTime = document.getElementById('mail-send-time').value;
|
||||||
|
const triggerType = document.getElementById('mail-trigger-type').value;
|
||||||
|
const capsuleStyle = document.getElementById('mail-capsule-style').value;
|
||||||
|
|
||||||
|
if (!title || !content || !sendTime) {
|
||||||
|
showResult('create-mail-result', '请填写必填字段', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const mailData = {
|
||||||
|
title: title,
|
||||||
|
content: content,
|
||||||
|
recipientType: recipientType,
|
||||||
|
recipientEmail: recipientEmail || undefined,
|
||||||
|
sendTime: new Date(sendTime).toISOString(),
|
||||||
|
triggerType: triggerType,
|
||||||
|
triggerCondition: {},
|
||||||
|
attachments: [],
|
||||||
|
isEncrypted: false,
|
||||||
|
capsuleStyle: capsuleStyle
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/mails/create`, mailData, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('create-mail-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('create-mail-result', `创建邮件失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取邮件列表
|
||||||
|
async function getMails() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const type = document.getElementById('mail-list-type').value;
|
||||||
|
const status = document.getElementById('mail-list-status').value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let url = `${API_BASE_URL}/mails?type=${type}`;
|
||||||
|
if (status) {
|
||||||
|
url += `&status=${status}`;
|
||||||
|
}
|
||||||
|
url += '&page=1&size=20';
|
||||||
|
|
||||||
|
const response = await axios.get(url, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-mails-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-mails-result', `获取邮件列表失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取邮件详情
|
||||||
|
async function getMailDetail() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const mailId = document.getElementById('mail-detail-id').value;
|
||||||
|
|
||||||
|
if (!mailId) {
|
||||||
|
showResult('get-mail-detail-result', '请输入邮件ID', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${API_BASE_URL}/mails/${mailId}`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-mail-detail-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-mail-detail-result', `获取邮件详情失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取时光胶囊视图
|
||||||
|
async function getCapsules() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${API_BASE_URL}/capsules`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-capsules-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-capsules-result', `获取胶囊视图失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// AI写作辅助
|
||||||
|
async function aiWritingAssistant() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const prompt = document.getElementById('ai-prompt').value;
|
||||||
|
const type = document.getElementById('ai-type').value;
|
||||||
|
const tone = document.getElementById('ai-tone').value;
|
||||||
|
const length = document.getElementById('ai-length').value;
|
||||||
|
|
||||||
|
if (!prompt) {
|
||||||
|
showResult('ai-writing-result', '请输入提示词', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/ai/writing-assistant`, {
|
||||||
|
prompt: prompt,
|
||||||
|
type: type,
|
||||||
|
tone: tone,
|
||||||
|
length: length
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('ai-writing-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('ai-writing-result', `AI写作辅助失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 情感分析
|
||||||
|
async function sentimentAnalysis() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const content = document.getElementById('sentiment-content').value;
|
||||||
|
|
||||||
|
if (!content) {
|
||||||
|
showResult('sentiment-analysis-result', '请输入待分析内容', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/ai/sentiment-analysis`, {
|
||||||
|
content: content
|
||||||
|
}, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`,
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('sentiment-analysis-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('sentiment-analysis-result', `情感分析失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取时间线
|
||||||
|
async function getTimeline() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const startDate = document.getElementById('timeline-start-date').value;
|
||||||
|
const endDate = document.getElementById('timeline-end-date').value;
|
||||||
|
const type = document.getElementById('timeline-type').value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
let url = `${API_BASE_URL}/timeline?type=${type}`;
|
||||||
|
if (startDate) {
|
||||||
|
url += `&startDate=${startDate}`;
|
||||||
|
}
|
||||||
|
if (endDate) {
|
||||||
|
url += `&endDate=${endDate}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await axios.get(url, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-timeline-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-timeline-result', `获取时间线失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取统计数据
|
||||||
|
async function getStatistics() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${API_BASE_URL}/statistics`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-statistics-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-statistics-result', `获取统计数据失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
async function getProfile() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(`${API_BASE_URL}/user/profile`, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('get-profile-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('get-profile-result', `获取用户信息失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传附件
|
||||||
|
async function uploadAttachment() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const fileInput = document.getElementById('attachment-file');
|
||||||
|
const fileType = document.getElementById('attachment-type').value;
|
||||||
|
|
||||||
|
if (!fileInput.files.length) {
|
||||||
|
showResult('upload-attachment-result', '请选择文件', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', fileInput.files[0]);
|
||||||
|
formData.append('type', fileType);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/upload/attachment`, formData, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`,
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('upload-attachment-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('upload-attachment-result', `上传附件失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传头像
|
||||||
|
async function uploadAvatar() {
|
||||||
|
if (!checkAuth()) return;
|
||||||
|
|
||||||
|
const fileInput = document.getElementById('avatar-file');
|
||||||
|
|
||||||
|
if (!fileInput.files.length) {
|
||||||
|
showResult('upload-avatar-result', '请选择头像文件', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append('file', fileInput.files[0]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(`${API_BASE_URL}/upload/avatar`, formData, {
|
||||||
|
headers: {
|
||||||
|
'Authorization': `Bearer ${authToken}`,
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
showResult('upload-avatar-result', JSON.stringify(response.data, null, 2), 'success');
|
||||||
|
} catch (error) {
|
||||||
|
showResult('upload-avatar-result', `上传头像失败: ${error.response?.data?.message || error.message}`, 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查认证状态
|
||||||
|
function checkAuth() {
|
||||||
|
if (!authToken) {
|
||||||
|
showResult('auth-status', '请先登录', 'error');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 显示结果
|
||||||
|
function showResult(elementId, message, type = 'info') {
|
||||||
|
const resultElement = document.getElementById(elementId);
|
||||||
|
resultElement.textContent = message;
|
||||||
|
resultElement.className = `result ${type}`;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
12
start_project.bat
Normal file
12
start_project.bat
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@echo off
|
||||||
|
echo 正在启动FutureMail API服务器...
|
||||||
|
cd /d "%~dp0FutureMailAPI"
|
||||||
|
start "FutureMail API Server" cmd /k "dotnet run"
|
||||||
|
echo API服务器正在启动,请等待几秒钟...
|
||||||
|
timeout /t 5 /nobreak > nul
|
||||||
|
echo 正在打开Swagger文档...
|
||||||
|
start http://localhost:5003/swagger
|
||||||
|
echo 正在打开API测试页面...
|
||||||
|
start "%~dp0api_test.html"
|
||||||
|
echo 完成!
|
||||||
|
pause
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>邮件创建测试</title>
|
|
||||||
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>邮件创建测试</h1>
|
|
||||||
<button onclick="testLogin()">登录</button>
|
|
||||||
<button onclick="testCreateMail()">创建邮件</button>
|
|
||||||
<div id="result"></div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
let authToken = '';
|
|
||||||
|
|
||||||
async function testLogin() {
|
|
||||||
try {
|
|
||||||
const response = await axios.post('http://localhost:5003/api/v1/auth/login', {
|
|
||||||
email: 'test@example.com',
|
|
||||||
password: 'test123'
|
|
||||||
});
|
|
||||||
|
|
||||||
authToken = response.data.data.token;
|
|
||||||
document.getElementById('result').innerHTML = '<pre>登录成功,令牌: ' + authToken + '</pre>';
|
|
||||||
} catch (error) {
|
|
||||||
document.getElementById('result').innerHTML = '<pre>登录失败: ' + JSON.stringify(error.response.data, null, 2) + '</pre>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function testCreateMail() {
|
|
||||||
if (!authToken) {
|
|
||||||
document.getElementById('result').innerHTML = '<pre>请先登录</pre>';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const mailData = {
|
|
||||||
title: "测试邮件标题",
|
|
||||||
content: "这是一封测试邮件的内容",
|
|
||||||
recipientType: "SELF",
|
|
||||||
sendTime: "2026-10-16T08:03:58.479Z",
|
|
||||||
triggerType: "TIME",
|
|
||||||
triggerCondition: {},
|
|
||||||
attachments: [],
|
|
||||||
isEncrypted: false,
|
|
||||||
capsuleStyle: "default"
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axios.post('http://localhost:5003/api/v1/mails/create', mailData, {
|
|
||||||
headers: {
|
|
||||||
'Authorization': 'Bearer ' + authToken,
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('result').innerHTML = '<pre>邮件创建成功: ' + JSON.stringify(response.data, null, 2) + '</pre>';
|
|
||||||
} catch (error) {
|
|
||||||
document.getElementById('result').innerHTML = '<pre>邮件创建失败: ' + JSON.stringify(error.response.data, null, 2) + '</pre>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"title": "测试邮件标题",
|
|
||||||
"content": "这是一封测试邮件的内容",
|
|
||||||
"recipientType": "SELF",
|
|
||||||
"sendTime": "2026-10-16T08:03:58.479Z",
|
|
||||||
"triggerType": "TIME",
|
|
||||||
"triggerCondition": {},
|
|
||||||
"attachments": [],
|
|
||||||
"isEncrypted": false,
|
|
||||||
"capsuleStyle": "default"
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user