From 64527ec6b206cd8de3f3852c7b45a06ac5b53a4b Mon Sep 17 00:00:00 2001 From: Michael Li Date: Thu, 29 Dec 2022 12:09:46 +0800 Subject: [PATCH] mir:add core api implement for new web service --- auto/api/v1/alipay_priv.go | 9 +- auto/api/v1/core.go | 243 ++++++++++++++++++------ internal/model/web/admin.go | 6 +- internal/model/web/alipay.go | 8 +- internal/model/web/core.go | 87 +++++++-- internal/model/web/web.go | 24 +++ internal/servants/base/base.go | 9 +- internal/servants/web/alipay.go | 5 +- internal/servants/web/core.go | 317 ++++++++++++++++++++++++++++++-- internal/servants/web/utils.go | 47 +++++ mirc/web/v1/core.go | 20 +- 11 files changed, 656 insertions(+), 119 deletions(-) create mode 100644 internal/servants/web/utils.go diff --git a/auto/api/v1/alipay_priv.go b/auto/api/v1/alipay_priv.go index 152465a0..4cb3fe0a 100644 --- a/auto/api/v1/alipay_priv.go +++ b/auto/api/v1/alipay_priv.go @@ -8,14 +8,13 @@ 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 AlipayPriv interface { // Chain provide handlers chain for gin Chain() gin.HandlersChain - UserWalletBills(*web.UserWalletBillsReq) (*base.PageResp, mir.Error) + UserWalletBills(*web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error) UserRechargeResult(*web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error) UserRechargeLink(*web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) @@ -31,7 +30,7 @@ type AlipayPrivBinding interface { } type AlipayPrivRender interface { - RenderUserWalletBills(*gin.Context, *base.PageResp, mir.Error) + RenderUserWalletBills(*gin.Context, *web.UserWalletBillsResp, mir.Error) RenderUserRechargeResult(*gin.Context, *web.UserRechargeResultResp, mir.Error) RenderUserRechargeLink(*gin.Context, *web.UserRechargeLinkResp, mir.Error) @@ -104,7 +103,7 @@ func (UnimplementedAlipayPrivServant) Chain() gin.HandlersChain { return nil } -func (UnimplementedAlipayPrivServant) UserWalletBills(req *web.UserWalletBillsReq) (*base.PageResp, mir.Error) { +func (UnimplementedAlipayPrivServant) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error) { return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -123,7 +122,7 @@ type UnimplementedAlipayPrivRender struct { RenderAny func(*gin.Context, any, mir.Error) } -func (r *UnimplementedAlipayPrivRender) RenderUserWalletBills(c *gin.Context, data *base.PageResp, err mir.Error) { +func (r *UnimplementedAlipayPrivRender) RenderUserWalletBills(c *gin.Context, data *web.UserWalletBillsResp, err mir.Error) { r.RenderAny(c, data, err) } diff --git a/auto/api/v1/core.go b/auto/api/v1/core.go index b49f480b..8e633c53 100644 --- a/auto/api/v1/core.go +++ b/auto/api/v1/core.go @@ -8,26 +8,25 @@ 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 { // Chain provide handlers chain for gin Chain() gin.HandlersChain - TweetCollectionStatus() mir.Error - TweetStarStatus() mir.Error - SuggestTags() mir.Error - SuggestUsers() mir.Error + TweetCollectionStatus(*web.TweetCollectionStatusReq) (*web.TweetCollectionStatusResp, mir.Error) + TweetStarStatus(*web.TweetStarStatusReq) (*web.TweetStarStatusResp, mir.Error) + SuggestTags(*web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) + SuggestUsers(*web.SuggestUsersReq) (*web.SuggestUsersResp, mir.Error) ChangeAvatar(*web.ChangeAvatarReq) mir.Error - ChangeNickname() mir.Error - ChangePassword() mir.Error - UserPhoneBind() mir.Error - GetStars() mir.Error - GetCollections() mir.Error - SendUserWhisper() mir.Error + ChangeNickname(*web.ChangeNicknameReq) mir.Error + ChangePassword(*web.ChangePasswordReq) mir.Error + UserPhoneBind(*web.UserPhoneBindReq) mir.Error + GetStars(*web.GetStarsReq) (*web.GetStarsResp, mir.Error) + GetCollections(*web.GetCollectionsReq) (*web.GetCollectionsResp, mir.Error) + SendUserWhisper(*web.SendWhisperReq) mir.Error ReadMessage(*web.ReadMessageReq) mir.Error - GetMessages(*web.GetMessagesReq) (*base.PageResp, mir.Error) + GetMessages(*web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) GetUnreadMsgCount(*web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) GetUserInfo(*web.UserInfoReq) (*web.UserInfoResp, mir.Error) SyncSearchIndex(*web.SyncSearchIndexReq) mir.Error @@ -36,7 +35,17 @@ type Core interface { } type CoreBinding interface { + BindTweetCollectionStatus(*gin.Context) (*web.TweetCollectionStatusReq, mir.Error) + BindTweetStarStatus(*gin.Context) (*web.TweetStarStatusReq, mir.Error) + BindSuggestTags(*gin.Context) (*web.SuggestTagsReq, mir.Error) + BindSuggestUsers(*gin.Context) (*web.SuggestUsersReq, mir.Error) BindChangeAvatar(*gin.Context) (*web.ChangeAvatarReq, mir.Error) + BindChangeNickname(*gin.Context) (*web.ChangeNicknameReq, mir.Error) + BindChangePassword(*gin.Context) (*web.ChangePasswordReq, mir.Error) + BindUserPhoneBind(*gin.Context) (*web.UserPhoneBindReq, mir.Error) + BindGetStars(*gin.Context) (*web.GetStarsReq, mir.Error) + BindGetCollections(*gin.Context) (*web.GetCollectionsReq, mir.Error) + BindSendUserWhisper(*gin.Context) (*web.SendWhisperReq, mir.Error) BindReadMessage(*gin.Context) (*web.ReadMessageReq, mir.Error) BindGetMessages(*gin.Context) (*web.GetMessagesReq, mir.Error) BindGetUnreadMsgCount(*gin.Context) (*web.GetUnreadMsgCountReq, mir.Error) @@ -47,19 +56,19 @@ type CoreBinding interface { } type CoreRender interface { - RenderTweetCollectionStatus(*gin.Context, mir.Error) - RenderTweetStarStatus(*gin.Context, mir.Error) - RenderSuggestTags(*gin.Context, mir.Error) - RenderSuggestUsers(*gin.Context, mir.Error) + RenderTweetCollectionStatus(*gin.Context, *web.TweetCollectionStatusResp, mir.Error) + RenderTweetStarStatus(*gin.Context, *web.TweetStarStatusResp, mir.Error) + RenderSuggestTags(*gin.Context, *web.SuggestTagsResp, mir.Error) + RenderSuggestUsers(*gin.Context, *web.SuggestUsersResp, mir.Error) RenderChangeAvatar(*gin.Context, mir.Error) RenderChangeNickname(*gin.Context, mir.Error) RenderChangePassword(*gin.Context, mir.Error) RenderUserPhoneBind(*gin.Context, mir.Error) - RenderGetStars(*gin.Context, mir.Error) - RenderGetCollections(*gin.Context, mir.Error) + RenderGetStars(*gin.Context, *web.GetStarsResp, mir.Error) + RenderGetCollections(*gin.Context, *web.GetCollectionsResp, mir.Error) RenderSendUserWhisper(*gin.Context, mir.Error) RenderReadMessage(*gin.Context, mir.Error) - RenderGetMessages(*gin.Context, *base.PageResp, mir.Error) + RenderGetMessages(*gin.Context, *web.GetMessagesResp, mir.Error) RenderGetUnreadMsgCount(*gin.Context, *web.GetUnreadMsgCountResp, mir.Error) RenderGetUserInfo(*gin.Context, *web.UserInfoResp, mir.Error) RenderSyncSearchIndex(*gin.Context, mir.Error) @@ -82,7 +91,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderTweetCollectionStatus(c, s.TweetCollectionStatus()) + req, err := b.BindTweetCollectionStatus(c) + if err != nil { + r.RenderTweetCollectionStatus(c, nil, err) + return + } + resp, err := s.TweetCollectionStatus(req) + r.RenderTweetCollectionStatus(c, resp, err) }) router.Handle("GET", "/post/star", func(c *gin.Context) { @@ -92,7 +107,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderTweetStarStatus(c, s.TweetStarStatus()) + req, err := b.BindTweetStarStatus(c) + if err != nil { + r.RenderTweetStarStatus(c, nil, err) + return + } + resp, err := s.TweetStarStatus(req) + r.RenderTweetStarStatus(c, resp, err) }) router.Handle("GET", "/suggest/tags", func(c *gin.Context) { @@ -102,7 +123,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderSuggestTags(c, s.SuggestTags()) + req, err := b.BindSuggestTags(c) + if err != nil { + r.RenderSuggestTags(c, nil, err) + return + } + resp, err := s.SuggestTags(req) + r.RenderSuggestTags(c, resp, err) }) router.Handle("GET", "/suggest/users", func(c *gin.Context) { @@ -112,7 +139,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderSuggestUsers(c, s.SuggestUsers()) + req, err := b.BindSuggestUsers(c) + if err != nil { + r.RenderSuggestUsers(c, nil, err) + return + } + resp, err := s.SuggestUsers(req) + r.RenderSuggestUsers(c, resp, err) }) router.Handle("POST", "/user/avatar", func(c *gin.Context) { @@ -137,7 +170,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderChangeNickname(c, s.ChangeNickname()) + req, err := b.BindChangeNickname(c) + if err != nil { + r.RenderChangeNickname(c, err) + return + } + r.RenderChangeNickname(c, s.ChangeNickname(req)) }) router.Handle("POST", "/user/password", func(c *gin.Context) { @@ -147,7 +185,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderChangePassword(c, s.ChangePassword()) + req, err := b.BindChangePassword(c) + if err != nil { + r.RenderChangePassword(c, err) + return + } + r.RenderChangePassword(c, s.ChangePassword(req)) }) router.Handle("POST", "/user/phone", func(c *gin.Context) { @@ -157,7 +200,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderUserPhoneBind(c, s.UserPhoneBind()) + req, err := b.BindUserPhoneBind(c) + if err != nil { + r.RenderUserPhoneBind(c, err) + return + } + r.RenderUserPhoneBind(c, s.UserPhoneBind(req)) }) router.Handle("GET", "/user/stars", func(c *gin.Context) { @@ -167,7 +215,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderGetStars(c, s.GetStars()) + req, err := b.BindGetStars(c) + if err != nil { + r.RenderGetStars(c, nil, err) + return + } + resp, err := s.GetStars(req) + r.RenderGetStars(c, resp, err) }) router.Handle("GET", "/user/collections", func(c *gin.Context) { @@ -177,7 +231,13 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderGetCollections(c, s.GetCollections()) + req, err := b.BindGetCollections(c) + if err != nil { + r.RenderGetCollections(c, nil, err) + return + } + resp, err := s.GetCollections(req) + r.RenderGetCollections(c, resp, err) }) router.Handle("POST", "/user/whisper", func(c *gin.Context) { @@ -187,7 +247,12 @@ func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) { default: } - r.RenderSendUserWhisper(c, s.SendUserWhisper()) + req, err := b.BindSendUserWhisper(c) + if err != nil { + r.RenderSendUserWhisper(c, err) + return + } + r.RenderSendUserWhisper(c, s.SendUserWhisper(req)) }) router.Handle("POST", "/user/message/read", func(c *gin.Context) { @@ -278,47 +343,47 @@ func (UnimplementedCoreServant) Chain() gin.HandlersChain { return nil } -func (UnimplementedCoreServant) TweetCollectionStatus() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) TweetCollectionStatus(req *web.TweetCollectionStatusReq) (*web.TweetCollectionStatusResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) TweetStarStatus() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) TweetStarStatus(req *web.TweetStarStatusReq) (*web.TweetStarStatusResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) SuggestTags() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) SuggestTags(req *web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) SuggestUsers() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) SuggestUsers(req *web.SuggestUsersReq) (*web.SuggestUsersResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } func (UnimplementedCoreServant) ChangeAvatar(req *web.ChangeAvatarReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) ChangeNickname() mir.Error { +func (UnimplementedCoreServant) ChangeNickname(req *web.ChangeNicknameReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) ChangePassword() mir.Error { +func (UnimplementedCoreServant) ChangePassword(req *web.ChangePasswordReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) UserPhoneBind() mir.Error { +func (UnimplementedCoreServant) UserPhoneBind(req *web.UserPhoneBindReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) GetStars() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) GetCollections() mir.Error { - return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) +func (UnimplementedCoreServant) GetCollections(req *web.GetCollectionsReq) (*web.GetCollectionsResp, mir.Error) { + return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) SendUserWhisper() mir.Error { +func (UnimplementedCoreServant) SendUserWhisper(req *web.SendWhisperReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -326,7 +391,7 @@ func (UnimplementedCoreServant) ReadMessage(req *web.ReadMessageReq) mir.Error { return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } -func (UnimplementedCoreServant) GetMessages(req *web.GetMessagesReq) (*base.PageResp, mir.Error) { +func (UnimplementedCoreServant) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) { return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented)) } @@ -349,20 +414,20 @@ type UnimplementedCoreRender struct { RenderAny func(*gin.Context, any, mir.Error) } -func (r *UnimplementedCoreRender) RenderTweetCollectionStatus(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderTweetCollectionStatus(c *gin.Context, data *web.TweetCollectionStatusResp, err mir.Error) { + r.RenderAny(c, data, err) } -func (r *UnimplementedCoreRender) RenderTweetStarStatus(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderTweetStarStatus(c *gin.Context, data *web.TweetStarStatusResp, err mir.Error) { + r.RenderAny(c, data, err) } -func (r *UnimplementedCoreRender) RenderSuggestTags(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderSuggestTags(c *gin.Context, data *web.SuggestTagsResp, err mir.Error) { + r.RenderAny(c, data, err) } -func (r *UnimplementedCoreRender) RenderSuggestUsers(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderSuggestUsers(c *gin.Context, data *web.SuggestUsersResp, err mir.Error) { + r.RenderAny(c, data, err) } func (r *UnimplementedCoreRender) RenderChangeAvatar(c *gin.Context, err mir.Error) { @@ -381,12 +446,12 @@ func (r *UnimplementedCoreRender) RenderUserPhoneBind(c *gin.Context, err mir.Er r.RenderAny(c, nil, err) } -func (r *UnimplementedCoreRender) RenderGetStars(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderGetStars(c *gin.Context, data *web.GetStarsResp, err mir.Error) { + r.RenderAny(c, data, err) } -func (r *UnimplementedCoreRender) RenderGetCollections(c *gin.Context, err mir.Error) { - r.RenderAny(c, nil, err) +func (r *UnimplementedCoreRender) RenderGetCollections(c *gin.Context, data *web.GetCollectionsResp, err mir.Error) { + r.RenderAny(c, data, err) } func (r *UnimplementedCoreRender) RenderSendUserWhisper(c *gin.Context, err mir.Error) { @@ -397,7 +462,7 @@ func (r *UnimplementedCoreRender) RenderReadMessage(c *gin.Context, err mir.Erro r.RenderAny(c, nil, err) } -func (r *UnimplementedCoreRender) RenderGetMessages(c *gin.Context, data *base.PageResp, err mir.Error) { +func (r *UnimplementedCoreRender) RenderGetMessages(c *gin.Context, data *web.GetMessagesResp, err mir.Error) { r.RenderAny(c, data, err) } @@ -420,12 +485,72 @@ type UnimplementedCoreBinding struct { BindAny func(*gin.Context, any) mir.Error } +func (b *UnimplementedCoreBinding) BindTweetCollectionStatus(c *gin.Context) (*web.TweetCollectionStatusReq, mir.Error) { + obj := new(web.TweetCollectionStatusReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindTweetStarStatus(c *gin.Context) (*web.TweetStarStatusReq, mir.Error) { + obj := new(web.TweetStarStatusReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindSuggestTags(c *gin.Context) (*web.SuggestTagsReq, mir.Error) { + obj := new(web.SuggestTagsReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindSuggestUsers(c *gin.Context) (*web.SuggestUsersReq, mir.Error) { + obj := new(web.SuggestUsersReq) + err := b.BindAny(c, obj) + return obj, err +} + func (b *UnimplementedCoreBinding) BindChangeAvatar(c *gin.Context) (*web.ChangeAvatarReq, mir.Error) { obj := new(web.ChangeAvatarReq) err := b.BindAny(c, obj) return obj, err } +func (b *UnimplementedCoreBinding) BindChangeNickname(c *gin.Context) (*web.ChangeNicknameReq, mir.Error) { + obj := new(web.ChangeNicknameReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindChangePassword(c *gin.Context) (*web.ChangePasswordReq, mir.Error) { + obj := new(web.ChangePasswordReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindUserPhoneBind(c *gin.Context) (*web.UserPhoneBindReq, mir.Error) { + obj := new(web.UserPhoneBindReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindGetStars(c *gin.Context) (*web.GetStarsReq, mir.Error) { + obj := new(web.GetStarsReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindGetCollections(c *gin.Context) (*web.GetCollectionsReq, mir.Error) { + obj := new(web.GetCollectionsReq) + err := b.BindAny(c, obj) + return obj, err +} + +func (b *UnimplementedCoreBinding) BindSendUserWhisper(c *gin.Context) (*web.SendWhisperReq, mir.Error) { + obj := new(web.SendWhisperReq) + err := b.BindAny(c, obj) + return obj, err +} + func (b *UnimplementedCoreBinding) BindReadMessage(c *gin.Context) (*web.ReadMessageReq, mir.Error) { obj := new(web.ReadMessageReq) err := b.BindAny(c, obj) diff --git a/internal/model/web/admin.go b/internal/model/web/admin.go index ec312f2c..6b1980ca 100644 --- a/internal/model/web/admin.go +++ b/internal/model/web/admin.go @@ -5,7 +5,7 @@ package web type ChangeUserStatusReq struct { - *BaseInfo `json:"-" binding:"-"` - ID int64 `json:"id" form:"id" binding:"required"` - Status int `json:"status" form:"status" binding:"required,oneof=1 2"` + BaseInfo `json:"-" binding:"-"` + ID int64 `json:"id" form:"id" binding:"required"` + Status int `json:"status" form:"status" binding:"required,oneof=1 2"` } diff --git a/internal/model/web/alipay.go b/internal/model/web/alipay.go index b431f8d2..84746309 100644 --- a/internal/model/web/alipay.go +++ b/internal/model/web/alipay.go @@ -17,12 +17,12 @@ type UserWalletBillsReq struct { PageSize int } -type UserWalletBillsResp = base.PageResp +type UserWalletBillsResp base.PageResp type UserRechargeLinkReq struct { - *BaseInfo `json:"-" form:"-" binding:"-"` - Host string `json:"-" form:"-" binding:"-"` - Amount int64 `json:"amount" form:"amount" binding:"required"` + BaseInfo `json:"-" form:"-" binding:"-"` + Host string `json:"-" form:"-" binding:"-"` + Amount int64 `json:"amount" form:"amount" binding:"required"` } type UserRechargeLinkResp struct { diff --git a/internal/model/web/core.go b/internal/model/web/core.go index 3da85471..c0e44e85 100644 --- a/internal/model/web/core.go +++ b/internal/model/web/core.go @@ -11,18 +11,18 @@ import ( ) type ChangeAvatarReq struct { - *BaseInfo `json:"-" binding:"-"` + BaseInfo `json:"-" binding:"-"` + Avatar string `json:"avatar" form:"avatar" binding:"required"` } type SyncSearchIndexReq struct { - *BaseInfo `json:"-" binding:"-"` - - Ctx context.Context `json:"-" binding:"-"` + BaseInfo `json:"-" binding:"-"` + Ctx context.Context `json:"-" binding:"-"` } type UserInfoReq struct { - *BaseInfo `json:"-" binding:"-"` - Username string `json:"username" form:"username" binding:"required"` + BaseInfo `json:"-" binding:"-"` + Username string `json:"username" form:"username" binding:"required"` } type UserInfoResp struct { @@ -37,23 +37,80 @@ type UserInfoResp struct { } type GetUnreadMsgCountReq struct { - *SimpleInfo `json:"-" binding:"-"` + SimpleInfo `json:"-" binding:"-"` } type GetUnreadMsgCountResp struct { Count int64 `json:"count"` } -type GetMessagesReq struct { - UserId int64 - Page int - PageSize int -} +type GetMessagesReq BasePageReq -type GetMessagesResp = base.PageResp +type GetMessagesResp base.PageResp type ReadMessageReq struct { - *SimpleInfo `json:"-" binding:"-"` + SimpleInfo `json:"-" binding:"-"` + ID int64 `json:"id" binding:"required"` +} +type SendWhisperReq struct { + SimpleInfo `json:"-" binding:"-"` + UserID int64 `json:"user_id" binding:"required"` + Content string `json:"content" binding:"required"` +} + +type GetCollectionsReq BasePageReq +type GetCollectionsResp base.PageResp + +type GetStarsReq BasePageReq +type GetStarsResp base.PageResp + +type UserPhoneBindReq struct { + BaseInfo `json:"-" binding:"-"` + Phone string `json:"phone" form:"phone" binding:"required"` + Captcha string `json:"captcha" form:"captcha" binding:"required"` +} + +type ChangePasswordReq struct { + BaseInfo `json:"-" binding:"-"` + Password string `json:"password" form:"password" binding:"required"` + OldPassword string `json:"old_password" form:"old_password" binding:"required"` +} + +type ChangeNicknameReq struct { + BaseInfo `json:"-" binding:"-"` + Nickname string `json:"nickname" form:"nickname" binding:"required"` +} + +type SuggestUsersReq struct { + Keyword string +} + +type SuggestUsersResp struct { + Suggests []string `json:"suggests"` +} + +type SuggestTagsReq struct { + Keyword string +} + +type SuggestTagsResp struct { + Suggests []string `json:"suggests"` +} + +type TweetStarStatusReq struct { + SimpleInfo `json:"-" binding:"-"` + TweetId int64 `form:"id"` +} + +type TweetStarStatusResp struct { + Status bool `json:"status"` +} + +type TweetCollectionStatusReq struct { + SimpleInfo `json:"-" binding:"-"` + TweetId int64 `form:"id"` +} - ID int64 `json:"id" binding:"required"` +type TweetCollectionStatusResp struct { + Status bool `json:"status"` } diff --git a/internal/model/web/web.go b/internal/model/web/web.go index bcddea3a..a4a8941f 100644 --- a/internal/model/web/web.go +++ b/internal/model/web/web.go @@ -5,7 +5,12 @@ package web import ( + "github.com/alimy/mir/v3" + "github.com/gin-gonic/gin" "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/internal/servants/base" + "github.com/rocboss/paopao-ce/pkg/app" + "github.com/rocboss/paopao-ce/pkg/xerror" ) type BaseInfo struct { @@ -16,6 +21,12 @@ type SimpleInfo struct { Uid int64 } +type BasePageReq struct { + UserId int64 + Page int + PageSize int +} + func (b *BaseInfo) SetUser(user *core.User) { b.User = user } @@ -23,3 +34,16 @@ func (b *BaseInfo) SetUser(user *core.User) { func (s *SimpleInfo) SetUserId(id int64) { s.Uid = id } + +func BasePageReqFrom(c *gin.Context) (*BasePageReq, mir.Error) { + uid, ok := base.UserIdFrom(c) + if !ok { + return nil, xerror.UnauthorizedTokenError + } + page, pageSize := app.GetPageOffset(c) + return &BasePageReq{ + UserId: uid, + Page: page, + PageSize: pageSize, + }, nil +} diff --git a/internal/servants/base/base.go b/internal/servants/base/base.go index abbe8944..dc1bbb9e 100644 --- a/internal/servants/base/base.go +++ b/internal/servants/base/base.go @@ -11,6 +11,7 @@ import ( "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/xerror" ) @@ -23,13 +24,9 @@ type DaoServant struct { Ds core.DataService } -type BaseBinding struct { - // TODO -} +type BaseBinding types.Empty -type BaseRender struct { - // TODO -} +type BaseRender types.Empty type JsonResp struct { Code int `json:"code"` diff --git a/internal/servants/web/alipay.go b/internal/servants/web/alipay.go index 9420ffe4..ab8401f7 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) (*base.PageResp, mir.Error) { +func (s *alipayPrivSrv) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserWalletBillsResp, 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) @@ -147,7 +147,8 @@ func (s *alipayPrivSrv) UserWalletBills(req *web.UserWalletBillsReq) (*base.Page logrus.Errorf("GetUserWalletBillCount err: %s", err) return nil, _errUserWalletBillsFailed } - return base.PageRespFrom(bills, req.Page, req.PageSize, totalRows), nil + resp := base.PageRespFrom(bills, req.Page, req.PageSize, totalRows) + return (*web.UserWalletBillsResp)(resp), nil } func (s *alipayPrivSrv) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) { diff --git a/internal/servants/web/core.go b/internal/servants/web/core.go index 102a7554..65c49fcb 100644 --- a/internal/servants/web/core.go +++ b/internal/servants/web/core.go @@ -9,7 +9,9 @@ import ( "fmt" "math" "time" + "unicode/utf8" + "github.com/alimy/cfg" "github.com/alimy/mir/v3" "github.com/gin-gonic/gin" api "github.com/rocboss/paopao-ce/auto/api/v1" @@ -17,15 +19,23 @@ import ( "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/convert" "github.com/rocboss/paopao-ce/pkg/xerror" "github.com/sirupsen/logrus" ) +const ( + // _MaxWhisperNumDaily 当日单用户私信总数限制(TODO 配置化、积分兑换等) + _MaxWhisperNumDaily = 20 + _MaxCaptchaTimes = 2 +) + var ( _ api.Core = (*coreSrv)(nil) _ api.CoreBinding = (*coreBinding)(nil) _ api.CoreRender = (*coreRender)(nil) + + _EnablePhoneVerify = cfg.If("Sms") ) type coreSrv struct { @@ -38,6 +48,7 @@ type coreSrv struct { type coreBinding struct { *api.UnimplementedCoreBinding + base.BaseBinding } type coreRender struct { @@ -47,7 +58,7 @@ type coreRender struct { func (b *coreBinding) BindSyncSearchIndex(c *gin.Context) (*web.SyncSearchIndexReq, mir.Error) { user, _ := base.UserFrom(c) return &web.SyncSearchIndexReq{ - BaseInfo: &web.BaseInfo{ + BaseInfo: web.BaseInfo{ User: user, }, Ctx: c.Request.Context(), @@ -55,8 +66,8 @@ func (b *coreBinding) BindSyncSearchIndex(c *gin.Context) (*web.SyncSearchIndexR } func (b *coreBinding) BindGetUserInfo(c *gin.Context) (*web.UserInfoReq, mir.Error) { - username, exists := base.UserNameFrom(c) - if !exists { + username, exist := base.UserNameFrom(c) + if !exist { return nil, xerror.UnauthorizedAuthNotExist } return &web.UserInfoReq{ @@ -65,15 +76,55 @@ func (b *coreBinding) BindGetUserInfo(c *gin.Context) (*web.UserInfoReq, mir.Err } 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, + v, err := web.BasePageReqFrom(c) + return (*web.GetMessagesReq)(v), err +} + +func (b *coreBinding) BindGetCollections(c *gin.Context) (*web.GetCollectionsReq, mir.Error) { + v, err := web.BasePageReqFrom(c) + return (*web.GetCollectionsReq)(v), err +} + +func (b *coreBinding) BindGetStars(c *gin.Context) (*web.GetStarsReq, mir.Error) { + v, err := web.BasePageReqFrom(c) + return (*web.GetStarsReq)(v), err +} + +func (b *coreBinding) BindSuggestTags(c *gin.Context) (*web.SuggestTagsReq, mir.Error) { + return &web.SuggestTagsReq{ + Keyword: c.Query("k"), + }, nil +} + +func (b *coreBinding) BindSuggestUsers(c *gin.Context) (*web.SuggestUsersReq, mir.Error) { + return &web.SuggestUsersReq{ + Keyword: c.Query("k"), + }, nil +} + +func (b *coreBinding) BindTweetCollectionStatus(c *gin.Context) (*web.TweetCollectionStatusReq, mir.Error) { + UserId, exist := base.UserIdFrom(c) + if !exist { + return nil, xerror.UnauthorizedAuthNotExist + } + return &web.TweetCollectionStatusReq{ + SimpleInfo: web.SimpleInfo{ + Uid: UserId, + }, + TweetId: convert.StrTo(c.Query("id")).MustInt64(), + }, nil +} + +func (b *coreBinding) BindTweetStarStatus(c *gin.Context) (*web.TweetStarStatusReq, mir.Error) { + UserId, exist := base.UserIdFrom(c) + if !exist { + return nil, xerror.UnauthorizedAuthNotExist + } + return &web.TweetStarStatusReq{ + SimpleInfo: web.SimpleInfo{ + Uid: UserId, + }, + TweetId: convert.StrTo(c.Query("id")).MustInt64(), }, nil } @@ -121,7 +172,7 @@ func (s *coreSrv) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnre }, nil } -func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*base.PageResp, mir.Error) { +func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) { conditions := &core.ConditionsT{ "receiver_user_id": req.UserId, "ORDER": "id DESC", @@ -162,7 +213,8 @@ func (s *coreSrv) GetMessages(req *web.GetMessagesReq) (*base.PageResp, mir.Erro return nil, _errGetMessagesFailed } totalRows, _ := s.Ds.GetMessageCount(conditions) - return base.PageRespFrom(messages, req.Page, req.PageSize, totalRows), nil + resp := base.PageRespFrom(messages, req.Page, req.PageSize, totalRows) + return (*web.GetMessagesResp)(resp), nil } func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error { @@ -180,6 +232,219 @@ func (s *coreSrv) ReadMessage(req *web.ReadMessageReq) mir.Error { return nil } +func (s *coreSrv) SendUserWhisper(req *web.SendWhisperReq) mir.Error { + // 不允许发送私信给自己 + if req.Uid == req.UserID { + return _errNoWhisperToSelf + } + + // 今日频次限制 + ctx := context.Background() + whisperKey := fmt.Sprintf("WhisperTimes:%d", req.Uid) + if res, _ := s.Redis.Get(ctx, whisperKey).Result(); convert.StrTo(res).MustInt() >= _MaxWhisperNumDaily { + return _errTooManyWhisperNum + } + + // 创建私信 + _, err := s.Ds.CreateMessage(&core.Message{ + SenderUserID: req.Uid, + ReceiverUserID: req.UserID, + Type: core.MsgTypeWhisper, + Brief: "给你发送新私信了", + Content: req.Content, + }) + if err != nil { + logrus.Errorf("Ds.CreateWhisper err: %s", err) + return _errSendWhisperFailed + } + + // 写入当日(自然日)计数缓存 + s.Redis.Incr(ctx, whisperKey).Result() + currentTime := time.Now() + endTime := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 23, 59, 59, 0, currentTime.Location()) + s.Redis.Expire(ctx, whisperKey, endTime.Sub(currentTime)) + + return nil +} + +func (s *coreSrv) GetCollections(req *web.GetCollectionsReq) (*web.GetCollectionsResp, mir.Error) { + collections, err := s.Ds.GetUserPostCollections(req.UserId, (req.Page-1)*req.PageSize, req.PageSize) + if err != nil { + logrus.Errorf("Ds.GetUserPostCollections err: %s", err) + return nil, _errGetCollectionsFailed + } + totalRows, err := s.Ds.GetUserPostCollectionCount(req.UserId) + if err != nil { + logrus.Errorf("Ds.GetUserPostCollectionCount err: %s", err) + return nil, _errGetCollectionsFailed + } + + var posts []*core.Post + for _, collection := range collections { + posts = append(posts, collection.Post) + } + postsFormated, err := s.Ds.MergePosts(posts) + if err != nil { + logrus.Errorf("Ds.MergePosts err: %s", err) + return nil, _errGetCollectionsFailed + } + resp := base.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows) + + return (*web.GetCollectionsResp)(resp), nil +} + +func (s *coreSrv) UserPhoneBind(req *web.UserPhoneBindReq) mir.Error { + // 手机重复性检查 + u, err := s.Ds.GetUserByPhone(req.Phone) + if err != nil { + logrus.Errorf("Ds.GetUserByPhone err: %v", err) + return _errExistedUserPhone + } + if u.Model == nil || u.ID == 0 { + return _errExistedUserPhone + } + if u.ID == req.User.ID { + return _errExistedUserPhone + } + + // 如果禁止phone verify 则允许通过任意验证码 + if !_EnablePhoneVerify { + c, err := s.Ds.GetLatestPhoneCaptcha(req.Phone) + if err != nil { + return _errErrorPhoneCaptcha + } + if c.Captcha != req.Captcha { + return _errErrorPhoneCaptcha + } + if c.ExpiredOn < time.Now().Unix() { + return _errErrorPhoneCaptcha + } + if c.UseTimes >= _MaxCaptchaTimes { + return _errMaxPhoneCaptchaUseTimes + } + // 更新检测次数 + s.Ds.UsePhoneCaptcha(c) + } + + // 执行绑定 + user := req.User + user.Phone = req.Phone + if err := s.Ds.UpdateUser(user); err != nil { + // TODO: 优化错误处理逻辑,失败后上面的逻辑也应该回退 + logrus.Errorf("Ds.UpdateUser err: %s", err) + return xerror.ServerError + } + return nil +} + +func (s *coreSrv) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) { + stars, err := s.Ds.GetUserPostStars(req.UserId, (req.Page-1)*req.PageSize, req.PageSize) + if err != nil { + logrus.Errorf("Ds.GetUserPostStars err: %s", err) + return nil, _errGetStarsFailed + } + totalRows, err := s.Ds.GetUserPostStarCount(req.UserId) + if err != nil { + logrus.Errorf("Ds.GetUserPostStars err: %s", err) + return nil, _errGetStarsFailed + } + + var posts []*core.Post + for _, star := range stars { + posts = append(posts, star.Post) + } + postsFormated, err := s.Ds.MergePosts(posts) + if err != nil { + logrus.Errorf("Ds.MergePosts err: %s", err) + return nil, _errGetStarsFailed + } + resp := base.PageRespFrom(postsFormated, req.Page, req.PageSize, totalRows) + + return (*web.GetStarsResp)(resp), nil +} + +func (s *coreSrv) ChangePassword(req *web.ChangePasswordReq) mir.Error { + // 密码检查 + if err := checkPassword(req.Password); err != nil { + return err + } + // 旧密码校验 + user := req.User + if !validPassword(user.Password, req.OldPassword, req.User.Salt) { + return _errErrorOldPassword + } + // 更新入库 + user.Password, user.Salt = encryptPasswordAndSalt(req.Password) + if err := s.Ds.UpdateUser(user); err != nil { + logrus.Errorf("Ds.UpdateUser err: %s", err) + return xerror.ServerError + } + return nil +} + +func (s *coreSrv) SuggestTags(req *web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) { + tags, err := s.Ds.GetTagsByKeyword(req.Keyword) + if err != nil { + logrus.Errorf("Ds.GetTagsByKeyword err: %s", err) + return nil, xerror.ServerError + } + resp := &web.SuggestTagsResp{} + for _, t := range tags { + resp.Suggests = append(resp.Suggests, t.Tag) + } + return resp, nil +} + +func (s *coreSrv) SuggestUsers(req *web.SuggestUsersReq) (*web.SuggestUsersResp, mir.Error) { + users, err := s.Ds.GetUsersByKeyword(req.Keyword) + if err != nil { + logrus.Errorf("Ds.GetUsersByKeyword err: %s", err) + return nil, xerror.ServerError + } + resp := &web.SuggestUsersResp{} + for _, user := range users { + resp.Suggests = append(resp.Suggests, user.Username) + } + return resp, nil +} + +func (s *coreSrv) ChangeNickname(req *web.ChangeNicknameReq) mir.Error { + if utf8.RuneCountInString(req.Nickname) < 2 || utf8.RuneCountInString(req.Nickname) > 12 { + return _errNicknameLengthLimit + } + user := req.User + user.Nickname = req.Nickname + if err := s.Ds.UpdateUser(user); err != nil { + logrus.Errorf("Ds.UpdateUser err: %s", err) + return xerror.ServerError + } + return nil +} + +func (s *coreSrv) ChangeAvatar(req *web.ChangeAvatarReq) (xerr mir.Error) { + defer func() { + if xerr != nil { + deleteOssObjects(s.oss, []string{req.Avatar}) + } + }() + + if err := s.Ds.CheckAttachment(req.Avatar); err != nil { + logrus.Errorf("Ds.CheckAttachment failed: %s", err) + return xerror.InvalidParams + } + if err := s.oss.PersistObject(s.oss.ObjectKey(req.Avatar)); err != nil { + logrus.Errorf("Ds.ChangeUserAvatar persist object failed: %s", err) + return xerror.ServerError + } + user := req.User + user.Avatar = req.Avatar + if err := s.Ds.UpdateUser(user); err != nil { + logrus.Errorf("Ds.UpdateUser failed: %s", err) + return xerror.ServerError + } + 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") @@ -212,6 +477,28 @@ func (s *coreSrv) pushPostsToSearch(c context.Context) { } } +func (s *coreSrv) TweetCollectionStatus(req *web.TweetCollectionStatusReq) (*web.TweetCollectionStatusResp, mir.Error) { + resp := &web.TweetCollectionStatusResp{ + Status: true, + } + if _, err := s.Ds.GetUserPostCollection(req.TweetId, req.Uid); err != nil { + resp.Status = false + return resp, nil + } + return resp, nil +} + +func (s *coreSrv) TweetStarStatus(req *web.TweetStarStatusReq) (*web.TweetStarStatusResp, mir.Error) { + resp := &web.TweetStarStatusResp{ + Status: true, + } + if _, err := s.Ds.GetUserPostStar(req.TweetId, req.Uid); err != nil { + resp.Status = false + return resp, nil + } + return resp, nil +} + func (s *coreSrv) deleteSearchPost(post *core.Post) error { return s.ts.DeleteDocuments([]string{fmt.Sprintf("%d", post.ID)}) } diff --git a/internal/servants/web/utils.go b/internal/servants/web/utils.go new file mode 100644 index 00000000..1b5a05d7 --- /dev/null +++ b/internal/servants/web/utils.go @@ -0,0 +1,47 @@ +package web + +import ( + "strings" + "unicode/utf8" + + "github.com/alimy/mir/v3" + "github.com/gofrs/uuid" + "github.com/rocboss/paopao-ce/internal/core" + "github.com/rocboss/paopao-ce/pkg/util" +) + +// checkPassword 密码检查 +func checkPassword(password string) mir.Error { + // 检测用户是否合规 + if utf8.RuneCountInString(password) < 6 || utf8.RuneCountInString(password) > 16 { + return _errPasswordLengthLimit + } + return nil +} + +// ValidPassword 检查密码是否一致 +func validPassword(dbPassword, password, salt string) bool { + return strings.Compare(dbPassword, util.EncodeMD5(util.EncodeMD5(password)+salt)) == 0 +} + +// encryptPasswordAndSalt 密码加密&生成salt +func encryptPasswordAndSalt(password string) (string, string) { + salt := uuid.Must(uuid.NewV4()).String()[:8] + password = util.EncodeMD5(util.EncodeMD5(password) + salt) + return password, salt +} + +// deleteOssObjects 删除推文的媒体内容, 宽松处理错误(就是不处理), 后续完善 +func deleteOssObjects(oss core.ObjectStorageService, mediaContents []string) { + mediaContentsSize := len(mediaContents) + if mediaContentsSize > 1 { + objectKeys := make([]string, 0, mediaContentsSize) + for _, cUrl := range mediaContents { + objectKeys = append(objectKeys, oss.ObjectKey(cUrl)) + } + // TODO: 优化处理尽量使用channel传递objectKeys使用可控数量的Goroutine集中处理object删除动作,后续完善 + go oss.DeleteObjects(objectKeys) + } else if mediaContentsSize == 1 { + oss.DeleteObject(oss.ObjectKey(mediaContents[0])) + } +} diff --git a/mirc/web/v1/core.go b/mirc/web/v1/core.go index 529f15de..af835074 100644 --- a/mirc/web/v1/core.go +++ b/mirc/web/v1/core.go @@ -31,35 +31,35 @@ type Core struct { ReadMessage func(Post, web.ReadMessageReq) `mir:"/user/message/read"` // SendUserWhisper 发送用户私信 - SendUserWhisper func(Post) `mir:"/user/whisper"` + SendUserWhisper func(Post, web.SendWhisperReq) `mir:"/user/whisper"` // GetCollections 获取用户收藏列表 - GetCollections func(Get) `mir:"/user/collections"` + GetCollections func(Get, web.GetCollectionsReq) web.GetCollectionsResp `mir:"/user/collections"` // GetStars 获取用户点赞列表 - GetStars func(Get) `mir:"/user/stars"` + GetStars func(Get, web.GetStarsReq) web.GetStarsResp `mir:"/user/stars"` // UserPhoneBind 绑定用户手机号 - UserPhoneBind func(Post) `mir:"/user/phone"` + UserPhoneBind func(Post, web.UserPhoneBindReq) `mir:"/user/phone"` // ChangePassword 修改密码 - ChangePassword func(Post) `mir:"/user/password"` + ChangePassword func(Post, web.ChangePasswordReq) `mir:"/user/password"` // ChangeNickname 修改昵称 - ChangeNickname func(Post) `mir:"/user/nickname"` + ChangeNickname func(Post, web.ChangeNicknameReq) `mir:"/user/nickname"` // ChangeAvatar 修改头像 ChangeAvatar func(Post, web.ChangeAvatarReq) `mir:"/user/avatar"` // SuggestUsers 检索用户 - SuggestUsers func(Get) `mir:"/suggest/users"` + SuggestUsers func(Get, web.SuggestUsersReq) web.SuggestUsersResp `mir:"/suggest/users"` // SuggestTags 检索标签 - SuggestTags func(Get) `mir:"/suggest/tags"` + SuggestTags func(Get, web.SuggestTagsReq) web.SuggestTagsResp `mir:"/suggest/tags"` // TweetStarStatus 获取动态点赞状态 - TweetStarStatus func(Get) `mir:"/post/star"` + TweetStarStatus func(Get, web.TweetStarStatusReq) web.TweetStarStatusResp `mir:"/post/star"` // TweetCollectionStatus 获取动态收藏状态 - TweetCollectionStatus func(Get) `mir:"/post/collection"` + TweetCollectionStatus func(Get, web.TweetCollectionStatusReq) web.TweetCollectionStatusResp `mir:"/post/collection"` }