all back-office api (#533)

* fix conflict

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

* all Back-office management api

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>

---------

Signed-off-by: ‘hanzhixiao’ <‘709674996@qq.com’>
Co-authored-by: ‘hanzhixiao’ <‘709674996@qq.com’>
This commit is contained in:
Alan 2023-07-13 15:11:33 +08:00 committed by GitHub
parent 058e2eee32
commit 0b306d996d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 1628 additions and 250 deletions

View File

@ -132,3 +132,6 @@ func (o *GroupApi) GetSuperGroupsInfo(c *gin.Context) {
func (o *GroupApi) GroupCreateCount(c *gin.Context) {
a2r.Call(group.GroupClient.GroupCreateCount, o.Client, c)
}
func (o *GroupApi) GetGroups(c *gin.Context) {
a2r.Call(group.GroupClient.GetGroups, o.Client, c)
}

View File

@ -15,6 +15,7 @@
package api
import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/mitchellh/mapstructure"
@ -204,7 +205,7 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
} else if err := m.validate.Struct(data); err != nil {
} else if err := m.validate.Struct(params); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
}
@ -227,7 +228,107 @@ func (m *MessageApi) SendMessage(c *gin.Context) {
}
func (m *MessageApi) ManagementBatchSendMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SendMsg, m.Client, c)
params := apistruct.ManagementBatchSendMsgReq{}
resp := apistruct.ManagementBatchSendMsgResp{}
var msgSendFailedFlag bool
if err := c.BindJSON(&params); err != nil {
apiresp.GinError(c, errs.ErrArgs.WithDetail(err.Error()).Wrap())
return
}
if !tokenverify.IsAppManagerUid(c) {
apiresp.GinError(c, errs.ErrNoPermission.Wrap("only app manager can send message"))
return
}
var data interface{}
switch params.ContentType {
case constant.Text:
data = apistruct.TextElem{}
case constant.Picture:
data = apistruct.PictureElem{}
case constant.Voice:
data = apistruct.SoundElem{}
case constant.Video:
data = apistruct.VideoElem{}
case constant.File:
data = apistruct.FileElem{}
case constant.Custom:
data = apistruct.CustomElem{}
case constant.Revoke:
data = apistruct.RevokeElem{}
case constant.OANotification:
data = apistruct.OANotificationElem{}
params.SessionType = constant.NotificationChatType
case constant.CustomNotTriggerConversation:
data = apistruct.CustomElem{}
case constant.CustomOnlineOnly:
data = apistruct.CustomElem{}
default:
apiresp.GinError(c, errs.ErrArgs.WithDetail("not support err contentType").Wrap())
return
}
if err := mapstructure.WeakDecode(params.Content, &data); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
} else if err := m.validate.Struct(params); err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
}
t := &apistruct.ManagementSendMsgReq{
SendID: params.SendID,
GroupID: params.GroupID,
SenderNickname: params.SenderNickname,
SenderFaceURL: params.SenderFaceURL,
SenderPlatformID: params.SenderPlatformID,
Content: params.Content,
ContentType: params.ContentType,
SessionType: params.SessionType,
IsOnlineOnly: params.IsOnlineOnly,
NotOfflinePush: params.NotOfflinePush,
OfflinePushInfo: params.OfflinePushInfo,
}
pbReq := m.newUserSendMsgReq(c, t)
var recvList []string
if params.IsSendAll {
req2 := &user.GetAllUserIDReq{}
resp2, err := m.Message.GetAllUserID(c, req2)
if err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
}
recvList = resp2.UserIDs
} else {
recvList = params.RecvIDList
}
for _, recvID := range recvList {
pbReq.MsgData.RecvID = recvID
rpcResp, err := m.Client.SendMsg(c, pbReq)
if err != nil {
resp.Data.FailedIDList = append(resp.Data.FailedIDList, recvID)
msgSendFailedFlag = true
continue
}
resp.Data.ResultList = append(resp.Data.ResultList, &apistruct.SingleReturnResult{
ServerMsgID: rpcResp.ServerMsgID,
ClientMsgID: rpcResp.ClientMsgID,
SendTime: rpcResp.SendTime,
RecvID: recvID,
})
}
var status int32
if msgSendFailedFlag {
status = constant.MsgSendFailed
} else {
status = constant.MsgSendSuccessed
}
_, err := m.Client.SetSendMsgStatus(c, &msg.SetSendMsgStatusReq{Status: status})
if err != nil {
apiresp.GinError(c, errs.ErrArgs.Wrap(err.Error()))
return
}
apiresp.GinSuccess(c, resp)
}
func (m *MessageApi) CheckMsgIsSendSuccess(c *gin.Context) {
@ -245,3 +346,11 @@ func (m *MessageApi) GetActiveUser(c *gin.Context) {
func (m *MessageApi) GetActiveGroup(c *gin.Context) {
a2r.Call(msg.MsgClient.GetActiveGroup, m.Client, c)
}
func (m *MessageApi) SearchMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.SearchMessage, m.Client, c)
}
func (m *MessageApi) ManagementMsg(c *gin.Context) {
a2r.Call(msg.MsgClient.ManageMsg, m.Client, c)
}

View File

@ -103,6 +103,7 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
groupRouterGroup.POST("/cancel_mute_group", g.CancelMuteGroup)
groupRouterGroup.POST("/set_group_member_info", g.SetGroupMemberInfo)
groupRouterGroup.POST("/get_group_abstract_info", g.GetGroupAbstractInfo)
groupRouterGroup.POST("/get_groups", g.GetGroups)
}
superGroupRouterGroup := r.Group("/super_group", ParseToken)
{
@ -124,6 +125,8 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
thirdGroup.POST("/fcm_update_token", t.FcmUpdateToken)
thirdGroup.POST("/set_app_badge", t.SetAppBadge)
thirdGroup.POST("/minio_upload", t.MinioUploadFile)
objectGroup := r.Group("/object", ParseToken)
objectGroup.POST("/part_limit", t.PartLimit)
@ -138,10 +141,12 @@ func NewGinRouter(discov discoveryregistry.SvcDiscoveryRegistry, rdb redis.Unive
msgGroup := r.Group("/msg", ParseToken)
{
msgGroup.POST("/newest_seq", m.GetSeq)
msgGroup.POST("/search_msg", m.SearchMsg)
msgGroup.POST("/send_msg", m.SendMessage)
msgGroup.POST("/pull_msg_by_seq", m.PullMsgBySeqs)
msgGroup.POST("/revoke_msg", m.RevokeMsg)
msgGroup.POST("/mark_msgs_as_read", m.MarkMsgsAsRead)
msgGroup.POST("/manage_msg", m.ManagementMsg)
msgGroup.POST("/mark_conversation_as_read", m.MarkConversationAsRead)
msgGroup.POST("/get_conversations_has_read_and_max_seq", m.GetConversationsHasReadAndMaxSeq)
msgGroup.POST("/set_conversation_has_read_seq", m.SetConversationHasReadSeq)

View File

@ -1,6 +1,11 @@
package api
import (
"github.com/OpenIMSDK/Open-IM-Server/pkg/apistruct"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/config"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/utils"
"github.com/minio/minio-go/v7"
"math/rand"
"net/http"
"strconv"
@ -84,3 +89,57 @@ func (o *ThirdApi) ObjectRedirect(c *gin.Context) {
}
c.Redirect(http.StatusTemporaryRedirect, resp.Url)
}
func (o *ThirdApi) MinioUploadFile(c *gin.Context) {
var (
req apistruct.MinioUploadFileReq
resp apistruct.MinioUploadFile
)
if err := c.Bind(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()})
return
}
switch req.FileType {
// videoType upload snapShot
case constant.VideoType:
snapShotFile, err := c.FormFile("snapShot")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": "missing snapshot arg: " + err.Error()})
return
}
snapShotFileObj, err := snapShotFile.Open()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()})
return
}
snapShotNewName, snapShotNewType := utils.GetNewFileNameAndContentType(snapShotFile.Filename, constant.ImageType)
_, err = o.MinioClient.PutObject(c, config.Config.Object.Minio.Bucket, snapShotNewName, snapShotFileObj, snapShotFile.Size, minio.PutObjectOptions{ContentType: snapShotNewType})
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": err.Error()})
return
}
resp.SnapshotURL = config.Config.Object.Minio.Endpoint + "/" + config.Config.Object.Minio.Bucket + "/" + snapShotNewName
resp.SnapshotNewName = snapShotNewName
}
file, err := c.FormFile("file")
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": "missing file arg: " + err.Error()})
return
}
fileObj, err := file.Open()
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"errCode": 400, "errMsg": "invalid file path" + err.Error()})
return
}
newName, newType := utils.GetNewFileNameAndContentType(file.Filename, req.FileType)
_, err = o.MinioClient.PutObject(c, config.Config.Object.Minio.Bucket, newName, fileObj, file.Size, minio.PutObjectOptions{ContentType: newType})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"errCode": 500, "errMsg": "upload file error" + err.Error()})
return
}
resp.NewName = newName
resp.URL = config.Config.Object.Minio.Endpoint + "/" + config.Config.Object.Minio.Bucket + "/" + newName
c.JSON(http.StatusOK, gin.H{"errCode": 0, "errMsg": "", "data": resp})
return
}

View File

@ -68,8 +68,9 @@ func StartTransfer(prometheusPort int) error {
client.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
msgModel := cache.NewMsgCacheModel(rdb)
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
chatLogDatabase := controller.NewChatLogDatabase(relation.NewChatLogGorm(db))
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel)
msgMysModel := relation.NewChatLogGorm(db)
chatLogDatabase := controller.NewChatLogDatabase(msgMysModel)
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, msgModel, msgMysModel)
conversationRpcClient := rpcclient.NewConversationRpcClient(client)
groupRpcClient := rpcclient.NewGroupRpcClient(client)
msgTransfer := NewMsgTransfer(chatLogDatabase, msgDatabase, &conversationRpcClient, &groupRpcClient)

View File

@ -124,3 +124,24 @@ func (m *msgServer) RevokeMsg(ctx context.Context, req *msg.RevokeMsgReq) (*msg.
}
return &msg.RevokeMsgResp{}, nil
}
func (m *msgServer) ManageMsg(ctx context.Context, req *msg.ManageMsgReq) (*msg.ManageMsgResp, error) {
resp := &msg.ManageMsgResp{}
msgData := &sdkws.MsgData{
SendID: req.SendID,
RecvID: req.RecvID,
SessionType: req.SessionType,
GroupID: req.GroupID,
}
conversationID := utils.GetChatConversationIDByMsg(msgData)
revokeReq := &msg.RevokeMsgReq{
ConversationID: conversationID,
Seq: req.Seq,
UserID: req.SendID,
}
_, err := m.RevokeMsg(ctx, revokeReq)
if err != nil {
return nil, err
}
return resp, nil
}

View File

@ -2,6 +2,7 @@ package msg
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
"google.golang.org/grpc"
@ -61,11 +62,13 @@ func Start(client discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
}
cacheModel := cache.NewMsgCacheModel(rdb)
msgDocModel := unrelation.NewMsgMongoDriver(mongo.GetDatabase())
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel)
conversationClient := rpcclient.NewConversationRpcClient(client)
userRpcClient := rpcclient.NewUserRpcClient(client)
groupRpcClient := rpcclient.NewGroupRpcClient(client)
friendRpcClient := rpcclient.NewFriendRpcClient(client)
mysql, err := relation.NewGormDB()
msgMysModel := relation.NewChatLogGorm(mysql)
msgDatabase := controller.NewCommonMsgDatabase(msgDocModel, cacheModel, msgMysModel)
s := &msgServer{
Conversation: &conversationClient,
User: &userRpcClient,

View File

@ -16,6 +16,8 @@ package msg
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/log"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/tokenverify"
@ -102,3 +104,50 @@ func (m *msgServer) GetMaxSeq(ctx context.Context, req *sdkws.GetMaxSeqReq) (*sd
resp.MaxSeqs = maxSeqs
return resp, nil
}
func (m *msgServer) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) (resp *msg.SearchMessageResp, err error) {
var chatLogs []*sdkws.MsgData
resp = &msg.SearchMessageResp{}
if chatLogs, err = m.MsgDatabase.SearchMessage(ctx, req); err != nil {
return nil, err
}
var num int
for _, chatLog := range chatLogs {
pbChatLog := &msg.ChatLog{}
utils.CopyStructFields(pbChatLog, chatLog)
pbChatLog.SendTime = chatLog.SendTime
pbChatLog.CreateTime = chatLog.CreateTime
if chatLog.SenderNickname == "" {
sendUser, err := m.User.GetUserInfo(ctx, chatLog.SendID)
if err != nil {
return nil, err
}
pbChatLog.SenderNickname = sendUser.Nickname
}
switch chatLog.SessionType {
case constant.SingleChatType:
recvUser, err := m.User.GetUserInfo(ctx, chatLog.RecvID)
if err != nil {
return nil, err
}
pbChatLog.SenderNickname = recvUser.Nickname
case constant.GroupChatType, constant.SuperGroupChatType:
group, err := m.Group.GetGroupInfo(ctx, chatLog.GroupID)
if err != nil {
return nil, err
}
pbChatLog.SenderFaceURL = group.FaceURL
pbChatLog.GroupMemberCount = group.MemberCount
pbChatLog.RecvID = group.GroupID
pbChatLog.GroupName = group.GroupName
pbChatLog.GroupOwner = group.OwnerUserID
pbChatLog.GroupType = group.GroupType
}
resp.ChatLogs = append(resp.ChatLogs, pbChatLog)
num++
}
resp.ChatLogsNum = int32(num)
return resp, nil
}

View File

@ -80,7 +80,7 @@ func InitMsgTool() (*MsgTool, error) {
}
discov.AddOption(mw.GrpcClient(), grpc.WithTransportCredentials(insecure.NewCredentials()))
userDB := relation.NewUserGorm(db)
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase())
msgDatabase := controller.InitCommonMsgDatabase(rdb, mongo.GetDatabase(), db)
userDatabase := controller.NewUserDatabase(
userDB,
cache.NewUserCacheRedis(rdb, relation.NewUserGorm(db), cache.GetDefaultOpt()),

View File

@ -1,6 +1,9 @@
package controller
import (
relation2 "github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/relation"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/db/table/relation"
"gorm.io/gorm"
"time"
"github.com/redis/go-redis/v9"
@ -102,6 +105,7 @@ type CommonMsgDatabase interface {
) (minSeqMongo, maxSeqMongo, minSeqCache, maxSeqCache int64, err error)
SetSendMsgStatus(ctx context.Context, id string, status int32) error
GetSendMsgStatus(ctx context.Context, id string) (int32, error)
SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error)
// to mq
MsgToMQ(ctx context.Context, key string, msg2mq *sdkws.MsgData) error
@ -128,8 +132,9 @@ type CommonMsgDatabase interface {
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error)
}
func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel cache.MsgModel) CommonMsgDatabase {
func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheModel cache.MsgModel, msgMyqModel relation.ChatLogModelInterface) CommonMsgDatabase {
return &commonMsgDatabase{
msgMyq: msgMyqModel,
msgDocDatabase: msgDocModel,
cache: cacheModel,
producer: kafka.NewKafkaProducer(config.Config.Kafka.Addr, config.Config.Kafka.LatestMsgToRedis.Topic),
@ -138,16 +143,18 @@ func NewCommonMsgDatabase(msgDocModel unRelationTb.MsgDocModelInterface, cacheMo
}
}
func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database) CommonMsgDatabase {
func InitCommonMsgDatabase(rdb redis.UniversalClient, database *mongo.Database, dbGrom *gorm.DB) CommonMsgDatabase {
cacheModel := cache.NewMsgCacheModel(rdb)
msgDocModel := unrelation.NewMsgMongoDriver(database)
CommonMsgDatabase := NewCommonMsgDatabase(msgDocModel, cacheModel)
msgMyqModel := relation2.NewChatLogGorm(dbGrom)
CommonMsgDatabase := NewCommonMsgDatabase(msgDocModel, cacheModel, msgMyqModel)
return CommonMsgDatabase
}
type commonMsgDatabase struct {
msgDocDatabase unRelationTb.MsgDocModelInterface
msg unRelationTb.MsgDocModel
msgMyq relation.ChatLogModelInterface
cache cache.MsgModel
producer *kafka.Producer
producerToMongo *kafka.Producer
@ -1163,3 +1170,15 @@ func (db *commonMsgDatabase) RangeGroupSendCount(
) (msgCount int64, userCount int64, groups []*unRelationTb.GroupCount, dateCount map[string]int64, err error) {
return db.msgDocDatabase.RangeGroupSendCount(ctx, start, end, ase, pageNumber, showNumber)
}
func (db *commonMsgDatabase) SearchMessage(ctx context.Context, req *pbMsg.SearchMessageReq) (msgData []*sdkws.MsgData, err error) {
var totalMsgs []*sdkws.MsgData
msgs, err := db.msgDocDatabase.SearchMessage(ctx, req)
if err != nil {
return nil, err
}
for _, msg := range msgs {
totalMsgs = append(totalMsgs, convert.MsgDB2Pb(msg.Msg))
}
return totalMsgs, nil
}

View File

@ -2,6 +2,7 @@ package relation
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
"time"
"gorm.io/gorm"
@ -58,7 +59,9 @@ func (g *GroupGorm) Search(
keyword string,
pageNumber, showNumber int32,
) (total uint32, groups []*relation.GroupModel, err error) {
return ormutil.GormSearch[relation.GroupModel](g.DB, []string{"name"}, keyword, pageNumber, showNumber)
db := g.DB
db = db.WithContext(ctx).Where("status!=?", constant.GroupStatusDismissed)
return ormutil.GormSearch[relation.GroupModel](db, []string{"name"}, keyword, pageNumber, showNumber)
}
func (g *GroupGorm) GetGroupIDsByGroupType(ctx context.Context, groupType int) (groupIDs []string, err error) {

View File

@ -16,6 +16,7 @@ package unrelation
import (
"context"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"strconv"
"time"
@ -108,6 +109,7 @@ type MsgDocModelInterface interface {
GetMsgDocModelByIndex(ctx context.Context, conversationID string, index, sort int64) (*MsgDocModel, error)
DeleteMsgsInOneDocByIndex(ctx context.Context, docID string, indexes []int) error
MarkSingleChatMsgsAsRead(ctx context.Context, userID string, docID string, indexes []int64) error
SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*MsgInfoModel, error)
RangeUserSendCount(
ctx context.Context,
start time.Time,

View File

@ -19,6 +19,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/msg"
"time"
"github.com/OpenIMSDK/Open-IM-Server/pkg/common/constant"
@ -1064,3 +1065,136 @@ func (m *MsgMongoDriver) RangeGroupSendCount(
}
return result[0].MsgCount, result[0].UserCount, groups, dateCount, nil
}
func (m *MsgMongoDriver) SearchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) {
msgs, err := m.searchMessage(ctx, req)
if err != nil {
return nil, err
}
for _, msg1 := range msgs {
if msg1.IsRead {
msg1.Msg.IsRead = true
}
}
return msgs, nil
}
func (m *MsgMongoDriver) searchMessage(ctx context.Context, req *msg.SearchMessageReq) ([]*table.MsgInfoModel, error) {
var pipe mongo.Pipeline
conditon := bson.A{}
if req.SendTime != "" {
conditon = append(conditon, bson.M{"$eq": bson.A{bson.M{"$dateToString": bson.M{"format": "%Y-%m-%d", "date": bson.M{"$toDate": "$$item.msg.send_time"}}}, req.SendTime}})
}
if req.MsgType != 0 {
conditon = append(conditon, bson.M{"$eq": bson.A{"$$item.msg.content_type", req.MsgType}})
}
if req.SessionType != 0 {
conditon = append(conditon, bson.M{"$eq": bson.A{"$$item.msg.session_type", req.SessionType}})
}
if req.RecvID != "" {
conditon = append(conditon, bson.M{"$regexFind": bson.M{"input": "$$item.msg.recv_id", "regex": req.RecvID}})
}
if req.SendID != "" {
conditon = append(conditon, bson.M{"$regexFind": bson.M{"input": "$$item.msg.send_id", "regex": req.SendID}})
}
or := bson.A{
bson.M{
"doc_id": bson.M{
"$regex": "^si_",
"$options": "i",
},
},
}
or = append(or,
bson.M{
"doc_id": bson.M{
"$regex": "^g_",
"$options": "i",
},
},
bson.M{
"doc_id": bson.M{
"$regex": "^sg_",
"$options": "i",
},
},
)
pipe = mongo.Pipeline{
{
{"$match", bson.D{
{
"$or", or,
},
}},
},
{
{"$project", bson.D{
{"msgs", bson.D{
{"$filter", bson.D{
{"input", "$msgs"},
{"as", "item"},
{"cond", bson.D{
{"$and", conditon},
},
}},
}},
},
{"doc_id", 1},
}},
},
}
cursor, err := m.MsgCollection.Aggregate(ctx, pipe)
if err != nil {
return nil, err
}
var msgsDocs []table.MsgDocModel
err = cursor.All(ctx, &msgsDocs)
if err != nil {
return nil, err
}
if len(msgsDocs) == 0 {
return nil, errs.Wrap(mongo.ErrNoDocuments)
}
msgs := make([]*table.MsgInfoModel, 0)
for index, _ := range msgsDocs {
for i := range msgsDocs[index].Msg {
msg := msgsDocs[index].Msg[i]
if msg == nil || msg.Msg == nil {
continue
}
if msg.Revoke != nil {
revokeContent := sdkws.MessageRevokedContent{
RevokerID: msg.Revoke.UserID,
RevokerRole: msg.Revoke.Role,
ClientMsgID: msg.Msg.ClientMsgID,
RevokerNickname: msg.Revoke.Nickname,
RevokeTime: msg.Revoke.Time,
SourceMessageSendTime: msg.Msg.SendTime,
SourceMessageSendID: msg.Msg.SendID,
SourceMessageSenderNickname: msg.Msg.SenderNickname,
SessionType: msg.Msg.SessionType,
Seq: msg.Msg.Seq,
Ex: msg.Msg.Ex,
}
data, err := json.Marshal(&revokeContent)
if err != nil {
return nil, err
}
elem := sdkws.NotificationElem{
Detail: string(data),
}
content, err := json.Marshal(&elem)
if err != nil {
return nil, err
}
msg.Msg.ContentType = constant.MsgRevokeNotification
msg.Msg.Content = string(content)
}
msgs = append(msgs, msg)
}
}
return msgs, nil
}

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,14 +22,13 @@ package auth
import (
context "context"
reflect "reflect"
sync "sync"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,16 +22,14 @@ package conversation
import (
context "context"
reflect "reflect"
sync "sync"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -7,11 +21,10 @@
package errinfo
import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,16 +22,14 @@ package friend
import (
context "context"
reflect "reflect"
sync "sync"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,17 +22,15 @@ package group
import (
context "context"
reflect "reflect"
sync "sync"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
reflect "reflect"
sync "sync"
)
const (

File diff suppressed because it is too large Load Diff

View File

@ -232,12 +232,66 @@ message GetActiveGroupResp {
repeated ActiveGroup groups = 4;
}
message SearchMessageReq{
string sendID=1;//ID
string recvID=2;//ID
int32 msgType=3;
string sendTime=4;
int32 sessionType=5;
sdkws.RequestPagination pagination = 6;
}
message SearchMessageResp{
repeated ChatLog chatLogs=1;
int32 chatLogsNum = 2;
}
message manageMsgReq{
string recvID=1;
string sendID=2;
string groupID=3;
int64 seq=4;
int32 sessionType=5;
}
message manageMsgResp{
}
message ChatLog {
string serverMsgID = 1;
string clientMsgID = 2;
string sendID = 3;
string recvID = 4;
string groupID = 5;
string recvNickname = 6;
int32 senderPlatformID = 7;
string senderNickname = 8;
string senderFaceURL = 9;
string groupName = 10;
int32 sessionType = 11;
int32 msgFrom = 12;
int32 contentType = 13;
string content = 14;
int32 status = 15;
int64 sendTime = 16;
int64 createTime = 17;
string ex = 18;
string groupFaceURL=19;
uint32 groupMemberCount=20;
int64 seq=21;
string groupOwner=22;
int32 groupType=23;
}
service msg {
//seq
rpc GetMaxSeq(sdkws.GetMaxSeqReq) returns(sdkws.GetMaxSeqResp);
rpc GetConversationMaxSeq(GetConversationMaxSeqReq) returns(GetConversationMaxSeqResp);
//
rpc PullMessageBySeqs(sdkws.PullMessageBySeqsReq) returns(sdkws.PullMessageBySeqsResp);
rpc SearchMessage(SearchMessageReq) returns(SearchMessageResp);
rpc ManageMsg(manageMsgReq) returns (manageMsgResp);
//
rpc SendMsg(SendMsgReq) returns(SendMsgResp);

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,16 +22,14 @@ package msggateway
import (
context "context"
reflect "reflect"
sync "sync"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,16 +22,14 @@ package push
import (
context "context"
reflect "reflect"
sync "sync"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -7,13 +21,11 @@
package sdkws
import (
reflect "reflect"
sync "sync"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
wrapperspb "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/wrapperspb"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -7,10 +21,9 @@
package statistics
import (
reflect "reflect"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,14 +22,13 @@ package third
import (
context "context"
reflect "reflect"
sync "sync"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -8,17 +22,15 @@ package user
import (
context "context"
reflect "reflect"
sync "sync"
conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
conversation "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/conversation"
sdkws "github.com/OpenIMSDK/Open-IM-Server/pkg/proto/sdkws"
reflect "reflect"
sync "sync"
)
const (

View File

@ -1,3 +1,17 @@
// Copyright © 2023 OpenIM. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.29.1
@ -7,11 +21,10 @@
package wrapperspb
import (
reflect "reflect"
sync "sync"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (

View File

@ -3,6 +3,7 @@ package rpcclient
import (
"context"
"encoding/json"
"github.com/OpenIMSDK/Open-IM-Server/pkg/proto/user"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
@ -283,3 +284,16 @@ func (s *NotificationSender) Notification(
) error {
return s.NotificationWithSesstionType(ctx, sendID, recvID, contentType, s.sessionTypeConf[contentType], m, opts...)
}
func (m *Message) GetAllUserID(ctx context.Context, req *user.GetAllUserIDReq) (*user.GetAllUserIDResp, error) {
conn, err := m.discov.GetConn(context.Background(), config.Config.RpcRegisterName.OpenImMsgName)
if err != nil {
panic(err)
}
client := user.NewUserClient(conn)
resp, err := client.GetAllUserID(ctx, req)
if err != nil {
return nil, err
}
return resp, nil
}

View File

@ -16,6 +16,9 @@ package rpcclient
import (
"context"
"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
"net/url"
"google.golang.org/grpc"
@ -25,9 +28,10 @@ import (
)
type Third struct {
conn grpc.ClientConnInterface
Client third.ThirdClient
discov discoveryregistry.SvcDiscoveryRegistry
conn grpc.ClientConnInterface
Client third.ThirdClient
discov discoveryregistry.SvcDiscoveryRegistry
MinioClient *minio.Client
}
func NewThird(discov discoveryregistry.SvcDiscoveryRegistry) *Third {
@ -36,5 +40,30 @@ func NewThird(discov discoveryregistry.SvcDiscoveryRegistry) *Third {
panic(err)
}
client := third.NewThirdClient(conn)
return &Third{discov: discov, Client: client, conn: conn}
minioClient, err := minioInit()
return &Third{discov: discov, Client: client, conn: conn, MinioClient: minioClient}
}
func minioInit() (*minio.Client, error) {
minioClient := &minio.Client{}
var initUrl string
initUrl = config.Config.Object.Minio.Endpoint
minioUrl, err := url.Parse(initUrl)
if err != nil {
return nil, err
}
opts := &minio.Options{
Creds: credentials.NewStaticV4(config.Config.Object.Minio.AccessKeyID, config.Config.Object.Minio.SecretAccessKey, ""),
//Region: config.Config.Credential.Minio.Location,
}
if minioUrl.Scheme == "http" {
opts.Secure = false
} else if minioUrl.Scheme == "https" {
opts.Secure = true
}
minioClient, err = minio.New(minioUrl.Host, opts)
if err != nil {
return nil, err
}
return minioClient, nil
}