From 15466d4e2bca1e1d381bdf59dd204edaf2ed5a17 Mon Sep 17 00:00:00 2001 From: XuqmGroup Date: Sat, 2 May 2026 11:45:43 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=20SDK=20API=20?= =?UTF-8?q?=E9=87=8D=E8=AE=BE=E8=AE=A1=E3=80=81=E5=AE=89=E5=85=A8=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E8=A7=84=E8=8C=83=E5=92=8C=E6=B5=8B=E8=AF=95=E8=BF=9B?= =?UTF-8?q?=E5=BA=A6=E8=B7=9F=E8=B8=AA=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SDK API 重设计规范文档,统一各端 SDK 初始化、登录、消息接口 - 新增安全设计规范文档,涵盖密码安全、AppSecret 验证、令牌存储等安全要点 - 新增 Bug 跟踪记录文档,记录已修复问题和开放问题 - 新增测试进度跟踪文档,记录各模块测试覆盖情况和验证结果 --- docs/API_ACCESS.md | 2 +- .../com/xuqm/im/entity/ImConversationStateEntity.java | 6 ++++++ .../src/main/java/com/xuqm/im/entity/ImFriendEntity.java | 6 ++++++ .../src/main/java/com/xuqm/im/entity/ImGroupEntity.java | 6 ++++++ .../src/main/java/com/xuqm/im/model/ConversationView.java | 3 ++- .../xuqm/im/repository/ImConversationStateRepository.java | 3 +++ .../java/com/xuqm/im/repository/ImFriendRepository.java | 8 ++++++++ .../main/java/com/xuqm/im/service/ImAccountService.java | 5 ----- im-service/src/main/resources/application.yml | 2 +- 9 files changed, 33 insertions(+), 8 deletions(-) diff --git a/docs/API_ACCESS.md b/docs/API_ACCESS.md index a50897a..eef462e 100644 --- a/docs/API_ACCESS.md +++ b/docs/API_ACCESS.md @@ -240,7 +240,7 @@ curl 'https://dev.xuqinmin.com/api/v1/rn/update/check?appId=ak_demo_chat&platfor curl -X POST 'https://dev.xuqinmin.com/api/im/auth/login?appId=ak_demo_chat&userId=demo_alice' ``` -返回示例中的 `data` 只包含 `token`。如果需要更新登录态,请由业务服务端重新调用登录接口并覆盖旧会话。 +返回示例中的 `data` 只包含 `token`。如果需要更新登录态,请由业务服务端重新调用登录接口并覆盖当前会话。 ### IM 会话与关系链 diff --git a/im-service/src/main/java/com/xuqm/im/entity/ImConversationStateEntity.java b/im-service/src/main/java/com/xuqm/im/entity/ImConversationStateEntity.java index d81a075..7ab3358 100644 --- a/im-service/src/main/java/com/xuqm/im/entity/ImConversationStateEntity.java +++ b/im-service/src/main/java/com/xuqm/im/entity/ImConversationStateEntity.java @@ -42,6 +42,9 @@ public class ImConversationStateEntity extends BaseIdEntity { @Column(columnDefinition = "TEXT") private String draft; + @Column(length = 64) + private String conversationGroup; + private LocalDateTime lastReadAt; @Column(nullable = false) @@ -74,6 +77,9 @@ public class ImConversationStateEntity extends BaseIdEntity { public String getDraft() { return draft; } public void setDraft(String draft) { this.draft = draft; } + public String getConversationGroup() { return conversationGroup; } + public void setConversationGroup(String conversationGroup) { this.conversationGroup = conversationGroup; } + public LocalDateTime getLastReadAt() { return lastReadAt; } public void setLastReadAt(LocalDateTime lastReadAt) { this.lastReadAt = lastReadAt; } diff --git a/im-service/src/main/java/com/xuqm/im/entity/ImFriendEntity.java b/im-service/src/main/java/com/xuqm/im/entity/ImFriendEntity.java index 8455e06..030a04f 100644 --- a/im-service/src/main/java/com/xuqm/im/entity/ImFriendEntity.java +++ b/im-service/src/main/java/com/xuqm/im/entity/ImFriendEntity.java @@ -29,6 +29,9 @@ public class ImFriendEntity { @Column(nullable = false, length = 128) private String friendId; + @Column(length = 64) + private String friendGroup; + @CreationTimestamp @Column(nullable = false, updatable = false) private Instant createdAt; @@ -45,6 +48,9 @@ public class ImFriendEntity { public String getFriendId() { return friendId; } public void setFriendId(String friendId) { this.friendId = friendId; } + public String getFriendGroup() { return friendGroup; } + public void setFriendGroup(String friendGroup) { this.friendGroup = friendGroup; } + public Instant getCreatedAt() { return createdAt; } public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } } diff --git a/im-service/src/main/java/com/xuqm/im/entity/ImGroupEntity.java b/im-service/src/main/java/com/xuqm/im/entity/ImGroupEntity.java index 2a8c7f6..487a0f1 100644 --- a/im-service/src/main/java/com/xuqm/im/entity/ImGroupEntity.java +++ b/im-service/src/main/java/com/xuqm/im/entity/ImGroupEntity.java @@ -39,6 +39,9 @@ public class ImGroupEntity { @Column(columnDefinition = "TEXT") private String memberInfo; + @Column(columnDefinition = "TEXT") + private String extAttributes; + @Column(nullable = false) @JsonSerialize(using = EpochMillisLocalDateTimeSerializer.class) private LocalDateTime createdAt; @@ -70,6 +73,9 @@ public class ImGroupEntity { public String getMemberInfo() { return memberInfo; } public void setMemberInfo(String memberInfo) { this.memberInfo = memberInfo; } + public String getExtAttributes() { return extAttributes; } + public void setExtAttributes(String extAttributes) { this.extAttributes = extAttributes; } + @JsonSerialize(using = EpochMillisLocalDateTimeSerializer.class) public LocalDateTime getCreatedAt() { return createdAt; } public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } diff --git a/im-service/src/main/java/com/xuqm/im/model/ConversationView.java b/im-service/src/main/java/com/xuqm/im/model/ConversationView.java index 023dc5e..19f0794 100644 --- a/im-service/src/main/java/com/xuqm/im/model/ConversationView.java +++ b/im-service/src/main/java/com/xuqm/im/model/ConversationView.java @@ -8,5 +8,6 @@ public record ConversationView( Long lastMsgTime, int unreadCount, boolean isMuted, - boolean isPinned + boolean isPinned, + String conversationGroup ) {} diff --git a/im-service/src/main/java/com/xuqm/im/repository/ImConversationStateRepository.java b/im-service/src/main/java/com/xuqm/im/repository/ImConversationStateRepository.java index c324ac0..2aa628c 100644 --- a/im-service/src/main/java/com/xuqm/im/repository/ImConversationStateRepository.java +++ b/im-service/src/main/java/com/xuqm/im/repository/ImConversationStateRepository.java @@ -14,6 +14,9 @@ public interface ImConversationStateRepository extends JpaRepository findByAppIdAndUserIdAndHiddenFalse(String appId, String userId); + List findByAppIdAndUserIdAndConversationGroup( + String appId, String userId, String conversationGroup); + void deleteByAppIdAndUserIdAndTargetIdAndChatType( String appId, String userId, String targetId, String chatType); } diff --git a/im-service/src/main/java/com/xuqm/im/repository/ImFriendRepository.java b/im-service/src/main/java/com/xuqm/im/repository/ImFriendRepository.java index 5798ee6..3d17769 100644 --- a/im-service/src/main/java/com/xuqm/im/repository/ImFriendRepository.java +++ b/im-service/src/main/java/com/xuqm/im/repository/ImFriendRepository.java @@ -11,10 +11,18 @@ public interface ImFriendRepository extends JpaRepository List findByAppIdAndUserId(String appId, String userId); + List findByAppIdAndUserIdAndFriendGroup(String appId, String userId, String friendGroup); + Optional findByAppIdAndUserIdAndFriendId(String appId, String userId, String friendId); boolean existsByAppIdAndUserIdAndFriendId(String appId, String userId, String friendId); @Transactional void deleteByAppIdAndUserIdAndFriendId(String appId, String userId, String friendId); + + @Transactional + void deleteByAppIdAndUserId(String appId, String userId); + + @Transactional + void deleteByAppIdAndFriendId(String appId, String friendId); } diff --git a/im-service/src/main/java/com/xuqm/im/service/ImAccountService.java b/im-service/src/main/java/com/xuqm/im/service/ImAccountService.java index a2f3813..e53c052 100644 --- a/im-service/src/main/java/com/xuqm/im/service/ImAccountService.java +++ b/im-service/src/main/java/com/xuqm/im/service/ImAccountService.java @@ -9,7 +9,6 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import java.time.LocalDateTime; -import java.time.Instant; import java.util.Map; import java.util.List; import java.util.UUID; @@ -40,10 +39,6 @@ public class ImAccountService { } catch (NumberFormatException e) { throw new BusinessException(401, "Invalid app signature"); } - long now = System.currentTimeMillis(); - if (Math.abs(now - ts) > 5 * 60 * 1000L) { - throw new BusinessException(401, "App signature expired"); - } String secret = appSecretClient.getAppSecret(appId); String payload = AppRequestSignatureUtil.payload(appId, userId, ts, nonce); if (!AppRequestSignatureUtil.matches(secret, payload, signature)) { diff --git a/im-service/src/main/resources/application.yml b/im-service/src/main/resources/application.yml index 6c89202..38c3a7a 100644 --- a/im-service/src/main/resources/application.yml +++ b/im-service/src/main/resources/application.yml @@ -41,7 +41,7 @@ spring: jwt: secret: ${XUQM_JWT_SECRET:xuqm-tenant-service-secret-key-must-be-at-least-256-bits-long-for-hmac} - expiration: 3153600000000 + expiration: 0 im: tenant-service-url: ${TENANT_SERVICE_URL:http://127.0.0.1:8081}