feat(messaging): implement optimistic updates with retry for failed messages
All checks were successful
Frontend CI / ota (android) (push) Successful in 3m24s
Frontend CI / ota (ios) (push) Successful in 3m22s
Frontend CI / build-and-push-web (push) Successful in 21m12s
Frontend CI / build-android-apk (push) Successful in 41m40s

- Add pending/failed message status to track send state
- Implement optimistic UI: show message immediately, update on server response
- Add retry functionality for failed messages via tap-to-retry
- Change send button from icon to text "发送" for clarity
- Add MessageSendService with temp ID generation to prevent collisions

feat(notification): add JPush notification deduplication and clear on tap

- Deduplicate notificationArrived events from dual JPush/vendor channels
- Clear all notifications on tap (QQ-style behavior)

feat(post): add client-side idempotency key for post creation

- Generate client_request_id per publish intent to prevent duplicates on retry
- Pass idempotency key through to postService and voteService
This commit is contained in:
lafay
2026-06-26 17:01:09 +08:00
parent 2bad59afbb
commit be77a9d04c
20 changed files with 451 additions and 134 deletions

View File

@@ -27,6 +27,8 @@ interface CreatePostRequest {
segments?: MessageSegment[];
images?: string[];
channel_id?: string;
// 客户端幂等键:同一 key 在服务端 TTL 内重复提交只创建一次,避免重复发帖
client_request_id?: string;
}
// 更新帖子请求
@@ -104,7 +106,6 @@ class PostService {
const response = await api.post<PostResponse>('/posts', data);
return response.data;
}
// 更新帖子
async updatePost(postId: string, data: UpdatePostRequest): Promise<Post | null> {
try {

View File

@@ -58,6 +58,7 @@ class VoteService {
segments,
images: data.images,
channel_id: data.channel_id,
client_request_id: data.client_request_id,
});
return response.data;
}