feat(schedule): add course table screens and navigation
Add complete schedule functionality including: - Schedule screen with weekly course table view - Course detail screen with transparent modal presentation - New ScheduleStack navigator integrated into main tab bar - Schedule service for API interactions - Type definitions for course entities Also includes bug fixes for group invite/request handlers to include required groupId parameter.
This commit is contained in:
@@ -145,6 +145,45 @@ func (s *groupService) publishGroupNotice(groupID string, notice groupNoticeMess
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateConversationCachesAfterSystemMessage 系统消息写入后失效相关缓存
|
||||
func (s *groupService) invalidateConversationCachesAfterSystemMessage(conversationID string) {
|
||||
if conversationID == "" || s.messageRepo == nil {
|
||||
return
|
||||
}
|
||||
// 新系统消息会影响消息分页列表
|
||||
cache.InvalidateMessagePages(s.cache, conversationID)
|
||||
// 参与者列表可能发生变化(加群/退群)后,这里统一清理一次
|
||||
s.cache.Delete(cache.ParticipantListKey(conversationID))
|
||||
|
||||
participants, err := s.messageRepo.GetConversationParticipants(conversationID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, p := range participants {
|
||||
if p == nil || p.UserID == "" {
|
||||
continue
|
||||
}
|
||||
// 会话最后消息、未读数会变化,清理用户维度缓存
|
||||
cache.InvalidateConversationList(s.cache, p.UserID)
|
||||
cache.InvalidateUnreadConversation(s.cache, p.UserID)
|
||||
cache.InvalidateUnreadDetail(s.cache, p.UserID, conversationID)
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateConversationCachesAfterMembershipChange 成员变更后失效相关缓存
|
||||
func (s *groupService) invalidateConversationCachesAfterMembershipChange(conversationID, userID string) {
|
||||
if conversationID == "" {
|
||||
return
|
||||
}
|
||||
s.cache.Delete(cache.ParticipantListKey(conversationID))
|
||||
if userID != "" {
|
||||
s.cache.Delete(cache.ParticipantKey(conversationID, userID))
|
||||
cache.InvalidateConversationList(s.cache, userID)
|
||||
cache.InvalidateUnreadConversation(s.cache, userID)
|
||||
cache.InvalidateUnreadDetail(s.cache, userID, conversationID)
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== 群组管理 ====================
|
||||
|
||||
// CreateGroup 创建群组
|
||||
@@ -444,6 +483,7 @@ func (s *groupService) broadcastMemberJoinNotice(groupID string, targetUserID st
|
||||
log.Printf("[broadcastMemberJoinNotice] 保存入群提示消息失败: groupID=%s, userID=%s, err=%v", groupID, targetUserID, err)
|
||||
} else {
|
||||
savedMessage = msg
|
||||
s.invalidateConversationCachesAfterSystemMessage(conv.ID)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[broadcastMemberJoinNotice] 获取群组会话失败: groupID=%s, err=%v", groupID, err)
|
||||
@@ -502,6 +542,7 @@ func (s *groupService) addMemberToGroupAndConversation(group *model.Group, userI
|
||||
if err := s.messageRepo.AddParticipant(conv.ID, userID); err != nil {
|
||||
log.Printf("[addMemberToGroupAndConversation] 添加会话参与者失败: groupID=%s, userID=%s, err=%v", group.ID, userID, err)
|
||||
}
|
||||
s.invalidateConversationCachesAfterMembershipChange(conv.ID, userID)
|
||||
}
|
||||
}
|
||||
cache.InvalidateGroupMembers(s.cache, group.ID)
|
||||
@@ -1036,6 +1077,7 @@ func (s *groupService) LeaveGroup(userID string, groupID string) error {
|
||||
// 如果移除参与者失败,记录日志但不阻塞退出群流程
|
||||
fmt.Printf("[WARN] LeaveGroup: failed to remove participant %s from conversation %s, error: %v\n", userID, conv.ID, err)
|
||||
}
|
||||
s.invalidateConversationCachesAfterMembershipChange(conv.ID, userID)
|
||||
}
|
||||
|
||||
// 失效群组成员缓存
|
||||
@@ -1092,6 +1134,7 @@ func (s *groupService) RemoveMember(userID string, groupID string, targetUserID
|
||||
if err := s.messageRepo.RemoveParticipant(conv.ID, targetUserID); err != nil {
|
||||
log.Printf("[RemoveMember] 移除会话参与者失败: groupID=%s, userID=%s, err=%v", groupID, targetUserID, err)
|
||||
}
|
||||
s.invalidateConversationCachesAfterMembershipChange(conv.ID, targetUserID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1290,6 +1333,7 @@ func (s *groupService) MuteMember(userID string, groupID string, targetUserID st
|
||||
} else {
|
||||
savedMessage = msg
|
||||
log.Printf("[MuteMember] 禁言消息已保存, ID=%s, Seq=%d", msg.ID, msg.Seq)
|
||||
s.invalidateConversationCachesAfterSystemMessage(conv.ID)
|
||||
}
|
||||
} else {
|
||||
log.Printf("[MuteMember] 获取群组会话失败: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user