diff --git a/internal/api/route.go b/internal/api/route.go index f1dd1df1a..576b319f9 100644 --- a/internal/api/route.go +++ b/internal/api/route.go @@ -44,7 +44,7 @@ import ( ) func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.UniversalClient) *gin.Engine { - discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) // 默认RPC中间件 + discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithDefaultServiceConfig(fmt.Sprintf(`{"LoadBalancingPolicy": "%s"}`, "round_robin"))) // Default RPC middleware gin.SetMode(gin.ReleaseMode) r := gin.New() if v, ok := binding.Validator.Engine().(*validator.Validate); ok { diff --git a/internal/msggateway/n_ws_server.go b/internal/msggateway/n_ws_server.go index 0620fa5b9..f466a7dc4 100644 --- a/internal/msggateway/n_ws_server.go +++ b/internal/msggateway/n_ws_server.go @@ -279,7 +279,7 @@ func (ws *WsServer) registerClient(client *Client) { log.ZDebug(client.ctx, "user exist", "userID", client.UserID, "platformID", client.PlatformID) if clientOK { ws.clients.Set(client.UserID, client) - // 已经有同平台的连接存在 + // There is already a connection to the platform log.ZInfo(client.ctx, "repeat login", "userID", client.UserID, "platformID", client.PlatformID, "old remote addr", getRemoteAdders(oldClients)) ws.onlineUserConnNum.Add(1) } else { diff --git a/internal/msggateway/options.go b/internal/msggateway/options.go index 6513ac5dc..b65f8e36c 100644 --- a/internal/msggateway/options.go +++ b/internal/msggateway/options.go @@ -19,15 +19,15 @@ import "time" type ( Option func(opt *configs) configs struct { - // 长连接监听端口 + // Long connection listening port port int - // 长连接允许最大链接数 + // Maximum number of connections allowed for long connection maxConnNum int64 - // 连接握手超时时间 + // Connection handshake timeout handshakeTimeout time.Duration - // 允许消息最大长度 + // Maximum length allowed for messages messageMaxMsgLength int - // websocket write buffer, default: 4096, 4kb. + // Websocket write buffer, default: 4096, 4kb. writeBufferSize int } ) diff --git a/internal/push/push_to_client.go b/internal/push/push_to_client.go index 5fce34e83..1140e8ce4 100644 --- a/internal/push/push_to_client.go +++ b/internal/push/push_to_client.go @@ -229,7 +229,8 @@ func (p *Pusher) Push2SuperGroup(ctx context.Context, groupID string, msg *sdkws }(groupID, kickedUsers) pushToUserIDs = append(pushToUserIDs, kickedUsers...) case constant.GroupDismissedNotification: - if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) { // 消息先到,通知后到 + // Messages arrive first, notifications arrive later + if msgprocessor.IsNotification(msgprocessor.GetConversationIDByMsg(msg)) { var tips sdkws.GroupDismissedTips if p.UnmarshalNotificationElem(msg.Content, &tips) != nil { return err diff --git a/internal/rpc/conversation/conversaion.go b/internal/rpc/conversation/conversaion.go index 8558a23ea..582f93246 100644 --- a/internal/rpc/conversation/conversaion.go +++ b/internal/rpc/conversation/conversaion.go @@ -310,7 +310,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, unequal++ } } - if err := c.conversationDatabase.SetUsersConversationFiledTx(ctx, req.UserIDs, &conversation, m); err != nil { + if err := c.conversationDatabase.SetUsersConversationFieldTx(ctx, req.UserIDs, &conversation, m); err != nil { return nil, err } if unequal > 0 { @@ -321,7 +321,7 @@ func (c *conversationServer) SetConversations(ctx context.Context, return &pbconversation.SetConversationsResp{}, nil } -// 获取超级大群开启免打扰的用户ID. +// Get user IDs with "Do Not Disturb" enabled in super large groups. func (c *conversationServer) GetRecvMsgNotNotifyUserIDs(ctx context.Context, req *pbconversation.GetRecvMsgNotNotifyUserIDsReq) (*pbconversation.GetRecvMsgNotNotifyUserIDsResp, error) { //userIDs, err := c.conversationDatabase.FindRecvMsgNotNotifyUserIDs(ctx, req.GroupID) //if err != nil { @@ -378,7 +378,7 @@ func (c *conversationServer) CreateGroupChatConversations(ctx context.Context, r } func (c *conversationServer) SetConversationMaxSeq(ctx context.Context, req *pbconversation.SetConversationMaxSeqReq) (*pbconversation.SetConversationMaxSeqResp, error) { - if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, req.OwnerUserID, req.ConversationID, + if err := c.conversationDatabase.UpdateUsersConversationField(ctx, req.OwnerUserID, req.ConversationID, map[string]any{"max_seq": req.MaxSeq}); err != nil { return nil, err } diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 84702f548..9c49af220 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -278,6 +278,7 @@ func (s *friendServer) GetDesignatedFriends(ctx context.Context, req *pbfriend.G return resp, nil } +// Get the list of friend requests sent out proactively. func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, req *pbfriend.GetDesignatedFriendsApplyReq) (resp *pbfriend.GetDesignatedFriendsApplyResp, err error) { friendRequests, err := s.friendDatabase.FindBothFriendRequests(ctx, req.FromUserID, req.ToUserID) @@ -292,7 +293,7 @@ func (s *friendServer) GetDesignatedFriendsApply(ctx context.Context, return resp, nil } -// ok 获取接收到的好友申请(即别人主动申请的). +// Get received friend requests (i.e., those initiated by others). func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyToReq) (resp *pbfriend.GetPaginationFriendsApplyToResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") if err := s.userRpcClient.Access(ctx, req.UserID); err != nil { @@ -311,7 +312,6 @@ func (s *friendServer) GetPaginationFriendsApplyTo(ctx context.Context, req *pbf return resp, nil } -// ok 获取主动发出去的好友申请列表. func (s *friendServer) GetPaginationFriendsApplyFrom(ctx context.Context, req *pbfriend.GetPaginationFriendsApplyFromReq) (resp *pbfriend.GetPaginationFriendsApplyFromResp, err error) { defer log.ZInfo(ctx, utils.GetFuncName()+" Return") resp = &pbfriend.GetPaginationFriendsApplyFromResp{} diff --git a/internal/rpc/group/group.go b/internal/rpc/group/group.go index 9b1198d58..60f6c3eb5 100644 --- a/internal/rpc/group/group.go +++ b/internal/rpc/group/group.go @@ -765,8 +765,8 @@ func (s *groupServer) GroupApplicationResponse(ctx context.Context, req *pbgroup return nil, errs.ErrGroupRequestHandled.Wrap("group request already processed") } var inGroup bool - if _, err := s.db.TakeGroupMember(ctx, req.GroupID, req.FromUserID); err == nil { - inGroup = true // 已经在群里了 + if _, takeErr := s.db.TakeGroupMember(ctx, req.GroupID, req.FromUserID); takeErr == nil { + inGroup = true // Already in group } else if !s.IsNotFound(err) { return nil, err } diff --git a/internal/rpc/third/third.go b/internal/rpc/third/third.go index 7a63d3526..0d474d2c4 100644 --- a/internal/rpc/third/third.go +++ b/internal/rpc/third/third.go @@ -67,7 +67,7 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e if err != nil { return err } - // 根据配置文件策略选择 oss 方式 + // Select based on the configuration file strategy enable := config.Config.Object.Enable var o s3.Interface switch config.Config.Object.Enable { diff --git a/internal/tools/conversation.go b/internal/tools/conversation.go index 0d0275339..6b918c0d1 100644 --- a/internal/tools/conversation.go +++ b/internal/tools/conversation.go @@ -58,9 +58,9 @@ import ( // continue // } // if len(seqs) > 0 { -// if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err +// if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]interface{}{"latest_msg_destruct_time": now}); err // != nil { -// log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) +// log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) // continue // } // if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil { @@ -139,8 +139,8 @@ func (c *MsgTool) ConversationsDestructMsgs() { continue } if len(seqs) > 0 { - if err := c.conversationDatabase.UpdateUsersConversationFiled(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil { - log.ZError(ctx, "updateUsersConversationFiled failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) + if err := c.conversationDatabase.UpdateUsersConversationField(ctx, []string{conversation.OwnerUserID}, conversation.ConversationID, map[string]any{"latest_msg_destruct_time": now}); err != nil { + log.ZError(ctx, "updateUsersConversationField failed", err, "conversationID", conversation.ConversationID, "ownerUserID", conversation.OwnerUserID) continue } if err := c.msgNotificationSender.UserDeleteMsgsNotification(ctx, conversation.OwnerUserID, conversation.ConversationID, seqs); err != nil { diff --git a/pkg/common/db/controller/auth.go b/pkg/common/db/controller/auth.go index 18c64ad8f..909518f59 100644 --- a/pkg/common/db/controller/auth.go +++ b/pkg/common/db/controller/auth.go @@ -30,9 +30,9 @@ import ( ) type AuthDatabase interface { - // 结果为空 不返回错误 + // If the result is empty, no error is returned. GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error) - // 创建token + // Create token CreateToken(ctx context.Context, userID string, platformID int) (string, error) } @@ -47,16 +47,12 @@ func NewAuthDatabase(cache cache.MsgModel, accessSecret string, accessExpire int return &authDatabase{cache: cache, accessSecret: accessSecret, accessExpire: accessExpire} } -// 结果为空 不返回错误. -func (a *authDatabase) GetTokensWithoutError( - ctx context.Context, - userID string, - platformID int, -) (map[string]int, error) { +// If the result is empty +func (a *authDatabase) GetTokensWithoutError(ctx context.Context, userID string, platformID int) (map[string]int, error) { return a.cache.GetTokensWithoutError(ctx, userID, platformID) } -// 创建token. +// Create Token func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformID int) (string, error) { tokens, err := a.cache.GetTokensWithoutError(ctx, userID, platformID) if err != nil { @@ -80,7 +76,7 @@ func (a *authDatabase) CreateToken(ctx context.Context, userID string, platformI token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString([]byte(a.accessSecret)) if err != nil { - return "", errs.Wrap(err) + return "", errs.Wrap(err, "token.SignedString") } return tokenString, a.cache.AddTokenFlag(ctx, userID, platformID, tokenString, constant.NormalToken) } diff --git a/pkg/common/db/controller/conversation.go b/pkg/common/db/controller/conversation.go index c53d4ab87..0c64169a7 100644 --- a/pkg/common/db/controller/conversation.go +++ b/pkg/common/db/controller/conversation.go @@ -32,32 +32,40 @@ import ( ) type ConversationDatabase interface { - // UpdateUserConversationFiled 更新用户该会话的属性信息 - UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error - // CreateConversation 创建一批新的会话 + // UpdateUsersConversationField updates the properties of a conversation for specified users. + UpdateUsersConversationField(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error + // CreateConversation creates a batch of new conversations. CreateConversation(ctx context.Context, conversations []*relationtb.ConversationModel) error - // SyncPeerUserPrivateConversation 同步对端私聊会话内部保证事务操作 + // SyncPeerUserPrivateConversationTx ensures transactional operation while syncing private conversations between peers. SyncPeerUserPrivateConversationTx(ctx context.Context, conversation []*relationtb.ConversationModel) error - // FindConversations 根据会话ID获取某个用户的多个会话 + // FindConversations retrieves multiple conversations of a user by conversation IDs. FindConversations(ctx context.Context, ownerUserID string, conversationIDs []string) ([]*relationtb.ConversationModel, error) - // FindRecvMsgNotNotifyUserIDs 获取超级大群开启免打扰的用户ID - //FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) - // GetUserAllConversation 获取一个用户在服务器上所有的会话 + // GetUserAllConversation fetches all conversations of a user on the server. GetUserAllConversation(ctx context.Context, ownerUserID string) ([]*relationtb.ConversationModel, error) - // SetUserConversations 设置用户多个会话属性,如果会话不存在则创建,否则更新,内部保证原子性 + // SetUserConversations sets multiple conversation properties for a user, creates new conversations if they do not exist, or updates them otherwise. This operation is atomic. SetUserConversations(ctx context.Context, ownerUserID string, conversations []*relationtb.ConversationModel) error - // SetUsersConversationFiledTx 设置多个用户会话关于某个字段的更新操作,如果会话不存在则创建,否则更新,内部保证事务操作 - SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) error + // SetUsersConversationFieldTx updates a specific field for multiple users' conversations, creating new conversations if they do not exist, or updates them otherwise. This operation is transactional. + SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, fieldMap map[string]any) error + // CreateGroupChatConversation creates a group chat conversation for the specified group ID and user IDs. CreateGroupChatConversation(ctx context.Context, groupID string, userIDs []string) error + // GetConversationIDs retrieves conversation IDs for a given user. GetConversationIDs(ctx context.Context, userID string) ([]string, error) + // GetUserConversationIDsHash gets the hash of conversation IDs for a given user. GetUserConversationIDsHash(ctx context.Context, ownerUserID string) (hash uint64, err error) + // GetAllConversationIDs fetches all conversation IDs. GetAllConversationIDs(ctx context.Context) ([]string, error) + // GetAllConversationIDsNumber returns the number of all conversation IDs. GetAllConversationIDsNumber(ctx context.Context) (int64, error) + // PageConversationIDs paginates through conversation IDs based on the specified pagination settings. PageConversationIDs(ctx context.Context, pagination pagination.Pagination) (conversationIDs []string, err error) - //GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) + // GetConversationsByConversationID retrieves conversations by their IDs. GetConversationsByConversationID(ctx context.Context, conversationIDs []string) ([]*relationtb.ConversationModel, error) + // GetConversationIDsNeedDestruct fetches conversations that need to be destructed based on specific criteria. GetConversationIDsNeedDestruct(ctx context.Context) ([]*relationtb.ConversationModel, error) + // GetConversationNotReceiveMessageUserIDs gets user IDs for users in a conversation who have not received messages. GetConversationNotReceiveMessageUserIDs(ctx context.Context, conversationID string) ([]string, error) + //GetUserAllHasReadSeqs(ctx context.Context, ownerUserID string) (map[string]int64, error) + //FindRecvMsgNotNotifyUserIDs(ctx context.Context, groupID string) ([]string, error) } func NewConversationDatabase(conversation relationtb.ConversationModelInterface, cache cache.ConversationCache, tx tx.CtxTx) ConversationDatabase { @@ -74,7 +82,7 @@ type conversationDatabase struct { tx tx.CtxTx } -func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, filedMap map[string]any) (err error) { +func (c *conversationDatabase) SetUsersConversationFieldTx(ctx context.Context, userIDs []string, conversation *relationtb.ConversationModel, fieldMap map[string]any) (err error) { return c.tx.Transaction(ctx, func(ctx context.Context) error { cache := c.cache.NewCache() if conversation.GroupID != "" { @@ -85,22 +93,22 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, return err } if len(haveUserIDs) > 0 { - _, err = c.conversationDB.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, filedMap) + _, err = c.conversationDB.UpdateByMap(ctx, haveUserIDs, conversation.ConversationID, fieldMap) if err != nil { return err } cache = cache.DelUsersConversation(conversation.ConversationID, haveUserIDs...) - if _, ok := filedMap["has_read_seq"]; ok { + if _, ok := fieldMap["has_read_seq"]; ok { for _, userID := range haveUserIDs { cache = cache.DelUserAllHasReadSeqs(userID, conversation.ConversationID) } } - if _, ok := filedMap["recv_msg_opt"]; ok { + if _, ok := fieldMap["recv_msg_opt"]; ok { cache = cache.DelConversationNotReceiveMessageUserIDs(conversation.ConversationID) } } NotUserIDs := utils.DifferenceString(haveUserIDs, userIDs) - log.ZDebug(ctx, "SetUsersConversationFiledTx", "NotUserIDs", NotUserIDs, "haveUserIDs", haveUserIDs, "userIDs", userIDs) + log.ZDebug(ctx, "SetUsersConversationFieldTx", "NotUserIDs", NotUserIDs, "haveUserIDs", haveUserIDs, "userIDs", userIDs) var conversations []*relationtb.ConversationModel now := time.Now() for _, v := range NotUserIDs { @@ -123,7 +131,7 @@ func (c *conversationDatabase) SetUsersConversationFiledTx(ctx context.Context, }) } -func (c *conversationDatabase) UpdateUsersConversationFiled(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error { +func (c *conversationDatabase) UpdateUsersConversationField(ctx context.Context, userIDs []string, conversationID string, args map[string]any) error { _, err := c.conversationDB.UpdateByMap(ctx, userIDs, conversationID, args) if err != nil { return err diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go index e3d494c7a..2e3b628a6 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/db/controller/friend.go @@ -16,6 +16,7 @@ package controller import ( "context" + "fmt" "time" "github.com/OpenIMSDK/tools/pagination" @@ -89,20 +90,30 @@ func NewFriendDatabase(friend relation.FriendModelInterface, friendRequest relat return &friendDatabase{friend: friend, friendRequest: friendRequest, cache: cache, tx: tx} } -// ok 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true). +// CheckIn verifies if user2 is in user1's friend list (inUser1Friends returns true) and +// if user1 is in user2's friend list (inUser2Friends returns true). func (f *friendDatabase) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Friends bool, inUser2Friends bool, err error) { + // Retrieve friend IDs of userID1 from the cache userID1FriendIDs, err := f.cache.GetFriendIDs(ctx, userID1) if err != nil { + err = fmt.Errorf("error retrieving friend IDs for user %s: %w", userID1, err) return } + + // Retrieve friend IDs of userID2 from the cache userID2FriendIDs, err := f.cache.GetFriendIDs(ctx, userID2) if err != nil { + err = fmt.Errorf("error retrieving friend IDs for user %s: %w", userID2, err) return } - return utils.IsContain(userID2, userID1FriendIDs), utils.IsContain(userID1, userID2FriendIDs), nil + + // Check if userID2 is in userID1's friend list and vice versa + inUser1Friends = utils.IsContain(userID2, userID1FriendIDs) + inUser2Friends = utils.IsContain(userID1, userID2FriendIDs) + return inUser1Friends, inUser2Friends, nil } -// 增加或者更新好友申请 如果之前有记录则更新,没有记录则新增. +// AddFriendRequest adds or updates a friend request func (f *friendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) { return f.tx.Transaction(ctx, func(ctx context.Context) error { _, err := f.friendRequest.Take(ctx, fromUserID, toUserID) @@ -170,26 +181,37 @@ func (f *friendDatabase) BecomeFriends(ctx context.Context, ownerUserID string, }) } -// 拒绝好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)修改申请记录 已拒绝. -func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { +// RefuseFriendRequest rejects a friend request. It first checks for an existing, unprocessed request. +// If no such request exists, it returns an error. Otherwise, it marks the request as refused. +func (f *friendDatabase) RefuseFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) error { + // Attempt to retrieve the friend request from the database. fr, err := f.friendRequest.Take(ctx, friendRequest.FromUserID, friendRequest.ToUserID) if err != nil { - return err + return fmt.Errorf("failed to retrieve friend request from %s to %s: %w", friendRequest.FromUserID, friendRequest.ToUserID, err) } + + // Check if the friend request has already been handled. if fr.HandleResult != 0 { - return errs.ErrArgs.Wrap("the friend request has been processed") + return fmt.Errorf("friend request from %s to %s has already been processed", friendRequest.FromUserID, friendRequest.ToUserID) } - log.ZDebug(ctx, "refuse friend request", "friendRequest db", fr, "friendRequest arg", friendRequest) + + // Log the action of refusing the friend request for debugging and auditing purposes. + log.ZDebug(ctx, "Refusing friend request", map[string]interface{}{ + "DB_FriendRequest": fr, + "Arg_FriendRequest": friendRequest, + }) + + // Mark the friend request as refused and update the handle time. friendRequest.HandleResult = constant.FriendResponseRefuse friendRequest.HandleTime = time.Now() - err = f.friendRequest.Update(ctx, friendRequest) - if err != nil { - return err + if err := f.friendRequest.Update(ctx, friendRequest); err != nil { + return fmt.Errorf("failed to update friend request from %s to %s as refused: %w", friendRequest.FromUserID, friendRequest.ToUserID, err) } + return nil } -// AgreeFriendRequest 同意好友申请 (1)检查是否有申请记录且为未处理状态 (没有记录返回错误) (2)检查是否好友(不返回错误) (3) 建立双向好友关系(存在的忽略). +// AgreeFriendRequest accepts a friend request. It first checks for an existing, unprocessed request. func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest *relation.FriendRequestModel) (err error) { return f.tx.Transaction(ctx, func(ctx context.Context) error { defer log.ZDebug(ctx, "return line") @@ -227,10 +249,10 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * return err } existsMap := utils.SliceSet(utils.Slice(exists, func(friend *relation.FriendModel) [2]string { - return [...]string{friend.OwnerUserID, friend.FriendUserID} // 自己 - 好友 + return [...]string{friend.OwnerUserID, friend.FriendUserID} // My - Friend })) var adds []*relation.FriendModel - if _, ok := existsMap[[...]string{friendRequest.ToUserID, friendRequest.FromUserID}]; !ok { // 自己 - 好友 + if _, ok := existsMap[[...]string{friendRequest.ToUserID, friendRequest.FromUserID}]; !ok { // My - Friend adds = append( adds, &relation.FriendModel{ @@ -241,7 +263,7 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * }, ) } - if _, ok := existsMap[[...]string{friendRequest.FromUserID, friendRequest.ToUserID}]; !ok { // 好友 - 自己 + if _, ok := existsMap[[...]string{friendRequest.FromUserID, friendRequest.ToUserID}]; !ok { // My - Friend adds = append( adds, &relation.FriendModel{ @@ -261,7 +283,7 @@ func (f *friendDatabase) AgreeFriendRequest(ctx context.Context, friendRequest * }) } -// 删除好友 外部判断是否好友关系. +// Delete removes a friend relationship. It is assumed that the external caller has verified the friendship status. func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) { if err := f.friend.Delete(ctx, ownerUserID, friendUserIDs); err != nil { return err @@ -269,7 +291,7 @@ func (f *friendDatabase) Delete(ctx context.Context, ownerUserID string, friendU return f.cache.DelFriendIDs(append(friendUserIDs, ownerUserID)...).ExecDel(ctx) } -// 更新好友备注 零值也支持. +// UpdateRemark updates the remark for a friend. Zero value for remark is also supported. func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) { if err := f.friend.UpdateRemark(ctx, ownerUserID, friendUserID, remark); err != nil { return err @@ -277,27 +299,27 @@ func (f *friendDatabase) UpdateRemark(ctx context.Context, ownerUserID, friendUs return f.cache.DelFriend(ownerUserID, friendUserID).ExecDel(ctx) } -// 获取ownerUserID的好友列表 无结果不返回错误. +// PageOwnerFriends retrieves the list of friends for the ownerUserID. It does not return an error if the result is empty. func (f *friendDatabase) PageOwnerFriends(ctx context.Context, ownerUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { return f.friend.FindOwnerFriends(ctx, ownerUserID, pagination) } -// friendUserID在哪些人的好友列表中. +// PageInWhoseFriends identifies in whose friend lists the friendUserID appears. func (f *friendDatabase) PageInWhoseFriends(ctx context.Context, friendUserID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendModel, err error) { return f.friend.FindInWhoseFriends(ctx, friendUserID, pagination) } -// 获取我发出去的好友申请 无结果不返回错误. +// PageFriendRequestFromMe retrieves friend requests sent by me. It does not return an error if the result is empty. func (f *friendDatabase) PageFriendRequestFromMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { return f.friendRequest.FindFromUserID(ctx, userID, pagination) } -// 获取我收到的的好友申请 无结果不返回错误. +// PageFriendRequestToMe retrieves friend requests received by me. It does not return an error if the result is empty. func (f *friendDatabase) PageFriendRequestToMe(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, friends []*relation.FriendRequestModel, err error) { return f.friendRequest.FindToUserID(ctx, userID, pagination) } -// 获取某人指定好友的信息 如果有好友不存在,也返回错误. +// FindFriendsWithError retrieves specified friends' information for ownerUserID. Returns an error if any friend does not exist. func (f *friendDatabase) FindFriendsWithError(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*relation.FriendModel, err error) { friends, err = f.friend.FindFriends(ctx, ownerUserID, friendUserIDs) if err != nil { diff --git a/pkg/common/db/controller/group.go b/pkg/common/db/controller/group.go index decd868d6..6f208cc24 100644 --- a/pkg/common/db/controller/group.go +++ b/pkg/common/db/controller/group.go @@ -31,47 +31,79 @@ import ( ) type GroupDatabase interface { - // Group + // CreateGroup creates new groups along with their members. CreateGroup(ctx context.Context, groups []*relationtb.GroupModel, groupMembers []*relationtb.GroupMemberModel) error + // TakeGroup retrieves a single group by its ID. TakeGroup(ctx context.Context, groupID string) (group *relationtb.GroupModel, err error) + // FindGroup retrieves multiple groups by their IDs. FindGroup(ctx context.Context, groupIDs []string) (groups []*relationtb.GroupModel, err error) + // SearchGroup searches for groups based on a keyword and pagination settings, returns total count and groups. SearchGroup(ctx context.Context, keyword string, pagination pagination.Pagination) (int64, []*relationtb.GroupModel, error) + // UpdateGroup updates the properties of a group identified by its ID. UpdateGroup(ctx context.Context, groupID string, data map[string]any) error - DismissGroup(ctx context.Context, groupID string, deleteMember bool) error // 解散群,并删除群成员 + // DismissGroup disbands a group and optionally removes its members based on the deleteMember flag. + DismissGroup(ctx context.Context, groupID string, deleteMember bool) error + // TakeGroupMember retrieves a specific group member by group ID and user ID. TakeGroupMember(ctx context.Context, groupID string, userID string) (groupMember *relationtb.GroupMemberModel, err error) + // TakeGroupOwner retrieves the owner of a group by group ID. TakeGroupOwner(ctx context.Context, groupID string) (*relationtb.GroupMemberModel, error) - FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) // * - FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) // * - FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) // * - FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) // * + // FindGroupMembers retrieves members of a group filtered by user IDs. + FindGroupMembers(ctx context.Context, groupID string, userIDs []string) (groupMembers []*relationtb.GroupMemberModel, err error) + // FindGroupMemberUser retrieves groups that a user is a member of, filtered by group IDs. + FindGroupMemberUser(ctx context.Context, groupIDs []string, userID string) (groupMembers []*relationtb.GroupMemberModel, err error) + // FindGroupMemberRoleLevels retrieves group members filtered by their role levels within a group. + FindGroupMemberRoleLevels(ctx context.Context, groupID string, roleLevels []int32) (groupMembers []*relationtb.GroupMemberModel, err error) + // FindGroupMemberAll retrieves all members of a group. + FindGroupMemberAll(ctx context.Context, groupID string) (groupMembers []*relationtb.GroupMemberModel, err error) + // FindGroupsOwner retrieves the owners for multiple groups. FindGroupsOwner(ctx context.Context, groupIDs []string) ([]*relationtb.GroupMemberModel, error) + // FindGroupMemberUserID retrieves the user IDs of all members in a group. FindGroupMemberUserID(ctx context.Context, groupID string) ([]string, error) + // FindGroupMemberNum retrieves the number of members in a group. FindGroupMemberNum(ctx context.Context, groupID string) (uint32, error) + // FindUserManagedGroupID retrieves group IDs managed by a user. FindUserManagedGroupID(ctx context.Context, userID string) (groupIDs []string, err error) + // PageGroupRequest paginates through group requests for specified groups. PageGroupRequest(ctx context.Context, groupIDs []string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) + // GetGroupRoleLevelMemberIDs retrieves user IDs of group members with a specific role level. GetGroupRoleLevelMemberIDs(ctx context.Context, groupID string, roleLevel int32) ([]string, error) + // PageGetJoinGroup paginates through groups that a user has joined. PageGetJoinGroup(ctx context.Context, userID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + // PageGetGroupMember paginates through members of a group. PageGetGroupMember(ctx context.Context, groupID string, pagination pagination.Pagination) (total int64, totalGroupMembers []*relationtb.GroupMemberModel, err error) + // SearchGroupMember searches for group members based on a keyword, group ID, and pagination settings. SearchGroupMember(ctx context.Context, keyword string, groupID string, pagination pagination.Pagination) (int64, []*relationtb.GroupMemberModel, error) + // HandlerGroupRequest processes a group join request with a specified result. HandlerGroupRequest(ctx context.Context, groupID string, userID string, handledMsg string, handleResult int32, member *relationtb.GroupMemberModel) error + // DeleteGroupMember removes specified users from a group. DeleteGroupMember(ctx context.Context, groupID string, userIDs []string) error + // MapGroupMemberUserID maps group IDs to their members' simplified user IDs. MapGroupMemberUserID(ctx context.Context, groupIDs []string) (map[string]*relationtb.GroupSimpleUserID, error) + // MapGroupMemberNum maps group IDs to their member count. MapGroupMemberNum(ctx context.Context, groupIDs []string) (map[string]uint32, error) - TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error // 转让群 + // TransferGroupOwner transfers the ownership of a group to another user. + TransferGroupOwner(ctx context.Context, groupID string, oldOwnerUserID, newOwnerUserID string, roleLevel int32) error + // UpdateGroupMember updates properties of a group member. UpdateGroupMember(ctx context.Context, groupID string, userID string, data map[string]any) error + // UpdateGroupMembers batch updates properties of group members. UpdateGroupMembers(ctx context.Context, data []*relationtb.BatchUpdateGroupMember) error - // GroupRequest + + // CreateGroupRequest creates new group join requests. CreateGroupRequest(ctx context.Context, requests []*relationtb.GroupRequestModel) error + // TakeGroupRequest retrieves a specific group join request. TakeGroupRequest(ctx context.Context, groupID string, userID string) (*relationtb.GroupRequestModel, error) + // FindGroupRequests retrieves multiple group join requests. FindGroupRequests(ctx context.Context, groupID string, userIDs []string) ([]*relationtb.GroupRequestModel, error) + // PageGroupRequestUser paginates through group join requests made by a user. PageGroupRequestUser(ctx context.Context, userID string, pagination pagination.Pagination) (int64, []*relationtb.GroupRequestModel, error) - // 获取群总数 + // CountTotal counts the total number of groups as of a certain date. CountTotal(ctx context.Context, before *time.Time) (count int64, err error) - // 获取范围内群增量 + // CountRangeEverydayTotal counts the daily group creation total within a specified date range. CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) + // DeleteGroupMemberHash deletes the hash entries for group members in specified groups. DeleteGroupMemberHash(ctx context.Context, groupIDs []string) error } diff --git a/pkg/common/db/controller/msg.go b/pkg/common/db/controller/msg.go index cb3355e34..0a440eedf 100644 --- a/pkg/common/db/controller/msg.go +++ b/pkg/common/db/controller/msg.go @@ -199,7 +199,7 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI } num := db.msg.GetSingleGocMsgNum() // num = 100 - for i, field := range fields { // 检查类型 + for i, field := range fields { // Check the type of the field var ok bool switch key { case updateKeyMsg: @@ -217,7 +217,7 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI return errs.ErrInternalServer.Wrap("field type is invalid") } } - // 返回值为true表示数据库存在该文档,false表示数据库不存在该文档 + // Returns true if the document exists in the database, false if the document does not exist in the database updateMsgModel := func(seq int64, i int) (bool, error) { var ( res *mongo.UpdateResult @@ -239,21 +239,21 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI } tryUpdate := true for i := 0; i < len(fields); i++ { - seq := firstSeq + int64(i) // 当前seq + seq := firstSeq + int64(i) // Current sequence number if tryUpdate { matched, err := updateMsgModel(seq, i) if err != nil { return err } if matched { - continue // 匹配到了,继续下一个(不一定修改) + continue // The current data has been updated, skip the current data } } doc := unrelationtb.MsgDocModel{ DocID: db.msg.GetDocID(conversationID, seq), Msg: make([]*unrelationtb.MsgInfoModel, num), } - var insert int // 插入的数量 + var insert int // Inserted data number for j := i; j < len(fields); j++ { seq = firstSeq + int64(j) if db.msg.GetDocID(conversationID, seq) != doc.DocID { @@ -282,14 +282,14 @@ func (db *commonMsgDatabase) BatchInsertBlock(ctx context.Context, conversationI } if err := db.msgDocDatabase.Create(ctx, &doc); err != nil { if mongo.IsDuplicateKeyError(err) { - i-- // 存在并发,重试当前数据 - tryUpdate = true // 以修改模式 + i-- // already inserted + tryUpdate = true // next block use update mode continue } return err } - tryUpdate = false // 当前以插入成功,下一块优先插入模式 - i += insert - 1 // 跳过已插入的数据 + tryUpdate = false // The current block is inserted successfully, and the next block is inserted preferentially + i += insert - 1 // Skip the inserted data } return nil } @@ -753,7 +753,7 @@ func (db *commonMsgDatabase) UserMsgsDestruct(ctx context.Context, userID string log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index) } } - // 获取报错,或者获取不到了,物理删除并且返回seq delMongoMsgsPhysical(delStruct.delDocIDList), 结束递归 + // If an error is reported, or the error cannot be obtained, it is physically deleted and seq delMongoMsgsPhysical(delStruct.delDocIDList) is returned to end the recursion break } index++ @@ -808,7 +808,7 @@ func (d *delMsgRecursionStruct) getSetMinSeq() int64 { // index 0....19(del) 20...69 // seq 70 // set minSeq 21 -// recursion 删除list并且返回设置的最小seq. +// recursion deletes the list and returns the set minimum seq. func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversationID string, index int64, delStruct *delMsgRecursionStruct, remainTime int64) (int64, error) { // find from oldest list msgDocModel, err := db.msgDocDatabase.GetMsgDocModelByIndex(ctx, conversationID, index, 1) @@ -820,7 +820,7 @@ func (db *commonMsgDatabase) deleteMsgRecursion(ctx context.Context, conversatio log.ZError(ctx, "deleteMsgRecursion GetUserMsgListByIndex failed", err, "conversationID", conversationID, "index", index) } } - // 获取报错,或者获取不到了,物理删除并且返回seq delMongoMsgsPhysical(delStruct.delDocIDList), 结束递归 + // If an error is reported, or the error cannot be obtained, it is physically deleted and seq delMongoMsgsPhysical(delStruct.delDocIDList) is returned to end the recursion err = db.msgDocDatabase.DeleteDocs(ctx, delStruct.delDocIDs) if err != nil { return 0, err diff --git a/pkg/common/db/s3/aws/aws.go b/pkg/common/db/s3/aws/aws.go index d996485c7..7588eea91 100644 --- a/pkg/common/db/s3/aws/aws.go +++ b/pkg/common/db/s3/aws/aws.go @@ -58,10 +58,10 @@ func NewAWS() (s3.Interface, error) { credential := credentials.NewStaticCredentials( conf.AccessKeyID, // accessKey conf.AccessKeySecret, // secretKey - "") // sts的临时凭证 + "") // stoken sess, err := session.NewSession(&aws.Config{ - Region: aws.String(conf.Region), // 桶所在的区域 + Region: aws.String(conf.Region), // The area where the bucket is located Credentials: credential, }) diff --git a/pkg/common/db/s3/cont/consts.go b/pkg/common/db/s3/cont/consts.go index a01a8312c..b51878e49 100644 --- a/pkg/common/db/s3/cont/consts.go +++ b/pkg/common/db/s3/cont/consts.go @@ -15,10 +15,24 @@ package cont const ( - hashPath = "openim/data/hash/" - tempPath = "openim/temp/" - DirectPath = "openim/direct" - UploadTypeMultipart = 1 // 分片上传 - UploadTypePresigned = 2 // 预签名上传 - partSeparator = "," + // hashPath defines the storage path for hash data within the 'openim' directory. + hashPath = "openim/data/hash/" + + // tempPath specifies the directory for temporary files in the 'openim' structure. + tempPath = "openim/temp/" + + // DirectPath indicates the directory for direct uploads or access within the 'openim' structure. + DirectPath = "openim/direct" + + // UploadTypeMultipart represents the identifier for multipart uploads, + // allowing large files to be uploaded in chunks. + UploadTypeMultipart = 1 + + // UploadTypePresigned signifies the use of presigned URLs for uploads, + // facilitating secure, authorized file transfers without requiring direct access to the storage credentials. + UploadTypePresigned = 2 + + // partSeparator is used as a delimiter in multipart upload processes, + // separating individual file parts. + partSeparator = "," ) diff --git a/pkg/common/db/s3/cont/controller.go b/pkg/common/db/s3/cont/controller.go index 2a66aeaf6..f60c2c650 100644 --- a/pkg/common/db/s3/cont/controller.go +++ b/pkg/common/db/s3/cont/controller.go @@ -114,7 +114,7 @@ func (c *Controller) InitiateUpload(ctx context.Context, hash string, size int64 return nil, err } if size <= partSize { - // 预签名上传 + // Pre-signed upload key := path.Join(tempPath, c.NowPath(), fmt.Sprintf("%s_%d_%s.presigned", hash, size, c.UUID())) rawURL, err := c.impl.PresignedPutObject(ctx, key, expire) if err != nil { @@ -139,7 +139,7 @@ func (c *Controller) InitiateUpload(ctx context.Context, hash string, size int64 }, }, nil } else { - // 分片上传 + // Fragment upload upload, err := c.impl.InitiateMultipartUpload(ctx, c.HashPath(hash)) if err != nil { return nil, err @@ -206,7 +206,7 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa ETag: part, } } - // todo: 验证大小 + // todo: Validation size result, err := c.impl.CompleteMultipartUpload(ctx, upload.ID, upload.Key, parts) if err != nil { return nil, err @@ -225,7 +225,7 @@ func (c *Controller) CompleteUpload(ctx context.Context, uploadID string, partHa if md5val := hex.EncodeToString(md5Sum[:]); md5val != upload.Hash { return nil, errs.ErrArgs.Wrap(fmt.Sprintf("md5 mismatching %s != %s", md5val, upload.Hash)) } - // 防止在这个时候,并发操作,导致文件被覆盖 + // Prevents concurrent operations at this time that cause files to be overwritten copyInfo, err := c.impl.CopyObject(ctx, uploadInfo.Key, upload.Key+"."+c.UUID()) if err != nil { return nil, err diff --git a/pkg/common/db/s3/cont/structs.go b/pkg/common/db/s3/cont/structs.go index ff5ca7943..de484cc5f 100644 --- a/pkg/common/db/s3/cont/structs.go +++ b/pkg/common/db/s3/cont/structs.go @@ -17,9 +17,14 @@ package cont import "github.com/openimsdk/open-im-server/v3/pkg/common/db/s3" type InitiateUploadResult struct { - UploadID string `json:"uploadID"` // 上传ID - PartSize int64 `json:"partSize"` // 分片大小 - Sign *s3.AuthSignResult `json:"sign"` // 分片信息 + // UploadID uniquely identifies the upload session for tracking and management purposes. + UploadID string `json:"uploadID"` + + // PartSize specifies the size of each part in a multipart upload. This is relevant for breaking down large uploads into manageable pieces. + PartSize int64 `json:"partSize"` + + // Sign contains the authentication and signature information necessary for securely uploading each part. This could include signed URLs or tokens. + Sign *s3.AuthSignResult `json:"sign"` } type UploadResult struct { diff --git a/pkg/common/db/s3/minio/image.go b/pkg/common/db/s3/minio/image.go index 71db1ea51..f363f94b1 100644 --- a/pkg/common/db/s3/minio/image.go +++ b/pkg/common/db/s3/minio/image.go @@ -42,79 +42,51 @@ func ImageWidthHeight(img image.Image) (int, int) { return bounds.X, bounds.Y } +// resizeImage resizes an image to a specified maximum width and height, maintaining the aspect ratio. +// If both maxWidth and maxHeight are set to 0, the original image is returned. +// If both are non-zero, the image is scaled to fit within the constraints while maintaining aspect ratio. +// If only one of maxWidth or maxHeight is non-zero, the image is scaled accordingly. func resizeImage(img image.Image, maxWidth, maxHeight int) image.Image { bounds := img.Bounds() - imgWidth := bounds.Max.X - imgHeight := bounds.Max.Y + imgWidth, imgHeight := bounds.Dx(), bounds.Dy() - // 计算缩放比例 - scaleWidth := float64(maxWidth) / float64(imgWidth) - scaleHeight := float64(maxHeight) / float64(imgHeight) - - // 如果都为0,则不缩放,返回原始图片 + // Return original image if no resizing is needed. if maxWidth == 0 && maxHeight == 0 { return img } - // 如果宽度和高度都大于0,则选择较小的缩放比例,以保持宽高比 + var scale float64 = 1 if maxWidth > 0 && maxHeight > 0 { - scale := scaleWidth - if scaleHeight < scaleWidth { - scale = scaleHeight - } - - // 计算缩略图尺寸 - thumbnailWidth := int(float64(imgWidth) * scale) - thumbnailHeight := int(float64(imgHeight) * scale) - - // 使用"image"库的Resample方法生成缩略图 - thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight)) - for y := 0; y < thumbnailHeight; y++ { - for x := 0; x < thumbnailWidth; x++ { - srcX := int(float64(x) / scale) - srcY := int(float64(y) / scale) - thumbnail.Set(x, y, img.At(srcX, srcY)) - } - } - - return thumbnail + scaleWidth := float64(maxWidth) / float64(imgWidth) + scaleHeight := float64(maxHeight) / float64(imgHeight) + // Choose the smaller scale to fit both constraints. + scale = min(scaleWidth, scaleHeight) + } else if maxWidth > 0 { + scale = float64(maxWidth) / float64(imgWidth) + } else if maxHeight > 0 { + scale = float64(maxHeight) / float64(imgHeight) } - // 如果只指定了宽度或高度,则根据最大不超过的规则生成缩略图 - if maxWidth > 0 { - thumbnailWidth := maxWidth - thumbnailHeight := int(float64(imgHeight) * scaleWidth) + newWidth := int(float64(imgWidth) * scale) + newHeight := int(float64(imgHeight) * scale) - // 使用"image"库的Resample方法生成缩略图 - thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight)) - for y := 0; y < thumbnailHeight; y++ { - for x := 0; x < thumbnailWidth; x++ { - srcX := int(float64(x) / scaleWidth) - srcY := int(float64(y) / scaleWidth) - thumbnail.Set(x, y, img.At(srcX, srcY)) - } + // Resize the image by creating a new image and manually copying pixels. + thumbnail := image.NewRGBA(image.Rect(0, 0, newWidth, newHeight)) + for y := 0; y < newHeight; y++ { + for x := 0; x < newWidth; x++ { + srcX := int(float64(x) / scale) + srcY := int(float64(y) / scale) + thumbnail.Set(x, y, img.At(srcX, srcY)) } - - return thumbnail } - if maxHeight > 0 { - thumbnailWidth := int(float64(imgWidth) * scaleHeight) - thumbnailHeight := maxHeight - - // 使用"image"库的Resample方法生成缩略图 - thumbnail := image.NewRGBA(image.Rect(0, 0, thumbnailWidth, thumbnailHeight)) - for y := 0; y < thumbnailHeight; y++ { - for x := 0; x < thumbnailWidth; x++ { - srcX := int(float64(x) / scaleHeight) - srcY := int(float64(y) / scaleHeight) - thumbnail.Set(x, y, img.At(srcX, srcY)) - } - } + return thumbnail +} - return thumbnail +// min returns the smaller of x or y. +func min(x, y float64) float64 { + if x < y { + return x } - - // 默认情况下,返回原始图片 - return img + return y } diff --git a/pkg/common/db/s3/oss/oss.go b/pkg/common/db/s3/oss/oss.go index 98473b87f..a6be41d39 100644 --- a/pkg/common/db/s3/oss/oss.go +++ b/pkg/common/db/s3/oss/oss.go @@ -30,6 +30,7 @@ import ( "strings" "time" + "github.com/OpenIMSDK/tools/errs" "github.com/aliyun/aliyun-oss-go-sdk/oss" "github.com/openimsdk/open-im-server/v3/pkg/common/config" @@ -60,7 +61,7 @@ const successCode = http.StatusOK func NewOSS() (s3.Interface, error) { conf := config.Config.Object.Oss if conf.BucketURL == "" { - return nil, errors.New("bucket url is empty") + return nil, errs.Wrap(errors.New("bucket url is empty")) } client, err := oss.New(conf.Endpoint, conf.AccessKeyID, conf.AccessKeySecret) if err != nil { @@ -68,7 +69,7 @@ func NewOSS() (s3.Interface, error) { } bucket, err := client.Bucket(conf.Bucket) if err != nil { - return nil, err + return nil, errs.Wrap(err, "ali-oss bucket error") } if conf.BucketURL[len(conf.BucketURL)-1] != '/' { conf.BucketURL += "/" @@ -138,10 +139,10 @@ func (o *OSS) CompleteMultipartUpload(ctx context.Context, uploadID string, name func (o *OSS) PartSize(ctx context.Context, size int64) (int64, error) { if size <= 0 { - return 0, errors.New("size must be greater than 0") + return 0, errs.Wrap(errors.New("size must be greater than 0")) } if size > maxPartSize*maxNumSize { - return 0, fmt.Errorf("OSS size must be less than the maximum allowed limit") + return 0, errs.Wrap(errors.New("size must be less than the maximum allowed limit")) } if size <= minPartSize*maxNumSize { return minPartSize, nil @@ -196,25 +197,25 @@ func (o *OSS) StatObject(ctx context.Context, name string) (*s3.ObjectInfo, erro } res := &s3.ObjectInfo{Key: name} if res.ETag = strings.ToLower(strings.ReplaceAll(header.Get("ETag"), `"`, ``)); res.ETag == "" { - return nil, errors.New("StatObject etag not found") + return nil, errs.Wrap(errors.New("StatObject etag not found")) } if contentLengthStr := header.Get("Content-Length"); contentLengthStr == "" { return nil, errors.New("StatObject content-length not found") } else { res.Size, err = strconv.ParseInt(contentLengthStr, 10, 64) if err != nil { - return nil, fmt.Errorf("StatObject content-length parse error: %w", err) + return nil, errs.Wrap(err, "StatObject content-length parse error") } if res.Size < 0 { - return nil, errors.New("StatObject content-length must be greater than 0") + return nil, errs.Wrap(errors.New("StatObject content-length must be greater than 0")) } } if lastModified := header.Get("Last-Modified"); lastModified == "" { - return nil, errors.New("StatObject last-modified not found") + return nil, errs.Wrap(errors.New("StatObject last-modified not found")) } else { res.LastModified, err = time.Parse(http.TimeFormat, lastModified) if err != nil { - return nil, fmt.Errorf("StatObject last-modified parse error: %w", err) + return nil, errs.Wrap(err, "StatObject last-modified parse error") } } return res, nil @@ -227,7 +228,7 @@ func (o *OSS) DeleteObject(ctx context.Context, name string) error { func (o *OSS) CopyObject(ctx context.Context, src string, dst string) (*s3.CopyObjectInfo, error) { result, err := o.bucket.CopyObject(src, dst) if err != nil { - return nil, err + return nil, errs.Wrap(err, "CopyObject error") } return &s3.CopyObjectInfo{ Key: dst, @@ -261,7 +262,7 @@ func (o *OSS) ListUploadedParts(ctx context.Context, uploadID string, name strin Bucket: o.bucket.BucketName, }, oss.MaxUploads(100), oss.MaxParts(maxParts), oss.PartNumberMarker(partNumberMarker)) if err != nil { - return nil, err + return nil, errs.Wrap(err, "ListUploadedParts error") } res := &s3.ListUploadedPartsResult{ Key: result.Key, @@ -286,7 +287,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, var opts []oss.Option if opt != nil { if opt.Image != nil { - // 文档地址: https://help.aliyun.com/zh/oss/user-guide/resize-images-4?spm=a2c4g.11186623.0.0.4b3b1e4fWW6yji + // Docs Address: https://help.aliyun.com/zh/oss/user-guide/resize-images-4?spm=a2c4g.11186623.0.0.4b3b1e4fWW6yji var format string switch opt.Image.Format { case @@ -329,7 +330,7 @@ func (o *OSS) AccessURL(ctx context.Context, name string, expire time.Duration, } rawParams, err := oss.GetRawParams(opts) if err != nil { - return "", err + return "", errs.Wrap(err, "AccessURL error") } params := getURLParams(*o.bucket.Client.Conn, rawParams) return getURL(o.um, o.bucket.BucketName, name, params).String(), nil @@ -351,12 +352,12 @@ func (o *OSS) FormData(ctx context.Context, name string, size int64, contentType } policyJson, err := json.Marshal(policy) if err != nil { - return nil, err + return nil, errs.Wrap(err, "Marshal json error") } policyStr := base64.StdEncoding.EncodeToString(policyJson) h := hmac.New(sha1.New, []byte(o.credentials.GetAccessKeySecret())) if _, err := io.WriteString(h, policyStr); err != nil { - return nil, err + return nil, errs.Wrap(err, "WriteString error") } fd := &s3.FormData{ URL: o.bucketURL, diff --git a/pkg/common/db/unrelation/msg.go b/pkg/common/db/unrelation/msg.go index 526e3c327..31d9ff8fc 100644 --- a/pkg/common/db/unrelation/msg.go +++ b/pkg/common/db/unrelation/msg.go @@ -651,7 +651,7 @@ func (m *MsgMongoDriver) RangeUserSendCount( "$dateToString": bson.M{ "format": "%Y-%m-%d", "date": bson.M{ - "$toDate": "$$item.msg.send_time", // 毫秒时间戳 + "$toDate": "$$item.msg.send_time", // Millisecond timestamp }, }, }, @@ -900,7 +900,7 @@ func (m *MsgMongoDriver) RangeGroupSendCount( "$dateToString": bson.M{ "format": "%Y-%m-%d", "date": bson.M{ - "$toDate": "$$item.msg.send_time", // 毫秒时间戳 + "$toDate": "$$item.msg.send_time", // Millisecond timestamp }, }, }, diff --git a/pkg/common/discoveryregister/discoveryregister_test.go b/pkg/common/discoveryregister/discoveryregister_test.go index 5317db5c6..e7a5fb276 100644 --- a/pkg/common/discoveryregister/discoveryregister_test.go +++ b/pkg/common/discoveryregister/discoveryregister_test.go @@ -39,7 +39,7 @@ func TestNewDiscoveryRegister(t *testing.T) { expectedResult bool }{ {"zookeeper", false, true}, - {"k8s", false, true}, // 假设 k8s 配置也已正确设置 + {"k8s", false, true}, // Assume that the k8s configuration is also set up correctly {"direct", false, true}, {"invalid", true, false}, } diff --git a/pkg/rpcclient/notification/conversation.go b/pkg/rpcclient/notification/conversation.go index 0fefb147e..58f00915a 100644 --- a/pkg/rpcclient/notification/conversation.go +++ b/pkg/rpcclient/notification/conversation.go @@ -31,7 +31,7 @@ func NewConversationNotificationSender(msgRpcClient *rpcclient.MessageRpcClient) return &ConversationNotificationSender{rpcclient.NewNotificationSender(rpcclient.WithRpcClient(msgRpcClient))} } -// SetPrivate调用. +// SetPrivate invote func (c *ConversationNotificationSender) ConversationSetPrivateNotification(ctx context.Context, sendID, recvID string, isPrivateChat bool, conversationID string, ) error { @@ -45,7 +45,6 @@ func (c *ConversationNotificationSender) ConversationSetPrivateNotification(ctx return c.Notification(ctx, sendID, recvID, constant.ConversationPrivateChatNotification, tips) } -// 会话改变. func (c *ConversationNotificationSender) ConversationChangeNotification(ctx context.Context, userID string, conversationIDs []string) error { tips := &sdkws.ConversationUpdateTips{ UserID: userID, @@ -55,7 +54,6 @@ func (c *ConversationNotificationSender) ConversationChangeNotification(ctx cont return c.Notification(ctx, userID, userID, constant.ConversationChangeNotification, tips) } -// 会话未读数同步. func (c *ConversationNotificationSender) ConversationUnreadChangeNotification( ctx context.Context, userID, conversationID string, diff --git a/pkg/rpcclient/notification/friend.go b/pkg/rpcclient/notification/friend.go index a55bc0e5e..a6b693724 100644 --- a/pkg/rpcclient/notification/friend.go +++ b/pkg/rpcclient/notification/friend.go @@ -31,7 +31,7 @@ import ( type FriendNotificationSender struct { *rpcclient.NotificationSender - // 找不到报错 + // Target not found err getUsersInfo func(ctx context.Context, userIDs []string) ([]CommonUser, error) // db controller db controller.FriendDatabase diff --git a/test/e2e/framework/config/config_test.go b/test/e2e/framework/config/config_test.go index b7259bf37..66f845db3 100644 --- a/test/e2e/framework/config/config_test.go +++ b/test/e2e/framework/config/config_test.go @@ -76,7 +76,7 @@ func TestCopyFlags(t *testing.T) { }() CopyFlags(tt.args.source, tt.args.target) - // 验证复制的标记 + // Verify the replicated tag if !tt.wantErr { tt.args.source.VisitAll(func(f *flag.Flag) { if gotFlag := tt.args.target.Lookup(f.Name); gotFlag == nil || !reflect.DeepEqual(gotFlag, f) { diff --git a/tools/data-conversion/chat/cmd/conversion-chat/chat.go b/tools/data-conversion/chat/cmd/conversion-chat/chat.go index 0fc49c782..f68b71b16 100644 --- a/tools/data-conversion/chat/cmd/conversion-chat/chat.go +++ b/tools/data-conversion/chat/cmd/conversion-chat/chat.go @@ -28,20 +28,20 @@ import ( func main() { var ( - usernameV2 = "root" // v2版本mysql用户名 - passwordV2 = "openIM" // v2版本mysql密码 - addrV2 = "127.0.0.1:13306" // v2版本mysql地址 - databaseV2 = "admin_chat" // v2版本mysql数据库名字 + usernameV2 = "root" // Username for MySQL v2 version + passwordV2 = "openIM" // Password for MySQL v2 version + addrV2 = "127.0.0.1:13306" // Address for MySQL v2 version + databaseV2 = "admin_chat" // Database name for MySQL v2 version ) var ( - usernameV3 = "root" // v3版本mysql用户名 - passwordV3 = "openIM123" // v3版本mysql密码 - addrV3 = "127.0.0.1:13306" // v3版本mysql地址 - databaseV3 = "openim_enterprise" // v3版本mysql数据库名字 + usernameV3 = "root" // Username for MySQL v3 version + passwordV3 = "openIM123" // Password for MySQL v3 version + addrV3 = "127.0.0.1:13306" // Address for MySQL v3 version + databaseV3 = "openim_enterprise" // Database name for MySQL v3 version ) - var concurrency = 1 // 并发数量 + var concurrency = 1 // Concurrency quantity log.SetFlags(log.LstdFlags | log.Llongfile) dsnV2 := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", usernameV2, passwordV2, addrV2, databaseV2) diff --git a/tools/data-conversion/chat/v2/admin.go b/tools/data-conversion/chat/v2/admin.go index fec11ff5b..20cf22a36 100644 --- a/tools/data-conversion/chat/v2/admin.go +++ b/tools/data-conversion/chat/v2/admin.go @@ -18,7 +18,7 @@ import ( "time" ) -// AppVersion pc端版本管理 +// AppVersion manages PC client versions type AppVersion struct { Version string `gorm:"column:version;size:64" json:"version"` Type int `gorm:"column:type;primary_key" json:"type"` @@ -29,7 +29,7 @@ type AppVersion struct { UpdateLog string `gorm:"column:update_log" json:"update_log"` } -// Admin 后台管理员 +// Admin manages backend administrators type Admin struct { Account string `gorm:"column:account;primary_key;type:char(64)" json:"account"` Password string `gorm:"column:Password;type:char(64)" json:"password"` @@ -40,19 +40,19 @@ type Admin struct { CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// RegisterAddFriend 注册时默认好友 +// RegisterAddFriend specifies default friends when registering type RegisterAddFriend struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)" json:"userID"` CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// RegisterAddGroup 注册时默认群组 +// RegisterAddGroup specifies default groups when registering type RegisterAddGroup struct { GroupID string `gorm:"column:group_id;primary_key;type:char(64)" json:"userID"` CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// ClientInitConfig 系统相关配置项 +// ClientInitConfig contains system-related configuration items type ClientInitConfig struct { DiscoverPageURL string `gorm:"column:discover_page_url;size:128" json:"discoverPageURL"` OrdinaryUserAddFriend int32 `gorm:"column:ordinary_user_add_friend; default:1" json:"ordinaryUserAddFriend"` diff --git a/tools/data-conversion/chat/v2/chat.go b/tools/data-conversion/chat/v2/chat.go index 15cc4797f..4e0a0c04a 100644 --- a/tools/data-conversion/chat/v2/chat.go +++ b/tools/data-conversion/chat/v2/chat.go @@ -18,7 +18,7 @@ import ( "time" ) -// Register 注册信息表 +// Register Registration information sheet type Register struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)" json:"userID"` DeviceID string `gorm:"column:device_id;type:varchar(255)" json:"deviceID"` @@ -29,7 +29,7 @@ type Register struct { CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// Account 账号密码表 +// Account username and password table type Account struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)" json:"userID"` Password string `gorm:"column:password;type:varchar(255)" json:"password"` @@ -38,7 +38,7 @@ type Account struct { OperatorUserID string `gorm:"column:operator_user_id;type:varchar(64)" json:"operatorUserID"` } -// Attribute 用户属性表 +// Attribute user information table type Attribute struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)" json:"userID"` Account string `gorm:"column:account;type:char(64)" json:"account"` @@ -58,7 +58,7 @@ type Attribute struct { AllowAddFriend int32 `gorm:"column:allow_add_friend;default:1" json:"allowAddFriend"` } -// 封号表 +// User friend relationship table type ForbiddenAccount struct { UserID string `gorm:"column:user_id;index:userID;primary_key;type:char(64)" json:"userID"` CreateTime time.Time `gorm:"column:create_time" json:"createTime"` @@ -66,7 +66,7 @@ type ForbiddenAccount struct { OperatorUserID string `gorm:"column:operator_user_id;type:varchar(255)" json:"operatorUserID"` } -// 用户登录信息表 +// user login record table type UserLoginRecord struct { UserID string `gorm:"column:user_id;size:64" json:"userID"` LoginTime time.Time `gorm:"column:login_time" json:"loginTime"` @@ -75,7 +75,7 @@ type UserLoginRecord struct { Platform string `gorm:"column:platform;type:varchar(32)" json:"platform"` } -// 禁止ip登录 注册 +// ip login registration is prohibited type IPForbidden struct { IP string `gorm:"column:ip;primary_key;type:char(32)" json:"ip"` LimitRegister int32 `gorm:"column:limit_register" json:"limitRegister"` @@ -83,14 +83,14 @@ type IPForbidden struct { CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// 限制userID只能在某些ip登录 +// Restrict userids to certain ip addresses type LimitUserLoginIP struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)" json:"userID"` IP string `gorm:"column:ip;primary_key;type:char(32)" json:"ip"` CreateTime time.Time `gorm:"column:create_time" json:"createTime"` } -// 邀请码被注册使用 +// The invitation code is registered for use type InvitationRegister struct { InvitationCode string `gorm:"column:invitation_code;primary_key;type:char(32)" json:"invitationCode"` CreateTime time.Time `gorm:"column:create_time" json:"createTime"` diff --git a/tools/data-conversion/chat/v3/admin/admin.go b/tools/data-conversion/chat/v3/admin/admin.go index 22a81a068..90bd7f8f7 100644 --- a/tools/data-conversion/chat/v3/admin/admin.go +++ b/tools/data-conversion/chat/v3/admin/admin.go @@ -18,7 +18,7 @@ import ( "time" ) -// Admin 后台管理员. +// Admin Background administrator. type Admin struct { Account string `gorm:"column:account;primary_key;type:varchar(64)"` Password string `gorm:"column:password;type:varchar(64)"` diff --git a/tools/data-conversion/chat/v3/admin/client_config.go b/tools/data-conversion/chat/v3/admin/client_config.go index ceccd5105..48869fceb 100644 --- a/tools/data-conversion/chat/v3/admin/client_config.go +++ b/tools/data-conversion/chat/v3/admin/client_config.go @@ -14,7 +14,7 @@ package admin -// ClientConfig 客户端相关配置项. +// ClientConfig Client related configuration items. type ClientConfig struct { Key string `gorm:"column:key;primary_key;type:varchar(255)"` Value string `gorm:"column:value;not null;type:text"` diff --git a/tools/data-conversion/chat/v3/admin/forbidden_account.go b/tools/data-conversion/chat/v3/admin/forbidden_account.go index 104e793b0..e08125699 100644 --- a/tools/data-conversion/chat/v3/admin/forbidden_account.go +++ b/tools/data-conversion/chat/v3/admin/forbidden_account.go @@ -18,7 +18,7 @@ import ( "time" ) -// ForbiddenAccount 封号表. +// ForbiddenAccount forbidden account. type ForbiddenAccount struct { UserID string `gorm:"column:user_id;index:userID;primary_key;type:char(64)"` Reason string `gorm:"column:reason;type:varchar(255)" ` diff --git a/tools/data-conversion/chat/v3/admin/invitation_register.go b/tools/data-conversion/chat/v3/admin/invitation_register.go index 60f9067e2..4b71ccfe0 100644 --- a/tools/data-conversion/chat/v3/admin/invitation_register.go +++ b/tools/data-conversion/chat/v3/admin/invitation_register.go @@ -18,7 +18,7 @@ import ( "time" ) -// 邀请码被注册使用. +// The invitation code is registered for use. type InvitationRegister struct { InvitationCode string `gorm:"column:invitation_code;primary_key;type:char(32)"` UsedByUserID string `gorm:"column:user_id;index:userID;type:char(64)"` diff --git a/tools/data-conversion/chat/v3/admin/ip_forbidden.go b/tools/data-conversion/chat/v3/admin/ip_forbidden.go index 40c9257ef..886924abb 100644 --- a/tools/data-conversion/chat/v3/admin/ip_forbidden.go +++ b/tools/data-conversion/chat/v3/admin/ip_forbidden.go @@ -18,7 +18,7 @@ import ( "time" ) -// 禁止ip登录 注册. +// ip login registration is prohibited. type IPForbidden struct { IP string `gorm:"column:ip;primary_key;type:char(32)"` LimitRegister bool `gorm:"column:limit_register"` diff --git a/tools/data-conversion/chat/v3/admin/limit_user_login_ip.go b/tools/data-conversion/chat/v3/admin/limit_user_login_ip.go index 8427eaf80..0eaa5bc1e 100644 --- a/tools/data-conversion/chat/v3/admin/limit_user_login_ip.go +++ b/tools/data-conversion/chat/v3/admin/limit_user_login_ip.go @@ -18,7 +18,7 @@ import ( "time" ) -// 限制userID只能在某些ip登录. +// Restrict userids to certain ip addresses. type LimitUserLoginIP struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)"` IP string `gorm:"column:ip;primary_key;type:char(32)"` diff --git a/tools/data-conversion/chat/v3/admin/register_add_friend.go b/tools/data-conversion/chat/v3/admin/register_add_friend.go index e21896d90..8281f6485 100644 --- a/tools/data-conversion/chat/v3/admin/register_add_friend.go +++ b/tools/data-conversion/chat/v3/admin/register_add_friend.go @@ -18,7 +18,7 @@ import ( "time" ) -// RegisterAddFriend 注册时默认好友. +// RegisterAddFriend Indicates the default friend when registering. type RegisterAddFriend struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)"` CreateTime time.Time `gorm:"column:create_time"` diff --git a/tools/data-conversion/chat/v3/admin/register_add_group.go b/tools/data-conversion/chat/v3/admin/register_add_group.go index e9c1317b9..1204ff97b 100644 --- a/tools/data-conversion/chat/v3/admin/register_add_group.go +++ b/tools/data-conversion/chat/v3/admin/register_add_group.go @@ -18,7 +18,7 @@ import ( "time" ) -// RegisterAddGroup 注册时默认群组. +// RegisterAddGroup Indicates the default group for registration. type RegisterAddGroup struct { GroupID string `gorm:"column:group_id;primary_key;type:char(64)"` CreateTime time.Time `gorm:"column:create_time"` diff --git a/tools/data-conversion/chat/v3/chat/account.go b/tools/data-conversion/chat/v3/chat/account.go index d2117e7ca..6d01c20e2 100644 --- a/tools/data-conversion/chat/v3/chat/account.go +++ b/tools/data-conversion/chat/v3/chat/account.go @@ -18,7 +18,7 @@ import ( "time" ) -// Account 账号密码表. +// Account Account password table. type Account struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)"` Password string `gorm:"column:password;type:varchar(32)"` diff --git a/tools/data-conversion/chat/v3/chat/attribute.go b/tools/data-conversion/chat/v3/chat/attribute.go index 6a6f975d1..23de217bd 100644 --- a/tools/data-conversion/chat/v3/chat/attribute.go +++ b/tools/data-conversion/chat/v3/chat/attribute.go @@ -18,7 +18,7 @@ import ( "time" ) -// Attribute 用户属性表. +// Attribute Indicates the user attribute table. type Attribute struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)"` Account string `gorm:"column:account;type:char(64)"` diff --git a/tools/data-conversion/chat/v3/chat/register.go b/tools/data-conversion/chat/v3/chat/register.go index 740159436..29e5cb698 100644 --- a/tools/data-conversion/chat/v3/chat/register.go +++ b/tools/data-conversion/chat/v3/chat/register.go @@ -18,7 +18,7 @@ import ( "time" ) -// Register 注册信息表. +// Register Indicates the registration information. type Register struct { UserID string `gorm:"column:user_id;primary_key;type:char(64)"` DeviceID string `gorm:"column:device_id;type:varchar(255)"` diff --git a/tools/data-conversion/chat/v3/chat/user_login_record.go b/tools/data-conversion/chat/v3/chat/user_login_record.go index 8db3699d6..31e57b6ce 100644 --- a/tools/data-conversion/chat/v3/chat/user_login_record.go +++ b/tools/data-conversion/chat/v3/chat/user_login_record.go @@ -18,7 +18,7 @@ import ( "time" ) -// 用户登录信息表. +// User login information table. type UserLoginRecord struct { UserID string `gorm:"column:user_id;size:64"` LoginTime time.Time `gorm:"column:login_time"` diff --git a/tools/data-conversion/openim/cmd/conversion-msg/conversion-msg.go b/tools/data-conversion/openim/cmd/conversion-msg/conversion-msg.go index f2b9623a6..416fdcb9f 100644 --- a/tools/data-conversion/openim/cmd/conversion-msg/conversion-msg.go +++ b/tools/data-conversion/openim/cmd/conversion-msg/conversion-msg.go @@ -38,11 +38,20 @@ import ( func main() { var ( - topic = "ws2ms_chat" // v2版本配置文件kafka.topic.ws2ms_chat - kafkaAddr = "127.0.0.1:9092" // v2版本配置文件kafka.topic.addr - rpcAddr = "127.0.0.1:10130" // v3版本配置文件rpcPort.openImMessagePort - adminUserID = "openIM123456" // v3版本管理员userID - concurrency = 1 // 并发数量 + // The Kafka topic for ws2ms_chat in version 2 configuration + topic = "ws2ms_chat" + + // The Kafka address in version 2 configuration + kafkaAddr = "127.0.0.1:9092" + + // The RPC address in version 3 configuration + rpcAddr = "127.0.0.1:10130" + + // The administrator userID in version 3 + adminUserID = "openIM123456" + + // The number of concurrent processes + concurrency = 1 ) getRpcConn := func() (*grpc.ClientConn, error) { @@ -99,7 +108,7 @@ func main() { ch := pc.Messages() for { select { - case <-time.After(time.Second * 10): // 10s读取不到就关闭 + case <-time.After(time.Second * 10): // 10s Shuts down when the data cannot be read return case message, ok := <-ch: if !ok { diff --git a/tools/data-conversion/openim/cmd/conversion-mysql/conversion-mysql.go b/tools/data-conversion/openim/cmd/conversion-mysql/conversion-mysql.go index 8a951e16f..08fa4ca55 100644 --- a/tools/data-conversion/openim/cmd/conversion-mysql/conversion-mysql.go +++ b/tools/data-conversion/openim/cmd/conversion-mysql/conversion-mysql.go @@ -27,21 +27,37 @@ import ( ) func main() { + var ( - usernameV2 = "root" // v2版本mysql用户名 - passwordV2 = "openIM" // v2版本mysql密码 - addrV2 = "127.0.0.1:13306" // v2版本mysql地址 - databaseV2 = "openIM_v2" // v2版本mysql数据库名字 + // MySQL username for version 2 + usernameV2 = "root" + + // MySQL password for version 2 + passwordV2 = "openIM" + + // MySQL address for version 2 + addrV2 = "127.0.0.1:13306" + + // MySQL database name for version 2 + databaseV2 = "openIM_v2" ) var ( - usernameV3 = "root" // v3版本mysql用户名 - passwordV3 = "openIM123" // v3版本mysql密码 - addrV3 = "127.0.0.1:13306" // v3版本mysql地址 - databaseV3 = "openim_v3" // v3版本mysql数据库名字 + // MySQL username for version 3 + usernameV3 = "root" + + // MySQL password for version 3 + passwordV3 = "openIM123" + + // MySQL address for version 3 + addrV3 = "127.0.0.1:13306" + + // MySQL database name for version 3 + databaseV3 = "openim_v3" ) - var concurrency = 1 // 并发数量 + // The number of concurrent processes + var concurrency = 1 log.SetFlags(log.LstdFlags | log.Llongfile) dsnV2 := fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", usernameV2, passwordV2, addrV2, databaseV2) diff --git a/tools/data-conversion/openim/mysql/v3/friend.go b/tools/data-conversion/openim/mysql/v3/friend.go index 58d8d1d34..4f3fb6bdf 100644 --- a/tools/data-conversion/openim/mysql/v3/friend.go +++ b/tools/data-conversion/openim/mysql/v3/friend.go @@ -38,41 +38,30 @@ func (FriendModel) TableName() string { } type FriendModelInterface interface { - // 插入多条记录 - Create(ctx context.Context, friends []*FriendModel) (err error) - // 删除ownerUserID指定的好友 - Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) (err error) - // 更新ownerUserID单个好友信息 更新零值 - UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) (err error) - // 更新好友信息的非零值 - Update(ctx context.Context, friends []*FriendModel) (err error) - // 更新好友备注(也支持零值 ) - UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) - // 获取单个好友信息,如没找到 返回错误 - Take(ctx context.Context, ownerUserID, friendUserID string) (friend *FriendModel, err error) - // 查找好友关系,如果是双向关系,则都返回 - FindUserState(ctx context.Context, userID1, userID2 string) (friends []*FriendModel, err error) - // 获取 owner指定的好友列表 如果有friendUserIDs不存在,也不返回错误 - FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*FriendModel, err error) - // 获取哪些人添加了friendUserID 如果有ownerUserIDs不存在,也不返回错误 - FindReversalFriends( - ctx context.Context, - friendUserID string, - ownerUserIDs []string, - ) (friends []*FriendModel, err error) - // 获取ownerUserID好友列表 支持翻页 - FindOwnerFriends( - ctx context.Context, - ownerUserID string, - pageNumber, showNumber int32, - ) (friends []*FriendModel, total int64, err error) - // 获取哪些人添加了friendUserID 支持翻页 - FindInWhoseFriends( - ctx context.Context, - friendUserID string, - pageNumber, showNumber int32, - ) (friends []*FriendModel, total int64, err error) - // 获取好友UserID列表 - FindFriendUserIDs(ctx context.Context, ownerUserID string) (friendUserIDs []string, err error) + // Create inserts multiple friend records. + Create(ctx context.Context, friends []*FriendModel) error + // Delete removes specified friends for an owner user. + Delete(ctx context.Context, ownerUserID string, friendUserIDs []string) error + // UpdateByMap updates a single friend's information for an owner user based on a map of arguments. Zero values are updated. + UpdateByMap(ctx context.Context, ownerUserID string, friendUserID string, args map[string]interface{}) error + // Update modifies the information of friends, excluding zero values. + Update(ctx context.Context, friends []*FriendModel) error + // UpdateRemark updates the remark for a friend, supporting zero values. + UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) error + // Take retrieves a single friend's information. Returns an error if not found. + Take(ctx context.Context, ownerUserID, friendUserID string) (*FriendModel, error) + // FindUserState finds the friendship status between two users, returning both if a mutual friendship exists. + FindUserState(ctx context.Context, userID1, userID2 string) ([]*FriendModel, error) + // FindFriends retrieves a list of friends for an owner, not returning an error for non-existent friendUserIDs. + FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) ([]*FriendModel, error) + // FindReversalFriends finds who has added the specified user as a friend, not returning an error for non-existent ownerUserIDs. + FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string) ([]*FriendModel, error) + // FindOwnerFriends paginates through the friends list of an owner user. + FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) ([]*FriendModel, int64, error) + // FindInWhoseFriends paginates through users who have added the specified user as a friend. + FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) ([]*FriendModel, int64, error) + // FindFriendUserIDs retrieves a list of friend user IDs for an owner user. + FindFriendUserIDs(ctx context.Context, ownerUserID string) ([]string, error) + // NewTx creates a new transactional instance of the FriendModelInterface. NewTx(tx any) FriendModelInterface } diff --git a/tools/data-conversion/openim/mysql/v3/group.go b/tools/data-conversion/openim/mysql/v3/group.go index 6759e0d35..ccf61266a 100644 --- a/tools/data-conversion/openim/mysql/v3/group.go +++ b/tools/data-conversion/openim/mysql/v3/group.go @@ -58,9 +58,10 @@ type GroupModelInterface interface { keyword string, pageNumber, showNumber int32, ) (total uint32, groups []*GroupModel, err error) + // GetGroupIDsByCreatorUserID retrieves a list of group IDs created by the specified user. GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) - // 获取群总数 + // CountTotal retrieves the total number of groups. CountTotal(ctx context.Context, before *time.Time) (count int64, err error) - // 获取范围内群增量 + // CountRangeEverydayTotal retrieves the total number of groups created every day within the specified time range. CountRangeEverydayTotal(ctx context.Context, start time.Time, end time.Time) (map[string]int64, error) } diff --git a/tools/infra/infra.go b/tools/infra/infra.go index c14b92fa3..da7adf48e 100644 --- a/tools/infra/infra.go +++ b/tools/infra/infra.go @@ -20,7 +20,7 @@ import ( "github.com/fatih/color" ) -// 定义一个函数以打印重要的链接信息 +// Define a function to print important link information func printLinks() { blue := color.New(color.FgBlue).SprintFunc() fmt.Printf("OpenIM Github: %s\n", blue("https://github.com/OpenIMSDK/Open-IM-Server"))