mir: add alipay api implement for new web service

pull/196/head
Michael Li 2 years ago
parent da939f7c73
commit dee07b6184
No known key found for this signature in database

@ -8,29 +8,32 @@ 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) (*web.UserWalletBillsResp, mir.Error)
UserRechargeResult() mir.Error
UserRechargeLink() mir.Error
UserWalletBills(*web.UserWalletBillsReq) (*base.PageResp, mir.Error)
UserRechargeResult(*web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error)
UserRechargeLink(*web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error)
mustEmbedUnimplementedAlipayPrivServant()
}
type AlipayPrivBinding interface {
BindUserWalletBills(*gin.Context) (*web.UserWalletBillsReq, mir.Error)
BindUserRechargeResult(*gin.Context) (*web.UserRechargeResultReq, mir.Error)
BindUserRechargeLink(*gin.Context) (*web.UserRechargeLinkReq, mir.Error)
mustEmbedUnimplementedAlipayPrivBinding()
}
type AlipayPrivRender interface {
RenderUserWalletBills(*gin.Context, *web.UserWalletBillsResp, mir.Error)
RenderUserRechargeResult(*gin.Context, mir.Error)
RenderUserRechargeLink(*gin.Context, mir.Error)
RenderUserWalletBills(*gin.Context, *base.PageResp, mir.Error)
RenderUserRechargeResult(*gin.Context, *web.UserRechargeResultResp, mir.Error)
RenderUserRechargeLink(*gin.Context, *web.UserRechargeLinkResp, mir.Error)
mustEmbedUnimplementedAlipayPrivRender()
}
@ -66,7 +69,13 @@ func RegisterAlipayPrivServant(e *gin.Engine, s AlipayPriv, b AlipayPrivBinding,
default:
}
r.RenderUserRechargeResult(c, s.UserRechargeResult())
req, err := b.BindUserRechargeResult(c)
if err != nil {
r.RenderUserRechargeResult(c, nil, err)
return
}
resp, err := s.UserRechargeResult(req)
r.RenderUserRechargeResult(c, resp, err)
})
router.Handle("POST", "/user/recharge", func(c *gin.Context) {
@ -76,7 +85,13 @@ func RegisterAlipayPrivServant(e *gin.Engine, s AlipayPriv, b AlipayPrivBinding,
default:
}
r.RenderUserRechargeLink(c, s.UserRechargeLink())
req, err := b.BindUserRechargeLink(c)
if err != nil {
r.RenderUserRechargeLink(c, nil, err)
return
}
resp, err := s.UserRechargeLink(req)
r.RenderUserRechargeLink(c, resp, err)
})
}
@ -89,16 +104,16 @@ func (UnimplementedAlipayPrivServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedAlipayPrivServant) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error) {
func (UnimplementedAlipayPrivServant) UserWalletBills(req *web.UserWalletBillsReq) (*base.PageResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) UserRechargeResult() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
func (UnimplementedAlipayPrivServant) UserRechargeResult(req *web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) UserRechargeLink() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
func (UnimplementedAlipayPrivServant) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) mustEmbedUnimplementedAlipayPrivServant() {}
@ -108,16 +123,16 @@ type UnimplementedAlipayPrivRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedAlipayPrivRender) RenderUserWalletBills(c *gin.Context, data *web.UserWalletBillsResp, err mir.Error) {
func (r *UnimplementedAlipayPrivRender) RenderUserWalletBills(c *gin.Context, data *base.PageResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeResult(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeResult(c *gin.Context, data *web.UserRechargeResultResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeLink(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeLink(c *gin.Context, data *web.UserRechargeLinkResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) mustEmbedUnimplementedAlipayPrivRender() {}
@ -133,4 +148,16 @@ func (b *UnimplementedAlipayPrivBinding) BindUserWalletBills(c *gin.Context) (*w
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) BindUserRechargeResult(c *gin.Context) (*web.UserRechargeResultReq, mir.Error) {
obj := new(web.UserRechargeResultReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) BindUserRechargeLink(c *gin.Context) (*web.UserRechargeLinkReq, mir.Error) {
obj := new(web.UserRechargeLinkReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) mustEmbedUnimplementedAlipayPrivBinding() {}

@ -36,7 +36,6 @@ type Core interface {
type CoreBinding interface {
BindChangeAvatar(*gin.Context) (*web.ChangeAvatarReq, mir.Error)
BindGetUserInfo(*gin.Context) (*web.UserInfoReq, mir.Error)
mustEmbedUnimplementedCoreBinding()

@ -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.2
github.com/alimy/mir/v3 v3.0.0-beta.3
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

@ -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.2 h1:qpg0l4FEUafkpzGXlBIJtJbFjQfzbK9lDP5FJjjgOrA=
github.com/alimy/mir/v3 v3.0.0-beta.2/go.mod h1:ybhT2ijOiDn0lLwWzIY6vXdv+uzZrctS7VFfczcXBWU=
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/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=

@ -7,15 +7,37 @@ package web
import (
"context"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/smartwalle/alipay/v3"
)
type UserWalletBillsReq struct {
*BaseInfo `json:"-" binding:"-"`
UserId int64
Page int
PageSize int
}
type UserWalletBillsResp struct {
// TODO
type UserWalletBillsResp = base.PageResp
type UserRechargeLinkReq struct {
*BaseInfo `json:"-" form:"-" binding:"-"`
Host string `json:"-" form:"-" binding:"-"`
Amount int64 `json:"amount" form:"amount" binding:"required"`
}
type UserRechargeLinkResp struct {
Id int64 `json:"id"`
Pay string `json:"pay"`
}
type UserRechargeResultReq struct {
UserId int64
Id int64
}
type UserRechargeResultResp struct {
Id int64 `json:"id"`
Status string `json:"status"`
}
type AlipayNotifyReq struct {

@ -49,6 +49,14 @@ func UserFrom(c *gin.Context) (*core.User, bool) {
return nil, false
}
func UserIdFrom(c *gin.Context) (int64, bool) {
if u, exists := c.Get("UID"); exists {
uid, ok := u.(int64)
return uid, ok
}
return -1, false
}
func BindAny(c *gin.Context, obj any) mir.Error {
var errs xerror.ValidErrors
err := c.ShouldBind(obj)
@ -57,7 +65,10 @@ func BindAny(c *gin.Context, obj any) mir.Error {
}
// setup *core.User if needed
if setter, ok := obj.(UserSetter); ok {
user, _ := UserFrom(c)
user, exist := UserFrom(c)
if !exist {
return xerror.UnauthorizedTokenError
}
setter.SetUser(user)
}
return nil

@ -0,0 +1,27 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package base
type Pager struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
TotalRows int64 `json:"total_rows"`
}
type PageResp struct {
List any `json:"list"`
Pager Pager `json:"pager"`
}
func PageRespFrom(list any, page int, pageSize int, totalRows int64) *PageResp {
return &PageResp{
List: list,
Pager: Pager{
Page: page,
PageSize: pageSize,
TotalRows: totalRows,
},
}
}

@ -5,6 +5,7 @@
package web
import (
"fmt"
"time"
"github.com/alimy/mir/v3"
@ -13,7 +14,9 @@ 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"
"github.com/smartwalle/alipay/v3"
)
@ -44,6 +47,9 @@ type alipayPubRender struct {
type alipayPrivSrv struct {
api.UnimplementedAlipayPrivServant
*base.DaoServant
alipayClient *alipay.Client
}
type alipayPrivBinding struct {
@ -94,10 +100,97 @@ func (s *alipayPubSrv) AlipayNotify(req *web.AlipayNotifyReq) mir.Error {
return nil
}
func (b *alipayPrivBinding) BindUserWalletBills(c *gin.Context) (*web.UserWalletBillsReq, mir.Error) {
uid, ok := base.UserIdFrom(c)
if !ok {
return nil, xerror.UnauthorizedTokenError
}
page, pageSize := app.GetPageOffset(c)
return &web.UserWalletBillsReq{
UserId: uid,
Page: page,
PageSize: pageSize,
}, nil
}
func (b *alipayPrivBinding) BindUserRechargeLink(c *gin.Context) (*web.UserRechargeLinkReq, mir.Error) {
v := &web.UserRechargeLinkReq{
Host: c.Request.Host,
}
err := b.BindAny(c, v)
return v, err
}
func (b *alipayPrivBinding) BindUserRechargeResult(c *gin.Context) (*web.UserRechargeResultReq, mir.Error) {
uid, exist := base.UserIdFrom(c)
if !exist {
return nil, xerror.UnauthorizedTokenError
}
return &web.UserRechargeResultReq{
UserId: uid,
Id: convert.StrTo(c.Query("id")).MustInt64(),
}, nil
}
func (s *alipayPrivSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JWT()}
}
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)
return nil, _errUserWalletBillsFailed
}
totalRows, err := s.Ds.GetUserWalletBillCount(req.UserId)
if err != nil {
logrus.Errorf("GetUserWalletBillCount err: %s", err)
return nil, _errUserWalletBillsFailed
}
return base.PageRespFrom(bills, req.Page, req.PageSize, totalRows), nil
}
func (s *alipayPrivSrv) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) {
recharge, err := s.Ds.CreateRecharge(req.User.ID, req.Amount)
if err != nil {
logrus.Errorf("Ds.CreateRecharge err: %v", err)
return nil, _errRechargeReqFail
}
p := alipay.TradePreCreate{}
p.OutTradeNo = fmt.Sprintf("%d", recharge.ID)
p.Subject = "PaoPao用户钱包充值"
p.TotalAmount = fmt.Sprintf("%.2f", float64(recharge.Amount)/100.0)
p.NotifyURL = "https://" + req.Host + "/v1/alipay/notify"
rsp, err := s.alipayClient.TradePreCreate(p)
if err != nil {
logrus.Errorf("client.TradePreCreate err: %v\n", err)
return nil, _errRechargeReqFail
}
if rsp.Content.Code != alipay.CodeSuccess {
return nil, _errRechargeReqFail
}
return &web.UserRechargeLinkResp{
Id: recharge.ID,
Pay: rsp.Content.QRCode,
}, nil
}
func (s *alipayPrivSrv) UserRechargeResult(req *web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error) {
recharge, err := s.Ds.GetRechargeByID(req.Id)
if err != nil {
logrus.Errorf("Ds.GetRechargeByID err: %v", err)
return nil, _errGetRechargeFailed
}
if recharge.UserID != req.UserId {
logrus.Errorf("Ds.GetRechargeByID userId not equel recharge.UserID: %d req.UserId %d", recharge.UserID, req.UserId)
return nil, _errGetRechargeFailed
}
return &web.UserRechargeResultResp{
Id: recharge.ID,
Status: recharge.TradeStatus,
}, nil
}
func newAlipayPubSrv(s *base.DaoServant) api.AlipayPub {
return &alipayPubSrv{
DaoServant: s,
@ -121,8 +214,11 @@ func newAlipayPubRender() api.AlipayPubRender {
}
}
func newAlipayPrivSrv() api.AlipayPriv {
return &alipayPrivSrv{}
func newAlipayPrivSrv(s *base.DaoServant, client *alipay.Client) api.AlipayPriv {
return &alipayPrivSrv{
DaoServant: s,
alipayClient: client,
}
}
func newAlipayPrivBinding() api.AlipayPrivBinding {

@ -34,7 +34,7 @@ func RouteWeb(e *gin.Engine) {
"Alipay": func() {
client := mustAlipayClient()
api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds), newAlipayPubBinding(client), newAlipayPubRender())
api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(), newAlipayPrivBinding(), newAlipayPrivRender())
api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(ds, client), newAlipayPrivBinding(), newAlipayPrivRender())
},
"Followship": func() {
api.RegisterFollowshipServant(e, newFollowshipSrv(), newFollowshipBinding(), newFollowshipRender())

@ -63,9 +63,10 @@ var (
_errGetCollectionsFailed = xerror.NewError(60001, "获取收藏列表失败")
_errGetStarsFailed = xerror.NewError(60002, "获取点赞列表失败")
_errRechargeReqFail = xerror.NewError(70001, "充值请求失败")
_errRechargeNotifyError = xerror.NewError(70002, "充值回调失败")
_errGetRechargeFailed = xerror.NewError(70003, "充值详情获取失败")
_errRechargeReqFail = xerror.NewError(70001, "充值请求失败")
_errRechargeNotifyError = xerror.NewError(70002, "充值回调失败")
_errGetRechargeFailed = xerror.NewError(70003, "充值详情获取失败")
_errUserWalletBillsFailed = xerror.NewError(70004, "用户钱包账单获取失败")
_errNoRequestingFriendToSelf = xerror.NewError(80001, "不允许添加自己为好友")
_errNotExistFriendId = xerror.NewError(80002, "好友id不存在")

@ -24,10 +24,10 @@ type AlipayPriv struct {
Group Group `mir:"v1"`
// UserRechargeLink 用户充值
UserRechargeLink func(Post) `mir:"/user/recharge"`
UserRechargeLink func(Post, web.UserRechargeLinkReq) web.UserRechargeLinkResp `mir:"/user/recharge"`
// UserRechargeResult 获取钱包余额
UserRechargeResult func(Get) `mir:"/user/recharge"`
// UserRechargeResult 获取充值结果
UserRechargeResult func(Get, web.UserRechargeResultReq) web.UserRechargeResultResp `mir:"/user/recharge"`
// UserWalletBills 获取用户账单
UserWalletBills func(Get, web.UserWalletBillsReq) web.UserWalletBillsResp `mir:"/user/wallet/bills"`

Loading…
Cancel
Save