瀏覽代碼

fenzhihebing

lianbingjie 1 年之前
父節點
當前提交
2f2b9b64af
共有 45 個文件被更改,包括 2225 次插入1199 次删除
  1. 4 4
      api/internal/handler/bitmapsavemsghandler.go
  2. 4 4
      api/internal/handler/newusersavemsghandler.go
  3. 14 9
      api/internal/handler/routes.go
  4. 28 0
      api/internal/handler/updatemsgsummaryhandler.go
  5. 60 0
      api/internal/logic/bitmapsavemsglogic.go
  6. 0 48
      api/internal/logic/getmsgtypelogic.go
  7. 1 0
      api/internal/logic/markreadlogic.go
  8. 0 10
      api/internal/logic/multiplesavemsglogic.go
  9. 59 0
      api/internal/logic/newusersavemsglogic.go
  10. 0 58
      api/internal/logic/unreadmessageslogic.go
  11. 41 0
      api/internal/logic/updatemsgsummarylogic.go
  12. 26 17
      api/internal/types/types.go
  13. 49 19
      api/message.api
  14. 2 0
      entity/message.go
  15. 17 0
      entity/newEntity.go
  16. 4 0
      go.mod
  17. 85 27
      go.sum
  18. 17 4
      rpc/etc/message.yaml
  19. 10 13
      rpc/internal/common/getBuoyMsg.go
  20. 29 19
      rpc/internal/common/messageClass.go
  21. 11 20
      rpc/internal/common/messageLog.go
  22. 35 51
      rpc/internal/common/messageService.go
  23. 502 0
      rpc/internal/common/msglistService.go
  24. 287 0
      rpc/internal/common/newSendMsgService.go
  25. 130 187
      rpc/internal/common/sendMsg.go
  26. 52 11
      rpc/internal/common/sendWxTmplMsg.go
  27. 33 0
      rpc/internal/common/task.go
  28. 21 4
      rpc/internal/config/config.go
  29. 42 0
      rpc/internal/logic/bitmapsavemsglogic.go
  30. 10 3
      rpc/internal/logic/changereadstatuslogic.go
  31. 6 14
      rpc/internal/logic/findmessagedetaillogic.go
  32. 0 39
      rpc/internal/logic/getmsgtypelogic.go
  33. 9 4
      rpc/internal/logic/msgopenloglogic.go
  34. 43 7
      rpc/internal/logic/multiplesavemsglogic.go
  35. 38 0
      rpc/internal/logic/newusermsglogic.go
  36. 43 0
      rpc/internal/logic/updatemsgsummarylogic.go
  37. 3 2
      rpc/internal/logic/usermsglistlogic.go
  38. 0 39
      rpc/internal/logic/userunreadmsglistlogic.go
  39. 18 12
      rpc/internal/server/messageserver.go
  40. 46 3
      rpc/message.go
  41. 63 25
      rpc/message.proto
  42. 0 160
      rpc/message/message.go
  43. 29 20
      rpc/messageclient/message.go
  44. 236 294
      rpc/type/message/message.pb.go
  45. 118 72
      rpc/type/message/message_grpc.pb.go

+ 4 - 4
api/internal/handler/getmsgtypehandler.go → api/internal/handler/bitmapsavemsghandler.go

@@ -9,16 +9,16 @@ import (
 	"github.com/zeromicro/go-zero/rest/httpx"
 )
 
-func GetMsgTypeHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+func BitmapSaveMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
-		var req types.GetMsgTypeReq
+		var req types.BitmapSaveMsgReq
 		if err := httpx.Parse(r, &req); err != nil {
 			httpx.Error(w, err)
 			return
 		}
 
-		l := logic.NewGetMsgTypeLogic(r.Context(), svcCtx)
-		resp, err := l.GetMsgType(&req)
+		l := logic.NewBitmapSaveMsgLogic(r.Context(), svcCtx)
+		resp, err := l.BitmapSaveMsg(&req)
 		if err != nil {
 			httpx.Error(w, err)
 		} else {

+ 4 - 4
api/internal/handler/unreadmessageshandler.go → api/internal/handler/newusersavemsghandler.go

@@ -9,16 +9,16 @@ import (
 	"github.com/zeromicro/go-zero/rest/httpx"
 )
 
-func UnreadMessagesHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+func NewUserSaveMsgHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
-		var req types.UnreadMessageReq
+		var req types.NewUserSaveMsgReq
 		if err := httpx.Parse(r, &req); err != nil {
 			httpx.Error(w, err)
 			return
 		}
 
-		l := logic.NewUnreadMessagesLogic(r.Context(), svcCtx)
-		resp, err := l.UnreadMessages(&req)
+		l := logic.NewNewUserSaveMsgLogic(r.Context(), svcCtx)
+		resp, err := l.NewUserSaveMsg(&req)
 		if err != nil {
 			httpx.Error(w, err)
 		} else {

+ 14 - 9
api/internal/handler/routes.go

@@ -14,13 +14,23 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 		[]rest.Route{
 			{
 				Method:  http.MethodPost,
-				Path:    "/messageCenter/messageDetail",
-				Handler: MessageDetailHandler(serverCtx),
+				Path:    "/messageCenter/BitmapSaveMsg",
+				Handler: BitmapSaveMsgHandler(serverCtx),
 			},
 			{
 				Method:  http.MethodPost,
-				Path:    "/messageCenter/getMsgType",
-				Handler: GetMsgTypeHandler(serverCtx),
+				Path:    "/messageCenter/UpdateMsgSummary",
+				Handler: UpdateMsgSummaryHandler(serverCtx),
+			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/messageCenter/NewUserSaveMsg",
+				Handler: NewUserSaveMsgHandler(serverCtx),
+			},
+			{
+				Method:  http.MethodPost,
+				Path:    "/messageCenter/messageDetail",
+				Handler: MessageDetailHandler(serverCtx),
 			},
 			{
 				Method:  http.MethodPost,
@@ -47,11 +57,6 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 				Path:    "/messageCenter/MessageList",
 				Handler: MessageListHandler(serverCtx),
 			},
-			{
-				Method:  http.MethodPost,
-				Path:    "/messageCenter/unreadMessages",
-				Handler: UnreadMessagesHandler(serverCtx),
-			},
 			{
 				Method:  http.MethodPost,
 				Path:    "/messageCenter/sendWxTmplMsg",

+ 28 - 0
api/internal/handler/updatemsgsummaryhandler.go

@@ -0,0 +1,28 @@
+package handler
+
+import (
+	"net/http"
+
+	"app.yhyue.com/moapp/MessageCenter/api/internal/logic"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+	"github.com/zeromicro/go-zero/rest/httpx"
+)
+
+func UpdateMsgSummaryHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.UpdateMsgSummaryReq
+		if err := httpx.Parse(r, &req); err != nil {
+			httpx.Error(w, err)
+			return
+		}
+
+		l := logic.NewUpdateMsgSummaryLogic(r.Context(), svcCtx)
+		resp, err := l.UpdateMsgSummary(&req)
+		if err != nil {
+			httpx.Error(w, err)
+		} else {
+			httpx.OkJson(w, resp)
+		}
+	}
+}

+ 60 - 0
api/internal/logic/bitmapsavemsglogic.go

@@ -0,0 +1,60 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"app.yhyue.com/moapp/MessageCenter/util"
+	"context"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type BitmapSaveMsgLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewBitmapSaveMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BitmapSaveMsgLogic {
+	return &BitmapSaveMsgLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *BitmapSaveMsgLogic) BitmapSaveMsg(req *types.BitmapSaveMsgReq) (resp *types.MultipleSaveMsgResp, err error) {
+	var (
+		msg  = "发送成功"
+		code = 0
+	)
+	lsi := l.svcCtx.MessageCenter
+	msgInfo := req.MsgInfo
+	_, err = lsi.BitmapSaveMsg(l.ctx, &messageclient.MultipleSaveMsgReq{
+		Appid:       util.ObjToString(msgInfo["appid"]),
+		Title:       util.ObjToString(msgInfo["title"]),
+		Content:     util.ObjToString(msgInfo["content"]),
+		MsgType:     int64(util.IntAll(msgInfo["msgType"])),
+		Link:        util.ObjToString(msgInfo["link"]),
+		UserIds:     req.UserIds,
+		MsgLogId:    int64(util.IntAll(msgInfo["msgLogId"])),
+		PositionIds: req.PositionIds,
+		Row4:        util.ObjToString(msgInfo["row4"]),
+		ProductName: util.ObjToString(msgInfo["productName"]),
+		OrderId:     util.ObjToString(msgInfo["orderId"]),
+		OrderMoney:  util.ObjToString(msgInfo["orderMoney"]),
+		AppPushUrl:  util.ObjToString(msgInfo["appPushUrl"]),
+		WxPushUrl:   util.ObjToString(msgInfo["wxPushUrl"]),
+		IosPushUrl:  util.ObjToString(msgInfo["iosPushUrl"]),
+		SendUserId:  util.ObjToString(msgInfo["sendUserId"]),
+	})
+	if err != nil {
+		msg = err.Error()
+		code = 0
+	}
+	return &types.MultipleSaveMsgResp{
+		Code:    int64(code),
+		Message: msg,
+	}, nil
+}

+ 0 - 48
api/internal/logic/getmsgtypelogic.go

@@ -1,48 +0,0 @@
-package logic
-
-import (
-	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
-	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
-	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
-	"context"
-
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type GetMsgTypeLogic struct {
-	logx.Logger
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-}
-
-func NewGetMsgTypeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMsgTypeLogic {
-	return &GetMsgTypeLogic{
-		Logger: logx.WithContext(ctx),
-		ctx:    ctx,
-		svcCtx: svcCtx,
-	}
-}
-
-func (l *GetMsgTypeLogic) GetMsgType(req *types.GetMsgTypeReq) (resp *types.GetMsgTypeRes, err error) {
-	result := &types.GetMsgTypeRes{}
-	lsi := l.svcCtx.MessageCenter
-	res, err := lsi.GetMsgType(l.ctx, &messageclient.GetMsgTypeReq{
-		Appid:  req.AppId,
-		UserId: req.UserId,
-	})
-	if err != nil {
-		return nil, err
-	}
-	for _, val := range res.Data {
-		result.Data = append(result.Data, map[string]interface{}{
-			"msgType":         val.MsgType,
-			"name":            val.Name,
-			"code":            val.Code,
-			"displayPlatform": val.DisplayPlatform,
-			"img":             val.Img,
-		})
-	}
-	result.Code = res.Code
-	result.Message = res.Message
-	return result, nil
-}

+ 1 - 0
api/internal/logic/markreadlogic.go

@@ -30,6 +30,7 @@ func (l *MarkReadLogic) MarkRead(req types.MarkReadReq) (*types.MarkReadRes, err
 		Appid:      req.AppId,
 		ReadStatus: 1,
 		Id:         req.MsgId,
+		UserId:     req.UserId,
 	})
 	if err != nil {
 		return nil, err

+ 0 - 10
api/internal/logic/multiplesavemsglogic.go

@@ -6,7 +6,6 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
 	"app.yhyue.com/moapp/MessageCenter/util"
 	"context"
-	"encoding/json"
 	"github.com/zeromicro/go-zero/core/logx"
 	"log"
 )
@@ -29,24 +28,15 @@ func (l *MultipleSaveMsgLogic) MultipleSaveMsg(req types.MultipleSaveMsgReq) (*t
 	errCount := 0
 	lsi := l.svcCtx.MessageCenter
 	msgInfo := req.MsgInfo
-	var showBuoyValue int64 = 0
-	if value, ok := msgInfo["showBuoy"].(json.Number); ok {
-		showBuoyValue, _ = value.Int64()
-	}
 	_, err := lsi.MultipleSaveMsg(l.ctx, &messageclient.MultipleSaveMsgReq{
 		Appid:       util.ObjToString(msgInfo["appid"]),
 		SendUserId:  util.ObjToString(msgInfo["sendUserId"]),
-		SendName:    util.ObjToString(msgInfo["sendName"]),
 		Title:       util.ObjToString(msgInfo["title"]),
 		Content:     util.ObjToString(msgInfo["content"]),
 		MsgType:     int64(util.IntAll(msgInfo["msgType"])),
 		Link:        util.ObjToString(msgInfo["link"]),
-		CiteId:      0,
 		UserIds:     req.UserIds,
-		UserNames:   req.UserNames,
 		MsgLogId:    int64(util.IntAll(msgInfo["msgLogId"])),
-		ShowBuoy:    showBuoyValue,
-		ShowContent: util.ObjToString(msgInfo["showContent"]),
 		PositionIds: req.PositionIds,
 		Row4:        util.ObjToString(msgInfo["row4"]),
 		ProductName: util.ObjToString(msgInfo["productName"]),

+ 59 - 0
api/internal/logic/newusersavemsglogic.go

@@ -0,0 +1,59 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"app.yhyue.com/moapp/MessageCenter/util"
+	"context"
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type NewUserSaveMsgLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewNewUserSaveMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewUserSaveMsgLogic {
+	return &NewUserSaveMsgLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *NewUserSaveMsgLogic) NewUserSaveMsg(req *types.NewUserSaveMsgReq) (resp *types.NewUserSaveMsgResp, err error) {
+	lsi := l.svcCtx.MessageCenter
+	msgInfo := req.MsgInfo
+	/*msgLogId, err := (msgInfo["msgLogId"]).(json.Number).Int64()
+	msgType, err := (msgInfo["msgType"]).(json.Number).Int64()
+	fmt.Println("msgInfo:", msgInfo)*/
+	_, err = lsi.NewUserMsg(l.ctx, &messageclient.NewUserInsertMsgReq{
+		Appid:       util.ObjToString(msgInfo["appid"]),
+		Title:       util.ObjToString(msgInfo["title"]),
+		Content:     util.ObjToString(msgInfo["content"]),
+		MsgType:     util.Int64All(msgInfo["msgType"]),
+		Link:        util.ObjToString(msgInfo["link"]),
+		UserIds:     req.UserIds,
+		MsgLogId:    util.Int64All(msgInfo["msgLogId"]),
+		PositionIds: req.PositionIds,
+		Row4:        util.ObjToString(msgInfo["row4"]),
+		ProductName: util.ObjToString(msgInfo["productName"]),
+		OrderId:     util.ObjToString(msgInfo["orderId"]),
+		OrderMoney:  util.ObjToString(msgInfo["orderMoney"]),
+		AppPushUrl:  util.ObjToString(msgInfo["appPushUrl"]),
+		WxPushUrl:   util.ObjToString(msgInfo["wxPushUrl"]),
+		IosPushUrl:  util.ObjToString(msgInfo["iosPushUrl"]),
+	})
+	if err != nil {
+		return &types.NewUserSaveMsgResp{
+			Code:    1,
+			Message: err.Error(),
+		}, nil
+	}
+	return &types.NewUserSaveMsgResp{
+		Code:    1,
+		Message: "保存成功",
+	}, nil
+}

+ 0 - 58
api/internal/logic/unreadmessageslogic.go

@@ -1,58 +0,0 @@
-package logic
-
-import (
-	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
-	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
-	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
-	"context"
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type UnreadMessagesLogic struct {
-	logx.Logger
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-}
-
-func NewUnreadMessagesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UnreadMessagesLogic {
-	return &UnreadMessagesLogic{
-		Logger: logx.WithContext(ctx),
-		ctx:    ctx,
-		svcCtx: svcCtx,
-	}
-}
-
-func (l *UnreadMessagesLogic) UnreadMessages(req *types.UnreadMessageReq) (resp *types.UnreadMessageResp, err error) {
-	result := &types.UnreadMessageResp{}
-	lsi := l.svcCtx.MessageCenter
-	res, err := lsi.UserUnreadMsgList(l.ctx, &messageclient.UserUnreadMsgListReq{
-		UserId:     req.UserId,
-		Appid:      req.AppId,
-		PageSize:   req.PageSize,
-		OffSet:     req.Offset,
-		IsNeedData: req.IsNeedData,
-	})
-	if err != nil {
-		return nil, err
-	}
-	if res.List != nil && len(res.List) > 0 {
-		for _, v := range res.List {
-			result.Data = append(result.Data, map[string]interface{}{
-				"id":         v.Id,
-				"appid":      v.Appid,
-				"createtime": v.Createtime,
-				"title":      v.Title,
-				"msg_type":   v.MsgType,
-				"link":       v.Link,
-				"content":    v.Content,
-				"isRead":     v.IsRead,
-				"msgLogId":   v.MsgLogId,
-				"url":        v.Url,
-			})
-		}
-	}
-	result.Code = res.Code
-	result.Message = res.Message
-	result.Total = res.Count
-	return result, nil
-}

+ 41 - 0
api/internal/logic/updatemsgsummarylogic.go

@@ -0,0 +1,41 @@
+package logic
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"context"
+
+	"app.yhyue.com/moapp/MessageCenter/api/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UpdateMsgSummaryLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewUpdateMsgSummaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateMsgSummaryLogic {
+	return &UpdateMsgSummaryLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx,
+	}
+}
+
+func (l *UpdateMsgSummaryLogic) UpdateMsgSummary(req *types.UpdateMsgSummaryReq) (resp *types.Response, err error) {
+	resp = new(types.Response)
+	lsi := l.svcCtx.MessageCenter
+	res, err := lsi.UpdateMsgSummary(l.ctx, &messageclient.UpdateMsgSummaryReq{
+		MsgLogId: req.MsgLogId,
+		GroupId:  req.GroupId,
+		MsgType:  req.MsgType,
+	})
+	if err != nil {
+		resp.Code = 1
+	}
+	resp.Code = res.Code
+	resp.Message = res.Message
+	return resp, nil
+}

+ 26 - 17
api/internal/types/types.go

@@ -42,8 +42,9 @@ type MsgReadStatusResp struct {
 }
 
 type MarkReadReq struct {
-	MsgId int64  `json:"msgId"`
-	AppId string `header:"appId"`
+	MsgId  int64  `json:"msgId"`
+	AppId  string `header:"appId"`
+	UserId string `header:"mgoUserId"`
 }
 
 type MarkReadRes struct {
@@ -114,21 +115,6 @@ type MessageListResp struct {
 	RollingTiming int64                    `json:"rollingTiming"`
 }
 
-type UnreadMessageReq struct {
-	UserId     string `header:"mgoUserId"`
-	AppId      string `header:"appId"`
-	Offset     int64  `json:"offset"` //
-	PageSize   int64  `json:"pageSize"`
-	IsNeedData int64  `json:"isNeedData"` //是否需要未读消息数据 0 不需要  1 需要
-}
-
-type UnreadMessageResp struct {
-	Code    int64                    `json:"code"`
-	Message string                   `json:"message"`
-	Data    []map[string]interface{} `json:"data"`
-	Total   int64                    `json:"total"`
-}
-
 type WxTmplMessageReq struct {
 	UserIds     string `json:"userIds,optional"`     // 用户id如果是多个就逗号分割
 	PositionIds string `json:"positionIds,optional"` //用户职位id
@@ -152,3 +138,26 @@ type MsgOpenLogReq struct {
 	UserId   string `header:"mgoUserId"`
 	AppId    string `header:"appId"`
 }
+
+type NewUserSaveMsgReq struct {
+	MsgInfo     map[string]interface{} `json:"msgInfo"`
+	UserIds     string                 `json:"userIds"`
+	PositionIds string                 `json:"positionIds,optional"` // 职位id 如果是多个就逗号分割 和用户id一一对应
+}
+
+type NewUserSaveMsgResp struct {
+	Code    int64  `json:"code"`
+	Message string `json:"message"`
+}
+
+type UpdateMsgSummaryReq struct {
+	MsgLogId int64 `json:"msgLogId"`
+	GroupId  int64 `json:"groupId"`
+	MsgType  int64 `json:"msgType"`
+}
+
+type BitmapSaveMsgReq struct {
+	MsgInfo     map[string]interface{} `json:"msgInfo"`
+	UserIds     string                 `json:"userIds"`
+	PositionIds string                 `json:"positionIds,optional"` // 职位id 如果是多个就逗号分割 和用户id一一对应
+}

+ 49 - 19
api/message.api

@@ -47,8 +47,9 @@ type MsgReadStatusResp {
 }
 
 type MarkReadReq {
-	MsgId int64  `json:"msgId"`
-	AppId string `header:"appId"`
+	MsgId  int64  `json:"msgId"`
+	AppId  string `header:"appId"`
+	UserId string `header:"mgoUserId"`
 }
 type MarkReadRes {
 	Code    int64  `json:"code"`
@@ -117,19 +118,19 @@ type MessageListResp {
 	Unread        int64                    `json:"unread"`
 	RollingTiming int64                    `json:"rollingTiming"`
 }
-type UnreadMessageReq {
-	UserId     string `header:"mgoUserId"`
-	AppId      string `header:"appId"`
-	Offset     int64  `json:"offset"` //
-	PageSize   int64  `json:"pageSize"`
-	IsNeedData int64  `json:"isNeedData"` //是否需要未读消息数据 0 不需要  1 需要
-}
-type UnreadMessageResp {
-	Code    int64                    `json:"code"`
-	Message string                   `json:"message"`
-	Data    []map[string]interface{} `json:"data"`
-	Total   int64                    `json:"total"`
-}
+//type UnreadMessageReq {
+//	UserId     string `header:"mgoUserId"`
+//	AppId      string `header:"appId"`
+//	Offset     int64  `json:"offset"` //
+//	PageSize   int64  `json:"pageSize"`
+//	IsNeedData int64  `json:"isNeedData"` //是否需要未读消息数据 0 不需要  1 需要
+//}
+//type UnreadMessageResp {
+//	Code    int64                    `json:"code"`
+//	Message string                   `json:"message"`
+//	Data    []map[string]interface{} `json:"data"`
+//	Total   int64                    `json:"total"`
+//}
 
 type WxTmplMessageReq {
 	UserIds     string `json:"userIds,optional"`     // 用户id如果是多个就逗号分割
@@ -154,13 +155,42 @@ type MsgOpenLogReq {
 	AppId    string `header:"appId"`
 }
 
+type NewUserSaveMsgReq {
+	MsgInfo     map[string]interface{} `json:"msgInfo"`
+	UserIds     string                 `json:"userIds"`
+	PositionIds string                 `json:"positionIds,optional"` // 职位id 如果是多个就逗号分割 和用户id一一对应
+}
+type NewUserSaveMsgResp {
+	Code    int64  `json:"code"`
+	Message string `json:"message"`
+}
+type UpdateMsgSummaryReq {
+	MsgLogId int64 `json:"msgLogId"`
+	GroupId  int64 `json:"groupId"`
+	MsgType  int64 `json:"msgType"`
+}
+type BitmapSaveMsgReq {
+	MsgInfo     map[string]interface{} `json:"msgInfo"`
+	UserIds     string                 `json:"userIds"`
+	PositionIds string                 `json:"positionIds,optional"` // 职位id 如果是多个就逗号分割 和用户id一一对应
+}
+
 service message-api {
+	// 更新用户all_msg bitmap
+	@handler BitmapSaveMsgHandler
+	post /messageCenter/BitmapSaveMsg (BitmapSaveMsgReq) returns (MultipleSaveMsgResp)
+	// 更新消息汇总表
+	@handler UpdateMsgSummaryHandler
+	post /messageCenter/UpdateMsgSummary (UpdateMsgSummaryReq) returns (response)
+	// 新用户发送消息
+	@handler NewUserSaveMsgHandler
+	post /messageCenter/NewUserSaveMsg (NewUserSaveMsgReq) returns (NewUserSaveMsgResp)
 	//查询消息详情
 	@handler MessageDetailHandler
 	post /messageCenter/messageDetail (MessageDetailReq) returns (MessageDetailResp)
 	// 获取消息分类
-	@handler GetMsgTypeHandler
-	post /messageCenter/getMsgType (GetMsgTypeReq) returns (GetMsgTypeRes)
+	//	@handler GetMsgTypeHandler
+	//	post /messageCenter/getMsgType (GetMsgTypeReq) returns (GetMsgTypeRes)
 	// 标记为已读
 	@handler MarkReadHandler
 	post /messageCenter/markRead (MarkReadReq) returns (MarkReadRes)
@@ -181,8 +211,8 @@ service message-api {
 	post /messageCenter/MessageList (MessageListReq) returns (MessageListResp)
 	
 	//未读消息列表
-	@handler UnreadMessages
-	post /messageCenter/unreadMessages (UnreadMessageReq) returns (UnreadMessageResp)
+	//	@handler UnreadMessages
+	//	post /messageCenter/unreadMessages (UnreadMessageReq) returns (UnreadMessageResp)
 	
 	// 发送微信模版消息
 	@handler SendWxTmplMsg

+ 2 - 0
entity/message.go

@@ -4,6 +4,7 @@ import (
 	"app.yhyue.com/moapp/jybase/mail"
 	m "app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
+	"github.com/ClickHouse/clickhouse-go/v2/lib/driver"
 	"time"
 
 	"github.com/go-xorm/xorm"
@@ -21,6 +22,7 @@ var RollingTiming int64
 var SaveConcurrencyChan chan int //  定义保存消息并发
 var ClassSearchMap map[int64][]MsgClass
 var ClassMap map[int64]MsgClass
+var ClickhouseConn driver.Conn
 
 type MsgClass struct {
 	MsgType int64  `json:"msgType"`

+ 17 - 0
entity/newEntity.go

@@ -0,0 +1,17 @@
+package entity
+
+type MsgGroup struct {
+	Name     string `ch:"name"`
+	GroupId  int32  `ch:"group_id"`
+	Switch   string `ch:"switch"`
+	Img      string `ch:"img"`
+	Sequence int32  `ch:"sequence"`
+	Msg_type int32  `ch:"msg_type"`
+}
+type GroupClass struct {
+	Switch      string `ch:"switch"`
+	Wxtmpl_Id   string `ch:"wxtmpl_Id"`
+	Msg_type    int32  `ch:"msg_type"`
+	Msg_name    string `ch:"msg_name"`
+	Wxtmp_value string `ch:"wxtmp_value"`
+}

+ 4 - 0
go.mod

@@ -5,7 +5,11 @@ go 1.13
 require (
 	app.yhyue.com/moapp/jybase v0.0.0-20230901064756-2fc66b18db40
 	bp.jydev.jianyu360.cn/BaseService/gateway v1.3.4
+	github.com/ClickHouse/clickhouse-go/v2 v2.2.0
+	github.com/RoaringBitmap/roaring v1.5.0
 	github.com/go-xorm/xorm v0.7.9
+	github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.6.1
+	github.com/robfig/cron/v3 v3.0.1
 	github.com/zeromicro/go-zero v1.3.5
 	google.golang.org/grpc v1.47.0
 	google.golang.org/protobuf v1.28.0

+ 85 - 27
go.sum

@@ -62,16 +62,21 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ
 github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
 github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
 github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
+github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
+github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/ClickHouse/clickhouse-go v1.5.1/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
+github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
 github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
+github.com/ClickHouse/clickhouse-go/v2 v2.0.15/go.mod h1:Z21o82zD8FFqefOQDg93c0XITlxGbTsWQuRm588Azkk=
+github.com/ClickHouse/clickhouse-go/v2 v2.2.0 h1:dj00TDKY+xwuTJdbpspCSmTLFyWzRJerTHwaBxut1C0=
 github.com/ClickHouse/clickhouse-go/v2 v2.2.0/go.mod h1:8f2XZUi7XoeU+uPIytSi1cvx8fmJxi7vIgqpvYTF1+o=
 github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
 github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
 github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
+github.com/RoaringBitmap/roaring v1.5.0 h1:V0VCSiHjroItEYCM3guC8T83ehi5QMt3oM9EefTTOms=
 github.com/RoaringBitmap/roaring v1.5.0/go.mod h1:plvDsJQpxOC5bw8LRteu/MLWHsHez/3y6cubLI4/1yE=
 github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 github.com/Shopify/sarama v1.30.0/go.mod h1:zujlQQx1kzHsh4jfV1USnptCQrHAEZ2Hk8fTKCulPVs=
@@ -99,6 +104,7 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
+github.com/bits-and-blooms/bitset v1.2.0 h1:Kn4yilvwNtMACtf1eYDlG8H77R07mZSPbMjLyS07ChA=
 github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
 github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@@ -108,8 +114,9 @@ github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
-github.com/clbanning/mxj/v2 v2.5.5 h1:oT81vUeEiQQ/DcHbzSytRngP6Ky9O+L+0Bw0zSJag9E=
 github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
+github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
+github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
@@ -157,16 +164,18 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
-github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
 github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
+github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
+github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
 github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
 github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
 github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
+github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
+github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/garyburd/redigo v1.6.2 h1:yE/pwKCrbLpLpQICzYTeZ7JsTA/C53wFTJHaEtRqniM=
 github.com/garyburd/redigo v1.6.2/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
@@ -187,8 +196,9 @@ github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
@@ -212,7 +222,6 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-test/deep v1.0.7 h1:/VSMRlnY/JSyqxQUzQLKVMAskpY/NZKFA5j2P+0pP2M=
 github.com/go-test/deep v1.0.7/go.mod h1:QV8Hv/iy04NyLBxAdO9njL0iVPN1S4d/A3NVv1V36o8=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:9wScpmSP5A3Bk8V3XHWUcJmYTh+ZnlHVyc+A4oZYS3Y=
 github.com/go-xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:56xuuqnHyryaerycW3BfssRdxQstACi0Epw/yC5E2xM=
@@ -244,8 +253,11 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
 github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
-github.com/gogf/gf/v2 v2.0.6 h1:2etb4FMpbQKWIJO+UjtIWrZUp01HUsFb6Po8pgizAWk=
+github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.6.1 h1:ECineDg2mz0fJgfh8Pyh7xwPC8MN/nHSyfsLD0qtrE0=
+github.com/gogf/gf/contrib/drivers/clickhouse/v2 v2.6.1/go.mod h1:wlqfsjkIw3ZLEbcns5jK5urj1lt2JLweaqB+OlduRl0=
 github.com/gogf/gf/v2 v2.0.6/go.mod h1:8uYzw7qNzuq8vrhVlWke1b1925FFqOJIgmyYW1sr/0M=
+github.com/gogf/gf/v2 v2.6.1 h1:n/cfXM506WjhPa6Z1CEDuHNM1XZ7C8JzSDPn2AfuxgQ=
+github.com/gogf/gf/v2 v2.6.1/go.mod h1:x2XONYcI4hRQ/4gMNbWHmZrNzSEIg20s2NULbzom5k0=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -305,8 +317,9 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
-github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
+github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
@@ -411,8 +424,9 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
 github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
 github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/longbridgeapp/sqlparser v0.3.1 h1:iWOZWGIFgQrJRgobLXUNJdvqGRpbVXkyKUKUA5CNJBE=
 github.com/longbridgeapp/sqlparser v0.3.1/go.mod h1:GIHaUq8zvYyHLCLMJJykx1CdM6LHtkUih/QaJXySSx4=
+github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo=
+github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
@@ -420,14 +434,19 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
 github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
 github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
 github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
-github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
 github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
+github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
+github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
 github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
 github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
 github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
@@ -445,6 +464,7 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
 github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
 github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
 github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
+github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
 github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -486,6 +506,7 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ
 github.com/openzipkin/zipkin-go v0.3.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ=
 github.com/openzipkin/zipkin-go v0.4.0 h1:CtfRrOVZtbDj8rt1WXjklw0kqqJQwICrCKmlfUuBUUw=
 github.com/openzipkin/zipkin-go v0.4.0/go.mod h1:4c3sLeE8xjNqehmF5RpAFLPLJxXscc0R4l6Zg0P1tTQ=
+github.com/paulmach/orb v0.7.1 h1:Zha++Z5OX/l168sqHK3k4z18LDvr+YAO/VjK0ReQ9rU=
 github.com/paulmach/orb v0.7.1/go.mod h1:FWRlTgl88VI1RBx/MkrwWDRhQ96ctqMCh8boXhmqB/A=
 github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
 github.com/pelletier/go-toml v1.7.0 h1:7utD74fnzVc/cpcyy8sjrlFr5vYpypUixARcHIMIGuI=
@@ -494,7 +515,10 @@ github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS
 github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI=
 github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
 github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
+github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
 github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -535,8 +559,11 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1
 github.com/rabbitmq/amqp091-go v1.1.0/go.mod h1:ogQDLSOACsLPsIq0NpbtiifNZi2YOz0VTJ0kHRghqbM=
 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
-github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
+github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
+github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
+github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
 github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
 github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -546,6 +573,7 @@ github.com/shirou/gopsutil v2.19.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMT
 github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
 github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4/go.mod h1:qsXQc7+bwAM3Q1u/4XEfrquwF8Lw7D7y5cD8CuHnfIc=
 github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
 github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -569,8 +597,9 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
@@ -580,8 +609,9 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
 github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
+github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
 github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
 github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
@@ -604,6 +634,7 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
 github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9 h1:k/gmLsJDWwWqbLCur2yWnJzwQEKRcAHXo6seXGuSwWw=
 github.com/yuin/gopher-lua v0.0.0-20210529063254-f4c35e4016d9/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA=
@@ -635,8 +666,9 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
 go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
 go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs=
 go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk=
-go.opentelemetry.io/otel v1.8.0 h1:zcvBFizPbpa1q7FehvFiHbQwGzmPILebO0tyqIR5Djg=
 go.opentelemetry.io/otel v1.8.0/go.mod h1:2pkj+iMj0o03Y+cW6/m8Y4WkRdYN3AvCXCnzRMp9yvM=
+go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
+go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
 go.opentelemetry.io/otel/exporters/jaeger v1.3.0/go.mod h1:KoYHi1BtkUPncGSRtCe/eh1ijsnePhSkxwzz07vU0Fc=
 go.opentelemetry.io/otel/exporters/jaeger v1.8.0 h1:TLLqD6kDhLPziEC7pgPrMvP9lAqdk3n1gf8DiFSnfW8=
 go.opentelemetry.io/otel/exporters/jaeger v1.8.0/go.mod h1:GbWg+ng88rDtx+id26C34QLqw2erqJeAjsCx9AFeHfE=
@@ -645,13 +677,15 @@ go.opentelemetry.io/otel/exporters/zipkin v1.8.0 h1:PIAiDdROZzATAFfxr5ASYuSOG0JI
 go.opentelemetry.io/otel/exporters/zipkin v1.8.0/go.mod h1:0uYAyCuGT67MFV9Z/Mmx93wGuugHw0FbxMc74fs3LNo=
 go.opentelemetry.io/otel/sdk v1.0.0/go.mod h1:PCrDHlSy5x1kjezSdL37PhbFUMjrsLRshJ2zCzeXwbM=
 go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs=
-go.opentelemetry.io/otel/sdk v1.8.0 h1:xwu69/fNuwbSHWe/0PGS888RmjWY181OmcXDQKu7ZQk=
 go.opentelemetry.io/otel/sdk v1.8.0/go.mod h1:uPSfc+yfDH2StDM/Rm35WE8gXSNdvCg023J6HeGNO0c=
+go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
+go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
 go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
 go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk=
 go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU=
-go.opentelemetry.io/otel/trace v1.8.0 h1:cSy0DF9eGI5WIfNwZ1q2iUyGj00tGzP24dE1lOlHrfY=
 go.opentelemetry.io/otel/trace v1.8.0/go.mod h1:0Bt3PXY8w+3pheS3hQUt+wow8b1ojPaTBoTCh2zIFI4=
+go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
+go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
 go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@@ -682,8 +716,10 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
-golang.org/x/crypto v0.0.0-20210920023735-84f357641f63 h1:kETrAMYZq6WVGPa8IIixL0CaEcIUNi+1WX7grUoi3y8=
 golang.org/x/crypto v0.0.0-20210920023735-84f357641f63/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
+golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -716,8 +752,10 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
 golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -761,8 +799,12 @@ golang.org/x/net v0.0.0-20210917221730-978cfadd31cf/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220531201128-c960675eff93 h1:MYimHLfoXEpOhqd/zgoA/uoXzHB86AEky4LAx5ij9xA=
 golang.org/x/net v0.0.0-20220531201128-c960675eff93/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
+golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -782,8 +824,10 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -851,13 +895,23 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220429233432-b5fbb4746d32/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
+golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
-golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
+golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -866,8 +920,11 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2 h1:GLw7MR8AfAG2GmGcmVgObFOHXYypgGjnGno25RDwn3Y=
 golang.org/x/text v0.3.8-0.20211105212822-18b340fc7af2/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -928,12 +985,13 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
-golang.org/x/tools v0.1.7 h1:6j8CgantCy3yc8JGBqkDLMKWqZ0RDU2g1HVgacojGWQ=
 golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk=
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=

+ 17 - 4
rpc/etc/message.yaml

@@ -7,7 +7,7 @@ Etcd:
   Key: message.rpc
 Timeout: 10000
 PushGrpcServer: 192.168.3.206:5566
-Mysql: root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/messageCenter?charset=utf8mb4&parseTime=true&loc=Local
+#Mysql: root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/messageCenter?charset=utf8mb4&parseTime=true&loc=Local
 Mongodb:
   Address: 192.168.3.206:27080
   Size: 10
@@ -18,7 +18,7 @@ Mongodb:
   Collection:
   Collection_back:
 DataSource:
-    DbName: messageCenter
+    DbName: jianyu
     Address: 192.168.3.217:4000
     UserName: root
     PassWord: =PDT49#80Z!RVv52_z
@@ -31,7 +31,7 @@ BaseSource:
   PassWord: =PDT49#80Z!RVv52_z
   MaxOpenConns: 50
   MaxIdleConns: 50
-RedisAddr: "msgCount=192.168.3.149:1712"
+RedisAddr: "msgCount=192.168.3.149:1713"
 FileSystemConf:
   Etcd:
     Hosts:
@@ -66,5 +66,18 @@ WxTmplConfig:
 Tidb: "root:=PDT49#80Z!RVv52_z@tcp(192.168.3.217:4000)/messageCenter?charset=utf8mb4&parseTime=true&loc=Local"
 ClassSearchList: # 需要按照messageClass 查询的groupId
   - 11  # 待办 group id
+<<<<<<< HEAD
 EquityInfoMsgType: 13 #营销权益消息需要特殊处理
-Registedate: 1705556502
+Registedate: 1705556502
+=======
+Clickhouse:
+  Addr: 192.168.3.207:19000
+  UserName: jytop
+  Password: pwdTopJy123
+  DbName: messageCenter
+  MaxIdleConns: 5
+  MaxOpenConns: 30
+GlobMsgLoadTime: "0 0/5 * * * *"
+EquityInfoMsgType: 13 #营销权益消息需要特殊处理
+NewUserMsgTitle: 做任务赚好礼
+>>>>>>> master

+ 10 - 13
rpc/internal/common/getBuoyMsg.go

@@ -6,6 +6,7 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/util"
 	qutil "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
+	"context"
 	"fmt"
 	"log"
 	"strconv"
@@ -68,16 +69,16 @@ func LinkSplit(url string) (link, androidUrl, iosUrl, weChatUrl string) {
 
 func ClearUnreadMsg(in *message.ClearUnreadMsgReq) error {
 	if in.Userid != "" {
-		query := map[string]interface{}{
-			"receive_userid": in.Userid,
-			"appid":          in.AppId,
-			"isdel":          1,
-			"isRead":         0,
+		//更新用户未读消息bitmap
+		sql := fmt.Sprintf(`alter table message_user_summary UPDATE readMsg = bitmapOr(allMsg,readMsg) where userId = '%s'`, in.Userid)
+		err1 := entity.ClickhouseConn.Exec(context.Background(), sql)
+		if err1 != nil {
+			return err1
 		}
-
-		//更新服务未读数
-		if !entity.Mysql.Update("message", query, map[string]interface{}{"isRead": 1}) {
-			log.Println("更新服务未读数失败")
+		//清缓存
+		for _, v := range entity.MessageColumn {
+			keyString := fmt.Sprintf(MsgCountKey, in.Userid, qutil.Int64All(v["group_id"]))
+			redis.Put(redisModule, keyString, 0, -1)
 		}
 		// p436  清空消息时  "msg_class_count_%s_%d" 下的消息数量也清空
 		for _, classes := range entity.ClassSearchMap {
@@ -86,11 +87,7 @@ func ClearUnreadMsg(in *message.ClearUnreadMsgReq) error {
 				redis.Put(redisModule, classKeyString, 0, -1)
 			}
 		}
-		for _, v := range entity.MessageColumn {
-			go MsgCountZero(in.Userid, in.AppId, qutil.Int64All(v["group_id"]))
-		}
 	}
-
 	//更新私信未读数
 	if in.PositionId > 0 {
 		sQuery := map[string]interface{}{

+ 29 - 19
rpc/internal/common/messageClass.go

@@ -4,7 +4,9 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/entity"
 	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
 	"app.yhyue.com/moapp/jybase/common"
+	"context"
 	"fmt"
+	"log"
 	"strings"
 )
 
@@ -20,26 +22,34 @@ func InitClassSearchMap() {
 			qArr = append(qArr, fmt.Sprintf("%d", groupIDs[i]))
 		}
 		// 查库
-		q := "SELECT * FROM message_class where group_id in (" + strings.Join(qArr, ",") + ") order by msg_type;"
-		rs := entity.Mysql.SelectBySql(q)
-		if rs != nil && len(*rs) > 0 {
-			for i := 0; i < len(*rs); i++ {
-				groupID := common.Int64All((*rs)[i]["group_id"])
-				msgName := common.ObjToString((*rs)[i]["msg_name"])
-				msgType := common.Int64All((*rs)[i]["msg_type"])
-				img := common.ObjToString((*rs)[i]["img"])
-				// 处理成map
-				if _, ok := entity.ClassSearchMap[groupID]; !ok {
-					entity.ClassSearchMap[groupID] = []entity.MsgClass{}
-				}
-				tmp := entity.MsgClass{
-					MsgType: msgType,
-					Name:    msgName,
-					Img:     img,
-				}
-				entity.ClassSearchMap[groupID] = append(entity.ClassSearchMap[groupID], tmp)
-				entity.ClassMap[msgType] = tmp
+		q := "SELECT msg_type,msg_name as name,group_id,img FROM message_class where group_id in (" + strings.Join(qArr, ",") + ") order by msg_type;"
+		rs, err := entity.ClickhouseConn.Query(context.Background(), q)
+		if err != nil {
+			log.Println("InitClassSearchMap 查询message_class出错:", err)
+			return
+		}
+		for rs.Next() {
+			mg := entity.MsgGroup{}
+			err = rs.ScanStruct(&mg)
+			if err != nil {
+				log.Println("InitClassSearchMap 初始化rs ScanStruct出错:", err)
+				return
+			}
+			groupID := common.Int64All(mg.GroupId)
+			msgName := common.ObjToString(mg.Name)
+			msgType := common.Int64All(mg.Msg_type)
+			img := common.ObjToString(mg.Img)
+			// 处理成map
+			if _, ok := entity.ClassSearchMap[groupID]; !ok {
+				entity.ClassSearchMap[groupID] = []entity.MsgClass{}
+			}
+			tmp := entity.MsgClass{
+				MsgType: msgType,
+				Name:    msgName,
+				Img:     img,
 			}
+			entity.ClassSearchMap[groupID] = append(entity.ClassSearchMap[groupID], tmp)
+			entity.ClassMap[msgType] = tmp
 		}
 	}
 }

+ 11 - 20
rpc/internal/common/messageLog.go

@@ -2,7 +2,9 @@ package common
 
 import (
 	"app.yhyue.com/moapp/MessageCenter/entity"
-	"github.com/go-xorm/xorm"
+	"app.yhyue.com/moapp/jybase/common"
+	"context"
+	"fmt"
 	"log"
 	"time"
 )
@@ -14,27 +16,16 @@ var (
 
 // SaveMessageClockLog 保存消息点击记录
 func SaveMessageClockLog(saveData []map[string]interface{}) {
-	orm := entity.Engine.NewSession()
-	defer func(orm *xorm.Session) {
-		orm.Close()
-	}(orm)
-	err := orm.Begin()
-	if err != nil {
-		log.Println("保存消息事务开启失败", err)
-		return
-	}
-	_, err = orm.Table("message_open_log").Insert(saveData)
-	if err != nil {
-		err2 := orm.Rollback()
-		if err2 != nil {
-			log.Println("存储消息rollback失败", err2)
-			return
+	sql := "INSERT INTO message_open_log (`userid`,`msg_log_id`,`platform`,`createtime`) values "
+	for i, data := range saveData {
+		if i != 0 {
+			sql += ","
 		}
-		log.Println("存储消息打开日志失败", err)
+		sql += fmt.Sprintf(" ('%s',%d,%d,%d) ", common.InterfaceToStr(data["userid"]), common.IntAll(data["msg_log_id"]), common.IntAll(data["platform"]), time.Now().Unix())
 	}
-	err = orm.Commit()
-	if err != nil {
-		log.Println("存储消息commit失败", err)
+	fmt.Println(sql)
+	if err := entity.ClickhouseConn.Exec(context.Background(), sql); err != nil {
+		log.Println("save 异常", err)
 		return
 	}
 }

+ 35 - 51
rpc/internal/common/messageService.go

@@ -6,6 +6,7 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/util"
 	qutil "app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
+	"context"
 	"errors"
 	"fmt"
 	"log"
@@ -16,49 +17,32 @@ import (
 type MessageService struct{}
 
 // 修改消息阅读状态
-func (service *MessageService) ChangeReadStatus(data *message.ChangeReadStatusReq) (int64, string) {
-	msg := entity.Mysql.FindOne("message", map[string]interface{}{"id": data.Id, "isdel": 1, "appid": data.Appid}, "", "")
-	//log.Println("查询到消息:", msg)
-	if msg == nil {
-		return 0, "该消息不存在"
+func (service *MessageService) ChangeReadStatus(data *message.ChangeReadStatusReq) error {
+	row := entity.ClickhouseConn.QueryRow(context.Background(), fmt.Sprintf("SELECT count(*) from message_user_summary WHERE  userId = '%s' ANd bitmapContains(readMsg,%d)", data.UserId, data.Id))
+	var count uint64
+	row.Scan(&count)
+	if count > 0 {
+		return nil
 	}
-	b := entity.Mysql.Update("message", map[string]interface{}{"id": data.Id, "isdel": 1}, map[string]interface{}{"isRead": int(data.ReadStatus)})
-	if !b {
-		return 0, "修改消息阅读状态失败"
-	}
-	MsgCountMinusOne(qutil.ObjToString((*msg)["receive_userid"]), data.Appid, qutil.Int64All((*msg)["group_id"]), qutil.Int64All((*msg)["msg_type"]))
-	return 1, "修改消息阅读状态成功"
-}
-
-// 删除消息
-func (service *MessageService) DeleteMessage(id []string, appId string) (int64, string) {
-	orm := entity.Engine.NewSession()
-	defer orm.Close()
-	msg := entity.Mysql.FindOne("message", map[string]interface{}{"id": id, "appid": appId}, "", "")
-	if msg == nil {
-		return 0, "该消息不存在"
-	}
-	m := entity.Message{}
-	m.Isdel = -1
-	count, err := orm.Where("appid=?", appId).In("id", id).Cols("isdel").Update(&m)
-	if err != nil || count == 0 {
-		log.Println(err)
-		orm.Rollback()
-		return 0, "删除消息失败"
-	}
-	err2 := orm.Commit()
-	if err2 != nil {
-		return 0, "删除消息失败"
+	msg := entity.Mysql.FindOne("message_send_log", map[string]interface{}{"id": data.Id}, "group_id", "")
+	if msg != nil && len(*msg) > 0 {
+		groupId := qutil.IntAll((*msg)["group_id"])
+		//更新用户未读消息bitmap
+		sql := fmt.Sprintf(`alter table message_user_summary UPDATE readMsg = bitmapOr(readMsg,bitmapBuild([toUInt64(%d)])) where userId = '%s'`, data.Id, data.UserId)
+		fmt.Println(sql)
+		err1 := entity.ClickhouseConn.Exec(context.Background(), sql)
+		if err1 != nil {
+			return err1
+		}
+		//清缓存
+		keyString := fmt.Sprintf(MsgCountKey, data.UserId, groupId)
+		if redis.GetInt(redisModule, keyString) > 0 {
+			redis.Decrby(redisModule, keyString, 1)
+		}
+	} else {
+		return errors.New(fmt.Sprintf("消息不存在:%d", data.Id))
 	}
-	FindUserMsg(message.FindUserMsgReq{
-		UserId:   qutil.ObjToString((*msg)["receive_userid"]),
-		Appid:    appId,
-		OffSet:   1,
-		PageSize: 5,
-		MsgType:  -1,
-		Read:     0,
-	}, true)
-	return 1, "删除消息成功"
+	return nil
 }
 
 // 未读消息合计 isRedis 是否需要初始化redis
@@ -134,11 +118,8 @@ func (service *MessageService) CountClassUnread(userId string, groupId int64) (c
 
 // 查询消息详情
 func FindMessageDetail(id, msgLogId int64, userId string) (msg *map[string]interface{}, err error) {
-	if id > 0 {
-		msg = entity.Mysql.FindOne("message", map[string]interface{}{"id": id}, "", "")
-	} else {
-		msg = entity.Mysql.FindOne("message", map[string]interface{}{"receive_userid": userId, "msg_log_id": msgLogId}, "", "")
-	}
+	//直接查询message_send_log
+	msg = entity.Mysql.FindOne("message_send_log", map[string]interface{}{"id": msgLogId}, "", "")
 	if msg != nil && len(*msg) > 0 {
 		return msg, nil
 	}
@@ -146,7 +127,7 @@ func FindMessageDetail(id, msgLogId int64, userId string) (msg *map[string]inter
 }
 
 // GetMsgType 消息的分类
-func (service *MessageService) GetMsgType() (data []*message.MsgTypes, err error) {
+/*func (service *MessageService) GetMsgType() (data []*message.MsgTypes, err error) {
 	types := entity.Mysql.SelectBySql("SELECT * FROM `message_group` WHERE group_id > 0 ORDER BY sequence ASC")
 	if types != nil && len(*types) > 0 {
 		for _, val := range *types {
@@ -161,11 +142,14 @@ func (service *MessageService) GetMsgType() (data []*message.MsgTypes, err error
 		return data, nil
 	}
 	return nil, nil
-}
+}*/
 
-func (service *MessageService) MsgOpenLog(platFrom, msgLogId int64, userId string) int64 {
+func (service *MessageService) MsgOpenLog(platFrom, msgLogId int64, userId string) error {
 	//判断用户是否已经在pc端打开过
-	count := entity.Mysql.CountBySql("SELECT COUNT(*) FROM message_open_log WHERE msg_log_id = ? and platform = ? and userid = ?", msgLogId, platFrom, userId)
+	sql := fmt.Sprintf("SELECT COUNT(*) FROM message_open_log WHERE msg_log_id = %d and platform = %d and userid = '%s'", msgLogId, platFrom, userId)
+	row := entity.ClickhouseConn.QueryRow(context.Background(), sql)
+	var count uint64
+	row.Scan(&count)
 	if count <= 0 {
 		tmp := map[string]interface{}{
 			"msg_log_id": msgLogId,
@@ -175,5 +159,5 @@ func (service *MessageService) MsgOpenLog(platFrom, msgLogId int64, userId strin
 		}
 		SaveCache <- tmp
 	}
-	return 0
+	return nil
 }

+ 502 - 0
rpc/internal/common/msglistService.go

@@ -0,0 +1,502 @@
+package common
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/entity"
+	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
+	"app.yhyue.com/moapp/MessageCenter/util"
+	"app.yhyue.com/moapp/jybase/common"
+	m "app.yhyue.com/moapp/jybase/mongodb"
+	"app.yhyue.com/moapp/jybase/redis"
+	"context"
+	"errors"
+	"fmt"
+	"log"
+	"strconv"
+	"time"
+)
+
+func BitmapUserMsgList(this *message.UserMsgListReq) (*message.UserMsgList, *message.Messages) {
+	var (
+		unread, count int64
+		data          = new(message.UserMsgList)
+	)
+	//取出用户所有消息、已读消息id bitmap 查库
+	userAllMsgArr, _, userUnreadArr, err := GetUserMsgSummary(this.UserId)
+	if len(userAllMsgArr) == 0 && err != nil {
+		fmt.Printf("此用户暂无消息 : %s", err.Error())
+	}
+	//用户分类消息
+	_, userClassMsgMap := FindUserClassMsg(this.UserId)
+	//用户分类未读消息
+	classUnreadCountMap, classUnreadMsgMap := FindUserClassUnread(this.UserId)
+	//fmt.Println("用户所有消息数:", userAllMsgArr, "已读消息数:", userReadArr, "未读消息数:", userUnreadArr)
+	//导航未读消息总数
+	if !this.IsMsgList && !this.IsColumnNewMsg && !this.IsColumn { //消息未读数统计
+		_, unread = BitmapCountUnread(this.UserId, classUnreadCountMap, true)
+		data.Unread = unread
+		return data, nil
+	}
+	//获取栏目下的数据
+	sData := make(map[string][]*message.Messages)
+	//移动端消息列表首页
+	if this.IsColumnNewMsg && this.SortSize > 0 {
+		messageColumn := entity.MessageColumn
+		if this.IsClassSearch {
+			messageColumn = append(messageColumn, map[string]interface{}{
+				"group_id": 12,
+			})
+		}
+		for _, val := range messageColumn {
+			if util.IntAll(val["group_id"]) > 0 && util.IntAll(val["group_id"]) < 999 {
+				//用户分类未读 交集
+				userClassUnreadMsgArr := classUnreadMsgMap[util.IntAll(val["group_id"])]
+				var lastMsgId int
+				if len(userClassUnreadMsgArr) > 0 {
+					lastMsgId = userClassUnreadMsgArr[len(userClassUnreadMsgArr)-1]
+				} else {
+					//没有未读,分类展示最新一条消息
+					classMsg := userClassMsgMap[util.IntAll(val["group_id"])]
+					if len(classMsg) > 0 {
+						lastMsgId = classMsg[len(classMsg)-1]
+					} else {
+						continue
+					}
+				}
+				lastMsg := GlobMsgMap[lastMsgId]
+				if lastMsg == nil || len(lastMsg) <= 0 {
+					mess := entity.Mysql.FindOne("message_send_log", map[string]interface{}{"id": int(lastMsgId)}, "id,msg_type,title,content,send_time,link,menu_name,group_id,sign", "")
+					if mess != nil && len(*mess) > 0 {
+						lastMsg = *mess
+					} else {
+						continue
+					}
+				}
+				if common.IntAll(lastMsg["sign"]) == 4 {
+					//查询用户注册时间
+					rData, _ := entity.MQFW.FindOneByField("user", map[string]interface{}{"_id": m.StringTOBsonId(this.UserId)}, `{"l_registedate":1}`)
+					if rData != nil && len(*rData) > 0 {
+						lastMsg["send_time"] = time.Unix(common.Int64All((*rData)["l_registedate"]), 0).Local().Format("2006-01-02 15:04:05")
+					}
+				}
+				var msg = message.Messages{
+					Id:         strconv.FormatInt(util.Int64All(lastMsg["id"]), 10),
+					Createtime: common.InterfaceToStr(lastMsg["send_time"]),
+					Title:      common.InterfaceToStr(lastMsg["title"]),
+					MsgType:    int64(util.IntAll(lastMsg["group_id"])),
+				}
+				if this.IsClassSearch && util.IntAll(val["group_id"]) == 12 {
+					sData[common.InterfaceToStr(val["group_id"])] = []*message.Messages{&msg}
+					continue
+				}
+				if sData[common.InterfaceToStr(lastMsg["group_id"])] == nil {
+					sData[common.InterfaceToStr(lastMsg["group_id"])] = []*message.Messages{&msg}
+				} else {
+					sData[common.InterfaceToStr(lastMsg["group_id"])] = append(sData[common.InterfaceToStr(lastMsg["group_id"])], &msg)
+				}
+			}
+		}
+	}
+	//pc消息列表消息分类
+	var columnData []*message.AllSortData
+	if this.IsColumn && this.MsgType > 0 && this.IsClassSearch {
+		// 获取小分类下的未读数
+		sortUnread, total := BitmapCountClassUnread(this.UserId, this.MsgType, classUnreadCountMap)
+		columnArr := []entity.MsgClass{}
+		if !this.IsColumnNewMsg { // 用于区分分类列表页和分类详情页   根据不同情况
+			columnArr = append(columnArr, entity.ClassMap[this.MsgType])
+		} else {
+			columnArr = entity.ClassSearchMap[this.MsgType]
+		}
+		unread += total
+		for i := 0; i < len(columnArr); i++ {
+			tmp := columnArr[i]
+			var column message.AllSortData
+			column.Name = tmp.Name
+			column.Img = fmt.Sprintf("/common-module/msgCenter/%s.png", tmp.Img)
+			column.MsgType = tmp.MsgType
+			// 消息未读数
+			msgType := common.InterfaceToStr(tmp.MsgType)
+			column.UnreadMessages = sortUnread[msgType]
+			column.Data = sData[msgType]
+			column.IsClassSearch = true
+			columnData = append(columnData, &column)
+		}
+	} else if this.IsColumn {
+		//获取所有分类未读数 不初始化
+		sortUnread, total := BitmapCountUnread(this.UserId, classUnreadCountMap, false)
+		//fmt.Println("*************", total)
+		unread += total
+		for _, v := range entity.MessageColumn {
+			var column message.AllSortData
+			column.Name = common.InterfaceToStr(v["name"])
+			column.Img = fmt.Sprintf("/common-module/msgCenter/%s.png", common.InterfaceToStr(v["img"]))
+			column.MsgType = common.Int64All(v["group_id"])
+			if column.Name == "私信" {
+				column.UnreadMessages = unreadMsg(this)
+			} else if common.IntAll(v["group_id"]) > 0 {
+				//消息未读数
+				msgType := common.InterfaceToStr(v["group_id"])
+				column.UnreadMessages = sortUnread[msgType]
+				column.Data = sData[msgType]
+			}
+			if _, ok := entity.ClassSearchMap[column.MsgType]; ok {
+				column.IsClassSearch = true
+			}
+			columnData = append(columnData, &column)
+		}
+	}
+	data.SortData = columnData
+	if len(userAllMsgArr) == 0 {
+		fmt.Printf("此用户暂无消息 : %s", err.Error())
+		return data, nil
+	}
+
+	count = int64(len(userAllMsgArr))
+	//pc列表数据、移动端分类列表
+	if this.IsMsgList {
+		if count > 0 {
+			var userMsgArr []int
+			if this.OffSet <= 0 {
+				this.OffSet = 1
+			}
+			if this.MsgType > 0 {
+				var totalMsg []int
+				//分类消息bitmap
+				totalMsg = userClassMsgMap[int(this.MsgType)]
+				if this.MsgType == 11 {
+					if !this.IsClassSearch {
+						totalMsg = append(totalMsg, userClassMsgMap[12]...)
+					}
+				}
+				userMsgArr = totalMsg
+			} else {
+				userMsgArr = Uint32ArrToIntArr(userAllMsgArr)
+			}
+			if this.Read == 0 { //未读
+				userMsgArr = Uint32ArrToIntArr(userUnreadArr)
+			}
+			if this.MsgType > 0 {
+				count = int64(len(userMsgArr))
+			}
+			if len(userMsgArr) > 0 {
+				userMsgArr = IntArrSort(userMsgArr)
+				fmt.Println("列表消息:", userMsgArr)
+				//总页数
+				var pageCount = 0
+				if this.PageSize != 0 {
+					if len(userMsgArr)%int(this.PageSize) > 0 {
+						pageCount = len(userMsgArr)/int(this.PageSize) + 1
+					} else {
+						pageCount = len(userMsgArr) / int(this.PageSize)
+					}
+				}
+				start := len(userMsgArr) - int(this.PageSize*(this.OffSet-1))
+				end := start - int(this.PageSize)
+				if int(this.OffSet) == pageCount || this.PageSize == 0 {
+					end = 0
+				}
+				//fmt.Println(end, start)
+				if end < 0 || start < 0 {
+					return data, nil
+				}
+				resArr := userMsgArr[end:start]
+				resData := []*message.Messages{}
+				if len(resArr) > 0 {
+					//count = int64(len(resArr))
+					unReadMap := map[int]bool{}
+					for _, vv := range userUnreadArr {
+						unReadMap[int(vv)] = true
+					}
+					for _, v := range resArr {
+						msg := GlobMsgMap[v]
+						if msg == nil || len(msg) <= 0 {
+							ms := entity.Mysql.FindOne("message_send_log", map[string]interface{}{"id": v}, "id,msg_type,title,content,send_time,link,menu_name,group_id,sign", "")
+							if ms != nil && len(*ms) > 0 {
+								msg = *ms
+							} else {
+								continue
+							}
+						}
+						if common.IntAll(msg["sign"]) == 4 {
+							//查询用户注册时间
+							rData, _ := entity.MQFW.FindOneByField("user", map[string]interface{}{"_id": m.StringTOBsonId(this.UserId)}, `{"l_registedate":1}`)
+							if rData != nil && len(*rData) > 0 {
+								msg["send_time"] = time.Unix(common.Int64All((*rData)["l_registedate"]), 0).Local().Format("2006-01-02 15:04:05")
+							}
+						}
+						resData = append(resData, &message.Messages{
+							Id:         common.InterfaceToStr(v),
+							Createtime: common.InterfaceToStr(msg["send_time"]),
+							Title:      common.InterfaceToStr(msg["title"]),
+							MsgType:    int64(util.IntAll(msg["group_id"])),
+							Link:       common.InterfaceToStr(msg["link"]),
+							Content:    common.InterfaceToStr(msg["content"]),
+							IsRead:     common.Int64All(common.If(unReadMap[v], 0, 1)),
+							MsgLogId:   int64(v),
+						})
+					}
+					for i := len(resData) - 1; i >= 0; i-- {
+						data.Data = append(data.Data, resData[i])
+					}
+				}
+			}
+		}
+	}
+	data.Count = count
+	if this.Read == 0 {
+		//unread = count
+		if this.IsContainLetter { //是否需要统计私信未读数
+			unread += unreadMsg(this)
+		}
+	}
+	data.Unread = unread
+	//置顶消息
+	if len(classUnreadMsgMap[1]) > 0 {
+		activeMsgArr := classUnreadMsgMap[1]
+		res2 := BitmapMessageGetLast(this, activeMsgArr[len(activeMsgArr)-1])
+		return data, res2
+	}
+	return data, nil
+}
+
+// BitmapMessageGetLast 获取优惠活动的最新一条消息
+func BitmapMessageGetLast(this *message.UserMsgListReq, msgId int) *message.Messages {
+	if !this.IsMsgList && !this.IsColumnNewMsg && !this.IsColumn {
+		return nil
+	}
+	lastMsg := GlobMsgMap[msgId]
+	if lastMsg == nil && len(lastMsg) <= 0 {
+		mess := entity.Mysql.FindOne("message_send_log", map[string]interface{}{"id": msgId}, "id,msg_type,title,content,send_time,link,menu_name,group_id,sign", "")
+		if mess != nil && len(*mess) > 0 {
+			lastMsg = *mess
+		}
+	}
+	if lastMsg != nil && len(lastMsg) > 0 {
+		if common.IntAll(lastMsg["sign"]) == 4 {
+			//查询用户注册时间
+			rData, _ := entity.MQFW.FindOneByField("user", map[string]interface{}{"_id": m.StringTOBsonId(this.UserId)}, `{"l_registedate":1}`)
+			if rData != nil && len(*rData) > 0 {
+				lastMsg["send_time"] = time.Unix(common.Int64All((*rData)["l_registedate"]), 0).Local().Format("2006-01-02 15:04:05")
+			}
+		}
+		msg := message.Messages{
+			Id:         common.InterfaceToStr(lastMsg["id"]),
+			Createtime: common.InterfaceToStr(lastMsg["send_time"]),
+			Title:      common.InterfaceToStr(lastMsg["title"]),
+			MsgType:    common.Int64All(lastMsg["group_id"]),
+			Link:       common.InterfaceToStr(lastMsg["link"]),
+			Content:    common.InterfaceToStr(lastMsg["content"]),
+			IsRead:     0,
+			MsgLogId:   common.Int64All(lastMsg["id"]),
+		}
+		return &msg
+	}
+	return nil
+}
+
+type UserClassUnread struct {
+	GroupId   int32    `ch:"group_id"`
+	UnreadArr []uint32 `ch:"unreadArr"`
+}
+
+// BitmapCountUnread 未读消息合计 isRedis 是否需要初始化redis
+func BitmapCountUnread(userId string, classUnreadCountMap map[int]int, isRedis bool) (map[string]int64, int64) {
+	var (
+		count              int64
+		msgTypes, groupIds []string
+	)
+	data := make(map[string]int64)
+	for _, v := range entity.MessageColumn {
+		if util.IntAll(v["group_id"]) > 0 && util.IntAll(v["group_id"]) < 999 {
+			//去除全部与私信
+			msgTypes = append(msgTypes, fmt.Sprintf(`"%s"`, common.InterfaceToStr(v["group_id"])))
+			key := fmt.Sprintf(MsgCountKey, userId, util.IntAll(v["group_id"]))
+			groupIds = append(groupIds, common.InterfaceToStr(v["group_id"]))
+			if exists, _ := redis.Exists(redisModule, key); exists {
+				ct := util.Int64All(redis.GetInt(redisModule, key))
+				data[common.InterfaceToStr(v["group_id"])] = ct
+				count += ct
+			}
+		}
+	}
+	//classUnreadCountMap, _ := FindUserClassUnread(userId)
+	if len(msgTypes) > 0 && len(msgTypes) != len(data) {
+		for _, val := range entity.MessageColumn {
+			if util.IntAll(val["group_id"]) > 0 && util.IntAll(val["group_id"]) < 999 {
+				oneClassUnread := classUnreadCountMap[util.IntAll(val["group_id"])]
+				if util.IntAll(val["group_id"]) == 11 {
+					oneClassUnread += classUnreadCountMap[12]
+				}
+				if isRedis {
+					//用户分类未读
+					if oneClassUnread >= 0 {
+						key := fmt.Sprintf(MsgCountKey, userId, util.IntAll(val["group_id"]))
+						redis.Put(redisModule, key, oneClassUnread, 60*60)
+					}
+				}
+				data[common.InterfaceToStr(val["group_id"])] = int64(oneClassUnread)
+				count += int64(oneClassUnread)
+			}
+		}
+	}
+	return data, count //分类未读、未读总量
+}
+
+//BitmapCountClassUnread    userUnreadBitmap 用户未读
+func BitmapCountClassUnread(userId string, groupId int64, classUnreadCountMap map[int]int) (classCount map[string]int64, total int64) {
+	var (
+		count int64
+	)
+	data := make(map[string]int64)
+	if _, ok := entity.ClassSearchMap[groupId]; !ok {
+		return
+	}
+	for i := 0; i < len(entity.ClassSearchMap[groupId]); i++ {
+		msgClass := entity.ClassSearchMap[groupId][i]
+		//fmt.Println("msgClass", msgClass)
+		key := fmt.Sprintf(MsgClassCountKey, userId, msgClass.MsgType)
+		if exists, _ := redis.Exists(redisModule, key); exists {
+			ct := util.Int64All(redis.GetInt(redisModule, key))
+			data[fmt.Sprintf("%d", msgClass.MsgType)] = ct
+			count += ct
+		} else {
+			//分类所有消息
+			classUnreadCount := classUnreadCountMap[util.IntAll(msgClass.MsgType)]
+			if classUnreadCount >= 0 {
+				redis.Put(redisModule, key, classUnreadCount, -1)
+				data[fmt.Sprintf("%d", msgClass.MsgType)] = int64(classUnreadCount)
+				count += int64(classUnreadCount)
+			} else {
+				log.Println("查询classUnreadCount失败,msgType:", msgClass.MsgType)
+			}
+		}
+	}
+
+	return data, count
+}
+
+//FindUserClassUnread 查询用户分类未读消息id
+func FindUserClassUnread(userId string) (map[int]int, map[int][]int) {
+	sql := fmt.Sprintf(`select a2.group_id,bitmapToArray(bitmapAnd(a1.unreadArr,a2.msg_bitmap)) as unreadArr from 
+							(SELECT bitmapAndnot(mus.allMsg,mus.readMsg) unreadArr FROM message_user_summary mus WHERE mus.userId = '%s') a1,
+						(select msg_bitmap,group_id from message_summary ms  where 1=1 limit 10) a2`, userId)
+	fmt.Println("FindUserClassUnread", sql)
+	rows, err := entity.ClickhouseConn.Query(context.Background(), sql)
+	if err != nil {
+		log.Println("获取各分类未读消息数组出错:", err)
+		return nil, nil
+	}
+	classUnreadCountMap := map[int]int{}
+	classUnreadMsgMap := map[int][]int{}
+	for rows.Next() {
+		group := UserClassUnread{}
+		err = rows.ScanStruct(&group)
+		if err != nil {
+			log.Println("获取各分类读取分类数据出错:", err)
+			return nil, nil
+		}
+		classUnreadCountMap[int(group.GroupId)] = len(group.UnreadArr)
+		classUnreadMsgMap[int(group.GroupId)] = Uint32ArrToIntArr(group.UnreadArr)
+	}
+	return classUnreadCountMap, classUnreadMsgMap
+}
+
+//FindUserClassMsg 查询用户分类所有消息id
+func FindUserClassMsg(userId string) (map[int]int, map[int][]int) {
+	sql := fmt.Sprintf(`select a2.group_id,bitmapToArray(bitmapAnd(a1.allMsg,a2.msg_bitmap)) as unreadArr from 
+				(SELECT mus.allMsg as allMsg FROM message_user_summary mus WHERE mus.userId = '%s') a1,
+			(select msg_bitmap,group_id from message_summary ms  where 1=1 limit 10) a2`, userId)
+	fmt.Println("FindUserClassMsg", sql)
+	rows, err := entity.ClickhouseConn.Query(context.Background(), sql)
+	if err != nil {
+		log.Println("获取各分类未读消息数组出错:", err)
+		return nil, nil
+	}
+	classCountMap := map[int]int{}
+	classMsgMap := map[int][]int{}
+	for rows.Next() {
+		group := UserClassUnread{}
+		err = rows.ScanStruct(&group)
+		if err != nil {
+			log.Println("获取各分类读取分类数据出错:", err)
+			return nil, nil
+		}
+		//fmt.Println(int(group.GroupId), len(group.UnreadArr))
+		classCountMap[int(group.GroupId)] = len(group.UnreadArr)
+		classMsgMap[int(group.GroupId)] = Uint32ArrToIntArr(group.UnreadArr)
+	}
+	return classCountMap, classMsgMap
+}
+
+// GetUserMsgSummary 从用户消息汇总表取数据
+func GetUserMsgSummary(userId string) (userAllMsg, userReadMsg, userUnreadMsg []uint32, err error) {
+	var count uint64
+	sqlc := fmt.Sprintf("SELECT COUNT(*) as count from message_user_summary WHERE userId = '%s'", userId)
+	log.Println("GetUserMsgSummary selcet ", sqlc)
+	row1 := entity.ClickhouseConn.QueryRow(context.Background(), sqlc)
+	err = row1.Scan(&count)
+	if count == 0 {
+		err = errors.New("用户暂无数据")
+		return
+	}
+	sql := fmt.Sprintf("SELECT bitmapToArray(allMsg) as userAllMsg,bitmapToArray(readMsg) as userReadMsg,bitmapToArray(bitmapAndnot(allMsg,readMsg)) as userunRead from message_user_summary where userId ='%s'", userId)
+	log.Println("GetUserMsgSummary selcet2 ", sql)
+	row := entity.ClickhouseConn.QueryRow(context.Background(), sql)
+	err = row.Scan(&userAllMsg, &userReadMsg, &userUnreadMsg)
+	if err != nil {
+		log.Println("此用户暂无数据:", err)
+	}
+	return
+}
+
+// Uint32ArrToIntArr []uint32转[]int
+func Uint32ArrToIntArr(arr []uint32) []int {
+	tmp := make([]int, 0)
+	for _, v := range arr {
+		tmp = append(tmp, int(v))
+	}
+	return tmp
+}
+
+func IntArrSort(arr []int) []int {
+	if len(arr) <= 1 {
+		return arr
+	}
+	splitData := arr[0]          //第一个数据为基准
+	low := make([]int, 0, 0)     //比我小的数据
+	height := make([]int, 0, 0)  //比我大的数据
+	mid := make([]int, 0, 0)     //与我一样大的数据
+	mid = append(mid, splitData) //加入一个
+	for i := 1; i < len(arr); i++ {
+		if arr[i] < splitData {
+			low = append(low, arr[i])
+		} else if arr[i] > splitData {
+			height = append(height, arr[i])
+		} else {
+			mid = append(mid, arr[i])
+		}
+	}
+	low, height = IntArrSort(low), IntArrSort(height) //切割递归处理
+	resArr := append(append(low, mid...), height...)
+	return resArr
+}
+
+// PutRedisUserAllMsg 加载用户的所有消息
+/*func PutRedisUserAllMsg(userId string, allMsgBitmap *roaring.Bitmap) (rData []map[string]interface{}) {
+	str := ""
+	for i, v := range allMsgBitmap.ToArray() {
+		if i < len(allMsgBitmap.ToArray())-1 {
+			str += common.InterfaceToStr(v) + ","
+		} else {
+			str += common.InterfaceToStr(v)
+		}
+	}
+	//查询用户所有消息
+	key := fmt.Sprintf(BitmapUserMsg, userId)
+	m := entity.Mysql.SelectBySql("SELECT id,msg_type,title,content,send_time,link,menu_name,group_id FROM message_send_log WHERE send_status = 4 AND isdel = 1 AND id in (?) ORDER BY send_time DESC", str)
+	if m != nil && len(*m) > 0 {
+		rData = *m
+		redis.Put(redisModule, key, rData, -1)
+	}
+	return rData
+}*/

+ 287 - 0
rpc/internal/common/newSendMsgService.go

@@ -0,0 +1,287 @@
+package common
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/entity"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
+	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
+	"app.yhyue.com/moapp/jybase/redis"
+	"context"
+	"errors"
+	"fmt"
+	"github.com/zeromicro/go-zero/core/logx"
+	"log"
+	"strconv"
+	"strings"
+	"sync"
+	"time"
+)
+
+var MsgGroupIdMap map[int]int
+
+func SetMsgSummary(newMsg, groupId, msgType int64) error {
+	//更新所有消息
+	if groupId == 11 {
+		groupId = msgType
+		//根据msgType更新待办二级分类汇总
+		/*err1 := entity.ClickhouseConn.Exec(context.Background(), fmt.Sprintf(`alter table message_summary UPDATE msg_bitmap = bitmapOr(msg_bitmap,bitmapBuild([toUInt64(%d)])) where group_id = %d`, newMsg, msgType))
+		if err1 != nil {
+			//插入失败
+			return err1
+		}*/
+	}
+	err := entity.ClickhouseConn.Exec(context.Background(), fmt.Sprintf(`alter table message_summary UPDATE msg_bitmap = bitmapOr(msg_bitmap,bitmapBuild([toUInt64(%d)])) where group_id = %d`, newMsg, groupId))
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func NewUserSendMsg(in *message.NewUserInsertMsgReq) error {
+	userIdArr := strings.Split(in.UserIds, ",")
+	//positionIdArr := strings.Split(in.PositionIds, ",")
+	if len(userIdArr) == 0 {
+		return errors.New("无效的用户id")
+	}
+	//wg := &sync.WaitGroup{}
+	group_id := MsgGroupIdMap[int(in.MsgType)]
+	for i := 0; i < len(userIdArr); i++ {
+		if userIdArr[i] == "" {
+			continue
+		}
+		//查询
+		/*var positionId int64
+		if len(positionIdArr) == len(userIdArr) {
+			positionId = common.Int64All(positionIdArr[i])
+		}*/
+		row := entity.ClickhouseConn.QueryRow(context.Background(), fmt.Sprintf("SELECT COUNT(*) from message_user_summary where userId = '%s'", userIdArr[i]))
+		var count uint64
+		row.Scan(&count)
+		if count > 0 { //存在则更新
+			err1 := entity.ClickhouseConn.Exec(context.Background(), fmt.Sprintf(`alter table message_user_summary UPDATE allMsg = bitmapOr(allMsg,bitmapBuild([toUInt64(%d)])) where userId = '%s'`, in.MsgLogId, userIdArr[i]))
+			if err1 != nil {
+				log.Println("新用户update message_user_summary表出错,error", err1)
+				return err1
+			}
+		} else {
+			//新用户需要insert
+			sql := "INSERT INTO message_user_summary values "
+			sql += fmt.Sprintf(" ('%s',bitmapBuild([toUInt64(%d)]),bitmapBuild([toUInt64(0)])) ", userIdArr[i], int(in.MsgLogId))
+			log.Println("sql", sql)
+			err1 := entity.ClickhouseConn.Exec(context.Background(), sql)
+			if err1 != nil {
+				//插入失败
+				log.Println("新用户insert message_user_summary表出错,error", err1)
+				return err1
+			}
+		}
+		//微信推送模板消息、app push
+		pushData := WxTmplAndPush{
+			MsgType:     in.MsgType,
+			Title:       in.Title,
+			Content:     in.Content,
+			WxPushUrl:   in.WxPushUrl,
+			AppPushUrl:  in.AppPushUrl,
+			ProductName: in.ProductName,
+			OrderId:     in.OrderId,
+			OrderMoney:  in.OrderMoney,
+			Row4:        in.Row4,
+		}
+		SentWxTmplAndAppPush(pushData, userIdArr[i], group_id, "", "")
+		key := fmt.Sprintf(MsgCountKey, userIdArr[i], group_id)
+		redis.Del(redisModule, key)
+		if in.MsgType == 11 || in.MsgType == 12 {
+			key1 := fmt.Sprintf(MsgClassCountKey, userIdArr[i], in.MsgType)
+			redis.Del(redisModule, key1)
+		}
+	}
+	//wg.Wait()
+	return nil
+}
+
+func UpdateUserMsgSummary(in *message.MultipleSaveMsgReq) error {
+	userIdArr := strings.Split(in.UserIds, ",")
+	//positionIdArr := strings.Split(in.PositionIds, ",")
+	if len(userIdArr) == 0 {
+		return errors.New("无效的用户id")
+	}
+	wg := &sync.WaitGroup{}
+	group_id := MsgGroupIdMap[int(in.MsgType)]
+	var ids []string
+	for _, v := range userIdArr {
+		ids = append(ids, fmt.Sprintf(`'%s'`, v))
+		if len(ids) == 1000 {
+			idStr := strings.Join(ids, ",")
+			go Update(idStr, in.MsgLogId)
+			ids = []string{}
+		}
+	}
+	if len(ids) > 0 {
+		go Update(strings.Join(ids, ","), in.MsgLogId)
+	}
+	//p459 特殊处理 传过来的消息内容格式为 消息内容#jy#微信模板项目名称#jy#服务地址
+	equityName, equityAddr := "", ""
+	if in.MsgType == config.ConfigJson.EquityInfoMsgType {
+		equityRs := strings.Split(in.Content, "#jy#")
+		if len(equityRs) != 3 {
+			log.Println("消息内容格式有误:", in.Content)
+			return errors.New("无效的消息内容格式")
+		}
+		in.Content = equityRs[0]
+		equityName = equityRs[1]
+		equityAddr = equityRs[2]
+	}
+	for i := 0; i < len(userIdArr); i++ {
+		if userIdArr[i] == "" {
+			continue
+		}
+		//查询
+		wg.Add(1)
+		entity.SaveConcurrencyChan <- 1
+		/*var positionId int64
+		if len(positionIdArr) == len(userIdArr) {
+			positionId = common.Int64All(positionIdArr[i])
+		}*/
+		go func(v string) {
+			defer func() {
+				<-entity.SaveConcurrencyChan
+				wg.Done()
+			}()
+			//微信推送模板消息、app push
+			pushData := WxTmplAndPush{
+				MsgType:     in.MsgType,
+				Title:       in.Title,
+				Content:     in.Content,
+				WxPushUrl:   in.WxPushUrl,
+				AppPushUrl:  in.AppPushUrl,
+				ProductName: in.ProductName,
+				OrderId:     in.OrderId,
+				OrderMoney:  in.OrderMoney,
+				Row4:        in.Row4,
+			}
+			SentWxTmplAndAppPush(pushData, v, group_id, equityName, equityAddr)
+			key := fmt.Sprintf(MsgCountKey, v, group_id)
+			redis.Del(redisModule, key)
+			if in.MsgType == 11 || in.MsgType == 12 {
+				key1 := fmt.Sprintf(MsgClassCountKey, v, in.MsgType)
+				redis.Del(redisModule, key1)
+			}
+		}(userIdArr[i])
+	}
+	wg.Wait()
+	return nil
+}
+
+func Update(str string, msgLogId int64) {
+	log.Println(fmt.Sprintf(`alter table message_user_summary UPDATE allMsg = bitmapOr(allMsg,bitmapBuild([toUInt64(%d)])) where userId in (%s)`, msgLogId, str))
+	err1 := entity.ClickhouseConn.Exec(context.Background(), fmt.Sprintf(`alter table message_user_summary UPDATE allMsg = bitmapOr(allMsg,bitmapBuild([toUInt64(%d)])) where userId in (%s)`, msgLogId, str))
+	if err1 != nil {
+		log.Printf("批量更新message_user_summary出错:%s", err1)
+		return
+	}
+}
+
+//附件下载、剑鱼币活动到期提醒存消息发送记录
+func InsertMsgSendLog(in *message.MultipleSaveMsgReq) int64 {
+	groupId := MsgGroupIdMap[int(in.MsgType)]
+	id := entity.Mysql.Insert("message_send_log", map[string]interface{}{
+		"send_usergroup_id":   "",
+		"send_usergroup_name": "",
+		"msg_type":            in.MsgType,
+		"title":               in.Title,
+		"content":             in.Content,
+		"send_mode":           2,
+		"send_time":           time.Now().Format("2006-01-02 15:04:05"),
+		"send_status":         4,
+		"update_time":         time.Now().Format("2006-01-02 15:04:05"),
+		"link":                in.Link,
+		"isdel":               1,
+		"send_userid":         "",
+		"update_user":         "",
+		"Sign":                5,
+		"menu_name":           "message",
+		"group_id":            groupId,
+	})
+	if id > 0 {
+		//更新消息汇总表
+		err := SetMsgSummary(id, int64(groupId), in.MsgType)
+		if err != nil {
+			log.Println("更新消息汇总表出错:", err)
+			return 0
+		}
+		return id
+	}
+	return 0
+}
+
+func ConvertToBitmap(num int) (res []uint32) {
+	binary := strconv.FormatInt(int64(num), 2)
+	total := len(binary)
+	for i := total - 1; i >= 0; i-- {
+		if binary[i] == '1' {
+			res = append(res, uint32(total-i))
+		}
+	}
+	return
+}
+
+type WxTmplAndPush struct {
+	MsgType     int64
+	Title       string
+	Content     string
+	WxPushUrl   string
+	AppPushUrl  string
+	ProductName string
+	OrderId     string
+	OrderMoney  string
+	Row4        string
+	SendUserId  string
+}
+
+func SentWxTmplAndAppPush(this WxTmplAndPush, v string, group_id int, equityName, equityAddr string) {
+	nTime := time.Now().Format("2006-01-02 15:04:05")
+	//发送消息成功,推送微信、app
+	//fmt.Println("this.MsgType", this.MsgType)
+	pushConfig, err := GetWxTmplConfig(this.MsgType)
+	if err != nil {
+		logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
+	}
+	p := &WxTmplPush{
+		Config: pushConfig,
+	}
+	p.MgoId = v
+	if this.MsgType == 10 {
+		this.Title = this.ProductName
+		this.Content = this.OrderId
+		nTime = this.OrderMoney
+	}
+	// 消息模版 工单类型 {{thing19.DATA}} 工单标题 {{thing6.DATA}} 项目名称 {{thing13.DATA}} 服务时间 {{time25.DATA}} 服务地址 {{thing26.DATA}}
+	if this.MsgType != 1 && this.MsgType != 10 {
+		if this.MsgType == config.ConfigJson.EquityInfoMsgType {
+			// p459 服务地址特殊处理
+			err = p.SendMsg(this.WxPushUrl, this.Title, equityName, nTime, this.Row4, equityAddr)
+		} else {
+			err = p.SendMsg(this.WxPushUrl, this.Title, this.Content, nTime, this.Row4, "")
+		}
+		if err != nil {
+			logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
+		} else {
+			logx.Infof("SendWxTmplMsg uId success %s ", v)
+		}
+	}
+	if this.MsgType == 1 {
+		mst := new(WxTmplConfig)
+		mst.Switch = AppPushMsgType[group_id]
+		p.Config = mst
+	}
+	uData := p.GetUserPushInfo()
+	//app推送
+	if this.MsgType != 10 {
+		category := ""
+		if this.SendUserId == "cbgl" {
+			category = "服务通知_工作事项"
+		}
+		if err = AppPushMsg(uData, AppPushMsgType[group_id], this.AppPushUrl, this.Title, this.Content, this.MsgType, category); err != nil {
+			logx.Error(fmt.Sprintf("SendAppMsg uId %s  Error %s", v, err.Error()))
+		}
+	}
+}

+ 130 - 187
rpc/internal/common/sendMsg.go

@@ -1,12 +1,9 @@
 package common
 
 import (
-	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
 	"fmt"
 	"log"
 	"strconv"
-	"strings"
-	"sync"
 	"time"
 
 	"app.yhyue.com/moapp/MessageCenter/entity"
@@ -14,7 +11,6 @@ import (
 	"app.yhyue.com/moapp/MessageCenter/util"
 	"app.yhyue.com/moapp/jybase/common"
 	"app.yhyue.com/moapp/jybase/redis"
-	"github.com/zeromicro/go-zero/core/logx"
 )
 
 // 类型的顺序
@@ -131,7 +127,7 @@ func UserMsgList(this *message.UserMsgListReq) *message.UserMsgList {
 	//获取栏目下的数据
 	sData := make(map[string][]*message.Messages)
 	t := time.Now()
-	if this.IsColumnNewMsg && this.SortSize > 0 {
+	if this.IsColumnNewMsg && this.SortSize > 0 { //this.SortSize app分类展示最新一条消息
 		var sortData *[]map[string]interface{}
 		if this.IsClassSearch { // p436 增加
 			sortDataQ := fmt.Sprintf(`SELECT title,createtime,msg_type as group_id ,id FROM (
@@ -286,59 +282,6 @@ func unreadMsg(this *message.UserMsgListReq) int64 {
 	}
 	return 0
 }
-func UserUnreadMsgList(this *message.UserUnreadMsgListReq) (int64, []*message.Messages) {
-	count := 0
-	data := []*message.Messages{}
-	types := entity.Mysql.Find("message_group", map[string]interface{}{}, `"group_id"`, "", -1, -1)
-	if types != nil && len(*types) > 0 {
-		for _, v := range *types {
-			key := fmt.Sprintf(MsgCountKey, this.UserId, util.IntAll(v["group_id"]))
-			if exists, _ := redis.Exists(redisModule, key); exists {
-				count += redis.GetInt(redisModule, key)
-			}
-		}
-	}
-	if this.IsNeedData == 1 && count > 0 {
-		query := map[string]interface{}{
-			"receive_userid": this.UserId,
-			"isdel":          1,
-			"appid":          this.Appid,
-			"isRead":         0,
-		}
-		res := entity.Mysql.Find("message", query, "", "createtime desc", (int(this.OffSet)-1)*int(this.PageSize), int(this.PageSize))
-		if res != nil && len(*res) > 0 {
-			for _, val := range *res {
-				_id := util.Int64All(val["id"])
-				id := strconv.FormatInt(_id, 10)
-				links4 := common.InterfaceToStr(val["link"])
-				link4, androidUrl4, iosUrl4, weChatUrl4 := util.LinkSplit(links4)
-				url := map[string]string{
-					"androidUrl": androidUrl4,
-					"iosUrl":     iosUrl4,
-					"weChatUrl":  weChatUrl4,
-				}
-				data = append(data, &message.Messages{
-					Id:            id,
-					Appid:         common.InterfaceToStr(val["appid"]),
-					ReceiveUserId: common.InterfaceToStr(val["receive_userid"]),
-					ReceiveName:   common.InterfaceToStr(val["receive_name"]),
-					SendUserId:    common.InterfaceToStr(val["send_userid"]),
-					SendName:      common.InterfaceToStr(val["send_name"]),
-					Createtime:    common.InterfaceToStr(val["createtime"]),
-					Title:         common.InterfaceToStr(val["title"]),
-					MsgType:       common.Int64All(val["group_id"]),
-					Link:          link4,
-					CiteId:        common.Int64All(val["cite_id"]),
-					Content:       common.InterfaceToStr(val["content"]),
-					IsRead:        common.Int64All(val["isRead"]),
-					MsgLogId:      common.Int64All(val["msg_log_id"]),
-					Url:           url,
-				})
-			}
-		}
-	}
-	return util.Int64All(count), data
-}
 
 func MessageGetLast(this *message.UserMsgListReq) *message.Messages {
 	if !this.IsMsgList && !this.IsColumnNewMsg && !this.IsColumn {
@@ -446,132 +389,132 @@ func MsgCountZero(userId, appId string, msgType int64) bool {
 	return true
 }
 
-func MultSave(this message.MultipleSaveMsgReq) (int64, string) {
-	userIdArr := strings.Split(this.UserIds, ",")
-	userNameArr := strings.Split(this.UserNames, ",")
-	positionIdArr := strings.Split(this.PositionIds, ",")
-	if len(userIdArr) == 0 {
-		return 0, "无效的用户id"
-	}
-	wg := &sync.WaitGroup{}
-	var group_id int
-	class := entity.Mysql.FindOne("message_class", map[string]interface{}{"msg_type": this.MsgType}, "group_id", "")
-	if class != nil && len(*class) > 0 {
-		group_id = util.IntAll((*class)["group_id"])
-	}
-	//p459 特殊处理 传过来的消息内容格式为 消息内容#jy#微信模板项目名称#jy#服务地址
-	equityName, equityAddr := "", ""
-	if this.MsgType == config.ConfigJson.EquityInfoMsgType {
-		equityRs := strings.Split(this.Content, "#jy#")
-		if len(equityRs) != 3 {
-			log.Println("消息内容格式有误:", this.Content)
-			return 0, "无效的消息内容格式"
-		}
-		this.Content = equityRs[0]
-		equityName = equityRs[1]
-		equityAddr = equityRs[2]
-	}
-	for i := 0; i < len(userIdArr); i++ {
-		if userIdArr[i] == "" {
-			continue
-		}
-		name := userNameArr[i]
-		wg.Add(1)
-		entity.SaveConcurrencyChan <- 1
-		var positionId int64
-		if len(positionIdArr) == len(userIdArr) {
-			positionId = common.Int64All(positionIdArr[i])
-		}
-
-		go func(v, userName string, positionId int64) {
-			defer func() {
-				<-entity.SaveConcurrencyChan
-				wg.Done()
-			}()
-			//消息数组
-			nTime := time.Now().Format("2006-01-02 15:04:05")
-			//c := entity.Mysql.Count("conversation", map[string]interface{}{"receive_id": v, "send_id": this.SendUserId})
-			sql3 := `INSERT INTO message(appid,receive_userid,receive_name,send_userid,send_name,title,content,msg_type,link,cite_id,createtime,isRead,isdel,msg_log_id,show_buoy,show_content,group_id,position_id) values ("%s",'%s','%s','%s','%s','%s','%s',%d,'%s',0,'%s',0,1,%d,%d,'%s',%d,?);`
-			sql3 = fmt.Sprintf(sql3, this.Appid, v, userName, this.SendUserId, this.SendName, this.Title, this.Content, this.MsgType, this.Link, nTime, this.MsgLogId, this.ShowBuoy, this.ShowContent, group_id)
-			var in int64
-			/*if c <= 0 {
-				sql1 := `INSERT INTO conversation(appid,secret_key,user_id,receive_id,receive_name,send_id,send_name,sort,createtime) values ('%s','','%s','%s','%s','%s','%s',0,'%s');`
-				sql1 = fmt.Sprintf(sql1, this.Appid, this.SendUserId, v, userName, this.SendUserId, this.SendName, nTime)
-
-				//插入会话表
-				in1 := entity.Mysql.InsertBySql(sql1)
-				sql2 := `INSERT INTO conversation(appid,secret_key,user_id,receive_id,receive_name,send_id,send_name,sort,createtime) values ('%s','','%s','%s','%s','%s','%s',0,'%s');`
-				sql2 = fmt.Sprintf(sql2, this.Appid, v, this.SendUserId, this.SendName, v, userName, nTime)
-				in2 := entity.Mysql.InsertBySql(sql2)
-				//插入消息表
-				in = entity.Mysql.InsertBySql(sql3, common.If(positionId != 0, positionId, nil))
-				logx.Info(in1, in2, in)
-
-				if in1 > -1 && in2 > -1 && in > -1 {
-					ok1 := MsgCountAdd(v, this.Appid, this.MsgType)
-					if !ok1 {
-						log.Println("存redis:", ok1, v)
-					}
-				}
-			} else {*/
-			in = entity.Mysql.InsertBySql(sql3, common.If(positionId != 0, positionId, nil))
-			logx.Info("插入消息返回 in1 id:", in, "消息类型:", this.MsgType, "用户id:", v)
-			if in > -1 {
-				ok := MsgCountAdd(v, this.Appid, util.Int64All(group_id), this.MsgType)
-				if !ok {
-					log.Println("存redis:", ok, v)
-				}
-			}
-			//}
-			if in > -1 {
-				//发送消息成功,推送微信、app
-				pushConfig, err := GetWxTmplConfig(this.MsgType)
-				if err != nil {
-					logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
-				}
-				p := &WxTmplPush{
-					Config:      pushConfig,
-					CustomWxTpl: this.CustomWxTpl,
-				}
-				p.MgoId = v
-				if this.MsgType == 10 {
-					this.Title = this.ProductName
-					this.Content = this.OrderId
-					nTime = this.OrderMoney
-				}
-				// 消息模版 工单类型 {{thing19.DATA}} 工单标题 {{thing6.DATA}} 项目名称 {{thing13.DATA}} 服务时间 {{time25.DATA}} 服务地址 {{thing26.DATA}}
-				if this.MsgType != 1 && this.MsgType != 10 {
-					if this.MsgType == config.ConfigJson.EquityInfoMsgType {
-						// p459 服务地址特殊处理
-						err = p.SendMsg(this.WxPushUrl, this.Title, equityName, nTime, this.Row4, equityAddr)
-					} else {
-						err = p.SendMsg(this.WxPushUrl, this.Title, this.Content, nTime, this.Row4, "")
-					}
-					if err != nil {
-						logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
-					} else {
-						logx.Infof("SendWxTmplMsg uId success %s ", v)
-					}
-				}
-				if this.MsgType == 1 {
-					mst := new(WxTmplConfig)
-					mst.Switch = AppPushMsgType[group_id]
-					p.Config = mst
-				}
-				//app推送
-				if this.MsgType != 10 {
-					uData := p.GetUserPushInfo()
-					category := ""
-					if this.SendUserId == "cbgl" {
-						category = "服务通知_工作事项"
-					}
-					if err = AppPushMsg(uData, AppPushMsgType[group_id], this.AppPushUrl, this.Title, this.Content, this.MsgType, category); err != nil {
-						logx.Error(fmt.Sprintf("SendAppMsg uId %s  Error %s", v, err.Error()))
-					}
-				}
-			}
-		}(userIdArr[i], name, positionId)
-	}
-	wg.Wait()
-	return 0, ""
-}
+//func MultSave(this message.MultipleSaveMsgReq) (int64, string) {
+//	userIdArr := strings.Split(this.UserIds, ",")
+//	userNameArr := strings.Split(this.UserNames, ",")
+//	positionIdArr := strings.Split(this.PositionIds, ",")
+//	if len(userIdArr) == 0 {
+//		return 0, "无效的用户id"
+//	}
+//	wg := &sync.WaitGroup{}
+//	var group_id int
+//	class := entity.Mysql.FindOne("message_class", map[string]interface{}{"msg_type": this.MsgType}, "group_id", "")
+//	if class != nil && len(*class) > 0 {
+//		group_id = util.IntAll((*class)["group_id"])
+//	}
+//	//p459 特殊处理 传过来的消息内容格式为 消息内容#jy#微信模板项目名称#jy#服务地址
+//	equityName, equityAddr := "", ""
+//	if this.MsgType == config.ConfigJson.EquityInfoMsgType {
+//		equityRs := strings.Split(this.Content, "#jy#")
+//		if len(equityRs) != 3 {
+//			log.Println("消息内容格式有误:", this.Content)
+//			return 0, "无效的消息内容格式"
+//		}
+//		this.Content = equityRs[0]
+//		equityName = equityRs[1]
+//		equityAddr = equityRs[2]
+//	}
+//	for i := 0; i < len(userIdArr); i++ {
+//		if userIdArr[i] == "" {
+//			continue
+//		}
+//		name := userNameArr[i]
+//		wg.Add(1)
+//		entity.SaveConcurrencyChan <- 1
+//		var positionId int64
+//		if len(positionIdArr) == len(userIdArr) {
+//			positionId = common.Int64All(positionIdArr[i])
+//		}
+//
+//		go func(v, userName string, positionId int64) {
+//			defer func() {
+//				<-entity.SaveConcurrencyChan
+//				wg.Done()
+//			}()
+//			//消息数组
+//			nTime := time.Now().Format("2006-01-02 15:04:05")
+//			//c := entity.Mysql.Count("conversation", map[string]interface{}{"receive_id": v, "send_id": this.SendUserId})
+//			sql3 := `INSERT INTO message(appid,receive_userid,receive_name,send_userid,send_name,title,content,msg_type,link,cite_id,createtime,isRead,isdel,msg_log_id,show_buoy,show_content,group_id,position_id) values ("%s",'%s','%s','%s','%s','%s','%s',%d,'%s',0,'%s',0,1,%d,%d,'%s',%d,?);`
+//			sql3 = fmt.Sprintf(sql3, this.Appid, v, userName, this.SendUserId, this.SendName, this.Title, this.Content, this.MsgType, this.Link, nTime, this.MsgLogId, this.ShowBuoy, this.ShowContent, group_id)
+//			var in int64
+//			/*if c <= 0 {
+//				sql1 := `INSERT INTO conversation(appid,secret_key,user_id,receive_id,receive_name,send_id,send_name,sort,createtime) values ('%s','','%s','%s','%s','%s','%s',0,'%s');`
+//				sql1 = fmt.Sprintf(sql1, this.Appid, this.SendUserId, v, userName, this.SendUserId, this.SendName, nTime)
+//
+//				//插入会话表
+//				in1 := entity.Mysql.InsertBySql(sql1)
+//				sql2 := `INSERT INTO conversation(appid,secret_key,user_id,receive_id,receive_name,send_id,send_name,sort,createtime) values ('%s','','%s','%s','%s','%s','%s',0,'%s');`
+//				sql2 = fmt.Sprintf(sql2, this.Appid, v, this.SendUserId, this.SendName, v, userName, nTime)
+//				in2 := entity.Mysql.InsertBySql(sql2)
+//				//插入消息表
+//				in = entity.Mysql.InsertBySql(sql3, common.If(positionId != 0, positionId, nil))
+//				logx.Info(in1, in2, in)
+//
+//				if in1 > -1 && in2 > -1 && in > -1 {
+//					ok1 := MsgCountAdd(v, this.Appid, this.MsgType)
+//					if !ok1 {
+//						log.Println("存redis:", ok1, v)
+//					}
+//				}
+//			} else {*/
+//			in = entity.Mysql.InsertBySql(sql3, common.If(positionId != 0, positionId, nil))
+//			logx.Info("插入消息返回 in1 id:", in, "消息类型:", this.MsgType, "用户id:", v)
+//			if in > -1 {
+//				ok := MsgCountAdd(v, this.Appid, util.Int64All(group_id), this.MsgType)
+//				if !ok {
+//					log.Println("存redis:", ok, v)
+//				}
+//			}
+//			//}
+//			if in > -1 {
+//				//发送消息成功,推送微信、app
+//				pushConfig, err := GetWxTmplConfig(this.MsgType)
+//				if err != nil {
+//					logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
+//				}
+//				p := &WxTmplPush{
+//					Config:      pushConfig,
+//					CustomWxTpl: this.CustomWxTpl,
+//				}
+//				p.MgoId = v
+//				if this.MsgType == 10 {
+//					this.Title = this.ProductName
+//					this.Content = this.OrderId
+//					nTime = this.OrderMoney
+//				}
+//				// 消息模版 工单类型 {{thing19.DATA}} 工单标题 {{thing6.DATA}} 项目名称 {{thing13.DATA}} 服务时间 {{time25.DATA}} 服务地址 {{thing26.DATA}}
+//				if this.MsgType != 1 && this.MsgType != 10 {
+//					if this.MsgType == config.ConfigJson.EquityInfoMsgType {
+//						// p459 服务地址特殊处理
+//						err = p.SendMsg(this.WxPushUrl, this.Title, equityName, nTime, this.Row4, equityAddr)
+//					} else {
+//						err = p.SendMsg(this.WxPushUrl, this.Title, this.Content, nTime, this.Row4, "")
+//					}
+//					if err != nil {
+//						logx.Error(fmt.Sprintf("SendWxTmplMsg uId %s  Error %s", v, err.Error()))
+//					} else {
+//						logx.Infof("SendWxTmplMsg uId success %s ", v)
+//					}
+//				}
+//				if this.MsgType == 1 {
+//					mst := new(WxTmplConfig)
+//					mst.Switch = AppPushMsgType[group_id]
+//					p.Config = mst
+//				}
+//				//app推送
+//				if this.MsgType != 10 {
+//					uData := p.GetUserPushInfo()
+//					category := ""
+//					if this.SendUserId == "cbgl" {
+//						category = "服务通知_工作事项"
+//					}
+//					if err = AppPushMsg(uData, AppPushMsgType[group_id], this.AppPushUrl, this.Title, this.Content, this.MsgType, category); err != nil {
+//						logx.Error(fmt.Sprintf("SendAppMsg uId %s  Error %s", v, err.Error()))
+//					}
+//				}
+//			}
+//		}(userIdArr[i], name, positionId)
+//	}
+//	wg.Wait()
+//	return 0, ""
+//}

+ 52 - 11
rpc/internal/common/sendWxTmplMsg.go

@@ -1,6 +1,7 @@
 package common
 
 import (
+	"context"
 	"encoding/json"
 	"fmt"
 	"log"
@@ -41,22 +42,46 @@ const CacheDb = "msgCount"
 
 func MessageType() (func() map[int64]WxTmplConfig, []map[string]interface{}) {
 	var data []map[string]interface{}
-	rData1 := entity.Mysql.SelectBySql(`SELECT * FROM message_group ORDER BY sequence ASC`)
+	rData1, err := entity.ClickhouseConn.Query(context.Background(), `SELECT group_id,name,switch,img,sequence FROM message_group ORDER BY sequence ASC`)
+	if err != nil {
+		log.Println("MessageType SELECT message_group出错:", err)
+		return nil, nil
+	}
 	switchName := map[int64]WxTmplConfig{}
 	appMsgType := map[int]string{}
-	if rData1 != nil && len(*rData1) > 0 {
-		data = *rData1
-		for _, v := range *rData1 {
-			groupId := util.IntAll(v["group_id"])
-			switchs := util.ObjToString(v["switch"])
-			appMsgType[groupId] = switchs
+	for rData1.Next() {
+		group := entity.MsgGroup{}
+		err = rData1.ScanStruct(&group)
+		if err != nil {
+			log.Println("MessageType 初始化rData1 ScanStruct出错:", err)
+			return nil, nil
 		}
-		AppPushMsgType = appMsgType
+		groupId := util.IntAll(group.GroupId)
+		switchs := util.ObjToString(group.Switch)
+		appMsgType[groupId] = switchs
+		data = append(data, map[string]interface{}{
+			"group_id": groupId,
+			"name":     group.Name,
+			"switch":   group.Switch,
+			"img":      group.Img,
+			"sequence": group.Sequence,
+		})
 	}
+	AppPushMsgType = appMsgType
 
-	rData2 := entity.Mysql.SelectBySql(`SELECT g.switch,c.wxtmpl_Id,c.msg_type,c.msg_name,c.wxtmp_value FROM message_class c INNER JOIN message_group g on c.group_id =g.group_id WHERE c.wxtmpl_Id IS NOT NULL`)
-	for _, mData := range *rData2 {
-		if msg_type, settingKey, messageName, tmplId, tmplValue := util.Int64All(mData["msg_type"]), util.ObjToString(mData["switch"]), util.ObjToString(mData["msg_name"]), util.ObjToString(mData["wxtmpl_Id"]), util.ObjToString(mData["wxtmp_value"]); msg_type > 0 && settingKey != "" && messageName != "" && tmplId != "" && tmplValue != "" {
+	rData2, err := entity.ClickhouseConn.Query(context.Background(), `SELECT g.switch,c.wxtmpl_Id,c.msg_type,c.msg_name,c.wxtmp_value FROM message_class c INNER JOIN message_group g on c.group_id =g.group_id WHERE c.wxtmpl_Id IS NOT NULL`)
+	if err != nil {
+		log.Println("MessageType SELECT message_group,message_class出错:", err)
+		return nil, nil
+	}
+	for rData2.Next() {
+		gc := entity.GroupClass{}
+		err = rData2.ScanStruct(&gc)
+		if err != nil {
+			log.Println("MessageType 初始化rData2 ScanStruct出错:", err)
+			return nil, nil
+		}
+		if msg_type, settingKey, messageName, tmplId, tmplValue := util.Int64All(gc.Msg_type), util.ObjToString(gc.Switch), util.ObjToString(gc.Msg_name), util.ObjToString(gc.Wxtmpl_Id), util.ObjToString(gc.Wxtmp_value); msg_type > 0 && settingKey != "" && messageName != "" && tmplId != "" && tmplValue != "" {
 			switchName[msg_type] = WxTmplConfig{
 				Name:      messageName,
 				Switch:    settingKey,
@@ -65,6 +90,22 @@ func MessageType() (func() map[int64]WxTmplConfig, []map[string]interface{}) {
 			}
 		}
 	}
+	rData3, err := entity.ClickhouseConn.Query(context.Background(), "SELECT msg_type,group_id FROM message_class WHERE msg_type < 999")
+	if err != nil {
+		log.Println("MessageType SELECT message_class出错:", err)
+		return nil, nil
+	}
+	mg := map[int]int{}
+	for rData3.Next() {
+		group := entity.MsgGroup{}
+		err = rData3.ScanStruct(&group)
+		if err != nil {
+			log.Println("MessageType 初始化rData1 ScanStruct出错:", err)
+			return nil, nil
+		}
+		mg[common.IntAll(group.Msg_type)] = common.IntAll(group.GroupId)
+	}
+	MsgGroupIdMap = mg
 
 	return func() map[int64]WxTmplConfig {
 		return switchName

+ 33 - 0
rpc/internal/common/task.go

@@ -0,0 +1,33 @@
+package common
+
+import (
+	"app.yhyue.com/moapp/MessageCenter/entity"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
+	"app.yhyue.com/moapp/jybase/common"
+	"fmt"
+	"github.com/robfig/cron/v3"
+)
+
+var GlobMsgMap map[int]map[string]interface{}
+
+func LoadTask() {
+	// 每隔10分钟执行一次
+	LoadMsgOnTime()
+	c := cron.New(cron.WithSeconds())
+	c.AddFunc(config.ConfigJson.GlobMsgLoadTime, LoadMsgOnTime)
+	go c.Start()
+	defer c.Stop()
+}
+
+func LoadMsgOnTime() {
+	fmt.Println("开始执行")
+	msgMap := make(map[int]map[string]interface{})
+	m := entity.Mysql.SelectBySql("SELECT id,msg_type,title,content,send_time,menu_name,link,group_id,sign FROM message_send_log WHERE send_status = 4 AND isdel = 1 ORDER BY send_time DESC limit 2000")
+	if m != nil && len(*m) > 0 {
+		for _, val := range *m {
+			msgMap[common.IntAll(val["id"])] = val
+		}
+		GlobMsgMap = msgMap
+	}
+	fmt.Println("GlobMsgMap len", len(GlobMsgMap))
+}

+ 21 - 4
rpc/internal/config/config.go

@@ -6,10 +6,10 @@ import (
 
 type Config struct {
 	zrpc.RpcServerConf
-	DataSource      *mysqlConfig // 手动代码
-	BaseSource      *mysqlConfig // 手动代码
-	WebRpcPort      int
-	Mysql           string
+	DataSource *mysqlConfig // 手动代码
+	BaseSource *mysqlConfig // 手动代码
+	WebRpcPort int
+	//Mysql           string
 	RedisAddr       string `json:"RedisAddr"`
 	Mongodb         *mgoConf
 	SurvivalTime    int
@@ -24,9 +24,26 @@ type Config struct {
 		User string `json:"user"`
 	} `json:"mail"`
 	TidbEng           string  `json:"Tidb"`
+<<<<<<< HEAD
 	ClassSearchList   []int64 `json:"ClassSearchList"`   // 需要按照messageclass 查询的groupId
 	EquityInfoMsgType int64   `json:"EquityInfoMsgType"` // 营销权益消息需要特殊处理的消息类型
 	Registedate       int64
+=======
+	ClassSearchList   []int64 `json:"ClassSearchList"` // 需要按照messageclass 查询的groupId
+	Clickhouse        *CHouseConfig
+	GlobMsgLoadTime   string `json:"GlobMsgLoadTime"`
+	EquityInfoMsgType int64  `json:"EquityInfoMsgType"` // 营销权益消息需要特殊处理的消息类型
+	NewUserMsgTitle   string `json:"NewUserMsgTitle"`
+}
+
+type CHouseConfig struct {
+	Addr         string
+	UserName     string
+	Password     string
+	DbName       string
+	MaxIdleConns int
+	MaxOpenConns int
+>>>>>>> master
 }
 
 type mysqlConfig struct {

+ 42 - 0
rpc/internal/logic/bitmapsavemsglogic.go

@@ -0,0 +1,42 @@
+package logic
+
+import (
+	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"context"
+
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type BitmapSaveMsgLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewBitmapSaveMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BitmapSaveMsgLogic {
+	return &BitmapSaveMsgLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+// BitmapSaveMsg bitmap发送消息
+func (l *BitmapSaveMsgLogic) BitmapSaveMsg(in *messageclient.MultipleSaveMsgReq) (*messageclient.MultipleSaveMsgResp, error) {
+	var (
+		code = 1
+		msg  = "发送成功"
+	)
+
+	err := service.UpdateUserMsgSummary(in)
+	if err != nil {
+		code = 0
+		msg = err.Error()
+	}
+	return &messageclient.MultipleSaveMsgResp{
+		Code:    int64(code),
+		Message: msg,
+	}, nil
+}

+ 10 - 3
rpc/internal/logic/changereadstatuslogic.go

@@ -27,11 +27,18 @@ func NewChangeReadStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
 
 // 修改消息阅读状态
 func (l *ChangeReadStatusLogic) ChangeReadStatus(in *messageclient.ChangeReadStatusReq) (*message.Response, error) {
-	// todo: add your logic here and delete this line
+	var (
+		code = 1
+		msg  = ""
+	)
 	m := &service.MessageService{}
-	code, msg := m.ChangeReadStatus(in)
+	err := m.ChangeReadStatus(in)
+	if err != nil {
+		code = 0
+		msg = err.Error()
+	}
 	return &messageclient.Response{
-		Code:    code,
+		Code:    int64(code),
 		Message: msg,
 	}, nil
 }

+ 6 - 14
rpc/internal/logic/findmessagedetaillogic.go

@@ -7,7 +7,6 @@ import (
 	qutil "app.yhyue.com/moapp/jybase/common"
 	"context"
 	"github.com/zeromicro/go-zero/core/logx"
-	"log"
 )
 
 type FindMessageDetailLogic struct {
@@ -34,23 +33,16 @@ func (l *FindMessageDetailLogic) FindMessageDetail(in *messageclient.MessageDeta
 	}
 	if msg != nil {
 		detail := &messageclient.Messages{
-			ReceiveUserId: qutil.ObjToString((*msg)["receive_userid"]),
-			ReceiveName:   qutil.ObjToString((*msg)["receive_name"]),
-			SendName:      qutil.ObjToString((*msg)["send_name"]),
-			SendUserId:    qutil.ObjToString((*msg)["send_userid"]),
-			Title:         qutil.ObjToString((*msg)["title"]),
-			Content:       qutil.ObjToString((*msg)["content"]),
-			MsgType:       qutil.Int64All((*msg)["group_id"]),
-			Link:          qutil.ObjToString((*msg)["link"]),
-			CiteId:        qutil.Int64All((*msg)["cite_id"]),
-			IsRead:        qutil.Int64All((*msg)["isRead"]),
-			Createtime:    qutil.ObjToString((*msg)["createtime"]),
-			MsgLogId:      qutil.Int64All((*msg)["msg_log_id"]),
+			Title:      qutil.ObjToString((*msg)["title"]),
+			Content:    qutil.ObjToString((*msg)["content"]),
+			MsgType:    qutil.Int64All((*msg)["group_id"]),
+			Link:       qutil.ObjToString((*msg)["link"]),
+			Createtime: qutil.ObjToString((*msg)["send_time"]),
+			MsgLogId:   qutil.Int64All((*msg)["id"]),
 		}
 		result.Code = 0
 		result.Message = "请求成功"
 		result.Data = detail
 	}
-	log.Println(result.Data)
 	return result, nil
 }

+ 0 - 39
rpc/internal/logic/getmsgtypelogic.go

@@ -1,39 +0,0 @@
-package logic
-
-import (
-	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
-	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
-	"context"
-
-	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type GetMsgTypeLogic struct {
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-	logx.Logger
-}
-
-func NewGetMsgTypeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMsgTypeLogic {
-	return &GetMsgTypeLogic{
-		ctx:    ctx,
-		svcCtx: svcCtx,
-		Logger: logx.WithContext(ctx),
-	}
-}
-
-// 获取指定用户收到消息的分类
-func (l *GetMsgTypeLogic) GetMsgType(in *messageclient.GetMsgTypeReq) (*messageclient.GetMsgTypeRes, error) {
-	m := service.MessageService{}
-	data, err := m.GetMsgType()
-	if err != nil {
-		return nil, err
-	}
-	return &messageclient.GetMsgTypeRes{
-		Code:    int64(0),
-		Message: "请求成功",
-		Data:    data,
-	}, nil
-
-}

+ 9 - 4
rpc/internal/logic/msgopenloglogic.go

@@ -27,10 +27,15 @@ func NewMsgOpenLogLogic(ctx context.Context, svcCtx *svc.ServiceContext) *MsgOpe
 //  点击消息-存查看记录
 func (l *MsgOpenLogLogic) MsgOpenLog(in *message.MsgOpenLogReq) (*message.Response, error) {
 	m := service.MessageService{}
-	ok := m.MsgOpenLog(in.Platform, in.MsgLogId, in.UserId)
-
+	err := m.MsgOpenLog(in.Platform, in.MsgLogId, in.UserId)
+	code := 0
+	msg := "保存成功"
+	if err != nil {
+		code = 1
+		msg = err.Error()
+	}
 	return &message.Response{
-		Code:    ok,
-		Message: "存入查看记录成功",
+		Code:    int64(code),
+		Message: msg,
 	}, nil
 }

+ 43 - 7
rpc/internal/logic/multiplesavemsglogic.go

@@ -2,10 +2,11 @@ package logic
 
 import (
 	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/config"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
 	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
 	"context"
-
-	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
 	"github.com/zeromicro/go-zero/core/logx"
 )
 
@@ -25,11 +26,46 @@ func NewMultipleSaveMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *M
 
 // 批量保存消息
 func (l *MultipleSaveMsgLogic) MultipleSaveMsg(in *messageclient.MultipleSaveMsgReq) (*messageclient.MultipleSaveMsgResp, error) {
-	// todo: add your logic here and delete this line
-	errCount, msg := service.MultSave(*in)
+	var (
+		code = 1
+		msg  = "发送成功"
+	)
+	msgLogId := service.InsertMsgSendLog(in)
+	if msgLogId > 0 {
+		var err error
+		in.MsgLogId = msgLogId
+		if in.Title == config.ConfigJson.NewUserMsgTitle {
+			err = service.NewUserSendMsg(&message.NewUserInsertMsgReq{
+				UserIds:     in.UserIds,
+				Title:       in.Title,
+				Content:     in.Content,
+				MsgType:     in.MsgType,
+				Link:        in.Link,
+				Appid:       in.Appid,
+				MsgLogId:    in.MsgLogId,
+				PositionIds: in.PositionIds,
+				Row4:        in.Row4,
+				ProductName: in.ProductName,
+				OrderId:     in.OrderId,
+				OrderMoney:  in.OrderMoney,
+				Identity:    in.Identity,
+				AppPushUrl:  in.AppPushUrl,
+				WxPushUrl:   in.WxPushUrl,
+				IosPushUrl:  in.IosPushUrl,
+			})
+		} else {
+			err = service.UpdateUserMsgSummary(in)
+		}
+		if err != nil {
+			code = 0
+			msg = err.Error()
+		}
+	} else {
+		code = 0
+		msg = "插入message_send_log表出错"
+	}
 	return &messageclient.MultipleSaveMsgResp{
-		Code:     1,
-		Message:  msg,
-		ErrCount: errCount,
+		Code:    int64(code),
+		Message: msg,
 	}, nil
 }

+ 38 - 0
rpc/internal/logic/newusermsglogic.go

@@ -0,0 +1,38 @@
+package logic
+
+import (
+	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"context"
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type NewUserMsgLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewNewUserMsgLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewUserMsgLogic {
+	return &NewUserMsgLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+// 新用户发送消息
+func (l *NewUserMsgLogic) NewUserMsg(in *messageclient.NewUserInsertMsgReq) (*messageclient.Response, error) {
+	// todo: add your logic here and delete this line
+	//fmt.Println(in)
+	msg := "发送成功"
+	err := service.NewUserSendMsg(in)
+	if err != nil {
+		msg = err.Error()
+	}
+	return &messageclient.Response{
+		Code:    1,
+		Message: msg,
+	}, nil
+}

+ 43 - 0
rpc/internal/logic/updatemsgsummarylogic.go

@@ -0,0 +1,43 @@
+package logic
+
+import (
+	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
+	"app.yhyue.com/moapp/MessageCenter/rpc/messageclient"
+	"context"
+
+	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
+	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type UpdateMsgSummaryLogic struct {
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+	logx.Logger
+}
+
+func NewUpdateMsgSummaryLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateMsgSummaryLogic {
+	return &UpdateMsgSummaryLogic{
+		ctx:    ctx,
+		svcCtx: svcCtx,
+		Logger: logx.WithContext(ctx),
+	}
+}
+
+// 发送消息更新一次消息汇总表
+func (l *UpdateMsgSummaryLogic) UpdateMsgSummary(in *messageclient.UpdateMsgSummaryReq) (*messageclient.Response, error) {
+	var (
+		code = 1
+		msg  = "成功"
+	)
+	err := service.SetMsgSummary(in.MsgLogId, in.GroupId, in.MsgType)
+	if err != nil {
+		code = 0
+		msg = err.Error()
+	}
+	return &message.Response{
+		Code:    int64(code),
+		Message: msg,
+	}, nil
+}

+ 3 - 2
rpc/internal/logic/usermsglistlogic.go

@@ -28,8 +28,9 @@ func NewUserMsgListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserM
 // new用户消息列表
 func (l *UserMsgListLogic) UserMsgList(in *message.UserMsgListReq) (*message.UserMsgListRes, error) {
 	data := new(message.UserMsgListRes)
-	res1 := service.UserMsgList(in)    //具体信息
-	res2 := service.MessageGetLast(in) //最新信息
+	/*res1 := service.UserMsgList(in)    //具体信息
+	res2 := service.MessageGetLast(in) //最新信息*/
+	res1, res2 := service.BitmapUserMsgList(in)
 	var finalData []*message.Messages
 	if res1 != nil && res1.Data != nil {
 		for _, v := range res1.Data {

+ 0 - 39
rpc/internal/logic/userunreadmsglistlogic.go

@@ -1,39 +0,0 @@
-package logic
-
-import (
-	service "app.yhyue.com/moapp/MessageCenter/rpc/internal/common"
-	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
-	"context"
-	"log"
-
-	"app.yhyue.com/moapp/MessageCenter/rpc/internal/svc"
-	"github.com/zeromicro/go-zero/core/logx"
-)
-
-type UserUnreadMsgListLogic struct {
-	ctx    context.Context
-	svcCtx *svc.ServiceContext
-	logx.Logger
-}
-
-func NewUserUnreadMsgListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserUnreadMsgListLogic {
-	return &UserUnreadMsgListLogic{
-		ctx:    ctx,
-		svcCtx: svcCtx,
-		Logger: logx.WithContext(ctx),
-	}
-}
-
-//    官网、移动端首页、工作桌面消息滚动
-func (l *UserUnreadMsgListLogic) UserUnreadMsgList(in *message.UserUnreadMsgListReq) (*message.UserUnreadMsgListRes, error) {
-	data := new(message.UserUnreadMsgListRes)
-	count, res := service.UserUnreadMsgList(in) //具体信息
-	log.Println(count, res)
-	if count > 0 && len(res) > 0 {
-		data.List = res
-		data.Count = count
-		data.Code = 0
-		data.Message = "请求成功"
-	}
-	return data, nil
-}

+ 18 - 12
rpc/internal/server/messageserver.go

@@ -22,6 +22,24 @@ func NewMessageServer(svcCtx *svc.ServiceContext) *MessageServer {
 	}
 }
 
+// 发送消息更新一次消息汇总表
+func (s *MessageServer) UpdateMsgSummary(ctx context.Context, in *message.UpdateMsgSummaryReq) (*message.Response, error) {
+	l := logic.NewUpdateMsgSummaryLogic(ctx, s.svcCtx)
+	return l.UpdateMsgSummary(in)
+}
+
+// 新用户发送消息
+func (s *MessageServer) NewUserMsg(ctx context.Context, in *message.NewUserInsertMsgReq) (*message.Response, error) {
+	l := logic.NewNewUserMsgLogic(ctx, s.svcCtx)
+	return l.NewUserMsg(in)
+}
+
+// bitmap保存消息
+func (s *MessageServer) BitmapSaveMsg(ctx context.Context, in *message.MultipleSaveMsgReq) (*message.MultipleSaveMsgResp, error) {
+	l := logic.NewBitmapSaveMsgLogic(ctx, s.svcCtx)
+	return l.BitmapSaveMsg(in)
+}
+
 // 批量保存消息
 func (s *MessageServer) MultipleSaveMsg(ctx context.Context, in *message.MultipleSaveMsgReq) (*message.MultipleSaveMsgResp, error) {
 	l := logic.NewMultipleSaveMsgLogic(ctx, s.svcCtx)
@@ -47,12 +65,6 @@ func (s *MessageServer) FindMessageDetail(ctx context.Context, in *message.Messa
 }
 
 //   消息的分类
-func (s *MessageServer) GetMsgType(ctx context.Context, in *message.GetMsgTypeReq) (*message.GetMsgTypeRes, error) {
-	l := logic.NewGetMsgTypeLogic(ctx, s.svcCtx)
-	return l.GetMsgType(in)
-}
-
-//   查询指定用户的浮标消息
 func (s *MessageServer) FindUserBuoyMsg(ctx context.Context, in *message.FindUserBuoyMsgReq) (*message.FindUserBuoyMsgRes, error) {
 	l := logic.NewFindUserBuoyMsgLogic(ctx, s.svcCtx)
 	return l.FindUserBuoyMsg(in)
@@ -77,12 +89,6 @@ func (s *MessageServer) SendWxTmplMsg(ctx context.Context, in *message.WxTmplMsg
 }
 
 //    官网、移动端首页、工作桌面消息滚动
-func (s *MessageServer) UserUnreadMsgList(ctx context.Context, in *message.UserUnreadMsgListReq) (*message.UserUnreadMsgListRes, error) {
-	l := logic.NewUserUnreadMsgListLogic(ctx, s.svcCtx)
-	return l.UserUnreadMsgList(in)
-}
-
-//  点击消息-存查看记录
 func (s *MessageServer) MsgOpenLog(ctx context.Context, in *message.MsgOpenLogReq) (*message.Response, error) {
 	l := logic.NewMsgOpenLogLogic(ctx, s.svcCtx)
 	return l.MsgOpenLog(in)

+ 46 - 3
rpc/message.go

@@ -16,14 +16,17 @@ import (
 	m "app.yhyue.com/moapp/jybase/mongodb"
 	"app.yhyue.com/moapp/jybase/mysql"
 	"app.yhyue.com/moapp/jybase/redis"
+	"context"
 	"flag"
 	"fmt"
-	"github.com/go-xorm/xorm"
+	"github.com/ClickHouse/clickhouse-go/v2"
+	_ "github.com/gogf/gf/contrib/drivers/clickhouse/v2"
 	"github.com/zeromicro/go-zero/core/conf"
 	"github.com/zeromicro/go-zero/core/logx"
 	"github.com/zeromicro/go-zero/zrpc"
 	"google.golang.org/grpc"
 	"log"
+	"time"
 )
 
 var configFile = flag.String("f", "etc/message.yaml", "the config file")
@@ -56,6 +59,12 @@ func main() {
 func init() {
 	conf.MustLoad(*configFile, &config.ConfigJson)
 	log.Println("开始初始化数据库。。。。。")
+	//初始化clickhouse
+	err := connectClickhouse(config.ConfigJson.Clickhouse)
+	if err != nil {
+		log.Println("初始化clickhouse出错:", err)
+	}
+
 	//初始化mysql
 	entity.Mysql = &mysql.Mysql{
 		Address:      config.ConfigJson.DataSource.Address,
@@ -66,6 +75,7 @@ func init() {
 		MaxIdleConns: config.ConfigJson.DataSource.MaxIdleConns,
 	}
 	entity.Mysql.Init()
+
 	common.AllMsgType, entity.MessageColumn = common.MessageType()
 	// 初始化需要展示消息细化分类的groupid 和对应的class信息
 	common.InitClassSearchMap()
@@ -122,6 +132,39 @@ func init() {
 	if config.ConfigJson.SurvivalTime != 0 {
 		entity.SurvivalTime = config.ConfigJson.SurvivalTime
 	}
-	entity.Engine, _ = xorm.NewEngine("mysql", config.ConfigJson.TidbEng)
-	entity.Engine.ShowSQL(true)
+	//entity.Engine, _ = xorm.NewEngine("mysql", config.ConfigJson.TidbEng)
+	//entity.Engine.ShowSQL(true)
+	common.LoadTask()
+}
+
+// 创建clickhouse连接
+func connectClickhouse(cHouseConfig *config.CHouseConfig) error {
+	var (
+		ctx = context.Background()
+		err error
+	)
+	entity.ClickhouseConn, err = clickhouse.Open(&clickhouse.Options{
+		Addr:         []string{cHouseConfig.Addr},
+		DialTimeout:  10 * time.Second,
+		MaxIdleConns: cHouseConfig.MaxIdleConns,
+		MaxOpenConns: cHouseConfig.MaxOpenConns,
+		Auth: clickhouse.Auth{
+			Database: cHouseConfig.DbName,
+			Username: cHouseConfig.UserName,
+			Password: cHouseConfig.Password,
+		},
+		Debugf: func(format string, v ...interface{}) {
+			fmt.Printf(format, v)
+		},
+	})
+	if err != nil {
+		return err
+	}
+	if err := entity.ClickhouseConn.Ping(ctx); err != nil {
+		if exception, ok := err.(*clickhouse.Exception); ok {
+			fmt.Printf("Exception [%d] %s \n%s\n", exception.Code, exception.Message, exception.StackTrace)
+		}
+		return err
+	}
+	return nil
 }

+ 63 - 25
rpc/message.proto

@@ -7,6 +7,7 @@ message ChangeReadStatusReq {
     int64 id = 1; // 消息id
     int64 readStatus = 2; // 阅读状态 0-未读 1-已读
     string appid = 3; //应用标识
+    string userId = 4;
 }
 message ResCount {
     int64 msgType = 1; // 类型及未读数量
@@ -93,10 +94,10 @@ message GetUnreadClassCountRes {
     repeated ResCount data = 3; //
     repeated Messages info = 4; // 每个类型最新消息列表
 }
-message GetMsgTypeReq {
+/*message GetMsgTypeReq {
     string userId = 1; // 用户id
     string appid = 2; //应用标识
-}
+}*/
 message MsgTypes{
     int64 msgType =1;
     string img = 2;
@@ -104,11 +105,11 @@ message MsgTypes{
     string code = 4;
     string displayPlatform = 5;
 }
-message GetMsgTypeRes {
+/*message GetMsgTypeRes {
     int64 code = 1; //状态码
     string message = 2; //响应消息
     repeated MsgTypes data = 3; //
-}
+}*/
 
 message user {
     string userId = 1;
@@ -117,18 +118,13 @@ message user {
 
 message multipleSaveMsgReq {
     string userIds = 1;
-    string userNames = 2;
     string sendUserId = 3; //发送方用户ID
-    string sendName = 4; //发送方用户名
     string title = 5; //主题
     string content = 6; //内容
     int64 msgType = 7; //消息类型 1:客服   2:系统通知  3:营销   4:用户会话
     string link = 8; //跳转链接
-    int64 citeId = 9; //引用id
     string appid = 10; //应用标识
     int64 msgLogId = 11;//消息记录表id
-    int64 showBuoy = 12;//是否展示为浮标
-    string showContent =13;//展示文案
     string positionIds = 14;// 职位id  逗号分割
     string row4 = 15;
     string productName = 16;
@@ -138,7 +134,7 @@ message multipleSaveMsgReq {
     string appPushUrl = 20;
     string wxPushUrl = 21;
     string iosPushUrl = 22;
-    CustomWxTpl customWxTpl = 23;
+    string baseUserIds = 23;
  }
 
 message CustomWxTpl {
@@ -235,29 +231,20 @@ message WxTmplResponse {
     string message = 2; //信息
 }
 
-message UserUnreadMsgListReq {
+/*message UserUnreadMsgListReq {
     string userId = 1; //用户id
     string appid = 3; //应用标识
     int64 offSet = 4; //当前
     int64 pageSize = 5; //大小
     int64 isNeedData = 6; //是否需要未读的消息数据,0 不需要  1需要
-}
+}*/
 
-message UserUnreadMsgListRes {
+/*message UserUnreadMsgListRes {
     int64 code = 1; //状态码
     string message = 2; //响应消息
     repeated Messages list = 3;
     int64 count = 4; //总数
-}
-
-// 剑鱼学堂模版消息
-//message JySchoolMsg {
-//  string userIds = 1;  //接受人 mongo_userId(多个用,分割)
-//  string title = 2;    //课程名称
-//  string date = 3;     //课程时间
-//  string address = 4;  //课程地点
-//  string url = 5;      //消息跳转连接
-//}
+}*/
 
 // 剑鱼系统通用模版
 message WxTmplMsgRequest {
@@ -282,7 +269,58 @@ message MsgOpenLogReq{
     string appId = 4;
 }
 
+//新用户消息调用接口
+message NewUserInsertMsgReq{
+    string userIds = 1;
+    string title = 5; //主题
+    string content = 6; //内容
+    int64 msgType = 7; //消息类型 1:客服   2:系统通知  3:营销   4:用户会话
+    string link = 8; //跳转链接
+    string appid = 10; //应用标识
+    int64 msgLogId = 11;//消息记录表id
+    string positionIds = 14;// 职位id  逗号分割
+    string row4 = 15;
+    string productName = 16;
+    string orderId = 17;
+    string orderMoney = 18;
+    string identity = 19;
+    string appPushUrl = 20;
+    string wxPushUrl = 21;
+    string iosPushUrl = 22;
+}
+message UpdateMsgSummaryReq{
+    int64 msgLogId = 1;
+    int64 groupId = 2;
+    int64 msgType = 3;
+}
+message BitmapSaveMsgReq{
+    string userIds = 1;
+    string title = 5; //主题
+    string content = 6; //内容
+    int64 msgType = 7; //消息类型 1:客服   2:系统通知  3:营销   4:用户会话
+    string link = 8; //跳转链接
+    string appid = 10; //应用标识
+    int64 msgLogId = 11;//消息记录表id
+    string positionIds = 14;// 职位id  逗号分割
+    string row4 = 15;
+    string productName = 16;
+    string orderId = 17;
+    string orderMoney = 18;
+    string identity = 19;
+    string appPushUrl = 20;
+    string wxPushUrl = 21;
+    string iosPushUrl = 22;
+    string baseUserIds = 23;
+    string sendUserId = 24;
+}
+
 service Message {
+    //发送消息更新一次消息汇总表
+    rpc UpdateMsgSummary (UpdateMsgSummaryReq) returns (Response);
+    //新用户发送消息
+    rpc NewUserMsg (NewUserInsertMsgReq) returns (Response);
+    //bitmap保存消息
+    rpc bitmapSaveMsg (multipleSaveMsgReq) returns (multipleSaveMsgResp);
     //批量保存消息
     rpc multipleSaveMsg (multipleSaveMsgReq) returns (multipleSaveMsgResp);
     // 修改消息阅读状态
@@ -292,7 +330,7 @@ service Message {
     //查看详细详情
     rpc FindMessageDetail (MessageDetailReq) returns (MessageDetailResp);
     //  消息的分类
-    rpc GetMsgType (GetMsgTypeReq) returns (GetMsgTypeRes);
+//    rpc GetMsgType (GetMsgTypeReq) returns (GetMsgTypeRes);
     //  查询指定用户的浮标消息
     rpc FindUserBuoyMsg (FindUserBuoyMsgReq) returns (FindUserBuoyMsgRes);
 
@@ -304,7 +342,7 @@ service Message {
     //  发送剑鱼微信模版消息
     rpc SendWxTmplMsg (WxTmplMsgRequest) returns(SendMsgResponse);
     //   官网、移动端首页、工作桌面消息滚动
-    rpc UserUnreadMsgList (UserUnreadMsgListReq) returns (UserUnreadMsgListRes);
+//    rpc UserUnreadMsgList (UserUnreadMsgListReq) returns (UserUnreadMsgListRes);
     // 点击消息-存查看记录
     rpc MsgOpenLog (MsgOpenLogReq) returns (Response);
 

+ 0 - 160
rpc/message/message.go

@@ -1,160 +0,0 @@
-// Code generated by goctl. DO NOT EDIT!
-// Source: message.proto
-
-package message
-
-import (
-	"context"
-
-	"app.yhyue.com/moapp/MessageCenter/rpc/type/message"
-
-	"github.com/zeromicro/go-zero/zrpc"
-	"google.golang.org/grpc"
-)
-
-type (
-	AllSortData            = message.AllSortData
-	BuoyMessages           = message.BuoyMessages
-	ChangeReadStatusReq    = message.ChangeReadStatusReq
-	ClearUnreadMsgReq      = message.ClearUnreadMsgReq
-	CustomWxTpl            = message.CustomWxTpl
-	FindUserBuoyMsgReq     = message.FindUserBuoyMsgReq
-	FindUserBuoyMsgRes     = message.FindUserBuoyMsgRes
-	FindUserMsgReq         = message.FindUserMsgReq
-	FindUserMsgRes         = message.FindUserMsgRes
-	GetClassUnreadCountReq = message.GetClassUnreadCountReq
-	GetLastMessageReq      = message.GetLastMessageReq
-	GetLastMessageRes      = message.GetLastMessageRes
-	GetMsgTypeReq          = message.GetMsgTypeReq
-	GetMsgTypeRes          = message.GetMsgTypeRes
-	GetUnreadClassCountReq = message.GetUnreadClassCountReq
-	GetUnreadClassCountRes = message.GetUnreadClassCountRes
-	MessageDetailReq       = message.MessageDetailReq
-	MessageDetailResp      = message.MessageDetailResp
-	Messages               = message.Messages
-	MsgOpenLogReq          = message.MsgOpenLogReq
-	MsgTypes               = message.MsgTypes
-	MultipleSaveMsgReq     = message.MultipleSaveMsgReq
-	MultipleSaveMsgResp    = message.MultipleSaveMsgResp
-	ResCount               = message.ResCount
-	Response               = message.Response
-	SendMsgResponse        = message.SendMsgResponse
-	TmplItem               = message.TmplItem
-	User                   = message.User
-	UserMsgList            = message.UserMsgList
-	UserMsgListReq         = message.UserMsgListReq
-	UserMsgListRes         = message.UserMsgListRes
-	UserUnreadMsgListReq   = message.UserUnreadMsgListReq
-	UserUnreadMsgListRes   = message.UserUnreadMsgListRes
-	WxTmplMsgRequest       = message.WxTmplMsgRequest
-	WxTmplResponse         = message.WxTmplResponse
-
-	Message interface {
-		// 批量保存消息
-		MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
-		//  修改消息阅读状态
-		ChangeReadStatus(ctx context.Context, in *ChangeReadStatusReq, opts ...grpc.CallOption) (*Response, error)
-		//   查询指定用户的历史消息记录
-		FindUserMsg(ctx context.Context, in *FindUserMsgReq, opts ...grpc.CallOption) (*FindUserMsgRes, error)
-		// 查看详细详情
-		FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error)
-		//   消息的分类
-		GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error)
-		//   查询指定用户的浮标消息
-		FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error)
-		//    一键清空未读消息
-		ClearUnreadMsg(ctx context.Context, in *ClearUnreadMsgReq, opts ...grpc.CallOption) (*Response, error)
-		//    new用户消息列表
-		UserMsgList(ctx context.Context, in *UserMsgListReq, opts ...grpc.CallOption) (*UserMsgListRes, error)
-		//   发送剑鱼微信模版消息
-		SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
-		//    官网、移动端首页、工作桌面消息滚动
-		UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error)
-		//  点击消息-存查看记录
-		MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error)
-		//   发送剑鱼微信模版消息
-		AppLetterPush(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
-	}
-
-	defaultMessage struct {
-		cli zrpc.Client
-	}
-)
-
-func NewMessage(cli zrpc.Client) Message {
-	return &defaultMessage{
-		cli: cli,
-	}
-}
-
-// 批量保存消息
-func (m *defaultMessage) MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.MultipleSaveMsg(ctx, in, opts...)
-}
-
-//  修改消息阅读状态
-func (m *defaultMessage) ChangeReadStatus(ctx context.Context, in *ChangeReadStatusReq, opts ...grpc.CallOption) (*Response, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.ChangeReadStatus(ctx, in, opts...)
-}
-
-//   查询指定用户的历史消息记录
-func (m *defaultMessage) FindUserMsg(ctx context.Context, in *FindUserMsgReq, opts ...grpc.CallOption) (*FindUserMsgRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.FindUserMsg(ctx, in, opts...)
-}
-
-// 查看详细详情
-func (m *defaultMessage) FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.FindMessageDetail(ctx, in, opts...)
-}
-
-//   消息的分类
-func (m *defaultMessage) GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.GetMsgType(ctx, in, opts...)
-}
-
-//   查询指定用户的浮标消息
-func (m *defaultMessage) FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.FindUserBuoyMsg(ctx, in, opts...)
-}
-
-//    一键清空未读消息
-func (m *defaultMessage) ClearUnreadMsg(ctx context.Context, in *ClearUnreadMsgReq, opts ...grpc.CallOption) (*Response, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.ClearUnreadMsg(ctx, in, opts...)
-}
-
-//    new用户消息列表
-func (m *defaultMessage) UserMsgList(ctx context.Context, in *UserMsgListReq, opts ...grpc.CallOption) (*UserMsgListRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.UserMsgList(ctx, in, opts...)
-}
-
-//   发送剑鱼微信模版消息
-func (m *defaultMessage) SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.SendWxTmplMsg(ctx, in, opts...)
-}
-
-//    官网、移动端首页、工作桌面消息滚动
-func (m *defaultMessage) UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.UserUnreadMsgList(ctx, in, opts...)
-}
-
-//  点击消息-存查看记录
-func (m *defaultMessage) MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.MsgOpenLog(ctx, in, opts...)
-}
-
-//   发送剑鱼微信模版消息
-func (m *defaultMessage) AppLetterPush(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.AppLetterPush(ctx, in, opts...)
-}

+ 29 - 20
rpc/messageclient/message.go

@@ -14,9 +14,11 @@ import (
 
 type (
 	AllSortData            = message.AllSortData
+	BitmapSaveMsgReq       = message.BitmapSaveMsgReq
 	BuoyMessages           = message.BuoyMessages
 	ChangeReadStatusReq    = message.ChangeReadStatusReq
 	ClearUnreadMsgReq      = message.ClearUnreadMsgReq
+	CustomWxTpl            = message.CustomWxTpl
 	FindUserBuoyMsgReq     = message.FindUserBuoyMsgReq
 	FindUserBuoyMsgRes     = message.FindUserBuoyMsgRes
 	FindUserMsgReq         = message.FindUserMsgReq
@@ -24,8 +26,6 @@ type (
 	GetClassUnreadCountReq = message.GetClassUnreadCountReq
 	GetLastMessageReq      = message.GetLastMessageReq
 	GetLastMessageRes      = message.GetLastMessageRes
-	GetMsgTypeReq          = message.GetMsgTypeReq
-	GetMsgTypeRes          = message.GetMsgTypeRes
 	GetUnreadClassCountReq = message.GetUnreadClassCountReq
 	GetUnreadClassCountRes = message.GetUnreadClassCountRes
 	MessageDetailReq       = message.MessageDetailReq
@@ -35,19 +35,26 @@ type (
 	MsgTypes               = message.MsgTypes
 	MultipleSaveMsgReq     = message.MultipleSaveMsgReq
 	MultipleSaveMsgResp    = message.MultipleSaveMsgResp
+	NewUserInsertMsgReq    = message.NewUserInsertMsgReq
 	ResCount               = message.ResCount
 	Response               = message.Response
 	SendMsgResponse        = message.SendMsgResponse
+	TmplItem               = message.TmplItem
+	UpdateMsgSummaryReq    = message.UpdateMsgSummaryReq
 	User                   = message.User
 	UserMsgList            = message.UserMsgList
 	UserMsgListReq         = message.UserMsgListReq
 	UserMsgListRes         = message.UserMsgListRes
-	UserUnreadMsgListReq   = message.UserUnreadMsgListReq
-	UserUnreadMsgListRes   = message.UserUnreadMsgListRes
 	WxTmplMsgRequest       = message.WxTmplMsgRequest
 	WxTmplResponse         = message.WxTmplResponse
 
 	Message interface {
+		// 发送消息更新一次消息汇总表
+		UpdateMsgSummary(ctx context.Context, in *UpdateMsgSummaryReq, opts ...grpc.CallOption) (*Response, error)
+		// 新用户发送消息
+		NewUserMsg(ctx context.Context, in *NewUserInsertMsgReq, opts ...grpc.CallOption) (*Response, error)
+		// bitmap保存消息
+		BitmapSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
 		// 批量保存消息
 		MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
 		//  修改消息阅读状态
@@ -57,8 +64,6 @@ type (
 		// 查看详细详情
 		FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error)
 		//   消息的分类
-		GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error)
-		//   查询指定用户的浮标消息
 		FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error)
 		//    一键清空未读消息
 		ClearUnreadMsg(ctx context.Context, in *ClearUnreadMsgReq, opts ...grpc.CallOption) (*Response, error)
@@ -67,8 +72,6 @@ type (
 		//   发送剑鱼微信模版消息
 		SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
 		//    官网、移动端首页、工作桌面消息滚动
-		UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error)
-		//  点击消息-存查看记录
 		MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error)
 		//   发送剑鱼微信模版消息
 		AppLetterPush(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
@@ -85,6 +88,24 @@ func NewMessage(cli zrpc.Client) Message {
 	}
 }
 
+// 发送消息更新一次消息汇总表
+func (m *defaultMessage) UpdateMsgSummary(ctx context.Context, in *UpdateMsgSummaryReq, opts ...grpc.CallOption) (*Response, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.UpdateMsgSummary(ctx, in, opts...)
+}
+
+// 新用户发送消息
+func (m *defaultMessage) NewUserMsg(ctx context.Context, in *NewUserInsertMsgReq, opts ...grpc.CallOption) (*Response, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.NewUserMsg(ctx, in, opts...)
+}
+
+// bitmap保存消息
+func (m *defaultMessage) BitmapSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
+	client := message.NewMessageClient(m.cli.Conn())
+	return client.BitmapSaveMsg(ctx, in, opts...)
+}
+
 // 批量保存消息
 func (m *defaultMessage) MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
 	client := message.NewMessageClient(m.cli.Conn())
@@ -110,12 +131,6 @@ func (m *defaultMessage) FindMessageDetail(ctx context.Context, in *MessageDetai
 }
 
 //   消息的分类
-func (m *defaultMessage) GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.GetMsgType(ctx, in, opts...)
-}
-
-//   查询指定用户的浮标消息
 func (m *defaultMessage) FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error) {
 	client := message.NewMessageClient(m.cli.Conn())
 	return client.FindUserBuoyMsg(ctx, in, opts...)
@@ -140,12 +155,6 @@ func (m *defaultMessage) SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest
 }
 
 //    官网、移动端首页、工作桌面消息滚动
-func (m *defaultMessage) UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error) {
-	client := message.NewMessageClient(m.cli.Conn())
-	return client.UserUnreadMsgList(ctx, in, opts...)
-}
-
-//  点击消息-存查看记录
 func (m *defaultMessage) MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error) {
 	client := message.NewMessageClient(m.cli.Conn())
 	return client.MsgOpenLog(ctx, in, opts...)

文件差異過大導致無法顯示
+ 236 - 294
rpc/type/message/message.pb.go


+ 118 - 72
rpc/type/message/message_grpc.pb.go

@@ -22,6 +22,12 @@ const _ = grpc.SupportPackageIsVersion7
 //
 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
 type MessageClient interface {
+	//发送消息更新一次消息汇总表
+	UpdateMsgSummary(ctx context.Context, in *UpdateMsgSummaryReq, opts ...grpc.CallOption) (*Response, error)
+	//新用户发送消息
+	NewUserMsg(ctx context.Context, in *NewUserInsertMsgReq, opts ...grpc.CallOption) (*Response, error)
+	//bitmap保存消息
+	BitmapSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
 	//批量保存消息
 	MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error)
 	// 修改消息阅读状态
@@ -31,7 +37,7 @@ type MessageClient interface {
 	//查看详细详情
 	FindMessageDetail(ctx context.Context, in *MessageDetailReq, opts ...grpc.CallOption) (*MessageDetailResp, error)
 	//  消息的分类
-	GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error)
+	//    rpc GetMsgType (GetMsgTypeReq) returns (GetMsgTypeRes);
 	//  查询指定用户的浮标消息
 	FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error)
 	//   一键清空未读消息
@@ -41,7 +47,7 @@ type MessageClient interface {
 	//  发送剑鱼微信模版消息
 	SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest, opts ...grpc.CallOption) (*SendMsgResponse, error)
 	//   官网、移动端首页、工作桌面消息滚动
-	UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error)
+	//    rpc UserUnreadMsgList (UserUnreadMsgListReq) returns (UserUnreadMsgListRes);
 	// 点击消息-存查看记录
 	MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error)
 	//  发送剑鱼微信模版消息
@@ -56,6 +62,33 @@ func NewMessageClient(cc grpc.ClientConnInterface) MessageClient {
 	return &messageClient{cc}
 }
 
+func (c *messageClient) UpdateMsgSummary(ctx context.Context, in *UpdateMsgSummaryReq, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/message.Message/UpdateMsgSummary", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *messageClient) NewUserMsg(ctx context.Context, in *NewUserInsertMsgReq, opts ...grpc.CallOption) (*Response, error) {
+	out := new(Response)
+	err := c.cc.Invoke(ctx, "/message.Message/NewUserMsg", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+func (c *messageClient) BitmapSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
+	out := new(MultipleSaveMsgResp)
+	err := c.cc.Invoke(ctx, "/message.Message/bitmapSaveMsg", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
 func (c *messageClient) MultipleSaveMsg(ctx context.Context, in *MultipleSaveMsgReq, opts ...grpc.CallOption) (*MultipleSaveMsgResp, error) {
 	out := new(MultipleSaveMsgResp)
 	err := c.cc.Invoke(ctx, "/message.Message/multipleSaveMsg", in, out, opts...)
@@ -92,15 +125,6 @@ func (c *messageClient) FindMessageDetail(ctx context.Context, in *MessageDetail
 	return out, nil
 }
 
-func (c *messageClient) GetMsgType(ctx context.Context, in *GetMsgTypeReq, opts ...grpc.CallOption) (*GetMsgTypeRes, error) {
-	out := new(GetMsgTypeRes)
-	err := c.cc.Invoke(ctx, "/message.Message/GetMsgType", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
 func (c *messageClient) FindUserBuoyMsg(ctx context.Context, in *FindUserBuoyMsgReq, opts ...grpc.CallOption) (*FindUserBuoyMsgRes, error) {
 	out := new(FindUserBuoyMsgRes)
 	err := c.cc.Invoke(ctx, "/message.Message/FindUserBuoyMsg", in, out, opts...)
@@ -137,15 +161,6 @@ func (c *messageClient) SendWxTmplMsg(ctx context.Context, in *WxTmplMsgRequest,
 	return out, nil
 }
 
-func (c *messageClient) UserUnreadMsgList(ctx context.Context, in *UserUnreadMsgListReq, opts ...grpc.CallOption) (*UserUnreadMsgListRes, error) {
-	out := new(UserUnreadMsgListRes)
-	err := c.cc.Invoke(ctx, "/message.Message/UserUnreadMsgList", in, out, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
 func (c *messageClient) MsgOpenLog(ctx context.Context, in *MsgOpenLogReq, opts ...grpc.CallOption) (*Response, error) {
 	out := new(Response)
 	err := c.cc.Invoke(ctx, "/message.Message/MsgOpenLog", in, out, opts...)
@@ -168,6 +183,12 @@ func (c *messageClient) AppLetterPush(ctx context.Context, in *WxTmplMsgRequest,
 // All implementations must embed UnimplementedMessageServer
 // for forward compatibility
 type MessageServer interface {
+	//发送消息更新一次消息汇总表
+	UpdateMsgSummary(context.Context, *UpdateMsgSummaryReq) (*Response, error)
+	//新用户发送消息
+	NewUserMsg(context.Context, *NewUserInsertMsgReq) (*Response, error)
+	//bitmap保存消息
+	BitmapSaveMsg(context.Context, *MultipleSaveMsgReq) (*MultipleSaveMsgResp, error)
 	//批量保存消息
 	MultipleSaveMsg(context.Context, *MultipleSaveMsgReq) (*MultipleSaveMsgResp, error)
 	// 修改消息阅读状态
@@ -177,7 +198,7 @@ type MessageServer interface {
 	//查看详细详情
 	FindMessageDetail(context.Context, *MessageDetailReq) (*MessageDetailResp, error)
 	//  消息的分类
-	GetMsgType(context.Context, *GetMsgTypeReq) (*GetMsgTypeRes, error)
+	//    rpc GetMsgType (GetMsgTypeReq) returns (GetMsgTypeRes);
 	//  查询指定用户的浮标消息
 	FindUserBuoyMsg(context.Context, *FindUserBuoyMsgReq) (*FindUserBuoyMsgRes, error)
 	//   一键清空未读消息
@@ -187,7 +208,7 @@ type MessageServer interface {
 	//  发送剑鱼微信模版消息
 	SendWxTmplMsg(context.Context, *WxTmplMsgRequest) (*SendMsgResponse, error)
 	//   官网、移动端首页、工作桌面消息滚动
-	UserUnreadMsgList(context.Context, *UserUnreadMsgListReq) (*UserUnreadMsgListRes, error)
+	//    rpc UserUnreadMsgList (UserUnreadMsgListReq) returns (UserUnreadMsgListRes);
 	// 点击消息-存查看记录
 	MsgOpenLog(context.Context, *MsgOpenLogReq) (*Response, error)
 	//  发送剑鱼微信模版消息
@@ -199,6 +220,15 @@ type MessageServer interface {
 type UnimplementedMessageServer struct {
 }
 
+func (UnimplementedMessageServer) UpdateMsgSummary(context.Context, *UpdateMsgSummaryReq) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method UpdateMsgSummary not implemented")
+}
+func (UnimplementedMessageServer) NewUserMsg(context.Context, *NewUserInsertMsgReq) (*Response, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method NewUserMsg not implemented")
+}
+func (UnimplementedMessageServer) BitmapSaveMsg(context.Context, *MultipleSaveMsgReq) (*MultipleSaveMsgResp, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method BitmapSaveMsg not implemented")
+}
 func (UnimplementedMessageServer) MultipleSaveMsg(context.Context, *MultipleSaveMsgReq) (*MultipleSaveMsgResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method MultipleSaveMsg not implemented")
 }
@@ -211,9 +241,6 @@ func (UnimplementedMessageServer) FindUserMsg(context.Context, *FindUserMsgReq)
 func (UnimplementedMessageServer) FindMessageDetail(context.Context, *MessageDetailReq) (*MessageDetailResp, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method FindMessageDetail not implemented")
 }
-func (UnimplementedMessageServer) GetMsgType(context.Context, *GetMsgTypeReq) (*GetMsgTypeRes, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method GetMsgType not implemented")
-}
 func (UnimplementedMessageServer) FindUserBuoyMsg(context.Context, *FindUserBuoyMsgReq) (*FindUserBuoyMsgRes, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method FindUserBuoyMsg not implemented")
 }
@@ -226,9 +253,6 @@ func (UnimplementedMessageServer) UserMsgList(context.Context, *UserMsgListReq)
 func (UnimplementedMessageServer) SendWxTmplMsg(context.Context, *WxTmplMsgRequest) (*SendMsgResponse, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method SendWxTmplMsg not implemented")
 }
-func (UnimplementedMessageServer) UserUnreadMsgList(context.Context, *UserUnreadMsgListReq) (*UserUnreadMsgListRes, error) {
-	return nil, status.Errorf(codes.Unimplemented, "method UserUnreadMsgList not implemented")
-}
 func (UnimplementedMessageServer) MsgOpenLog(context.Context, *MsgOpenLogReq) (*Response, error) {
 	return nil, status.Errorf(codes.Unimplemented, "method MsgOpenLog not implemented")
 }
@@ -248,6 +272,60 @@ func RegisterMessageServer(s grpc.ServiceRegistrar, srv MessageServer) {
 	s.RegisterService(&Message_ServiceDesc, srv)
 }
 
+func _Message_UpdateMsgSummary_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(UpdateMsgSummaryReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MessageServer).UpdateMsgSummary(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/message.Message/UpdateMsgSummary",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MessageServer).UpdateMsgSummary(ctx, req.(*UpdateMsgSummaryReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Message_NewUserMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(NewUserInsertMsgReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MessageServer).NewUserMsg(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/message.Message/NewUserMsg",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MessageServer).NewUserMsg(ctx, req.(*NewUserInsertMsgReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+func _Message_BitmapSaveMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(MultipleSaveMsgReq)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(MessageServer).BitmapSaveMsg(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/message.Message/bitmapSaveMsg",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(MessageServer).BitmapSaveMsg(ctx, req.(*MultipleSaveMsgReq))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
 func _Message_MultipleSaveMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(MultipleSaveMsgReq)
 	if err := dec(in); err != nil {
@@ -320,24 +398,6 @@ func _Message_FindMessageDetail_Handler(srv interface{}, ctx context.Context, de
 	return interceptor(ctx, in, info, handler)
 }
 
-func _Message_GetMsgType_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(GetMsgTypeReq)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MessageServer).GetMsgType(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/message.Message/GetMsgType",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MessageServer).GetMsgType(ctx, req.(*GetMsgTypeReq))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
 func _Message_FindUserBuoyMsg_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(FindUserBuoyMsgReq)
 	if err := dec(in); err != nil {
@@ -410,24 +470,6 @@ func _Message_SendWxTmplMsg_Handler(srv interface{}, ctx context.Context, dec fu
 	return interceptor(ctx, in, info, handler)
 }
 
-func _Message_UserUnreadMsgList_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(UserUnreadMsgListReq)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(MessageServer).UserUnreadMsgList(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/message.Message/UserUnreadMsgList",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(MessageServer).UserUnreadMsgList(ctx, req.(*UserUnreadMsgListReq))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
 func _Message_MsgOpenLog_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
 	in := new(MsgOpenLogReq)
 	if err := dec(in); err != nil {
@@ -471,6 +513,18 @@ var Message_ServiceDesc = grpc.ServiceDesc{
 	ServiceName: "message.Message",
 	HandlerType: (*MessageServer)(nil),
 	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "UpdateMsgSummary",
+			Handler:    _Message_UpdateMsgSummary_Handler,
+		},
+		{
+			MethodName: "NewUserMsg",
+			Handler:    _Message_NewUserMsg_Handler,
+		},
+		{
+			MethodName: "bitmapSaveMsg",
+			Handler:    _Message_BitmapSaveMsg_Handler,
+		},
 		{
 			MethodName: "multipleSaveMsg",
 			Handler:    _Message_MultipleSaveMsg_Handler,
@@ -487,10 +541,6 @@ var Message_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "FindMessageDetail",
 			Handler:    _Message_FindMessageDetail_Handler,
 		},
-		{
-			MethodName: "GetMsgType",
-			Handler:    _Message_GetMsgType_Handler,
-		},
 		{
 			MethodName: "FindUserBuoyMsg",
 			Handler:    _Message_FindUserBuoyMsg_Handler,
@@ -507,10 +557,6 @@ var Message_ServiceDesc = grpc.ServiceDesc{
 			MethodName: "SendWxTmplMsg",
 			Handler:    _Message_SendWxTmplMsg_Handler,
 		},
-		{
-			MethodName: "UserUnreadMsgList",
-			Handler:    _Message_UserUnreadMsgList_Handler,
-		},
 		{
 			MethodName: "MsgOpenLog",
 			Handler:    _Message_MsgOpenLog_Handler,

部分文件因文件數量過多而無法顯示