diff --git a/cmd/open_im_api/main.go b/cmd/open_im_api/main.go index 7a1fb2993..58378e119 100644 --- a/cmd/open_im_api/main.go +++ b/cmd/open_im_api/main.go @@ -108,11 +108,6 @@ func main() { conversationGroup.POST("/set_conversation", conversation.SetConversation) conversationGroup.POST("/batch_set_conversation", conversation.BatchSetConversations) conversationGroup.POST("/set_recv_msg_opt", conversation.SetRecvMsgOpt) - - // Deprecated - conversationGroup.POST("/set_receive_message_opt", conversation.SetReceiveMessageOpt) //1 - conversationGroup.POST("/get_receive_message_opt", conversation.GetReceiveMessageOpt) //1 - conversationGroup.POST("/get_all_conversation_message_opt", conversation.GetAllConversationMessageOpt) //1 } // office officeGroup := r.Group("/office") @@ -122,7 +117,7 @@ func main() { officeGroup.POST("/delete_tag", office.DeleteTag) officeGroup.POST("/set_tag", office.SetTag) officeGroup.POST("/send_msg_to_tag", office.SendMsg2Tag) - officeGroup.POST("/get_send_tag_log", office.GetSendTagLogs) + officeGroup.POST("/get_send_tag_log", office.GetTagSendLogs) } apiThird.MinioInit() diff --git a/internal/api/office/tag.go b/internal/api/office/tag.go index 4644a27ed..23b5d2e54 100644 --- a/internal/api/office/tag.go +++ b/internal/api/office/tag.go @@ -159,12 +159,12 @@ func SendMsg2Tag(c *gin.Context) { c.JSON(http.StatusOK, resp) } -func GetSendTagLogs(c *gin.Context) { +func GetTagSendLogs(c *gin.Context) { var ( - req apistruct.SendMsg2TagReq - resp apistruct.SendMsg2TagResp - reqPb pbOffice.SendMsg2TagReq - respPb *pbOffice.SendMsg2TagResp + req apistruct.GetTagSendLogsReq + resp apistruct.GetTagSendLogsResp + reqPb pbOffice.GetTagSendLogsReq + respPb *pbOffice.GetTagSendLogsResp ) if err := c.BindJSON(&req); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "bind json failed", err.Error()) @@ -176,7 +176,7 @@ func GetSendTagLogs(c *gin.Context) { } etcdConn := getcdv3.GetConn(config.Config.Etcd.EtcdSchema, strings.Join(config.Config.Etcd.EtcdAddr, ","), config.Config.RpcRegisterName.OpenImOfficeName) client := pbOffice.NewOfficeServiceClient(etcdConn) - respPb, err := client.SendMsg2Tag(context.Background(), &reqPb) + respPb, err := client.GetTagSendLogs(context.Background(), &reqPb) if err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserTags failed", err.Error()) c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": "CreateTag rpc server failed" + err.Error()}) @@ -185,5 +185,8 @@ func GetSendTagLogs(c *gin.Context) { if err := utils.CopyStructFields(&resp.CommResp, respPb.CommonResp); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error()) } + resp.Data.Logs = respPb.TagSendLogs + resp.Data.ShowNumber = respPb.Pagination.ShowNumber + resp.Data.CurrentPage = respPb.Pagination.CurrentPage c.JSON(http.StatusOK, resp) } diff --git a/internal/rpc/office/office.go b/internal/rpc/office/office.go index 9e297531d..1f803359b 100644 --- a/internal/rpc/office/office.go +++ b/internal/rpc/office/office.go @@ -5,6 +5,7 @@ import ( "Open_IM/pkg/common/config" "Open_IM/pkg/common/constant" "Open_IM/pkg/common/db" + "Open_IM/pkg/common/db/mysql_model/im_mysql_model" "Open_IM/pkg/common/log" "Open_IM/pkg/grpc-etcdv3/getcdv3" pbOffice "Open_IM/pkg/proto/office" @@ -77,11 +78,23 @@ func (s *officeServer) GetUserTags(_ context.Context, req *pbOffice.GetUserTagsR resp.CommonResp.ErrCode = constant.ErrDB.ErrCode return resp, nil } - if err := utils.CopyStructFields(resp.Tags, tags); err != nil { - log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error()) - } - for _, v := range resp.Tags { - + for _, v := range tags { + tag := &pbOffice.Tag{ + TagID: v.TagID, + TagName: v.TagName, + } + for _, userID := range v.UserList { + UserName, err := im_mysql_model.GetUserNameByUserID(userID) + if err != nil { + log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserNameByUserID failed", err.Error()) + continue + } + tag.UserList = append(tag.UserList, &pbOffice.TagUser{ + UserID: userID, + UserName: UserName, + }) + } + resp.Tags = append(resp.Tags, tag) } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp ", resp.String()) return resp, nil @@ -89,8 +102,10 @@ func (s *officeServer) GetUserTags(_ context.Context, req *pbOffice.GetUserTagsR func (s *officeServer) CreateTag(_ context.Context, req *pbOffice.CreateTagReq) (resp *pbOffice.CreateTagResp, err error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "CreateTag req", req.String()) + userIDList := utils.RemoveUserIDRepByMap(req.UserIDList) + log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "userIDList: ", userIDList) resp = &pbOffice.CreateTagResp{CommonResp: &pbOffice.CommonResp{}} - if err := db.DB.CreateTag(req.UserID, req.TagName, req.UserIDList); err != nil { + if err := db.DB.CreateTag(req.UserID, req.TagName, userIDList); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetUserTags failed", err.Error()) resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg resp.CommonResp.ErrCode = constant.ErrDB.ErrCode @@ -116,14 +131,16 @@ func (s *officeServer) DeleteTag(_ context.Context, req *pbOffice.DeleteTagReq) func (s *officeServer) SetTag(_ context.Context, req *pbOffice.SetTagReq) (resp *pbOffice.SetTagResp, err error) { log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "req: ", req.String()) resp = &pbOffice.SetTagResp{CommonResp: &pbOffice.CommonResp{}} - if err := db.DB.SetTag(req.UserID, req.TagID, req.NewName, req.ReduceUserIDList, req.ReduceUserIDList); err != nil { + IncreaseUserIDList := utils.RemoveUserIDRepByMap(req.IncreaseUserIDList) + reduceUserIDList := utils.RemoveUserIDRepByMap(req.ReduceUserIDList) + if err := db.DB.SetTag(req.UserID, req.TagID, req.NewName, IncreaseUserIDList, reduceUserIDList); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "SetTag failed", err.Error()) resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg resp.CommonResp.ErrCode = constant.ErrDB.ErrCode return resp, nil } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) - return resp, err + return resp, nil } func (s *officeServer) SendMsg2Tag(_ context.Context, req *pbOffice.SendMsg2TagReq) (resp *pbOffice.SendMsg2TagResp, err error) { @@ -135,9 +152,12 @@ func (s *officeServer) SendMsg2Tag(_ context.Context, req *pbOffice.SendMsg2TagR } if err := db.DB.SaveTagSendLog(req); err != nil { log.NewError(req.OperationID, utils.GetSelfFuncName(), "SaveTagSendLog failed", err.Error()) + resp.CommonResp.ErrCode = constant.ErrDB.ErrCode + resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg + return resp, nil } log.NewInfo(req.OperationID, utils.GetSelfFuncName(), "resp: ", resp.String()) - return resp, err + return resp, nil } func (s *officeServer) GetTagSendLogs(_ context.Context, req *pbOffice.GetTagSendLogsReq) (resp *pbOffice.GetTagSendLogsResp, err error) { @@ -150,6 +170,7 @@ func (s *officeServer) GetTagSendLogs(_ context.Context, req *pbOffice.GetTagSen log.NewError(req.OperationID, utils.GetSelfFuncName(), "GetTagSendLogs", err.Error()) resp.CommonResp.ErrMsg = constant.ErrDB.ErrMsg resp.CommonResp.ErrCode = constant.ErrDB.ErrCode + return resp, nil } if err := utils.CopyStructFields(resp.TagSendLogs, tagSendLogs); err != nil { log.NewDebug(req.OperationID, utils.GetSelfFuncName(), "CopyStructFields failed", err.Error()) diff --git a/pkg/base_info/office_struct.go b/pkg/base_info/office_struct.go index 2c6dd84c1..85cb86090 100644 --- a/pkg/base_info/office_struct.go +++ b/pkg/base_info/office_struct.go @@ -1,6 +1,9 @@ package base_info -import pbOffice "Open_IM/pkg/proto/office" +import ( + pbOffice "Open_IM/pkg/proto/office" + server_api_params "Open_IM/pkg/proto/sdk_ws" +) type GetUserTagsReq struct { pbOffice.GetUserTagsReq @@ -44,3 +47,18 @@ type SendMsg2TagReq struct { type SendMsg2TagResp struct { CommResp } + +type GetTagSendLogsReq struct { + server_api_params.RequestPagination + UserID string `json:"userID"` + OperationID string `json:"operationID"` +} + +type GetTagSendLogsResp struct { + CommResp + Data struct { + Logs []*pbOffice.TagSendLog `json:"logs"` + CurrentPage int32 `json:"currentPage"` + ShowNumber int32 `json:"showNumber"` + } `json:"data"` +} diff --git a/pkg/common/db/mongoModel.go b/pkg/common/db/mongoModel.go index 370d1acd3..6320a6d8e 100644 --- a/pkg/common/db/mongoModel.go +++ b/pkg/common/db/mongoModel.go @@ -12,6 +12,7 @@ import ( "errors" "fmt" "github.com/gogo/protobuf/sortkeys" + "go.mongodb.org/mongo-driver/mongo/options" "math/rand" //"github.com/garyburd/redigo/redis" @@ -435,27 +436,22 @@ func (d *DataBases) DelGroupMember(groupID, uid string) error { } type Tag struct { + UserID string `bson:"userID"` TagID string `bson:"tagID"` TagName string `bson:"tagName"` UserList []string `bson:"userList"` } -type TagsStruct struct { - Uid string `bson:"uid"` - Tags map[string]Tag `bson:"tags"` -} - -type TagSendLogStruct struct { -} - func (d *DataBases) GetUserTags(userID string) ([]Tag, error) { ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cTag) - var tagStruct TagsStruct var tags []Tag - _ = c.FindOne(ctx, bson.M{"uid": userID}).Decode(&tagStruct) - for _, v := range tagStruct.Tags { - tags = append(tags, v) + cursor, err := c.Find(ctx, bson.M{"userID": userID}) + if err != nil { + return tags, err + } + if err = cursor.Decode(tags); err != nil { + return tags, err } return tags, nil } @@ -465,58 +461,68 @@ func (d *DataBases) CreateTag(userID, tagName string, userList []string) error { c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cTag) tagID := generateTagID(tagName, userID) tag := Tag{ + UserID: userID, TagID: tagID, TagName: tagName, UserList: userList, } - _, err := c.InsertOne(ctx, TagsStruct{ - Uid: userID, - Tags: map[string]Tag{tagID: tag}, - }) + _, err := c.InsertOne(ctx, tag) return err } func (d *DataBases) DeleteTag(userID, tagID string) error { ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cTag) - _, err := c.DeleteOne(ctx, bson.M{"uid": userID, "tags": bson.M{"$unset": tagID}}) + _, err := c.DeleteOne(ctx, bson.M{"userID": userID, "tagID": tagID}) return err } -func (d *DataBases) SetTag(userID, tagID, newName string, increaseUserList []string, reduceUserIDList []string) error { +func (d *DataBases) SetTag(userID, tagID, newName string, increaseUserIDList []string, reduceUserIDList []string) error { ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cTag) - _, err := c.UpdateOne(ctx, bson.M{"uid": userID, "tags": tagID}, bson.M{"tagName": newName}) + var tag Tag + err := c.FindOne(ctx, bson.M{"tagID": tagID, "userID": userID}).Decode(&tag) + if newName != "" { + _, err = c.UpdateOne(ctx, bson.M{"userID": userID, "tagID": tagID}, bson.D{ + {"$set", bson.D{ + {"tagName", newName}, + }}, + }) + if err != nil { + return err + } + } + tag.UserList = append(tag.UserList, increaseUserIDList...) + tag.UserList = utils.RemoveUserIDRepByMap(tag.UserList) + for _, v := range reduceUserIDList { + for i2, v2 := range tag.UserList { + if v == v2 { + tag.UserList = append(tag.UserList[:i2], tag.UserList[i2+1:]...) + } + } + } + _, err = c.UpdateOne(ctx, bson.M{"userID": userID, "tagID": tagID}, bson.D{ + {"$set", bson.D{ + {"userList", tag.UserList}, + }}, + }) if err != nil { return err } - _, err = c.InsertOne(ctx, bson.M{"uid": userID, "tags": bson.M{tagID: ""}}) - if err != nil { - return err - } - //_, err = c.InsertOne(ctx) - //if err != nil { - // return err - //} return nil } func (d *DataBases) GetUserIDListByTagID(userID, tagID string) ([]string, error) { - var tagIDList []string - var tagStruct TagsStruct + var tag Tag ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cTag) - _ = c.FindOne(ctx, bson.M{"uid": userID}).Decode(&tagStruct) - for k, tag := range tagStruct.Tags { - if k == tagID { - tagIDList = tag.UserList - } - } - return tagIDList, nil + _ = c.FindOne(ctx, bson.M{"userID": userID, "tagID": tagID}).Decode(&tag) + return tag.UserList, nil } type TagSendLog struct { TagID string `bson:"tagID"` + TagName string `bson:"tagName"` SendID string `bson:"sendID"` SenderPlatformID int32 `bson:"senderPlatformID"` Content string `bson:"content"` @@ -528,8 +534,11 @@ type TagSendLog struct { func (d *DataBases) SaveTagSendLog(sendReq *officePb.SendMsg2TagReq) error { ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSendLog) + var tag Tag + _ = c.FindOne(ctx, bson.M{"userID": sendReq.SendID, "tagID": sendReq.TagID}).Decode(&tag) tagSendLog := TagSendLog{ TagID: sendReq.TagID, + TagName: tag.TagName, SendID: sendReq.SendID, SenderPlatformID: sendReq.SenderPlatformID, Content: sendReq.Content, @@ -544,7 +553,8 @@ func (d *DataBases) GetTagSendLogs(userID string, showNumber, pageNumber int32) var tagSendLogs []*TagSendLog ctx, _ := context.WithTimeout(context.Background(), time.Duration(config.Config.Mongo.DBTimeout)*time.Second) c := d.mongoClient.Database(config.Config.Mongo.DBDatabase).Collection(cSendLog) - cursor, err := c.Find(ctx, bson.M{"sendID": userID}) + findOpts := options.Find().SetSort(-1).SetLimit(int64(showNumber)).SetSkip(int64(showNumber) * (int64(pageNumber) - 1)) + cursor, err := c.Find(ctx, bson.M{"sendID": userID}, findOpts) if err != nil { return tagSendLogs, err } diff --git a/pkg/utils/utils.go b/pkg/utils/utils.go index 0ee464aad..f0e34aa90 100644 --- a/pkg/utils/utils.go +++ b/pkg/utils/utils.go @@ -76,3 +76,16 @@ func Difference(slice1, slice2 []uint32) []uint32 { func OperationIDGenerator() string { return strconv.FormatInt(time.Now().UnixNano()+int64(rand.Uint32()), 10) } + +func RemoveUserIDRepByMap(slc []string) []string { + var result []string + tempMap := map[string]byte{} + for _, e := range slc { + l := len(tempMap) + tempMap[e] = 0 + if len(tempMap) != l { + result = append(result, e) + } + } + return result +}