Files
mipu-open/docs/11-06_mailbox-mail-search.md
杨柳杰 b450b512a2 init: mipu-open 对外开放项目统一管理仓库
- 添加 mipu-api 作为 git submodule (Claude Code Skill)
- 迁移 API 文档源文件到 docs/ 目录统一维护
- 添加 Gitea Actions 工作流:tag推送自动打包docs并发布Release
- Skill 运行时自动从 mipu-open Release 下载最新文档

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-04 12:16:08 +08:00

401 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- mipuyun-api-doc: mailbox-mail-search -->
# mailbox/mail/search - 搜索邮件
## 概述
根据关键词、邮件类型等条件搜索邮件,返回分页结果。
### 使用场景
- 用户需要在邮箱中查找特定邮件
- 根据关键词、邮件类型等条件筛选邮件
- 分页浏览邮件列表
## 请求说明
| 项目 | 值 |
|------|-----|
| **请求地址** | `https://${endpoint}/mailbox/mail/search` |
| **请求方法** | POST |
### Header 参数
| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 |
|----------|------|----------|--------|------|
| Content-Type | String | 是 | application/json | 固定值,指定请求体格式为 JSON |
| Accept-Encoding | String | 是 | gzip, deflate, br | 必须要填写,否则服务器会拒绝 |
| client-key | String | 是 | xxxxx | 联系我们获取生产环境 key |
| client-secret | String | 是 | xxxxx | 联系我们获取生产环境 secret |
### 请求体参数
| 参数名称 | 类型 | 是否必选 | 示例值 | 说明 |
|----------|------|----------|--------|------|
| keyword | String | 否 | 机票 | 搜索关键词,支持邮件主题、发件人等 |
| mailType | Integer | 否 | 1 | 邮件类型1-收件2-发件 |
| domainName | String | 否 | example.com | 域名过滤 |
| hasAttachment | Boolean | 否 | true | 是否有附件 |
| readStatus | Integer | 否 | 0 | 阅读状态0-未读1-已读 |
| startTime | String | 否 | 2025-01-01T00:00:00Z | 起始时间ISO 8601格式**必须使用UTC时区**,以`Z`结尾) |
| endTime | String | 否 | 2025-01-31T23:59:59Z | 结束时间ISO 8601格式**必须使用UTC时区**,以`Z`结尾) |
| airlineCode | String | 否 | CA | 航空代码CA-国航、MU-东航、CZ-南航等) |
| pageIndex | Integer | 是 | 1 | 页码从1开始 |
| pageSize | Integer | 是 | 20 | 每页数量建议10-50最大100 |
| orderBy | String | 否 | sendTime | 排序字段,支持:`sendTime`(发送时间)、`receiveTime`(接收时间)、`subject`(主题) |
| orderDirection | String | 否 | DESC | 排序方向:`ASC`=升序,`DESC`=降序 |
#### 请求体示例
```json
{
"keyword": "机票",
"mailType": 1,
"airlineCode": "CA",
"pageIndex": 1,
"pageSize": 20,
"orderBy": "sendTime",
"orderDirection": "DESC"
}
```
## 返回参数
返回分页结果 `PageResult<MailInfo>`
| 参数名称 | 类型 | 示例值 | 说明 |
|----------|------|--------|------|
| pageIndex | Integer | 1 | 当前页码 |
| pageSize | Integer | 20 | 每页数量 |
| total | Long | 150 | 总记录数 |
| records | Array\<MailInfo\> | - | 邮件列表 |
> **注意**
> - 请求和响应统一使用 `pageIndex`
> - 总页数 `totalPages` 字段已移除,前端需自行计算:`totalPages = Math.ceil(total / pageSize)`
### MailInfo 对象字段
| 参数名称 | 类型 | 示例值 | 说明 |
|----------|------|--------|------|
| mailId | String | MSG_001 | 邮件ID |
| subject | String | 机票预订确认 | 邮件主题 |
| fromAddress | String | airline@example.com | 发件人地址 |
| toAddresses | String\[\] | ["user@example.com"] | 收件人列表 |
| ccAddresses | String\[\] | ["cc@example.com"] | 抄送列表 |
| mailType | Integer | 1 | 邮件类型1-收件2-发件 |
| mailTypeText | String | 收件 | 类型文本 |
| hasAttachment | Boolean | true | 是否有附件 |
| attachmentCount | Integer | 2 | 附件数量 |
| mailSize | Long | 1024000 | 邮件大小(字节) |
| mailSizeText | String | 1.0 MB | 人性化大小 |
| readStatus | Integer | 0 | 阅读状态0-未读1-已读 |
| receiveTime | String | 2025-01-02T10:00:00Z | 接收时间 |
| sendTime | String | 2025-01-02T10:00:00Z | 发送时间 |
| emlDownloadUrl | String | https://... | 原始EML文件下载地址临时链接1小时有效期 |
## 返回示例
```json
{
"pageIndex": 1,
"pageSize": 20,
"total": 150,
"records": [
{
"mailId": "MSG_001",
"subject": "机票预订确认",
"fromAddress": "airline@example.com",
"toAddresses": ["user@example.com"],
"ccAddresses": ["cc@example.com"],
"mailType": 1,
"mailTypeText": "收件",
"hasAttachment": true,
"attachmentCount": 2,
"mailSize": 1024000,
"mailSizeText": "1.0 MB",
"readStatus": 0,
"receiveTime": "2025-01-02T10:00:00Z",
"sendTime": "2025-01-02T10:00:00Z",
"emlDownloadUrl": "https://cdn.example.com/download/eml/MSG_001?token=xxx"
},
{
"mailId": "MSG_002",
"subject": "航班变更通知",
"fromAddress": "airline@example.com",
"toAddresses": ["user@example.com"],
"ccAddresses": [],
"mailType": 1,
"mailTypeText": "收件",
"hasAttachment": false,
"attachmentCount": 0,
"mailSize": 51200,
"mailSizeText": "50.0 KB",
"readStatus": 1,
"receiveTime": "2025-01-02T09:00:00Z",
"sendTime": "2025-01-02T09:00:00Z",
"emlDownloadUrl": "https://cdn.example.com/download/eml/MSG_002?token=yyy"
}
]
}
```
## 时区说明
### UTC 时区要求
本接口要求所有时间参数**必须使用 UTC 时区**(协调世界时)。
**什么是 UTC**
- UTCCoordinated Universal Time是世界标准时间不受夏令时影响
- UTC 是全球统一的时间基准,与地理位置无关
- 北京时间 = UTC + 8小时纽约时间 = UTC - 5小时东部标准时间
**为什么使用 UTC**
1. **避免时区混淆**:不同地区的服务器和客户端使用不同时区会导致时间解释错误
2. **跨时区一致**:确保全球用户查询结果一致
3. **简化逻辑**:无需处理复杂的时区转换和夏令时问题
**时间格式要求:**
```
ISO 8601 格式2025-01-15T00:00:00Z
^^^^^^^^^^^ ^^^^^^^ ^ ^
日期 时间 时区标识UTC
```
### 时间转换示例
| 本地时间 | UTC 时间(需要发送) | 说明 |
|----------|---------------------|------|
| 2025-01-15 00:00:00 (北京) | 2025-01-14T16:00:00Z | 北京时间 UTC+8减8小时 |
| 2025-01-15 00:00:00 (纽约) | 2025-01-15T05:00:00Z | 纽约时间 UTC-5加5小时 |
| 2025-01-15 00:00:00 (伦敦) | 2025-01-15T00:00:00Z | 伦敦时间 UTC+0冬季 |
| 2025-01-15 00:00:00 (东京) | 2025-01-14T15:00:00Z | 东京时间 UTC+9减9小时 |
> **重要**:发送时间前,请务必将本地时间转换为 UTC 时间!
### 代码示例
#### Java 示例
```java
import java.time.*;
import java.time.format.DateTimeFormatter;
import okhttp3.*;
import com.google.gson.Gson;
public class MailSearchExample {
private static final String API_ENDPOINT = "https://api.example.com/mailbox/mail/search";
private static final String CLIENT_KEY = "your-client-key";
private static final String CLIENT_SECRET = "your-client-secret";
public static void main(String[] args) {
// 方式1: 使用当前时间自动转换为UTC
ZonedDateTime nowUtc = ZonedDateTime.now(ZoneOffset.UTC);
ZonedDateTime oneDayAgoUtc = nowUtc.minusDays(1);
// 方式2: 从本地时间转换到UTC
ZonedDateTime localTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));
ZonedDateTime utcTime = localTime.withZoneSameInstant(ZoneOffset.UTC);
// 方式3: 指定特定时间例如北京时间2025-01-15 00:00:00
ZonedDateTime beijingTime = ZonedDateTime.of(
2025, 1, 15, 0, 0, 0, 0,
ZoneId.of("Asia/Shanghai")
);
ZonedDateTime startTimeUtc = beijingTime.withZoneSameInstant(ZoneOffset.UTC);
ZonedDateTime endTimeUtc = beijingTime.plusDays(1).minusSeconds(1)
.withZoneSameInstant(ZoneOffset.UTC);
// 格式化为ISO 8601格式带Z后缀
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
String startTime = startTimeUtc.format(formatter); // 2025-01-14T16:00:00Z
String endTime = endTimeUtc.format(formatter); // 2025-01-15T15:59:59Z
// 构建请求体
MailSearchRequest request = new MailSearchRequest();
request.setKeyword("机票");
request.setMailType(1);
request.setStartTime(startTime);
request.setEndTime(endTime);
request.setPageIndex(1);
request.setPageSize(20);
// 设置排序(按发送时间降序)
request.setOrderBy("sendTime");
request.setOrderDirection("DESC");
// 发送请求
sendRequest(request);
}
static class MailSearchRequest {
private String keyword;
private Integer mailType;
private String startTime;
private String endTime;
private Integer pageIndex;
private Integer pageSize;
private String orderBy;
private String orderDirection;
// getters and setters...
}
private static void sendRequest(MailSearchRequest request) throws Exception {
Gson gson = new Gson();
String json = gson.toJson(request);
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(
json,
MediaType.parse("application/json; charset=utf-8")
);
Request httpRequest = new Request.Builder()
.url(API_ENDPOINT)
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("Accept-Encoding", "gzip, deflate, br")
.addHeader("client-key", CLIENT_KEY)
.addHeader("client-secret", CLIENT_SECRET)
.build();
try (Response response = client.newCall(httpRequest).execute()) {
System.out.println(response.body().string());
}
}
}
```
#### Python 示例
```python
import requests
from datetime import datetime, timezone, timedelta
from zoneinfo import ZoneInfo # Python 3.9+
import json
API_ENDPOINT = "https://api.example.com/mailbox/mail/search"
CLIENT_KEY = "your-client-key"
CLIENT_SECRET = "your-client-secret"
def search_mails():
# 方式1: 使用当前UTC时间
now_utc = datetime.now(timezone.utc)
one_day_ago_utc = now_utc - timedelta(days=1)
# 方式2: 从本地时间转换到UTC例如北京时间
beijing_tz = ZoneInfo("Asia/Shanghai")
local_time = datetime(2025, 1, 15, 0, 0, 0, tzinfo=beijing_tz)
start_time_utc = local_time.astimezone(timezone.utc)
end_time_utc = (local_time + timedelta(days=1) - timedelta(seconds=1)).astimezone(timezone.utc)
# 方式3: 直接创建UTC时间
start_time_utc = datetime(2025, 1, 14, 16, 0, 0, tzinfo=timezone.utc)
end_time_utc = datetime(2025, 1, 15, 15, 59, 59, tzinfo=timezone.utc)
# 格式化为ISO 8601格式带Z后缀
start_time = start_time_utc.isoformat()
end_time = end_time_utc.isoformat()
# 结果: "2025-01-14T16:00:00+00:00" 或 "2025-01-14T16:00:00Z"
# 确保以Z结尾某些库可能使用+00:00
if not start_time.endswith('Z'):
start_time = start_time.replace('+00:00', 'Z').replace('+00:00:00', 'Z')
if not end_time.endswith('Z'):
end_time = end_time.replace('+00:00', 'Z').replace('+00:00:00', 'Z')
# 构建请求体
payload = {
"keyword": "机票",
"mailType": 1,
"startTime": start_time, # "2025-01-14T16:00:00Z"
"endTime": end_time, # "2025-01-15T15:59:59Z"
"pageIndex": 1,
"pageSize": 20,
"orderBy": "sendTime",
"orderDirection": "DESC"
}
# 发送请求
headers = {
"Content-Type": "application/json",
"Accept-Encoding": "gzip, deflate, br",
"client-key": CLIENT_KEY,
"client-secret": CLIENT_SECRET
}
response = requests.post(
API_ENDPOINT,
data=json.dumps(payload),
headers=headers
)
print(f"Status Code: {response.status_code}")
print(f"Response: {response.json()}")
return response.json()
# 常用时区转换工具函数
def convert_to_utc(local_time_str, local_timezone="Asia/Shanghai"):
"""
将本地时间字符串转换为UTC时间字符串
Args:
local_time_str: 本地时间,如 "2025-01-15 00:00:00"
local_timezone: 本地时区,默认 "Asia/Shanghai"
Returns:
UTC时间字符串"2025-01-14T16:00:00Z"
"""
local_tz = ZoneInfo(local_timezone)
local_dt = datetime.strptime(local_time_str, "%Y-%m-%d %H:%M:%S")
local_dt = local_dt.replace(tzinfo=local_tz)
utc_dt = local_dt.astimezone(timezone.utc)
return utc_dt.isoformat().replace('+00:00', 'Z')
# 使用示例
if __name__ == "__main__":
# 北京时间 2025-01-15 00:00:00 转换为 UTC
utc_time = convert_to_utc("2025-01-15 00:00:00", "Asia/Shanghai")
print(f"UTC Time: {utc_time}") # 输出: 2025-01-14T16:00:00Z
search_mails()
```
#### cURL 示例
```bash
curl -X POST "https://api.example.com/mailbox/mail/search" \
-H "Content-Type: application/json" \
-H "Accept-Encoding: gzip, deflate, br" \
-H "client-key: your-client-key" \
-H "client-secret: your-client-secret" \
-d '{
"keyword": "机票",
"mailType": 1,
"startTime": "2025-01-14T16:00:00Z",
"endTime": "2025-01-15T15:59:59Z",
"pageIndex": 1,
"pageSize": 20,
"orderBy": "sendTime",
"orderDirection": "DESC"
}'
```
## 搜索技巧
- 支持模糊匹配,关键词可以匹配邮件主题和发件人
- mailType 为可选参数,不传则搜索所有类型邮件
- 建议 pageSize 设置为 20-50 以获得最佳性能
- **时间参数必须使用 UTC 时区**,发送前请确保时间已正确转换
## 错误码说明
| 错误码 | 说明 |
|--------|------|
| 400 | 请求参数错误pageIndex、pageSize、orderBy 或 orderDirection 不合法 |
| 401 | 认证失败client-key 或 client-secret 无效 |
| 500 | 服务器内部错误 |