mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-05-12 13:05:58 +08:00
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:
@@ -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)
|
||||
}
|
||||
|
||||
+111
-2
@@ -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(¶ms); 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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()),
|
||||
|
||||
Reference in New Issue
Block a user