From 2d2c245ca1725e5abd44af7c661b35e76a55897b Mon Sep 17 00:00:00 2001 From: Michael Li Date: Wed, 28 Dec 2022 12:10:57 +0800 Subject: [PATCH] mir: partial api implement for new web service --- auto/api/v1/core.go | 91 ++++++++++++---- go.mod | 2 +- go.sum | 4 +- internal/model/web/core.go | 48 +++++++- internal/model/web/web.go | 8 ++ internal/servants/base/base.go | 54 +++++++-- internal/servants/web/alipay.go | 2 +- internal/servants/web/core.go | 187 ++++++++++++++++++++++++++++++++ mirc/web/v1/core.go | 8 +- 9 files changed, 366 insertions(+), 38 deletions(-) diff --git a/auto/api/v1/core.go b/auto/api/v1/core.go index bffc2879..b49f480b 100644 --- a/auto/api/v1/core.go +++ b/auto/api/v1/core.go @@ -8,6 +8,7 @@ import ( "github.com/alimy/mir/v3" "github.com/gin-gonic/gin" "github.com/rocboss/paopao-ce/internal/model/web" + "github.com/rocboss/paopao-ce/internal/servants/base" ) type Core interface { @@ -25,18 +26,22 @@ type Core interface { GetStars() mir.Error GetCollections() mir.Error SendUserWhisper() mir.Error - ReadMessage() mir.Error - GetMessages() mir.Error - GetUnreadMsgCount() mir.Error + ReadMessage(*web.ReadMessageReq) mir.Error + GetMessages(*web.GetMessagesReq) (*base.PageResp, mir.Error) + GetUnreadMsgCount(*web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) GetUserInfo(*web.UserInfoReq) (*web.UserInfoResp, mir.Error) - SyncSearchIndex() mir.Error + SyncSearchIndex(*web.SyncSearchIndexReq) mir.Error mustEmbedUnimplementedCoreServant() } type CoreBinding interface { BindChangeAvatar(*gin.Context) (*web.ChangeAvatarReq, mir.Error) + BindReadMessage(*gin.Context) (*web.ReadMessageReq, mir.Error) + BindGetMessages(*gin.Context) (*web.GetMessagesReq, mir.Error) + BindGetUnreadMsgCount(*gin.Context) (*web.GetUnreadMsgCountReq, mir.Error) BindGetUserInfo(*gin.Context) (*web.UserInfoReq, mir.Error) + BindSyncSearchIndex(*gin.Context) (*web.SyncSearchIndexReq, mir.Error) mustEmbedUnimplementedCoreBinding() } @@ -54,8 +59,8 @@ type CoreRender interface { RenderGetCollections(*gin.Context, mir.Error) RenderSendUserWhisper(*gin.Context, mir.Error) RenderReadMessage(*gin.Context, mir.Error) - RenderGetMessages(*gin.Context, mir.Error) - RenderGetUnreadMsgCount(*gin.Context, mir.Error) + RenderGetMessages(*gin.Context, *base.PageResp, mir.Error) + RenderGetUnreadMsgCount(*gin.Context, *web.GetUnreadMsgCountResp, mir.Error) RenderGetUserInfo(*gin.Context, *web.UserInfoResp, mir.Error) RenderSyncSearchIndex(*gin.Context, mir.Error) @@ -192,7 +197,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderReadMessage(c, s.ReadMessage()) + req, err := b.BindReadMessage(c) + if err != nil { + r.RenderReadMessage(c, err) + return + } + r.RenderReadMessage(c, s.ReadMessage(req)) }) router.Handle("GET", "/user/messages", func(c *gin.Context) { @@ -202,7 +212,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderGetMessages(c, s.GetMessages()) + req, err := b.BindGetMessages(c) + if err != nil { + r.RenderGetMessages(c, nil, err) + return + } + resp, err := s.GetMessages(req) + r.RenderGetMessages(c, resp, err) }) router.Handle("GET", "/user/msgcount/unread", func(c *gin.Context) { @@ -212,7 +228,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderGetUnreadMsgCount(c, s.GetUnreadMsgCount()) + req, err := b.BindGetUnreadMsgCount(c) + if err != nil { + r.RenderGetUnreadMsgCount(c, nil, err) + return + } + resp, err := s.GetUnreadMsgCount(req) + r.RenderGetUnreadMsgCount(c, resp, err) }) router.Handle("GET", "/user/info", func(c *gin.Context) { @@ -238,7 +260,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderSyncSearchIndex(c, s.SyncSearchIndex()) + req, err := b.BindSyncSearchIndex(c) + if err != nil { + r.RenderSyncSearchIndex(c, err) + return + } + r.RenderSyncSearchIndex(c, s.SyncSearchIndex(req)) }) } @@ -295,23 +322,23 @@ func (UnimplementedCoreServant) SendUserWhisper() mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) ReadMessage() mir.Error { +func (UnimplementedCoreServant) ReadMessage(req *web.ReadMessageReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) GetMessages() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) GetMessages(req *web.GetMessagesReq) (*base.PageResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) GetUnreadMsgCount() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } func (UnimplementedCoreServant) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Error) { return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) SyncSearchIndex() mir.Error { +func (UnimplementedCoreServant) SyncSearchIndex(req *web.SyncSearchIndexReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -370,12 +397,12 @@ func (r *UnimplementedCoreRender) RenderReadMessage(c *gin.Context, err mir.Erro r.RenderAny(c, nil, err) } -func (r *UnimplementedCoreRender) RenderGetMessages(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderGetMessages(c *gin.Context, data *base.PageResp, err mir.Error) { + r.RenderAny(c, data, err) } -func (r *UnimplementedCoreRender) RenderGetUnreadMsgCount(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderGetUnreadMsgCount(c *gin.Context, data *web.GetUnreadMsgCountResp, err mir.Error) { + r.RenderAny(c, data, err) } func (r *UnimplementedCoreRender) RenderGetUserInfo(c *gin.Context, data *web.UserInfoResp, err mir.Error) { @@ -399,10 +426,34 @@ func (b *UnimplementedCoreBinding) BindChangeAvatar(c *gin.Context) (*web.Change return obj, err } +func (b *UnimplementedCoreBinding) BindReadMessage(c *gin.Context) (*web.ReadMessageReq, mir.Error) { + obj := new(web.ReadMessageReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindGetMessages(c *gin.Context) (*web.GetMessagesReq, mir.Error) { + obj := new(web.GetMessagesReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindGetUnreadMsgCount(c *gin.Context) (*web.GetUnreadMsgCountReq, mir.Error) { + obj := new(web.GetUnreadMsgCountReq) + err := b.BindAny(c, obj) + return obj, err +} + func (b *UnimplementedCoreBinding) BindGetUserInfo(c *gin.Context) (*web.UserInfoReq, mir.Error) { obj := new(web.UserInfoReq) err := b.BindAny(c, obj) return obj, err } +func (b *UnimplementedCoreBinding) BindSyncSearchIndex(c *gin.Context) (*web.SyncSearchIndexReq, mir.Error) { + obj := new(web.SyncSearchIndexReq) + err := b.BindAny(c, obj) + return obj, err +} + func (b *UnimplementedCoreBinding) mustEmbedUnimplementedCoreBinding() {} diff --git a/go.mod b/go.mod index 23b5d680..7bd04004 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/Masterminds/semver/v3 v3.1.1 github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868 github.com/alimy/cfg v0.3.0 - github.com/alimy/mir/v3 v3.0.0-beta.3 + github.com/alimy/mir/v3 v3.0.0-beta.4 github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible github.com/allegro/bigcache/v3 v3.0.2 github.com/bytedance/sonic v1.5.0 diff --git a/go.sum b/go.sum index 588a3b56..bb2a4603 100644 --- a/go.sum +++ b/go.sum @@ -147,8 +147,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alimy/cfg v0.3.0 h1:9xgA0QWVCPSq9fFNRcYahVCAX22IL9ts2wrTQPfAStY= github.com/alimy/cfg v0.3.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c= -github.com/alimy/mir/v3 v3.0.0-beta.3 h1:b+2C9rvZg2ssZ0+gMUf9aYwhuJFKExO611ybXRP+/30= -github.com/alimy/mir/v3 v3.0.0-beta.3/go.mod h1:ybhT2ijOiDn0lLwWzIY6vXdv+uzZrctS7VFfczcXBWU= +github.com/alimy/mir/v3 v3.0.0-beta.4 h1:4++lea7OWmykHRVbF1nCnKOJXCvBifmnhe47e91aV6c= +github.com/alimy/mir/v3 v3.0.0-beta.4/go.mod h1:ybhT2ijOiDn0lLwWzIY6vXdv+uzZrctS7VFfczcXBWU= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= diff --git a/internal/model/web/core.go b/internal/model/web/core.go index 12243a1e..3da85471 100644 --- a/internal/model/web/core.go +++ b/internal/model/web/core.go @@ -4,14 +4,56 @@ package web +import ( + "context" + + "github.com/rocboss/paopao-ce/internal/servants/base" +) + type ChangeAvatarReq struct { - *BaseInfo `json:"-"` + *BaseInfo `json:"-" binding:"-"` +} + +type SyncSearchIndexReq struct { + *BaseInfo `json:"-" binding:"-"` + + Ctx context.Context `json:"-" binding:"-"` } type UserInfoReq struct { - *BaseInfo `json:"-"` + *BaseInfo `json:"-" binding:"-"` + Username string `json:"username" form:"username" binding:"required"` } type UserInfoResp struct { - // TODO + Id int64 `json:"id"` + Nickname string `json:"nickname"` + Username string `json:"username"` + Status int `json:"status"` + Avatar string `json:"avatar"` + Balance int64 `json:"balance"` + Phone string `json:"phone"` + IsAdmin bool `json:"is_admin"` +} + +type GetUnreadMsgCountReq struct { + *SimpleInfo `json:"-" binding:"-"` +} + +type GetUnreadMsgCountResp struct { + Count int64 `json:"count"` +} + +type GetMessagesReq struct { + UserId int64 + Page int + PageSize int +} + +type GetMessagesResp = base.PageResp + +type ReadMessageReq struct { + *SimpleInfo `json:"-" binding:"-"` + + ID int64 `json:"id" binding:"required"` } diff --git a/internal/model/web/web.go b/internal/model/web/web.go index dd04971a..bcddea3a 100644 --- a/internal/model/web/web.go +++ b/internal/model/web/web.go @@ -12,6 +12,14 @@ type BaseInfo struct { User *core.User } +type SimpleInfo struct { + Uid int64 +} + func (b *BaseInfo) SetUser(user *core.User) { b.User = user } + +func (s *SimpleInfo) SetUserId(id int64) { + s.Uid = id +} diff --git a/internal/servants/base/base.go b/internal/servants/base/base.go index b6f244f1..abbe8944 100644 --- a/internal/servants/base/base.go +++ b/internal/servants/base/base.go @@ -41,6 +41,10 @@ type UserSetter interface { SetUser(*core.User) } +type UserIdSetter interface { + SetUserId(int64) +} + func UserFrom(c *gin.Context) (*core.User, bool) { if u, exists := c.Get("USER"); exists { user, ok := u.(*core.User) @@ -50,13 +54,21 @@ func UserFrom(c *gin.Context) (*core.User, bool) { } func UserIdFrom(c *gin.Context) (int64, bool) { - if u, exists := c.Get("UID"); exists { - uid, ok := u.(int64) - return uid, ok + if uid, exists := c.Get("UID"); exists { + v, ok := uid.(int64) + return v, ok } return -1, false } +func UserNameFrom(c *gin.Context) (string, bool) { + if username, exists := c.Get("USERNAME"); exists { + v, ok := username.(string) + return v, ok + } + return "", false +} + func BindAny(c *gin.Context, obj any) mir.Error { var errs xerror.ValidErrors err := c.ShouldBind(obj) @@ -65,12 +77,14 @@ func BindAny(c *gin.Context, obj any) mir.Error { } // setup *core.User if needed if setter, ok := obj.(UserSetter); ok { - user, exist := UserFrom(c) - if !exist { - return xerror.UnauthorizedTokenError - } + user, _ := UserFrom(c) setter.SetUser(user) } + // setup UserId if needed + if setter, ok := obj.(UserIdSetter); ok { + uid, _ := UserIdFrom(c) + setter.SetUserId(uid) + } return nil } @@ -88,3 +102,29 @@ func RenderAny(c *gin.Context, data any, err mir.Error) { }) } } + +func (s *DaoServant) GetTweetBy(id int64) (*core.PostFormated, error) { + post, err := s.Ds.GetPostByID(id) + if err != nil { + return nil, err + } + postContents, err := s.Ds.GetPostContentsByIDs([]int64{post.ID}) + if err != nil { + return nil, err + } + users, err := s.Ds.GetUsersByIDs([]int64{post.UserID}) + if err != nil { + return nil, err + } + // 数据整合 + postFormated := post.Format() + for _, user := range users { + postFormated.User = user.Format() + } + for _, content := range postContents { + if content.PostID == post.ID { + postFormated.Contents = append(postFormated.Contents, content.Format()) + } + } + return postFormated, nil +} diff --git a/internal/servants/web/alipay.go b/internal/servants/web/alipay.go index ccbf00bc..9420ffe4 100644 --- a/internal/servants/web/alipay.go +++ b/internal/servants/web/alipay.go @@ -136,7 +136,7 @@ func (s *alipayPrivSrv) Chain() gin.HandlersChain { return gin.HandlersChain{chain.JWT()} } -func (s *alipayPrivSrv) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error) { +func (s *alipayPrivSrv) UserWalletBills(req *web.UserWalletBillsReq) (*base.PageResp, mir.Error) { bills, err := s.Ds.GetUserWalletBills(req.UserId, (req.Page-1)*req.PageSize, req.PageSize) if err != nil { logrus.Errorf("GetUserWalletBills err: %s", err) diff --git a/internal/servants/web/core.go b/internal/servants/web/core.go index f4eef6e9..102a7554 100644 --- a/internal/servants/web/core.go +++ b/internal/servants/web/core.go @@ -5,11 +5,21 @@ package web import ( + "context" + "fmt" + "math" + "time" + + "github.com/alimy/mir/v3" "github.com/gin-gonic/gin" api "github.com/rocboss/paopao-ce/auto/api/v1" "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/internal/model/web" "github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/chain" + "github.com/rocboss/paopao-ce/pkg/app" + "github.com/rocboss/paopao-ce/pkg/xerror" + "github.com/sirupsen/logrus" ) var ( @@ -34,10 +44,187 @@ type coreRender struct { *api.UnimplementedCoreRender } +func (b *coreBinding) BindSyncSearchIndex(c *gin.Context) (*web.SyncSearchIndexReq, mir.Error) { + user, _ := base.UserFrom(c) + return &web.SyncSearchIndexReq{ + BaseInfo: &web.BaseInfo{ + User: user, + }, + Ctx: c.Request.Context(), + }, nil +} + +func (b *coreBinding) BindGetUserInfo(c *gin.Context) (*web.UserInfoReq, mir.Error) { + username, exists := base.UserNameFrom(c) + if !exists { + return nil, xerror.UnauthorizedAuthNotExist + } + return &web.UserInfoReq{ + Username: username, + }, nil +} + +func (b *coreBinding) BindGetMessages(c *gin.Context) (*web.GetMessagesReq, mir.Error) { + uid, ok := base.UserIdFrom(c) + if !ok { + return nil, xerror.UnauthorizedTokenError + } + page, pageSize := app.GetPageOffset(c) + return &web.GetMessagesReq{ + UserId: uid, + Page: page, + PageSize: pageSize, + }, nil +} + func (s *coreSrv) Chain() gin.HandlersChain { return gin.HandlersChain{chain.JWT()} } +func (s *coreSrv) SyncSearchIndex(req *web.SyncSearchIndexReq) mir.Error { + if req.User != nil && req.User.IsAdmin { + go s.pushPostsToSearch(req.Ctx) + } + return nil +} + +func (s *coreSrv) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Error) { + user, err := s.Ds.GetUserByUsername(req.Username) + if err != nil { + return nil, xerror.UnauthorizedAuthNotExist + } + if user.Model == nil || user.ID < 0 { + return nil, xerror.UnauthorizedAuthNotExist + } + resp := &web.UserInfoResp{ + Id: user.ID, + Nickname: user.Nickname, + Username: user.Username, + Status: user.Status, + Avatar: user.Avatar, + Balance: user.Balance, + IsAdmin: user.IsAdmin, + } + if user.Phone != "" && len(user.Phone) == 11 { + resp.Phone = user.Phone[0:3] + "****" + user.Phone[7:] + } + return resp, nil +} + +func (s *coreSrv) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) { + count, err := s.Ds.GetUnreadCount(req.Uid) + if err != nil { + return nil, xerror.ServerError + } + return &web.GetUnreadMsgCountResp{ + Count: count, + }, nil +} + +func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*base.PageResp, mir.Error) { + conditions := &core.ConditionsT{ + "receiver_user_id": req.UserId, + "ORDER": "id DESC", + } + messages, err := s.Ds.GetMessages(conditions, (req.Page-1)*req.PageSize, req.PageSize) + for _, mf := range messages { + if mf.SenderUserID > 0 { + user, err := s.Ds.GetUserByID(mf.SenderUserID) + if err == nil { + mf.SenderUser = user.Format() + } + } + // 好友申请消息不需要获取其他信息 + if mf.Type == core.MsgTypeRequestingFriend { + continue + } + if mf.PostID > 0 { + post, err := s.GetTweetBy(mf.PostID) + if err == nil { + mf.Post = post + if mf.CommentID > 0 { + comment, err := s.Ds.GetCommentByID(mf.CommentID) + if err == nil { + mf.Comment = comment + if mf.ReplyID > 0 { + reply, err := s.Ds.GetCommentReplyByID(mf.ReplyID) + if err == nil { + mf.Reply = reply + } + } + } + } + } + } + } + if err != nil { + logrus.Errorf("Ds.GetMessages err: %v\n", err) + return nil, _errGetMessagesFailed + } + totalRows, _ := s.Ds.GetMessageCount(conditions) + return base.PageRespFrom(messages, req.Page, req.PageSize, totalRows), nil +} + +func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error { + message, err := s.Ds.GetMessageByID(req.ID) + if err != nil { + return _errReadMessageFailed + } + if message.ReceiverUserID != req.Uid { + return _errNoPermission + } + if err = s.Ds.ReadMessage(message); err != nil { + logrus.Errorf("Ds.ReadMessage err: %s", err) + return _errReadMessageFailed + } + return nil +} + +func (s *coreSrv) pushPostsToSearch(c context.Context) { + if ok, _ := s.Redis.SetNX(c, "JOB_PUSH_TO_SEARCH", 1, time.Hour).Result(); ok { + defer s.Redis.Del(c, "JOB_PUSH_TO_SEARCH") + + splitNum := 1000 + totalRows, _ := s.Ds.GetPostCount(&core.ConditionsT{ + "visibility IN ?": []core.PostVisibleT{core.PostVisitPublic, core.PostVisitFriend}, + }) + pages := math.Ceil(float64(totalRows) / float64(splitNum)) + nums := int(pages) + for i := 0; i < nums; i++ { + posts, postsFormated, err := s.getTweetList(&core.ConditionsT{}, i*splitNum, splitNum) + if err != nil || len(posts) != len(postsFormated) { + continue + } + for i, pf := range postsFormated { + contentFormated := "" + for _, content := range pf.Contents { + if content.Type == core.ContentTypeText || content.Type == core.ContentTypeTitle { + contentFormated = contentFormated + content.Content + "\n" + } + } + docs := []core.TsDocItem{{ + Post: posts[i], + Content: contentFormated, + }} + s.ts.AddDocuments(docs, fmt.Sprintf("%d", posts[i].ID)) + } + } + } +} + +func (s *coreSrv) deleteSearchPost(post *core.Post) error { + return s.ts.DeleteDocuments([]string{fmt.Sprintf("%d", post.ID)}) +} + +func (s *coreSrv) getTweetList(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, []*core.PostFormated, error) { + posts, err := s.Ds.GetPosts(conditions, offset, limit) + if err != nil { + return nil, nil, err + } + postFormated, err := s.Ds.MergePosts(posts) + return posts, postFormated, err +} + func newCoreSrv(s *base.DaoServant, ts core.TweetSearchService, oss core.ObjectStorageService) api.Core { return &coreSrv{ DaoServant: s, diff --git a/mirc/web/v1/core.go b/mirc/web/v1/core.go index 1500e3db..529f15de 100644 --- a/mirc/web/v1/core.go +++ b/mirc/web/v1/core.go @@ -16,19 +16,19 @@ type Core struct { Group Group `mir:"v1"` // SyncSearchIndex 同步索引 - SyncSearchIndex func(Get) `mir:"/sync/index"` + SyncSearchIndex func(Get, web.SyncSearchIndexReq) `mir:"/sync/index"` // GetUserInfo 获取当前用户信息 GetUserInfo func(Get, web.UserInfoReq) web.UserInfoResp `mir:"/user/info"` // GetUnreadMsgCount 获取当前用户未读消息数量 - GetUnreadMsgCount func(Get) `mir:"/user/msgcount/unread"` + GetUnreadMsgCount func(Get, web.GetUnreadMsgCountReq) web.GetUnreadMsgCountResp `mir:"/user/msgcount/unread"` // GetMessages 获取消息列表 - GetMessages func(Get) `mir:"/user/messages"` + GetMessages func(Get, web.GetMessagesReq) web.GetMessagesResp `mir:"/user/messages"` // ReadMessage 标记消息已读 - ReadMessage func(Post) `mir:"/user/message/read"` + ReadMessage func(Post, web.ReadMessageReq) `mir:"/user/message/read"` // SendUserWhisper 发送用户私信 SendUserWhisper func(Post) `mir:"/user/whisper"`