fix: align favorite batch endpoint

This commit is contained in:
richjohnrambo
2026-08-20 23:29:10 +08:00
parent 2b3480fa5f
commit ff616b9c5d
3 changed files with 118 additions and 120 deletions
+40 -36
View File
@@ -42,40 +42,41 @@ type result struct {
} }
type audit struct { type audit struct {
baseURL string baseURL string
wsURL string wsURL string
apiKey string apiKey string
tenantCode string tenantCode string
client *http.Client client *http.Client
results []result results []result
tokenA string tokenA string
userA string userA string
usernameA string usernameA string
phoneA string phoneA string
passA string passA string
tokenB string tokenB string
userB string userB string
usernameB string usernameB string
phoneB string phoneB string
passB string passB string
groupTopic string groupTopic string
groupVer int groupVer int
groupQR string groupQR string
friendReq string friendReq string
p2pTopic string p2pTopic string
meQR string meQR string
meQRPurpose string meQRPurpose string
meetingID string meetingID string
meetingVer int meetingVer int
dailyID string dailyID string
dailyVer int dailyVer int
monthlyID string monthlyID string
monthlyVer int monthlyVer int
actionTok string mailboxNoticeVersion string
abuseReason string actionTok string
profileVer int abuseReason string
privacyVer int profileVer int
feedbackCat string privacyVer int
feedbackCat string
} }
func main() { func main() {
@@ -265,8 +266,11 @@ func (a *audit) run() {
return fmt.Sprintf("report_id=%s version=%d", a.monthlyID, a.monthlyVer) return fmt.Sprintf("report_id=%s version=%d", a.monthlyID, a.monthlyVer)
}) })
a.testHTTP("9", "9.monthly-stats", "月报统计", "GET", "/v1/im/reports/monthly/statistics?month="+month, nil, a.tokenA, false, []int{200}, nil) a.testHTTP("9", "9.monthly-stats", "月报统计", "GET", "/v1/im/reports/monthly/statistics?month="+month, nil, a.tokenA, false, []int{200}, nil)
a.testHTTP("9", "9.mailbox-config", "总经理信箱配置", "GET", "/v1/im/executive-mailbox/config", nil, a.tokenA, false, []int{200}, nil) a.testHTTP("9", "9.mailbox-config", "总经理信箱配置", "GET", "/v1/im/executive-mailbox/config", nil, a.tokenA, false, []int{200}, func(r imResp) string {
a.testHTTP("9", "9.mailbox-submit", "总经理信箱提交", "POST", "/v1/im/executive-mailbox/submissions", map[string]any{"subject": "联调建议", "content": "自动化测试提交", "anonymous": false, "attachment_file_ids": []string{}, "notice_version": "v1"}, a.tokenA, true, []int{200, 400, 403}, nil) a.mailboxNoticeVersion = asString(dig(r.Data, "notice", "version"))
return "notice_version=" + a.mailboxNoticeVersion
})
a.testHTTP("9", "9.mailbox-submit", "总经理信箱提交", "POST", "/v1/im/executive-mailbox/submissions", map[string]any{"subject": "联调建议", "content": "自动化测试提交", "anonymous": false, "attachment_file_ids": []string{}, "notice_version": a.mailboxNoticeVersion}, a.tokenA, true, []int{200, 400, 403}, nil)
a.testHTTP("10", "10.me", "我的账号", "GET", "/v1/im/me", nil, a.tokenA, false, []int{200}, nil) a.testHTTP("10", "10.me", "我的账号", "GET", "/v1/im/me", nil, a.tokenA, false, []int{200}, nil)
a.testHTTP("10", "10.profile", "个人资料", "GET", "/v1/im/me/profile", nil, a.tokenA, false, []int{200}, func(r imResp) string { a.testHTTP("10", "10.profile", "个人资料", "GET", "/v1/im/me/profile", nil, a.tokenA, false, []int{200}, func(r imResp) string {
@@ -3,45 +3,35 @@
## 1. 测试范围 ## 1. 测试范围
- 对照文档:`docs/IM-前后端对接文档.md` - 对照文档:`docs/IM-前后端对接文档.md`
- 测试时间:`2026-08-20 22:59:05 +0800` - 测试时间:`2026-08-20 23:15:31 +0800`
- 测试环境:`https://api.118im.com` - 测试环境:`https://api.118im.com`
- WebSocket:`wss://api.118im.com/v0/channels` - WebSocket:`wss://api.118im.com/v0/channels`
- 租户:`default` - 租户:`default`
- 测试账号 A:`a35758000` / `15535758000` / `usrv5HSlKE-PQk` - 测试账号 A:`a98656000` / `15598656000` / `usr--xhFVUQ8Qs`
- 测试账号 B:`b35758000` / `15635758000` / `usrmHgqblBLy8Q` - 测试账号 B:`b98656000` / `15698656000` / `usrkzrIHX2xBXc`
- API Key 与 Token 已脱敏,不在文档中展开。 - API Key 与 Token 已脱敏,不在文档中展开。
## 2. 总体结论 ## 2. 总体结论
本轮按前后端对接文档从第 1 章到第 11 章直接访问测试环境接口,共执行 `96` 项,符合预期 `85` 项,不符合预期 `11` 项。符合预期不等于业务全链路完全验收;部分接口以 404/405/409/403 作为当前文档标注的未实现、无数据或权限分支记录。 本轮按前后端对接文档从第 1 章到第 11 章直接访问测试环境接口,共执行 `98` 项,符合预期 `97` 项,不符合预期 `1` 项。符合预期不等于业务全链路完全验收;部分接口以 404/405/409/403 作为当前文档标注的未实现、无数据或权限分支记录。
| 章 | 符合预期 | 不符合预期 | | 章 | 符合预期 | 不符合预期 |
| --- | ---: | ---: | | --- | ---: | ---: |
| 1 | 12 | 2 | | 1 | 16 | 0 |
| 2 | 4 | 0 | | 2 | 4 | 0 |
| 3 | 2 | 2 | | 3 | 4 | 0 |
| 4 | 5 | 1 | | 4 | 6 | 0 |
| 5 | 12 | 0 | | 5 | 12 | 0 |
| 6 | 19 | 2 | | 6 | 21 | 0 |
| 7 | 5 | 1 | | 7 | 5 | 1 |
| 8 | 2 | 0 | | 8 | 2 | 0 |
| 9 | 12 | 2 | | 9 | 14 | 0 |
| 10 | 8 | 0 | | 10 | 8 | 0 |
| 11 | 4 | 1 | | 11 | 5 | 0 |
## 3. 需要关注的问题 ## 3. 需要关注的问题
- `1.6a` POST `/v1/im/auth/verification-codes`:HTTP `502`,code `0`,reason ``。未返回 challenge_id
- `1.7a` POST `/v1/im/security/challenges`:HTTP `502`,code `0`,reason ``。challenge_id=
- `3.conv-settings` GET `/v1/im/conversations/p2pv5HSlKE-PQmYeCpuUEvLxA/settings`:HTTP `502`,code `0`,reason ``。
- `3.conv-messages` GET `/v1/im/conversations/p2pv5HSlKE-PQmYeCpuUEvLxA/messages?since=1&limit=20`:HTTP `502`,code `0`,reason ``。
- `4.forward-targets` GET `/v1/im/forward-targets?query=&cursor=`:HTTP `404`,code `0`,reason ``。
- `6.ann-latest` GET `/v1/im/groups/grppe4qw1ad4QQ/announcements/latest`:HTTP `500`,code `90000`,reason `INTERNAL_ERROR`。
- `6.ann-put` PUT `/v1/im/groups/grppe4qw1ad4QQ/announcements/current`:HTTP `500`,code `90000`,reason `INTERNAL_ERROR`。
- `7.favorite-batch` POST `/v1/im/favorites/batch`:HTTP `405`,code `30002`,reason `METHOD_NOT_ALLOWED`。 - `7.favorite-batch` POST `/v1/im/favorites/batch`:HTTP `405`,code `30002`,reason `METHOD_NOT_ALLOWED`。
- `9.mailbox-config` GET `/v1/im/executive-mailbox/config`:HTTP `500`,code `90000`,reason `INTERNAL_ERROR`。
- `9.mailbox-submit` POST `/v1/im/executive-mailbox/submissions`:HTTP `500`,code `90000`,reason `INTERNAL_ERROR`。
- `11.abuse-reasons` GET `/v1/im/reports/abuse/reasons?target_type=user`:HTTP `500`,code `90000`,reason `INTERNAL_ERROR`。reason=
## 4. 分章明细 ## 4. 分章明细
@@ -50,14 +40,16 @@
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `1.1` | 企业码解析 | `POST` | `/v1/im/tenants/resolve` | 200 | `0/` | 通过 | tenant=default endpoints=https://api.118im.com/v1/im | | `1.1` | 企业码解析 | `POST` | `/v1/im/tenants/resolve` | 200 | `0/` | 通过 | tenant=default endpoints=https://api.118im.com/v1/im |
| `1.2A-code` | 注册发码 a35758000 | `POST` | `/v1/im/auth/verification-codes` | 200 | `0/` | 通过 | challenge_id=frGG...cN-C | | `1.2A-code` | 注册发码 a98656000 | `POST` | `/v1/im/auth/verification-codes` | 200 | `0/` | 通过 | challenge_id=CDk2...OJRB |
| `1.2A-verify` | 注册验证码校验 a35758000 | `POST` | `/v1/im/auth/verification-codes/frGGY0QrywDO98cxSmKWcN-C/verify` | 200 | `0/` | 通过 | verification_token=ywPa...iDMI | | `1.2A-verify` | 注册验证码校验 a98656000 | `POST` | `/v1/im/auth/verification-codes/CDk2pfsTzVTcHZ4ToFWLOJRB/verify` | 200 | `0/` | 通过 | verification_token=w4q6...t_xs |
| `1.2A-ws-acc` | WebSocket hi+acc 注册 a35758000 | `WS` | `/v0/channels` | 0 | `0/` | 通过 | user=usrv5HSlKE-PQk token=AwEA...MZw9 | | `1.2A-ws-acc` | WebSocket hi+acc 注册 a98656000 | `WS` | `/v0/channels` | 0 | `0/` | 通过 | user=usr--xhFVUQ8Qs token=AwEA...awQ6 |
| `1.2B-code` | 注册发码 b35758000 | `POST` | `/v1/im/auth/verification-codes` | 200 | `0/` | 通过 | challenge_id=Lg5n...oIsP | | `1.2B-code` | 注册发码 b98656000 | `POST` | `/v1/im/auth/verification-codes` | 200 | `0/` | 通过 | challenge_id=DVmh...ZWZ0 |
| `1.2B-verify` | 注册验证码校验 b35758000 | `POST` | `/v1/im/auth/verification-codes/Lg5nd34yIlk8KIXw0nv0oIsP/verify` | 200 | `0/` | 通过 | verification_token=ZihI...ovI8 | | `1.2B-verify` | 注册验证码校验 b98656000 | `POST` | `/v1/im/auth/verification-codes/DVmh4897_KsYDoIdof9aZWZ0/verify` | 200 | `0/` | 通过 | verification_token=Vyvk...sGBg |
| `1.2B-ws-acc` | WebSocket hi+acc 注册 b35758000 | `WS` | `/v0/channels` | 0 | `0/` | 通过 | user=usrmHgqblBLy8Q token=AwEA...9zCX | | `1.2B-ws-acc` | WebSocket hi+acc 注册 b98656000 | `WS` | `/v0/channels` | 0 | `0/` | 通过 | user=usrkzrIHX2xBXc token=AwEA...gsYR |
| `1.6a` | 忘记密码发码 | `POST` | `/v1/im/auth/verification-codes` | 502 | `0/` | 未通过 | 未返回 challenge_id | | `1.6b` | 忘记密码验证码校验 | `POST` | `/v1/im/auth/password-reset/challenges/XOuAkUsIQgDsddmRSmaigs12/verify` | 200 | `0/` | 通过 | reset_token=XOuA...BSvE |
| `1.7a` | 二次身份验证发起 | `POST` | `/v1/im/security/challenges` | 502 | `0/` | 未通过 | challenge_id= | | `1.6a` | 忘记密码发码 | `POST` | `/v1/im/auth/verification-codes` | 200 | `0/` | 通过 | challenge_id=XOuA...gs12 |
| `1.7b` | 二次身份验证码校验 | `POST` | `/v1/im/security/challenges/PapKGWb1YkgkoM2GOISkhWrF/verify` | 200 | `0/` | 通过 | action_token=_udB...ddt4 |
| `1.7a` | 二次身份验证发起 | `POST` | `/v1/im/security/challenges` | 200 | `0/` | 通过 | challenge_id=PapK...hWrF |
| `1.8` | 实名状态查询 | `GET` | `/v1/im/security/realname` | 200 | `0/` | 通过 | | | `1.8` | 实名状态查询 | `GET` | `/v1/im/security/realname` | 200 | `0/` | 通过 | |
| `1.8-submit` | 实名提交 | `POST` | `/v1/im/security/realname/submissions` | 200 | `0/` | 通过 | | | `1.8-submit` | 实名提交 | `POST` | `/v1/im/security/realname/submissions` | 200 | `0/` | 通过 | |
| `1.11` | 设置独立密码 | `POST` | `/v1/im/settings/independent-password` | 400 | `30040/PASSWORD_POLICY_VIOLATION` | 通过 | | | `1.11` | 设置独立密码 | `POST` | `/v1/im/settings/independent-password` | 400 | `30040/PASSWORD_POLICY_VIOLATION` | 通过 | |
@@ -68,7 +60,7 @@
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `2.1` | Bootstrap | `GET` | `/v1/im/bootstrap` | 200 | `0/` | 通过 | entries=true limits=false | | `2.1` | Bootstrap | `GET` | `/v1/im/bootstrap` | 200 | `0/` | 通过 | entries=true limits=true |
| `2.search` | 会话搜索 | `GET` | `/v1/im/search/conversations?q=&cursor=` | 200 | `0/` | 通过 | | | `2.search` | 会话搜索 | `GET` | `/v1/im/search/conversations?q=&cursor=` | 200 | `0/` | 通过 | |
| `2.sys` | 系统通知列表 | `GET` | `/v1/im/system-notifications?limit=20` | 200 | `0/` | 通过 | | | `2.sys` | 系统通知列表 | `GET` | `/v1/im/system-notifications?limit=20` | 200 | `0/` | 通过 | |
| `2.sys-read` | 系统通知已读不存在 ID | `POST` | `/v1/im/system-notifications/nonexistent/read` | 404 | `30044/CHALLENGE_EXPIRED` | 通过 | | | `2.sys-read` | 系统通知已读不存在 ID | `POST` | `/v1/im/system-notifications/nonexistent/read` | 404 | `30044/CHALLENGE_EXPIRED` | 通过 | |
@@ -77,64 +69,64 @@
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `3.context` | P2P 会话上下文 | `GET` | `/v1/im/conversations/p2pv5HSlKE-PQmYeCpuUEvLxA/context` | 200 | `0/` | 通过 | | | `3.context` | P2P 会话上下文 | `GET` | `/v1/im/conversations/p2p--xhFVUQ8QuTOsgdfbEFdw/context` | 200 | `0/` | 通过 | |
| `3.p2p-create` | 创建 P2P 会话目标接口 | `POST` | `/v1/im/conversations/p2p` | 405 | `30002/METHOD_NOT_ALLOWED` | 通过 | | | `3.p2p-create` | 创建 P2P 会话目标接口 | `POST` | `/v1/im/conversations/p2p` | 405 | `30002/METHOD_NOT_ALLOWED` | 通过 | |
| `3.conv-settings` | 会话设置查询 | `GET` | `/v1/im/conversations/p2pv5HSlKE-PQmYeCpuUEvLxA/settings` | 502 | `0/` | 未通过 | | | `3.conv-settings` | 会话设置查询 | `GET` | `/v1/im/conversations/p2p--xhFVUQ8QuTOsgdfbEFdw/settings` | 200 | `0/` | 通过 | |
| `3.conv-messages` | 会话消息列表 | `GET` | `/v1/im/conversations/p2pv5HSlKE-PQmYeCpuUEvLxA/messages?since=1&limit=20` | 502 | `0/` | 未通过 | | | `3.conv-messages` | 会话消息列表 | `GET` | `/v1/im/conversations/p2p--xhFVUQ8QuTOsgdfbEFdw/messages?since=1&limit=20` | 200 | `0/` | 通过 | |
### 第 4 章 ### 第 4 章
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `4.forward-targets` | 转发目标列表 | `GET` | `/v1/im/forward-targets?query=&cursor=` | 404 | `0/` | 未通过 | | | `4.forward-targets` | 转发目标列表 | `GET` | `/v1/im/forward-targets?query=&cursor=` | 200 | `0/` | 通过 | |
| `4.forward` | 消息逐条转发 | `POST` | `/v1/im/messages/forward` | 404 | `0/` | 通过 | | | `4.forward` | 消息逐条转发 | `POST` | `/v1/im/messages/forward` | 404 | `0/` | 通过 | |
| `4.bundle` | 合并转发详情 | `GET` | `/v1/im/forward-bundles/fbundle_missing?cursor=` | 404 | `0/` | 通过 | | | `4.bundle` | 合并转发详情 | `GET` | `/v1/im/forward-bundles/fbundle_missing?cursor=` | 404 | `0/` | 通过 | |
| `4.recall` | 消息撤回不存在 seq | `POST` | `/v1/im/topics/p2pv5HSlKE-PQmYeCpuUEvLxA/messages/1/recall` | 404 | `30004/MALFORMED_REQUEST` | 通过 | | | `4.recall` | 消息撤回不存在 seq | `POST` | `/v1/im/topics/p2p--xhFVUQ8QuTOsgdfbEFdw/messages/1/recall` | 404 | `30004/MALFORMED_REQUEST` | 通过 | |
| `4.revision` | 消息编辑不存在 seq | `POST` | `/v1/im/topics/p2pv5HSlKE-PQmYeCpuUEvLxA/messages/1/revisions` | 404 | `30004/MALFORMED_REQUEST` | 通过 | | | `4.revision` | 消息编辑不存在 seq | `POST` | `/v1/im/topics/p2p--xhFVUQ8QuTOsgdfbEFdw/messages/1/revisions` | 404 | `30004/MALFORMED_REQUEST` | 通过 | |
| `4.receipts` | 消息回执查询 | `GET` | `/v1/im/topics/p2pv5HSlKE-PQmYeCpuUEvLxA/messages/1/receipts?cursor=` | 200 | `0/` | 通过 | | | `4.receipts` | 消息回执查询 | `GET` | `/v1/im/topics/p2p--xhFVUQ8QuTOsgdfbEFdw/messages/1/receipts?cursor=` | 200 | `0/` | 通过 | |
### 第 5 章 ### 第 5 章
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `5.search` | 用户搜索 B | `GET` | `/v1/im/users/search?q=b35758000&type=account&cursor=` | 200 | `0/` | 通过 | | | `5.search` | 用户搜索 B | `GET` | `/v1/im/users/search?q=b98656000&type=account&cursor=` | 200 | `0/` | 通过 | |
| `5.profile` | 查看 B 资料 | `GET` | `/v1/im/users/b35758000/profile` | 403 | `30005/PERMISSION_DENIED` | 通过 | | | `5.profile` | 查看 B 资料 | `GET` | `/v1/im/users/b98656000/profile` | 403 | `30005/PERMISSION_DENIED` | 通过 | |
| `5.user-qr` | 查看 B 加好友二维码 | `POST` | `/v1/im/users/b35758000/qrcodes` | 403 | `30005/PERMISSION_DENIED` | 通过 | | | `5.user-qr` | 查看 B 加好友二维码 | `POST` | `/v1/im/users/b98656000/qrcodes` | 403 | `30005/PERMISSION_DENIED` | 通过 | |
| `5.friend-create` | 创建好友申请 A->B | `POST` | `/v1/im/friend-requests` | 200 | `0/` | 通过 | request_id=frq_Z8SqjqK1iNg | | `5.friend-create` | 创建好友申请 A->B | `POST` | `/v1/im/friend-requests` | 200 | `0/` | 通过 | request_id=frq_4BCvvh7aJaQ |
| `5.friend-accept` | B 同意好友申请 | `POST` | `/v1/im/friend-requests/frq_Z8SqjqK1iNg/accept` | 200 | `0/` | 通过 | topic=p2pv5HSlKE-PQmYeCpuUEvLxA | | `5.friend-accept` | B 同意好友申请 | `POST` | `/v1/im/friend-requests/frq_4BCvvh7aJaQ/accept` | 200 | `0/` | 通过 | topic=p2p--xhFVUQ8QuTOsgdfbEFdw |
| `5.friends` | 好友列表 | `GET` | `/v1/im/friends?query=&initial=&cursor=` | 200 | `0/` | 通过 | | | `5.friends` | 好友列表 | `GET` | `/v1/im/friends?query=&initial=&cursor=` | 200 | `0/` | 通过 | |
| `5.requests` | 好友申请列表 | `GET` | `/v1/im/friend-requests?direction=inbound&status=all&cursor=` | 200 | `0/` | 通过 | | | `5.requests` | 好友申请列表 | `GET` | `/v1/im/friend-requests?direction=inbound&status=all&cursor=` | 200 | `0/` | 通过 | |
| `5.blocks` | 黑名单列表 | `GET` | `/v1/im/blocks?cursor=` | 200 | `0/` | 通过 | | | `5.blocks` | 黑名单列表 | `GET` | `/v1/im/blocks?cursor=` | 200 | `0/` | 通过 | |
| `5.block-put` | 拉黑 B | `PUT` | `/v1/im/blocks/usrmHgqblBLy8Q` | 200 | `0/` | 通过 | | | `5.block-put` | 拉黑 B | `PUT` | `/v1/im/blocks/usrkzrIHX2xBXc` | 200 | `0/` | 通过 | |
| `5.block-del` | 解除拉黑 B | `DELETE` | `/v1/im/blocks/usrmHgqblBLy8Q` | 200 | `0/` | 通过 | | | `5.block-del` | 解除拉黑 B | `DELETE` | `/v1/im/blocks/usrkzrIHX2xBXc` | 200 | `0/` | 通过 | |
| `5.me-qr` | 我的二维码 | `POST` | `/v1/im/me/qrcodes` | 200 | `0/` | 通过 | qr_token=eyJ2...umSY | | `5.me-qr` | 我的二维码 | `POST` | `/v1/im/me/qrcodes` | 200 | `0/` | 通过 | qr_token=eyJ2...J5N8 |
| `5.qr-resolve` | 二维码解析 | `POST` | `/v1/im/qrcodes/resolve` | 200 | `0/` | 通过 | | | `5.qr-resolve` | 二维码解析 | `POST` | `/v1/im/qrcodes/resolve` | 200 | `0/` | 通过 | |
### 第 6 章 ### 第 6 章
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `6.create` | 创建群 | `POST` | `/v1/im/groups` | 200 | `0/` | 通过 | topic=grppe4qw1ad4QQ version=1 | | `6.create` | 创建群 | `POST` | `/v1/im/groups` | 200 | `0/` | 通过 | topic=grp4ch145Ku80k version=1 |
| `6.list` | 群列表 | `GET` | `/v1/im/groups?category=owned&query=&cursor=` | 200 | `0/` | 通过 | | | `6.list` | 群列表 | `GET` | `/v1/im/groups?category=owned&query=&cursor=` | 200 | `0/` | 通过 | |
| `6.detail` | 群详情 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ` | 200 | `0/` | 通过 | | | `6.detail` | 群详情 | `GET` | `/v1/im/groups/grp4ch145Ku80k` | 200 | `0/` | 通过 | |
| `6.patch` | 更新群资料 | `PATCH` | `/v1/im/groups/grppe4qw1ad4QQ` | 200 | `0/` | 通过 | version=2 | | `6.patch` | 更新群资料 | `PATCH` | `/v1/im/groups/grp4ch145Ku80k` | 200 | `0/` | 通过 | version=2 |
| `6.settings` | 群设置 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/settings` | 200 | `0/` | 通过 | | | `6.settings` | 群设置 | `GET` | `/v1/im/groups/grp4ch145Ku80k/settings` | 200 | `0/` | 通过 | |
| `6.member-settings` | 群个人设置 | `PATCH` | `/v1/im/groups/grppe4qw1ad4QQ/member-settings` | 200 | `0/` | 通过 | | | `6.member-settings` | 群个人设置 | `PATCH` | `/v1/im/groups/grp4ch145Ku80k/member-settings` | 200 | `0/` | 通过 | |
| `6.my-profile` | 群内昵称 | `PUT` | `/v1/im/groups/grppe4qw1ad4QQ/members/me/profile` | 409 | `20009/VERSION_CONFLICT` | 通过 | | | `6.my-profile` | 群内昵称 | `PUT` | `/v1/im/groups/grp4ch145Ku80k/members/me/profile` | 409 | `20009/VERSION_CONFLICT` | 通过 | |
| `6.members` | 群成员 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/members?query=&cursor=&mentionable=true` | 200 | `0/` | 通过 | | | `6.members` | 群成员 | `GET` | `/v1/im/groups/grp4ch145Ku80k/members?query=&cursor=&mentionable=true` | 200 | `0/` | 通过 | |
| `6.member-profile` | 群成员资料 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/members/usrmHgqblBLy8Q/profile` | 200 | `0/` | 通过 | | | `6.member-profile` | 群成员资料 | `GET` | `/v1/im/groups/grp4ch145Ku80k/members/usrkzrIHX2xBXc/profile` | 200 | `0/` | 通过 | |
| `6.qrcode` | 群二维码 | `POST` | `/v1/im/groups/grppe4qw1ad4QQ/qrcodes` | 200 | `0/` | 通过 | qr_token=eyJ2...Kzjo | | `6.qrcode` | 群二维码 | `POST` | `/v1/im/groups/grp4ch145Ku80k/qrcodes` | 200 | `0/` | 通过 | qr_token=eyJ2...cq2U |
| `6.invite` | 群邀请 | `POST` | `/v1/im/groups/grppe4qw1ad4QQ/invitations` | 200 | `0/` | 通过 | | | `6.invite` | 群邀请 | `POST` | `/v1/im/groups/grp4ch145Ku80k/invitations` | 200 | `0/` | 通过 | |
| `6.join-requests` | 入群申请列表 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/join-requests?status=pending&cursor=` | 200 | `0/` | 通过 | | | `6.join-requests` | 入群申请列表 | `GET` | `/v1/im/groups/grp4ch145Ku80k/join-requests?status=pending&cursor=` | 200 | `0/` | 通过 | |
| `6.summary` | 群概要 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/summary` | 200 | `0/` | 通过 | | | `6.summary` | 群概要 | `GET` | `/v1/im/groups/grp4ch145Ku80k/summary` | 200 | `0/` | 通过 | |
| `6.ann-latest` | 群公告最新 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/announcements/latest` | 500 | `90000/INTERNAL_ERROR` | 未通过 | | | `6.ann-latest` | 群公告最新 | `GET` | `/v1/im/groups/grp4ch145Ku80k/announcements/latest` | 200 | `0/` | 通过 | |
| `6.ann-put` | 发布群公告 | `PUT` | `/v1/im/groups/grppe4qw1ad4QQ/announcements/current` | 500 | `90000/INTERNAL_ERROR` | 未通过 | | | `6.ann-put` | 发布群公告 | `PUT` | `/v1/im/groups/grp4ch145Ku80k/announcements/current` | 200 | `0/` | 通过 | |
| `6.governance` | 群治理配置 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/governance` | 200 | `0/` | 通过 | | | `6.governance` | 群治理配置 | `GET` | `/v1/im/groups/grp4ch145Ku80k/governance` | 200 | `0/` | 通过 | |
| `6.governance-patch` | 更新群治理配置 | `PATCH` | `/v1/im/groups/grppe4qw1ad4QQ/governance` | 409 | `20009/VERSION_CONFLICT` | 通过 | | | `6.governance-patch` | 更新群治理配置 | `PATCH` | `/v1/im/groups/grp4ch145Ku80k/governance` | 409 | `20009/VERSION_CONFLICT` | 通过 | |
| `6.role-limits` | 管理员数量限制 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/role-limits` | 200 | `0/` | 通过 | | | `6.role-limits` | 管理员数量限制 | `GET` | `/v1/im/groups/grp4ch145Ku80k/role-limits` | 200 | `0/` | 通过 | |
| `6.admins` | 管理员列表 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/members?role=admin&cursor=` | 200 | `0/` | 通过 | | | `6.admins` | 管理员列表 | `GET` | `/v1/im/groups/grp4ch145Ku80k/members?role=admin&cursor=` | 200 | `0/` | 通过 | |
| `6.mutes` | 禁言列表 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/mutes?cursor=` | 200 | `0/` | 通过 | | | `6.mutes` | 禁言列表 | `GET` | `/v1/im/groups/grp4ch145Ku80k/mutes?cursor=` | 200 | `0/` | 通过 | |
| `6.files` | 群文件列表 | `GET` | `/v1/im/groups/grppe4qw1ad4QQ/files?query=&type=&cursor=` | 200 | `0/` | 通过 | | | `6.files` | 群文件列表 | `GET` | `/v1/im/groups/grp4ch145Ku80k/files?query=&type=&cursor=` | 404 | `30004/MALFORMED_REQUEST` | 通过 | |
### 第 7 章 ### 第 7 章
@@ -142,9 +134,9 @@
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `7.favorites` | 收藏列表 | `GET` | `/v1/im/favorites?type=all&q=&cursor=` | 200 | `0/` | 通过 | | | `7.favorites` | 收藏列表 | `GET` | `/v1/im/favorites?type=all&q=&cursor=` | 200 | `0/` | 通过 | |
| `7.favorite-batch` | 批量收藏不存在消息 | `POST` | `/v1/im/favorites/batch` | 405 | `30002/METHOD_NOT_ALLOWED` | 未通过 | | | `7.favorite-batch` | 批量收藏不存在消息 | `POST` | `/v1/im/favorites/batch` | 405 | `30002/METHOD_NOT_ALLOWED` | 未通过 | |
| `7.message-search` | 聊天记录搜索 | `GET` | `/v1/im/topics/grppe4qw1ad4QQ/messages/search?q=%E8%81%94%E8%B0%83&type=text&cursor=` | 200 | `0/` | 通过 | | | `7.message-search` | 聊天记录搜索 | `GET` | `/v1/im/topics/grp4ch145Ku80k/messages/search?q=%E8%81%94%E8%B0%83&type=text&cursor=` | 200 | `0/` | 通过 | |
| `7.media` | 会话媒体列表 | `GET` | `/v1/im/topics/grppe4qw1ad4QQ/media?type=image&cursor=` | 200 | `0/` | 通过 | | | `7.media` | 会话媒体列表 | `GET` | `/v1/im/topics/grp4ch145Ku80k/media?type=image&cursor=` | 200 | `0/` | 通过 | |
| `7.msg-context` | 消息上下文 | `GET` | `/v1/im/topics/grppe4qw1ad4QQ/messages/1/context?before=20&after=20` | 200 | `0/` | 通过 | | | `7.msg-context` | 消息上下文 | `GET` | `/v1/im/topics/grp4ch145Ku80k/messages/1/context?before=20&after=20` | 200 | `0/` | 通过 | |
| `7.file-download` | 文件下载不存在文件 | `GET` | `/v0/file/s/nonexistent` | 400 | `0/` | 通过 | | | `7.file-download` | 文件下载不存在文件 | `GET` | `/v0/file/s/nonexistent` | 400 | `0/` | 通过 | |
### 第 8 章 ### 第 8 章
@@ -152,7 +144,7 @@
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `8.calls` | 通话记录列表 | `GET` | `/v1/im/calls?limit=5` | 200 | `0/` | 通过 | | | `8.calls` | 通话记录列表 | `GET` | `/v1/im/calls?limit=5` | 200 | `0/` | 通过 | |
| `8.topic-calls` | 会话通话记录 | `GET` | `/v1/im/topics/p2pv5HSlKE-PQmYeCpuUEvLxA/calls?limit=5` | 200 | `0/` | 通过 | | | `8.topic-calls` | 会话通话记录 | `GET` | `/v1/im/topics/p2p--xhFVUQ8QuTOsgdfbEFdw/calls?limit=5` | 200 | `0/` | 通过 | |
### 第 9 章 ### 第 9 章
@@ -161,17 +153,17 @@
| `9.workbench` | 工作台 | `GET` | `/v1/im/workbench` | 200 | `0/` | 通过 | | | `9.workbench` | 工作台 | `GET` | `/v1/im/workbench` | 200 | `0/` | 通过 | |
| `9.depts` | 组织部门 | `GET` | `/v1/im/organization/departments?parent_id=&cursor=` | 200 | `0/` | 通过 | | | `9.depts` | 组织部门 | `GET` | `/v1/im/organization/departments?parent_id=&cursor=` | 200 | `0/` | 通过 | |
| `9.org-search-empty` | 组织空关键词搜索 | `GET` | `/v1/im/organization/search?q=` | 400 | `30000/MALFORMED_REQUEST` | 通过 | | | `9.org-search-empty` | 组织空关键词搜索 | `GET` | `/v1/im/organization/search?q=` | 400 | `30000/MALFORMED_REQUEST` | 通过 | |
| `9.meeting-create` | 创建会议 | `POST` | `/v1/im/meetings` | 200 | `0/` | 通过 | meeting_id=mtg_RAAFy893M5I9Ikt_ version=1 | | `9.meeting-create` | 创建会议 | `POST` | `/v1/im/meetings` | 200 | `0/` | 通过 | meeting_id=mtg_FMdvsdTBSc8mAUiB version=1 |
| `9.meeting-list` | 会议列表 | `GET` | `/v1/im/meetings?limit=5` | 405 | `30002/METHOD_NOT_ALLOWED` | 通过 | | | `9.meeting-list` | 会议列表 | `GET` | `/v1/im/meetings?limit=5` | 405 | `30002/METHOD_NOT_ALLOWED` | 通过 | |
| `9.meeting-get` | 会议详情 | `GET` | `/v1/im/meetings/mtg_RAAFy893M5I9Ikt_` | 200 | `0/` | 通过 | | | `9.meeting-get` | 会议详情 | `GET` | `/v1/im/meetings/mtg_FMdvsdTBSc8mAUiB` | 200 | `0/` | 通过 | |
| `9.daily-list` | 日报列表 | `GET` | `/v1/im/reports/daily?limit=5` | 200 | `0/` | 通过 | | | `9.daily-list` | 日报列表 | `GET` | `/v1/im/reports/daily?limit=5` | 200 | `0/` | 通过 | |
| `9.daily-create` | 创建日报草稿 | `POST` | `/v1/im/reports/daily` | 200 | `0/` | 通过 | report_id=dr_YKKH30euBrcDvopX version=1 | | `9.daily-create` | 创建日报草稿 | `POST` | `/v1/im/reports/daily` | 200 | `0/` | 通过 | report_id=dr_akcU6KDAcH9g9nwJ version=1 |
| `9.daily-stats` | 日报统计 | `GET` | `/v1/im/reports/daily/statistics?date=2026-08-20` | 200 | `0/` | 通过 | | | `9.daily-stats` | 日报统计 | `GET` | `/v1/im/reports/daily/statistics?date=2026-08-20` | 200 | `0/` | 通过 | |
| `9.monthly-list` | 月报列表 | `GET` | `/v1/im/reports/monthly?limit=5` | 200 | `0/` | 通过 | | | `9.monthly-list` | 月报列表 | `GET` | `/v1/im/reports/monthly?limit=5` | 200 | `0/` | 通过 | |
| `9.monthly-create` | 创建月报草稿 | `POST` | `/v1/im/reports/monthly` | 200 | `0/` | 通过 | report_id=mr_psOsrZzBuyiGhjZP version=1 | | `9.monthly-create` | 创建月报草稿 | `POST` | `/v1/im/reports/monthly` | 200 | `0/` | 通过 | report_id=mr_iULR69u4Y8_IbXMg version=1 |
| `9.monthly-stats` | 月报统计 | `GET` | `/v1/im/reports/monthly/statistics?month=2026-08` | 200 | `0/` | 通过 | | | `9.monthly-stats` | 月报统计 | `GET` | `/v1/im/reports/monthly/statistics?month=2026-08` | 200 | `0/` | 通过 | |
| `9.mailbox-config` | 总经理信箱配置 | `GET` | `/v1/im/executive-mailbox/config` | 500 | `90000/INTERNAL_ERROR` | 未通过 | | | `9.mailbox-config` | 总经理信箱配置 | `GET` | `/v1/im/executive-mailbox/config` | 200 | `0/` | 通过 | notice_version=2026-08-13T15:04:31.004Z |
| `9.mailbox-submit` | 总经理信箱提交 | `POST` | `/v1/im/executive-mailbox/submissions` | 500 | `90000/INTERNAL_ERROR` | 未通过 | | | `9.mailbox-submit` | 总经理信箱提交 | `POST` | `/v1/im/executive-mailbox/submissions` | 200 | `0/` | 通过 | |
### 第 10 章 ### 第 10 章
@@ -184,27 +176,27 @@
| `10.privacy-patch` | 更新隐私设置 | `PATCH` | `/v1/im/me/privacy` | 200 | `0/` | 通过 | | | `10.privacy-patch` | 更新隐私设置 | `PATCH` | `/v1/im/me/privacy` | 200 | `0/` | 通过 | |
| `10.youth` | 青少年模式 | `GET` | `/v1/im/settings/youth-mode` | 200 | `0/` | 通过 | | | `10.youth` | 青少年模式 | `GET` | `/v1/im/settings/youth-mode` | 200 | `0/` | 通过 | |
| `10.independent-verify` | 独立密码验证 | `POST` | `/v1/im/settings/independent-password/verify` | 403 | `30042/ACTION_TOKEN_INVALID` | 通过 | | | `10.independent-verify` | 独立密码验证 | `POST` | `/v1/im/settings/independent-password/verify` | 403 | `30042/ACTION_TOKEN_INVALID` | 通过 | |
| `10.push` | 设备 Push Token | `PUT` | `/v1/im/devices/audit-device-35758000/push-token` | 200 | `0/` | 通过 | | | `10.push` | 设备 Push Token | `PUT` | `/v1/im/devices/audit-device-98656000/push-token` | 200 | `0/` | 通过 | |
### 第 11 章 ### 第 11 章
| ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 | | ID | 场景 | 方法 | 路径 | HTTP | code/reason | 结果 | 备注 |
| --- | --- | --- | --- | ---: | --- | --- | --- | | --- | --- | --- | --- | ---: | --- | --- | --- |
| `11.url` | URL 风险检查 | `POST` | `/v1/im/security/urls/check` | 200 | `0/` | 通过 | | | `11.url` | URL 风险检查 | `POST` | `/v1/im/security/urls/check` | 200 | `0/` | 通过 | |
| `11.abuse-reasons` | 举报原因 | `GET` | `/v1/im/reports/abuse/reasons?target_type=user` | 500 | `90000/INTERNAL_ERROR` | 未通过 | reason= | | `11.abuse-reasons` | 举报原因 | `GET` | `/v1/im/reports/abuse/reasons?target_type=user` | 200 | `0/` | 通过 | reason=fraud |
| `11.abuse-submit` | 提交举报 | `POST` | `/v1/im/reports/abuse` | 400 | `30000/MALFORMED_REQUEST` | 通过 | | | `11.abuse-submit` | 提交举报 | `POST` | `/v1/im/reports/abuse` | 400 | `30000/MALFORMED_REQUEST` | 通过 | |
| `11.feedback-config` | 反馈配置 | `GET` | `/v1/im/feedback/config` | 200 | `0/` | 通过 | category=bug | | `11.feedback-config` | 反馈配置 | `GET` | `/v1/im/feedback/config` | 200 | `0/` | 通过 | category=bug |
| `11.feedback` | 提交反馈 | `POST` | `/v1/im/feedback` | 200 | `0/` | 通过 | | | `11.feedback` | 提交反馈 | `POST` | `/v1/im/feedback` | 200 | `0/` | 通过 | |
## 5. 测试产生的数据 ## 5. 测试产生的数据
- 用户 A:`usrv5HSlKE-PQk`,username `a35758000`,phone `15535758000` - 用户 A:`usr--xhFVUQ8Qs`,username `a98656000`,phone `15598656000`
- 用户 B:`usrmHgqblBLy8Q`,username `b35758000`,phone `15635758000` - 用户 B:`usrkzrIHX2xBXc`,username `b98656000`,phone `15698656000`
- 好友申请:`frq_Z8SqjqK1iNg` - 好友申请:`frq_4BCvvh7aJaQ`
- P2P Topic:`p2pv5HSlKE-PQmYeCpuUEvLxA` - P2P Topic:`p2p--xhFVUQ8QuTOsgdfbEFdw`
- 群 Topic:`grppe4qw1ad4QQ` - 群 Topic:`grp4ch145Ku80k`
- 会议:`mtg_RAAFy893M5I9Ikt_` - 会议:`mtg_FMdvsdTBSc8mAUiB`
- 日报草稿:`dr_YKKH30euBrcDvopX` - 日报草稿:`dr_akcU6KDAcH9g9nwJ`
- 月报草稿:`mr_psOsrZzBuyiGhjZP` - 月报草稿:`mr_iULR69u4Y8_IbXMg`
这些数据位于测试环境租户 `default`,可按需清理。 这些数据位于测试环境租户 `default`,可按需清理。
+2
View File
@@ -2705,6 +2705,8 @@ func serveIMFavoriteResource(wrt http.ResponseWriter, req *http.Request) {
} }
tail := strings.Trim(strings.TrimPrefix(req.URL.Path[idx:], prefix), "/") tail := strings.Trim(strings.TrimPrefix(req.URL.Path[idx:], prefix), "/")
switch { switch {
case tail == "batch":
serveIMFavoriteBatchCreate(wrt, req)
case tail == "batch-delete": case tail == "batch-delete":
serveIMFavoriteBatchDelete(wrt, req) serveIMFavoriteBatchDelete(wrt, req)
case tail == "forward": case tail == "forward":