From 5402d33519e94d08b8afec76b03d6385c90e3f60 Mon Sep 17 00:00:00 2001 From: skiffer-git <44203734@qq.com> Date: Thu, 2 Feb 2023 16:39:29 +0800 Subject: [PATCH 1/7] Error code standardization --- go.sum | 2 - internal/rpc/friend/friend.go | 97 ++++++++++++------------ internal/rpc/friend/other.go | 14 ---- pkg/common/db/controller/friend.go | 60 ++++++++++++--- pkg/common/db/controller/user.go | 50 +++++++++--- pkg/common/db/relation/friend_model_k.go | 22 +++++- pkg/common/db/relation/user_model_k.go | 5 +- 7 files changed, 161 insertions(+), 89 deletions(-) delete mode 100644 internal/rpc/friend/other.go diff --git a/go.sum b/go.sum index 0c4dff748..6da44054e 100644 --- a/go.sum +++ b/go.sum @@ -391,8 +391,6 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/OpenIMSDK/getcdv3 v1.0.3 h1:3/j92MuDPFhAJYBy/ht0qnybdaaCezefF1pMTClvvq4= -github.com/OpenIMSDK/getcdv3 v1.0.3/go.mod h1:ZvsBwAjOZZr7HBF3SytJaHCltuOfBKbM1vLSCjut7kw= github.com/OpenIMSDK/getcdv3 v1.0.4 h1:wKpLcp1gbLbh+fa7b5iCL4fTBLm87hB0+p0ZQMg9tK8= github.com/OpenIMSDK/getcdv3 v1.0.4/go.mod h1:ZvsBwAjOZZr7HBF3SytJaHCltuOfBKbM1vLSCjut7kw= github.com/OpenIMSDK/open_log v1.0.0 h1:ZQ908aWgPqfHOfkQ/oFSV20AZdRwPw+sZjC/sAPd5cA= diff --git a/internal/rpc/friend/friend.go b/internal/rpc/friend/friend.go index 8caa41a76..3a57642f3 100644 --- a/internal/rpc/friend/friend.go +++ b/internal/rpc/friend/friend.go @@ -7,14 +7,15 @@ import ( "Open_IM/pkg/common/constant" "Open_IM/pkg/common/db/controller" "Open_IM/pkg/common/db/relation" + "Open_IM/pkg/common/db/table" "Open_IM/pkg/common/log" "Open_IM/pkg/common/middleware" promePkg "Open_IM/pkg/common/prometheus" "Open_IM/pkg/common/token_verify" "Open_IM/pkg/common/tracelog" - "Open_IM/pkg/getcdv3" pbFriend "Open_IM/pkg/proto/friend" sdkws "Open_IM/pkg/proto/sdk_ws" + pbUser "Open_IM/pkg/proto/user" "Open_IM/pkg/utils" "context" grpcPrometheus "github.com/grpc-ecosystem/go-grpc-prometheus" @@ -23,6 +24,7 @@ import ( "strings" "Open_IM/internal/common/check" + "github.com/OpenIMSDK/getcdv3" "google.golang.org/grpc" ) @@ -33,6 +35,8 @@ type friendServer struct { etcdAddr []string controller.FriendInterface controller.BlackInterface + + userRpc pbUser.UserClient } func NewFriendServer(port int) *friendServer { @@ -43,10 +47,33 @@ func NewFriendServer(port int) *friendServer { etcdSchema: config.Config.Etcd.EtcdSchema, etcdAddr: config.Config.Etcd.EtcdAddr, } + ttl := 10 + etcdClient, err := getcdv3.NewEtcdConn(config.Config.Etcd.EtcdSchema, strings.Join(f.etcdAddr, ","), config.Config.RpcRegisterIP, config.Config.Etcd.UserName, config.Config.Etcd.Password, port, ttl) + if err != nil { + panic("NewEtcdConn failed" + err.Error()) + } + err = etcdClient.RegisterEtcd("", f.rpcRegisterName) + if err != nil { + panic("NewEtcdConn failed" + err.Error()) + } + + etcdClient.SetDefaultEtcdConfig(config.Config.RpcRegisterName.OpenImUserName, config.Config.RpcPort.OpenImUserPort) + conn := etcdClient.GetConn("", config.Config.RpcRegisterName.OpenImUserName) + f.userRpc = pbUser.NewUserClient(conn) + //mysql init var mysql relation.Mysql var model relation.FriendGorm - err := mysql.InitConn().AutoMigrateModel(&relation.FriendModel{}) + err = mysql.InitConn().AutoMigrateModel(&table.FriendModel{}) + if err != nil { + panic("db init err:" + err.Error()) + } + err = mysql.InitConn().AutoMigrateModel(&table.FriendRequestModel{}) + if err != nil { + panic("db init err:" + err.Error()) + } + + err = mysql.InitConn().AutoMigrateModel(&table.BlackModel{}) if err != nil { panic("db init err:" + err.Error()) } @@ -93,21 +120,7 @@ func (s *friendServer) Run() { } srv := grpc.NewServer(grpcOpts...) defer srv.GracefulStop() - //User friend related services register to etcd pbFriend.RegisterFriendServer(srv, s) - rpcRegisterIP := config.Config.RpcRegisterIP - if config.Config.RpcRegisterIP == "" { - rpcRegisterIP, err = utils.GetLocalIP() - if err != nil { - log.Error("", "GetLocalIP failed ", err.Error()) - } - } - log.NewInfo("", "rpcRegisterIP", rpcRegisterIP) - err = getcdv3.RegisterEtcd(s.etcdSchema, strings.Join(s.etcdAddr, ","), rpcRegisterIP, s.rpcPort, s.rpcRegisterName, 10, "") - if err != nil { - log.NewError("0", "RegisterEtcd failed ", err.Error(), s.etcdSchema, strings.Join(s.etcdAddr, ","), rpcRegisterIP, s.rpcPort, s.rpcRegisterName) - panic(utils.Wrap(err, "register friend module rpc to etcd err")) - } err = srv.Serve(listener) if err != nil { log.NewError("0", "Serve failed ", err.Error(), listener) @@ -153,9 +166,9 @@ func (s *friendServer) ImportFriends(ctx context.Context, req *pbFriend.ImportFr return nil, err } - var friends []*relation.Friend + var friends []*table.FriendModel for _, userID := range utils.RemoveDuplicateElement(req.FriendUserIDs) { - friends = append(friends, &relation.Friend{OwnerUserID: userID, FriendUserID: req.OwnerUserID, AddSource: constant.BecomeFriendByImport, OperatorUserID: tracelog.GetOpUserID(ctx)}) + friends = append(friends, &table.FriendModel{OwnerUserID: userID, FriendUserID: req.OwnerUserID, AddSource: constant.BecomeFriendByImport, OperatorUserID: tracelog.GetOpUserID(ctx)}) } if len(friends) > 0 { if err := s.FriendInterface.BecomeFriend(ctx, friends); err != nil { @@ -171,7 +184,7 @@ func (s *friendServer) RespondFriendApply(ctx context.Context, req *pbFriend.Res if err := check.Access(ctx, req.ToUserID); err != nil { return nil, err } - friendRequest := controller.FriendRequest{FromUserID: req.FromUserID, ToUserID: req.ToUserID, HandleMsg: req.HandleMsg, HandleResult: req.HandleResult} + friendRequest := table.FriendRequestModel{FromUserID: req.FromUserID, ToUserID: req.ToUserID, HandleMsg: req.HandleMsg, HandleResult: req.HandleResult} if req.HandleResult == constant.FriendResponseAgree { err := s.AgreeFriendRequest(ctx, &friendRequest) if err != nil { @@ -220,7 +233,7 @@ func (s *friendServer) GetFriends(ctx context.Context, req *pbFriend.GetFriendsR if err := check.Access(ctx, req.UserID); err != nil { return nil, err } - friends, err := s.FriendInterface.FindOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + friends, total, err := s.FriendInterface.FindOwnerFriends(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } @@ -236,14 +249,11 @@ func (s *friendServer) GetFriends(ctx context.Context, req *pbFriend.GetFriendsR for i, user := range users { userMap[user.UserID] = users[i] } - for _, friendUser := range friends { - - friendUserInfo, err := (convert.NewDBFriend(friendUser)).Convert() - if err != nil { - return nil, err - } - resp.FriendsInfo = append(resp.FriendsInfo, friendUserInfo) + resp.FriendsInfo, err = (*convert.DBFriend)(nil).DB2PB(friends) + if err != nil { + return nil, err } + resp.Total = int32(total) return resp, nil } @@ -253,17 +263,15 @@ func (s *friendServer) GetToFriendsApply(ctx context.Context, req *pbFriend.GetT if err := check.Access(ctx, req.UserID); err != nil { return nil, err } - friendRequests, err := s.FriendInterface.FindFriendRequestToMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + friendRequests, total, err := s.FriendInterface.FindFriendRequestToMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } - for _, v := range friendRequests { - fUser, err := convert.NewDBFriendRequest(v).Convert() - if err != nil { - return nil, err - } - resp.FriendRequests = append(resp.FriendRequests, fUser) + resp.FriendRequests, err = (*convert.DBFriendRequest)(nil).DB2PB(friendRequests) + if err != nil { + return nil, err } + resp.Total = int32(total) return resp, nil } @@ -273,17 +281,15 @@ func (s *friendServer) GetFromFriendsApply(ctx context.Context, req *pbFriend.Ge if err := check.Access(ctx, req.UserID); err != nil { return nil, err } - friendRequests, err := s.FriendInterface.FindFriendRequestFromMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) + friendRequests, total, err := s.FriendInterface.FindFriendRequestFromMe(ctx, req.UserID, req.Pagination.PageNumber, req.Pagination.ShowNumber) if err != nil { return nil, err } - for _, v := range friendRequests { - fUser, err := convert.NewDBFriendRequest(v).Convert() - if err != nil { - return nil, err - } - resp.FriendRequests = append(resp.FriendRequests, fUser) + resp.FriendRequests, err = (*convert.DBFriendRequest)(nil).DB2PB(friendRequests) + if err != nil { + return nil, err } + resp.Total = int32(total) return resp, nil } @@ -304,12 +310,9 @@ func (s *friendServer) GetFriendsInfo(ctx context.Context, req *pbFriend.GetFrie if err != nil { return nil, err } - for _, v := range friends { - fUser, err := convert.NewDBFriend(v).Convert() - if err != nil { - return nil, err - } - resp.FriendsInfo = append(resp.FriendsInfo, fUser) + resp.FriendsInfo, err = (*convert.DBFriend)(nil).DB2PB(friends) + if err != nil { + return nil, err } return &resp, nil } diff --git a/internal/rpc/friend/other.go b/internal/rpc/friend/other.go deleted file mode 100644 index 052caa171..000000000 --- a/internal/rpc/friend/other.go +++ /dev/null @@ -1,14 +0,0 @@ -package friend - -import ( - server_api_params "Open_IM/pkg/proto/sdk_ws" - "context" - "errors" -) - -func GetPublicUserInfoBatch(ctx context.Context, userIDs []string) ([]*server_api_params.PublicUserInfo, error) { - if len(userIDs) == 0 { - return []*server_api_params.PublicUserInfo{}, nil - } - return nil, errors.New("TODO:GetUserInfo") -} diff --git a/pkg/common/db/controller/friend.go b/pkg/common/db/controller/friend.go index 13bfd16b3..e61fe7054 100644 --- a/pkg/common/db/controller/friend.go +++ b/pkg/common/db/controller/friend.go @@ -1,6 +1,7 @@ package controller import ( + "Open_IM/pkg/common/constant" "Open_IM/pkg/common/db/relation" "Open_IM/pkg/common/db/table" "context" @@ -9,11 +10,11 @@ import ( type FriendInterface interface { // CheckIn 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true) - CheckIn(ctx context.Context, user1, user2 string) (err error, inUser1Friends bool, inUser2Friends bool) + CheckIn(ctx context.Context, user1, user2 string) (inUser1Friends bool, inUser2Friends bool, err error) // AddFriendRequest 增加或者更新好友申请 AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) // BecomeFriend 先判断是否在好友表,如果在则不插入 - BecomeFriend(ctx context.Context, friends []*table.FriendModel) (err error) + BecomeFriend(ctx context.Context, friends []*table.FriendModel, revFriends []*table.FriendModel) (err error) // RefuseFriendRequest 拒绝好友申请 RefuseFriendRequest(ctx context.Context, friendRequest *table.FriendRequestModel) (err error) // AgreeFriendRequest 同意好友申请 @@ -23,14 +24,14 @@ type FriendInterface interface { // UpdateRemark 更新好友备注 UpdateRemark(ctx context.Context, ownerUserID, friendUserID, remark string) (err error) // FindOwnerFriends 获取ownerUserID的好友列表 - FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, err error) + FindOwnerFriends(ctx context.Context, ownerUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) // FindInWhoseFriends friendUserID在哪些人的好友列表中 - FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, err error) + FindInWhoseFriends(ctx context.Context, friendUserID string, pageNumber, showNumber int32) (friends []*table.FriendModel, total int64, err error) // FindFriendRequestFromMe 获取我发出去的好友申请 - FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, err error) + FindFriendRequestFromMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) // FindFriendRequestToMe 获取我收到的的好友申请 - FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, err error) - // FindFriends 获取某人指定好友的信息 + FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, total int64, err error) + // FindFriends 获取某人指定好友的信息 如果有一个不存在也返回错误 FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) } @@ -92,7 +93,7 @@ func (f *FriendController) FindFriends(ctx context.Context, ownerUserID string, type FriendDatabaseInterface interface { // CheckIn 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true) - CheckIn(ctx context.Context, user1, user2 string) (err error, inUser1Friends bool, inUser2Friends bool) + CheckIn(ctx context.Context, user1, user2 string) (inUser1Friends bool, inUser2Friends bool, err error) // AddFriendRequest 增加或者更新好友申请 AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) // BecomeFriend 先判断是否在好友表,如果在则不插入 @@ -127,15 +128,44 @@ func NewFriendDatabase(db *gorm.DB) *FriendDatabase { } // CheckIn 检查user2是否在user1的好友列表中(inUser1Friends==true) 检查user1是否在user2的好友列表中(inUser2Friends==true) -func (f *FriendDatabase) CheckIn(ctx context.Context, user1, user2 string) (err error, inUser1Friends bool, inUser2Friends bool) { +func (f *FriendDatabase) CheckIn(ctx context.Context, userID1, userID2 string) (inUser1Friends bool, inUser2Friends bool, err error) { + friends, err := f.friend.FindUserState(ctx, userID1, userID2) + for _, v := range friends { + if v.OwnerUserID == userID1 && v.FriendUserID == userID2 { + inUser1Friends = true + } + if v.OwnerUserID == userID2 && v.FriendUserID == userID1 { + inUser2Friends = true + } + } + return } // AddFriendRequest 增加或者更新好友申请 func (f *FriendDatabase) AddFriendRequest(ctx context.Context, fromUserID, toUserID string, reqMsg string, ex string) (err error) { + } // BecomeFriend 先判断是否在好友表,如果在则不插入 -func (f *FriendDatabase) BecomeFriend(ctx context.Context, friends []*table.FriendModel) (err error) { +func (f *FriendDatabase) BecomeFriend(ctx context.Context, ownerUserID string, friends []*table.FriendModel) (err error) { + return f.friend.DB.Transaction(func(tx *gorm.DB) error { + //先find 找出重复的 去掉重复的 + friendUserIDs := make([]string, 0, len(friends)) + for _, v := range friends { + friendUserIDs = append(friendUserIDs, v.FriendUserID) + } + fs1, err := f.friend.FindFriends(ctx, ownerUserID, friendUserIDs, tx) + if err != nil { + return err + } + fs2, err := f.friend.FindReversalFriends(ctx, ownerUserID, friendUserIDs, tx) + if err != nil { + return err + } + + return nil + }) + } // RefuseFriendRequest 拒绝好友申请 @@ -170,6 +200,14 @@ func (f *FriendDatabase) FindFriendRequestFromMe(ctx context.Context, userID str func (f *FriendDatabase) FindFriendRequestToMe(ctx context.Context, userID string, pageNumber, showNumber int32) (friends []*table.FriendRequestModel, err error) { } -// FindFriends 获取某人指定好友的信息 +// FindFriends 获取某人指定好友的信息 如果有一个不存在也返回错误 func (f *FriendDatabase) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string) (friends []*table.FriendModel, err error) { + friends, err = f.friend.Find(ctx, ownerUserID, friendUserIDs) + if err != nil { + return + } + if len(friends) != len(friendUserIDs) { + err = constant.ErrRecordNotFound.Wrap() + } + return } diff --git a/pkg/common/db/controller/user.go b/pkg/common/db/controller/user.go index 0fefe77c6..1f904e8bf 100644 --- a/pkg/common/db/controller/user.go +++ b/pkg/common/db/controller/user.go @@ -1,6 +1,7 @@ package controller import ( + "Open_IM/pkg/common/constant" "Open_IM/pkg/common/db/relation" "Open_IM/pkg/common/db/table" "context" @@ -10,11 +11,17 @@ import ( type UserInterface interface { //获取指定用户的信息 如果有记录未找到 也返回错误 Find(ctx context.Context, userIDs []string) (users []*table.UserModel, err error) + //插入 Create(ctx context.Context, users []*table.UserModel) error + //更新 Update(ctx context.Context, users []*table.UserModel) (err error) + //更新带零值的 UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) + //通过名字搜索 GetByName(ctx context.Context, userName string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) + //通过名字和id搜索 GetByNameAndID(ctx context.Context, content string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) + //获取,如果没找到,不不返回错误 Get(ctx context.Context, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) //userIDs是否存在 只要有一个存在就为true IsExist(ctx context.Context, userIDs []string) (exist bool, err error) @@ -30,24 +37,29 @@ func (u *UserController) Find(ctx context.Context, userIDs []string) (users []*t func (u *UserController) Create(ctx context.Context, users []*table.UserModel) error { return u.database.Create(ctx, users) } -func (u *UserController) Take(ctx context.Context, userID string) (user *table.UserModel, err error) { - return u.database.Take(ctx, userID) -} + func (u *UserController) Update(ctx context.Context, users []*table.UserModel) (err error) { return u.database.Update(ctx, users) } func (u *UserController) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) { return u.database.UpdateByMap(ctx, userID, args) } + func (u *UserController) GetByName(ctx context.Context, userName string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) { return u.database.GetByName(ctx, userName, showNumber, pageNumber) } + func (u *UserController) GetByNameAndID(ctx context.Context, content string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) { return u.database.GetByNameAndID(ctx, content, showNumber, pageNumber) } + func (u *UserController) Get(ctx context.Context, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) { return u.database.Get(ctx, showNumber, pageNumber) } + +func (u *UserController) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) { + return u.IsExist(ctx, userIDs) +} func NewUserController(db *gorm.DB) *UserController { controller := &UserController{database: newUserDatabase(db)} return controller @@ -56,12 +68,12 @@ func NewUserController(db *gorm.DB) *UserController { type UserDatabaseInterface interface { Find(ctx context.Context, userIDs []string) (users []*table.UserModel, err error) Create(ctx context.Context, users []*table.UserModel) error - Take(ctx context.Context, userID string) (user *table.UserModel, err error) Update(ctx context.Context, users []*table.UserModel) (err error) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) GetByName(ctx context.Context, userName string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) GetByNameAndID(ctx context.Context, content string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) Get(ctx context.Context, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) + IsExist(ctx context.Context, userIDs []string) (exist bool, err error) } type UserDatabase struct { @@ -76,16 +88,22 @@ func newUserDatabase(db *gorm.DB) *UserDatabase { return database } +// 获取指定用户的信息 如果有记录未找到 也返回错误 func (u *UserDatabase) Find(ctx context.Context, userIDs []string) (users []*table.UserModel, err error) { - return u.sqlDB.Find(ctx, userIDs) + users, err = u.sqlDB.Find(ctx, userIDs) + if err != nil { + return + } + if len(users) != len(userIDs) { + err = constant.ErrRecordNotFound.Wrap() + } + return } -func (u *UserDatabase) Create(ctx context.Context, users []*table.UserModel) error { +func (u *UserDatabase) Create(ctx context.Context, users []*table.UserModel) (err error) { return u.sqlDB.Create(ctx, users) } -func (u *UserDatabase) Take(ctx context.Context, userID string) (user *table.UserModel, err error) { - return u.sqlDB.Take(ctx, userID) -} + func (u *UserDatabase) Update(ctx context.Context, users []*table.UserModel) (err error) { return u.sqlDB.Update(ctx, users) } @@ -98,6 +116,20 @@ func (u *UserDatabase) GetByName(ctx context.Context, userName string, showNumbe func (u *UserDatabase) GetByNameAndID(ctx context.Context, content string, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) { return u.sqlDB.GetByNameAndID(ctx, content, showNumber, pageNumber) } + +// 获取,如果没找到,不返回错误 func (u *UserDatabase) Get(ctx context.Context, showNumber, pageNumber int32) (users []*table.UserModel, count int64, err error) { return u.sqlDB.Get(ctx, showNumber, pageNumber) } + +// userIDs是否存在 只要有一个存在就为true +func (u *UserDatabase) IsExist(ctx context.Context, userIDs []string) (exist bool, err error) { + users, err := u.sqlDB.Find(ctx, userIDs) + if err != nil { + return + } + if len(users) > 0 { + return true, nil + } + return false, nil +} diff --git a/pkg/common/db/relation/friend_model_k.go b/pkg/common/db/relation/friend_model_k.go index b270fef99..05e889841 100644 --- a/pkg/common/db/relation/friend_model_k.go +++ b/pkg/common/db/relation/friend_model_k.go @@ -30,11 +30,11 @@ type FriendUser struct { Nickname string `gorm:"column:name;size:255"` } -func (f *FriendGorm) Create(ctx context.Context, friends []*table.FriendModel) (err error) { +func (f *FriendGorm) Create(ctx context.Context, friends []*table.FriendModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friends", friends) }() - return utils.Wrap(f.DB.Model(&table.FriendModel{}).Create(&friends).Error, "") + return utils.Wrap(getDBConn(f.DB, tx).Model(&table.FriendModel{}).Create(&friends).Error, "") } func (f *FriendGorm) Delete(ctx context.Context, ownerUserID string, friendUserIDs string) (err error) { @@ -52,7 +52,7 @@ func (f *FriendGorm) UpdateByMap(ctx context.Context, ownerUserID string, args m return utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("owner_user_id = ?", ownerUserID).Updates(args).Error, "") } -func (f *FriendGorm) Update(ctx context.Context, friends []*table.FriendModel) (err error) { +func (f *FriendGorm) Update(ctx context.Context, friends []*table.FriendModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friends", friends) }() @@ -92,3 +92,19 @@ func (f *FriendGorm) FindUserState(ctx context.Context, userID1, userID2 string) }() return friends, utils.Wrap(f.DB.Model(&table.FriendModel{}).Where("(owner_user_id = ? and friend_user_id = ?) or (owner_user_id = ? and friend_user_id = ?)", userID1, userID2, userID2, userID1).Find(&friends).Error, "") } + +// 获取 owner的好友列表 +func (f *FriendGorm) FindFriends(ctx context.Context, ownerUserID string, friendUserIDs []string, tx ...*gorm.DB) (friends []*table.FriendModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserIDs", friendUserIDs, "friends", friends) + }() + return friends, utils.Wrap(getDBConn(f.DB, tx).Where("owner_user_id = ? AND friend_user_id in (?)", ownerUserID, friendUserIDs).Find(&friends).Error, "") +} + +// 获取哪些人添加了friendUserID +func (f *FriendGorm) FindReversalFriends(ctx context.Context, friendUserID string, ownerUserIDs []string, tx ...*gorm.DB) (friends []*table.FriendModel, err error) { + defer func() { + tracelog.SetCtxDebug(ctx, utils.GetSelfFuncName(), err, "friendUserID", friendUserID, "friends", friends) + }() + return friends, utils.Wrap(getDBConn(f.DB, tx).Where("friend_user_id = ? AND owner_user_id in (?)", friendUserID, ownerUserIDs).Find(&friends).Error, "") +} diff --git a/pkg/common/db/relation/user_model_k.go b/pkg/common/db/relation/user_model_k.go index ce36d44fa..37dfb4e64 100644 --- a/pkg/common/db/relation/user_model_k.go +++ b/pkg/common/db/relation/user_model_k.go @@ -19,12 +19,11 @@ func NewUserGorm(db *gorm.DB) *UserGorm { return &user } -func (u *UserGorm) Create(ctx context.Context, users []*table.UserModel) (err error) { +func (u *UserGorm) Create(ctx context.Context, users []*table.UserModel, tx ...*gorm.DB) (err error) { defer func() { tracelog.SetCtxDebug(ctx, utils.GetFuncName(1), err, "users", users) }() - err = utils.Wrap(u.DB.Model(&table.UserModel{}).Create(&users).Error, "") - return err + return utils.Wrap(getDBConn(u.DB, tx).Model(&table.UserModel{}).Create(&users).Error, "") } func (u *UserGorm) UpdateByMap(ctx context.Context, userID string, args map[string]interface{}) (err error) { From 348cb921eb7e764d24d01114ea27c05138b42eec Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:25:09 +0800 Subject: [PATCH 2/7] Update config.yaml --- config/config.yaml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index 9499c99a0..c13e92673 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -738,18 +738,18 @@ demo: #demo对外服务端口,默认即可,需要开放此端口或做nginx转发 openImDemoPort: [ 10004 ] alismsverify: #阿里云短信配置,在阿里云申请成功后修改以下四项,enable为true则必须修改,阿里云为默认短信验证方式 - accessKeyId: LTAI5tJPkn4HuuePdiLdGqe7 - accessKeySecret: 4n9OJ7ZCVN1U6KeHDAtOyNeVZcjOuV - signName: 托云信息技术 - verificationCodeTemplateCode: SMS_226810164 + accessKeyId: + accessKeySecret: + signName: + verificationCodeTemplateCode: enable: false tencentsms: #腾讯云短信配置,在腾讯云申请成功后,修改以下选项,enable为true则必须修改 - appID: 2400000648 - region: "ap-singapore" - secretID: IKIDra4JPGsFMDwQedMq42lESQBgwwgBQQAe - secretKey: HI6fz4uUotjJdiX6QUIrAE2buxlKdgU2 - signName: "" - verificationCodeTemplateCode: 2902877 + appID: + region: + secretID: + secretKey: + signName: + verificationCodeTemplateCode: enable: true superCode: 666666 #超级验证码,建议修改掉,收不到短信验证码时可以用此替代 needInvitationCode: false @@ -757,11 +757,11 @@ demo: codeTTL: 60 useSuperCode: true mail: #仅支持qq邮箱,具体操作参考 https://service.mail.qq.com/cgi-bin/help?subtype=1&id=28&no=1001256 必须修改 - title: "openIM" - senderMail: "765567899@qq.com" - senderAuthorizationCode: "gxyausfoevlzbfag" - smtpAddr: "smtp.qq.com" - smtpPort: 25 #需开放此端口 出口方向 + title: + senderMail: + senderAuthorizationCode: + smtpAddr: + smtpPort: #需开放此端口 出口方向 testDepartMentID: 001 imAPIURL: http://127.0.0.1:10002 onboardProcess: false # 是否开启注册流程 @@ -791,4 +791,4 @@ prometheus: conversationPrometheusPort: [ 20230 ] cachePrometheusPort: [ 20240 ] realTimeCommPrometheusPort: [ 21300 ] - messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] # 端口数量和 script/path_info.cfg msg_transfer_service_num保持一致 \ No newline at end of file + messageTransferPrometheusPort: [ 21400, 21401, 21402, 21403 ] # 端口数量和 script/path_info.cfg msg_transfer_service_num保持一致 From 082a3b7e6552d5ecfded01fd6c1139dd29306471 Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:34:11 +0800 Subject: [PATCH 3/7] Update config.yaml --- config/config.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index c13e92673..f2d7c5868 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -115,11 +115,11 @@ sdk: #对象存储服务,以下配置二选一,目前支持两种,腾讯云和minio,二者配置好其中一种即可(如果使用minio参考https://doc.rentsoft.cn/#/qa/minio搭建minio服务器) credential: #腾讯cos,发送图片、视频、文件时需要,请自行申请后替换,必须修改 tencent: - appID: 1302656840 - region: ap-chengdu - bucket: echat-1302656840 - secretID: AKIDGNYVChzIQinu7QEgtNp0hnNgqcV8vZTC1 - secretKey: kz15vW83qM6dBUWIq681eBZA0c0vlIbe1 + appID: + region: + bucket: + secretID: + secretKey: minio: #MinIO 发送图片、视频、文件时需要,请自行申请后替换,必须修改。 客户端初始化InitSDK,中 object_storage参数为minio bucket: openim # 存储内容桶 appBucket: app # 存储app的桶 From 778e3e5cd275e69509447b110c842213a4c29a23 Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 2 Feb 2023 17:49:19 +0800 Subject: [PATCH 4/7] 1 --- pkg/utilsv2/slice.go | 229 +++++++++++++++++++++++++++++--------- pkg/utilsv2/slice_test.go | 34 ++++++ 2 files changed, 211 insertions(+), 52 deletions(-) diff --git a/pkg/utilsv2/slice.go b/pkg/utilsv2/slice.go index edeb1dc12..ab0d2e945 100644 --- a/pkg/utilsv2/slice.go +++ b/pkg/utilsv2/slice.go @@ -4,12 +4,12 @@ import ( "sort" ) -// DistinctAny 切片去重 -func DistinctAny[T any, V comparable](ts []T, fn func(t T) V) []T { - v := make([]T, 0, len(ts)) - tmp := map[V]struct{}{} - for i := 0; i < len(ts); i++ { - t := ts[i] +// DistinctAny remove duplicate elements +func DistinctAny[E any, K comparable](es []E, fn func(e E) K) []E { + v := make([]E, 0, len(es)) + tmp := map[K]struct{}{} + for i := 0; i < len(es); i++ { + t := es[i] k := fn(t) if _, ok := tmp[k]; !ok { tmp[k] = struct{}{} @@ -19,80 +19,204 @@ func DistinctAny[T any, V comparable](ts []T, fn func(t T) V) []T { return v } -// Distinct 切片去重 +// Distinct remove duplicate elements func Distinct[T comparable](ts []T) []T { return DistinctAny(ts, func(t T) T { return t }) } -// DeleteAt 删除切片元素, 支持负数删除倒数第几个 -func DeleteAt[T any](ts []T, index ...int) []T { +// DeleteAt delete slice element, support negative number to delete the penultimate +func DeleteAt[E any](es []E, index ...int) []E { switch len(index) { case 0: - return ts + return es case 1: i := index[0] if i < 0 { - i = len(ts) + i + i = len(es) + i } - if len(ts) <= i { - return ts + if len(es) <= i { + return es } - return append(ts[:i], ts[i+1:]...) + return append(es[:i], es[i+1:]...) default: tmp := make(map[int]struct{}) for _, i := range index { if i < 0 { - i = len(ts) + i + i = len(es) + i } tmp[i] = struct{}{} } - v := make([]T, 0, len(ts)) - for i := 0; i < len(ts); i++ { + v := make([]E, 0, len(es)) + for i := 0; i < len(es); i++ { if _, ok := tmp[i]; !ok { - v = append(v, ts[i]) + v = append(v, es[i]) } } return v } } -// IndexAny 获取元素所在的下标 -func IndexAny[T any, V comparable](ts []T, t T, fn func(t T) V) int { - k := fn(t) - for i := 0; i < len(ts); i++ { - if fn(ts[i]) == k { +// IndexAny get the index of the element +func IndexAny[E any, K comparable](es []E, e E, fn func(e E) K) int { + k := fn(e) + for i := 0; i < len(es); i++ { + if fn(es[i]) == k { return i } } return -1 } -// IndexOf 可比较的元素index下标 -func IndexOf[T comparable](ts []T, t T) int { - return IndexAny(ts, t, func(t T) T { +// IndexOf get the index of the element +func IndexOf[E comparable](es []E, e E) int { + return IndexAny(es, e, func(t E) E { return t }) } -// IsContain 是否包含元素 -func IsContain[T comparable](ts []T, t T) bool { - return IndexOf(ts, t) >= 0 +// Contain include element or not +func Contain[E comparable](es []E, e E) bool { + return IndexOf(es, e) >= 0 } -// SliceToMap 切片转map -func SliceToMap[T any, K comparable](ts []T, fn func(t T) K) map[K]T { - kv := make(map[K]T) - for i := 0; i < len(ts); i++ { - t := ts[i] - k := fn(t) - kv[k] = t +// SliceToMapOkAny slice to map +func SliceToMapOkAny[E any, K comparable, V any](es []E, fn func(e E) (K, V, bool)) map[K]V { + kv := make(map[K]V) + for i := 0; i < len(es); i++ { + t := es[i] + if k, v, ok := fn(t); ok { + kv[k] = v + } } return kv } -// MapKey map获取所有key +// SliceToMapAny slice to map +func SliceToMapAny[E any, K comparable, V any](es []E, fn func(e E) (K, V)) map[K]V { + return SliceToMapOkAny(es, func(e E) (K, V, bool) { + k, v := fn(e) + return k, v, true + }) +} + +// SliceToMap slice to map +func SliceToMap[E any, K comparable](es []E, fn func(e E) K) map[K]E { + return SliceToMapOkAny[E, K, E](es, func(e E) (K, E, bool) { + k := fn(e) + return k, e, true + }) +} + +// SliceSetAny slice to map[K]struct{} +func SliceSetAny[E any, K comparable](es []E, fn func(e E) K) map[K]struct{} { + return SliceToMapAny(es, func(e E) (K, struct{}) { + return fn(e), struct{}{} + }) +} + +// SliceSet slice to map[E]struct{} +func SliceSet[E comparable](es []E) map[E]struct{} { + return SliceSetAny(es, func(e E) E { + return e + }) +} + +// HasKey get whether the map contains key +func HasKey[K comparable, V any](m map[K]V, k K) bool { + if m == nil { + return false + } + _, ok := m[k] + return ok +} + +// Min get minimum value +func Min[E Ordered](e ...E) E { + v := e[0] + for _, t := range e[1:] { + if v > t { + v = t + } + } + return v +} + +// Max get maximum value +func Max[E Ordered](e ...E) E { + v := e[0] + for _, t := range e[1:] { + if v < t { + v = t + } + } + return v +} + +// BothExistAny get elements common to multiple slices +func BothExistAny[E any, K comparable](es [][]E, fn func(e E) K) []E { + if len(es) == 0 { + return []E{} + } + var idx int + ei := make([]map[K]E, len(es)) + for i := 0; i < len(ei); i++ { + e := es[i] + if len(e) == 0 { + return []E{} + } + kv := make(map[K]E) + for j := 0; j < len(e); j++ { + t := e[j] + k := fn(t) + kv[k] = t + } + ei[i] = kv + if len(kv) < len(ei[idx]) { + idx = i + } + } + v := make([]E, 0, len(ei[idx])) + for k := range ei[idx] { + all := true + for i := 0; i < len(ei); i++ { + if i == idx { + continue + } + if _, ok := ei[i][k]; !ok { + all = false + break + } + } + if !all { + continue + } + v = append(v, ei[idx][k]) + } + return v +} + +// BothExist get elements common to multiple slices +func BothExist[E comparable](es ...[]E) []E { + return BothExistAny(es, func(e E) E { + return e + }) +} + +// CompleteAny complete inclusion +func CompleteAny[K comparable, E any](ks []K, es []E, fn func(e E) K) bool { + a := SliceSetAny(es, fn) + for k := range SliceSet(ks) { + if !HasKey(a, k) { + return false + } + delete(a, k) + } + return len(a) == 0 +} + +// MapKey get map keys func MapKey[K comparable, V any](kv map[K]V) []K { ks := make([]K, 0, len(kv)) for k := range kv { @@ -101,7 +225,7 @@ func MapKey[K comparable, V any](kv map[K]V) []K { return ks } -// MapValue map获取所有key +// MapValue get map values func MapValue[K comparable, V any](kv map[K]V) []V { vs := make([]V, 0, len(kv)) for k := range kv { @@ -110,43 +234,44 @@ func MapValue[K comparable, V any](kv map[K]V) []V { return vs } -// Sort 排序 -func Sort[T Ordered](ts []T, asc bool) []T { - SortAny(ts, func(a, b T) bool { +// Sort basic type sorting +func Sort[E Ordered](es []E, asc bool) []E { + SortAny(es, func(a, b E) bool { if asc { return a < b } else { return a > b } }) - return ts + return es } -// SortAny 排序 -func SortAny[T any](ts []T, fn func(a, b T) bool) { - sort.Sort(&sortSlice[T]{ - ts: ts, +// SortAny custom sort method +func SortAny[E any](es []E, fn func(a, b E) bool) { + sort.Sort(&sortSlice[E]{ + ts: es, fn: fn, }) } -type sortSlice[T any] struct { - ts []T - fn func(a, b T) bool +type sortSlice[E any] struct { + ts []E + fn func(a, b E) bool } -func (o *sortSlice[T]) Len() int { +func (o *sortSlice[E]) Len() int { return len(o.ts) } -func (o *sortSlice[T]) Less(i, j int) bool { +func (o *sortSlice[E]) Less(i, j int) bool { return o.fn(o.ts[i], o.ts[j]) } -func (o *sortSlice[T]) Swap(i, j int) { +func (o *sortSlice[E]) Swap(i, j int) { o.ts[i], o.ts[j] = o.ts[j], o.ts[i] } +// Ordered types that can be sorted type Ordered interface { ~int | ~int8 | ~int16 | ~int32 | ~int64 | ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | ~float32 | ~float64 | ~string } diff --git a/pkg/utilsv2/slice_test.go b/pkg/utilsv2/slice_test.go index 2dc81d80a..fd18c497e 100644 --- a/pkg/utilsv2/slice_test.go +++ b/pkg/utilsv2/slice_test.go @@ -46,5 +46,39 @@ func TestIndexOf(t *testing.T) { func TestSort(t *testing.T) { arr := []int{1, 1, 1, 4, 4, 5, 2, 3, 3, 3, 6} fmt.Println(Sort(arr, false)) +} + +func TestBothExist(t *testing.T) { + arr1 := []int{1, 1, 1, 4, 4, 5, 2, 3, 3, 3, 6} + arr2 := []int{6, 1, 3} + arr3 := []int{5, 1, 3, 6} + fmt.Println(BothExist(arr1, arr2, arr3)) +} + +func TestCompleteAny(t *testing.T) { + type Item struct { + ID int + Value string + } + + ids := []int{1, 2, 3, 4, 5, 6, 7, 8} + + var list []Item + + for _, id := range ids { + list = append(list, Item{ + ID: id, + Value: fmt.Sprintf("%d", id*1000), + }) + } + + list = DeleteAt(list, -1) + ids = DeleteAt(ids, -1) + + ok := CompleteAny(ids, list, func(t Item) int { + return t.ID + }) + + fmt.Printf("%+v\n", ok) } From 0e5f3dacd6ab9bacea5415852678a539d2fa0285 Mon Sep 17 00:00:00 2001 From: skiffer-git <72860476+skiffer-git@users.noreply.github.com> Date: Thu, 2 Feb 2023 17:51:59 +0800 Subject: [PATCH 5/7] Update config.yaml --- config/config.yaml | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/config/config.yaml b/config/config.yaml index f2d7c5868..14f383eb0 100644 --- a/config/config.yaml +++ b/config/config.yaml @@ -132,24 +132,24 @@ credential: #腾讯cos,发送图片、视频、文件时需要,请自行申 storageTime: 50 #文件在minio中保存的时间 isDistributedMod: false # 是否分布式多硬盘部署 默认docker-compose中为false ali: # ali oss - regionID: "oss-cn-beijing" - accessKeyID: "" - accessKeySecret: "" - stsEndpoint: "sts.cn-beijing.aliyun.com" - ossEndpoint: "oss-cn-beijing.aliyuncs.com" - bucket: "bucket1" - finalHost: "http://bucket1.oss-cn-beijing.aliyuncs.com" - stsDurationSeconds: 3600 - OssRoleArn: "acs:ram::xxx:role/xxx" + regionID: + accessKeyID: + accessKeySecret: + stsEndpoint: + ossEndpoint: + bucket: + finalHost: + stsDurationSeconds: + OssRoleArn: aws: - accessKeyID: 1 #AssumeRole用户关联的accessKeyID - accessKeySecret: 2 #AssumeRole用户关联的accessKeySecrect - region: ap-southeast-1 #分区 - bucket: ouyang #桶 - finalHost: ouyang.s3.ap-southeast-1.amazonaws.com #对外Host - roleArn: arn:aws:iam::192209831083:role/AWS_S3_FOR_OUYANG #RoleArn - externalId: AssumeRoleExtend #角色扩展Id - roleSessionName: Required-AWS-ID-OPENIM #角色SESSION名称 + accessKeyID: #AssumeRole用户关联的accessKeyID + accessKeySecret: #AssumeRole用户关联的accessKeySecrect + region: #分区 + bucket: #桶 + finalHost: #对外Host + roleArn: #RoleArn + externalId: #角色扩展Id + roleSessionName: #角色SESSION名称 rpcport: #rpc服务端口 默认即可 @@ -221,10 +221,10 @@ push: secretKey: 111 enable: false # true or false (bool) jpns: #极光推送 在极光后台申请后,修改以下四项,必须修改 - appKey: cf47465a368f24c659608e7e - masterSecret: 02204efe3f3832947a236ee5 - pushUrl: "https://api.jpush.cn/v3/push" - pushIntent: "intent:#Intent;component=io.openim.app.enterprisechat/io.openim.app.enterprisechat.MainActivity;end" + appKey: + masterSecret: + pushUrl: + pushIntent: enable: false # true or false (bool) getui: #个推推送 pushUrl: @@ -238,10 +238,10 @@ push: serviceAccount: "openim-5c6c0-firebase-adminsdk-ppwol-8765884a78.json" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下 enable: false mob: #袤博推送 - appKey: "3377f689a25" #帐号文件,此处需要改修配置,并且这个文件放在 config目录下 - pushUrl: "https://api.push.mob.com/v3/push/createPush" - scheme: "dianzhijiaunilinks://dianzhijia.com?page=rent" - appSecret: "77b4e20e94db3a776b87d8693be23e" + appKey: #帐号文件,此处需要改修配置,并且这个文件放在 config目录下 + pushUrl: + scheme: + appSecret: enable: false From e8a24ab59e782cf2ee37b8744550db75a39b244a Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 2 Feb 2023 17:54:02 +0800 Subject: [PATCH 6/7] 1 --- pkg/{utilsv2/slice.go => utils/utils_v2.go} | 13 ++++++++++--- .../slice_test.go => utils/utils_v2_test.go} | 12 ++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) rename pkg/{utilsv2/slice.go => utils/utils_v2.go} (95%) rename pkg/{utilsv2/slice_test.go => utils/utils_v2_test.go} (88%) diff --git a/pkg/utilsv2/slice.go b/pkg/utils/utils_v2.go similarity index 95% rename from pkg/utilsv2/slice.go rename to pkg/utils/utils_v2.go index ab0d2e945..342638421 100644 --- a/pkg/utilsv2/slice.go +++ b/pkg/utils/utils_v2.go @@ -1,4 +1,4 @@ -package utilsv2 +package utils import ( "sort" @@ -26,8 +26,8 @@ func Distinct[T comparable](ts []T) []T { }) } -// DeleteAt delete slice element, support negative number to delete the penultimate -func DeleteAt[E any](es []E, index ...int) []E { +// Delete delete slice element, support negative number to delete the penultimate +func Delete[E any](es []E, index ...int) []E { switch len(index) { case 0: return es @@ -58,6 +58,13 @@ func DeleteAt[E any](es []E, index ...int) []E { } } +// DeleteAt delete slice element, support negative number to delete the penultimate +func DeleteAt[E any](es *[]E, index ...int) []E { + v := Delete(*es, index...) + *es = v + return v +} + // IndexAny get the index of the element func IndexAny[E any, K comparable](es []E, e E, fn func(e E) K) int { k := fn(e) diff --git a/pkg/utilsv2/slice_test.go b/pkg/utils/utils_v2_test.go similarity index 88% rename from pkg/utilsv2/slice_test.go rename to pkg/utils/utils_v2_test.go index fd18c497e..270cf4d69 100644 --- a/pkg/utilsv2/slice_test.go +++ b/pkg/utils/utils_v2_test.go @@ -1,4 +1,4 @@ -package utilsv2 +package utils import ( "fmt" @@ -12,9 +12,9 @@ func TestDistinct(t *testing.T) { func TestDeleteAt(t *testing.T) { arr := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - fmt.Println(DeleteAt(arr, 0, 1, -1, -2)) - fmt.Println(DeleteAt(arr)) - fmt.Println(DeleteAt(arr, 1)) + fmt.Println(Delete(arr, 0, 1, -1, -2)) + fmt.Println(Delete(arr)) + fmt.Println(Delete(arr, 1)) } func TestSliceToMap(t *testing.T) { @@ -72,8 +72,8 @@ func TestCompleteAny(t *testing.T) { }) } - list = DeleteAt(list, -1) - ids = DeleteAt(ids, -1) + DeleteAt(&list, -1) + DeleteAt(&ids, -1) ok := CompleteAny(ids, list, func(t Item) int { return t.ID From dec0c8cc47e5134aacc816567ea980bcefd0affc Mon Sep 17 00:00:00 2001 From: withchao <993506633@qq.com> Date: Thu, 2 Feb 2023 18:45:43 +0800 Subject: [PATCH 7/7] 1 --- pkg/utils/utils_v2.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/utils/utils_v2.go b/pkg/utils/utils_v2.go index 342638421..1822f0c89 100644 --- a/pkg/utils/utils_v2.go +++ b/pkg/utils/utils_v2.go @@ -261,6 +261,14 @@ func SortAny[E any](es []E, fn func(a, b E) bool) { }) } +// If true -> a, false -> b +func If[T any](isa bool, a, b T) T { + if isa { + return a + } + return b +} + type sortSlice[E any] struct { ts []E fn func(a, b E) bool