mir: add partital interface implement for new web service

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

@ -5,5 +5,7 @@
package web package web
type ChangeUserStatusReq struct { type ChangeUserStatusReq struct {
*BaseInfo `json:"-"` *BaseInfo `json:"-" binding:"-"`
ID int64 `json:"id" form:"id" binding:"required"`
Status int `json:"status" form:"status" binding:"required,oneof=1 2"`
} }

@ -4,8 +4,14 @@
package web package web
import (
"context"
"github.com/smartwalle/alipay/v3"
)
type UserWalletBillsReq struct { type UserWalletBillsReq struct {
*BaseInfo `json:"-"` *BaseInfo `json:"-" binding:"-"`
} }
type UserWalletBillsResp struct { type UserWalletBillsResp struct {
@ -13,5 +19,8 @@ type UserWalletBillsResp struct {
} }
type AlipayNotifyReq struct { type AlipayNotifyReq struct {
// TODO Ctx context.Context
ID int64
TradeNo string
TradeStatus alipay.TradeStatus
} }

@ -9,6 +9,7 @@ import (
"github.com/alimy/mir/v3" "github.com/alimy/mir/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/go-redis/redis/v8"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/pkg/xerror" "github.com/rocboss/paopao-ce/pkg/xerror"
) )
@ -17,6 +18,11 @@ type BaseServant struct {
// TODO // TODO
} }
type DaoServant struct {
Redis *redis.Client
Ds core.DataService
}
type BaseBinding struct { type BaseBinding struct {
// TODO // TODO
} }
@ -47,7 +53,7 @@ func BindAny(c *gin.Context, obj any) mir.Error {
var errs xerror.ValidErrors var errs xerror.ValidErrors
err := c.ShouldBind(obj) err := c.ShouldBind(obj)
if err != nil { if err != nil {
return mir.NewError(xerror.InvalidParams.Code(), xerror.InvalidParams.WithDetails(errs.Error())) return mir.NewError(xerror.InvalidParams.StatusCode(), xerror.InvalidParams.WithDetails(errs.Error()))
} }
// setup *core.User if needed // setup *core.User if needed
if setter, ok := obj.(UserSetter); ok { if setter, ok := obj.(UserSetter); ok {
@ -65,7 +71,7 @@ func RenderAny(c *gin.Context, data any, err mir.Error) {
Data: data, Data: data,
}) })
} else { } else {
c.JSON(http.StatusInternalServerError, &JsonResp{ c.JSON(xerror.HttpStatusCode(err), &JsonResp{
Code: err.StatusCode(), Code: err.StatusCode(),
Msg: err.Error(), Msg: err.Error(),
}) })

@ -5,10 +5,13 @@
package web package web
import ( import (
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
"github.com/rocboss/paopao-ce/pkg/xerror"
) )
var ( var (
@ -18,17 +21,15 @@ var (
) )
type adminSrv struct { type adminSrv struct {
base.BaseServant
api.UnimplementedAdminServant api.UnimplementedAdminServant
*base.DaoServant
} }
type adminBinding struct { type adminBinding struct {
base.BaseBinding
*api.UnimplementedAdminBinding *api.UnimplementedAdminBinding
} }
type adminRender struct { type adminRender struct {
base.BaseRender
*api.UnimplementedAdminRender *api.UnimplementedAdminRender
} }
@ -36,8 +37,23 @@ func (s *adminSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JWT(), chain.Admin()} return gin.HandlersChain{chain.JWT(), chain.Admin()}
} }
func newAdminSrv() api.Admin { func (s *adminSrv) ChangeUserStatus(req *web.ChangeUserStatusReq) mir.Error {
return &adminSrv{} user, err := s.Ds.GetUserByID(req.ID)
if err != nil || user.Model == nil || user.ID <= 0 {
return _errNoExistUsername
}
// 执行更新
user.Status = req.Status
if err := s.Ds.UpdateUser(user); err != nil {
return xerror.ServerError
}
return nil
}
func newAdminSrv(s *base.DaoServant) api.Admin {
return &adminSrv{
DaoServant: s,
}
} }
func newAdminBinding() api.AdminBinding { func newAdminBinding() api.AdminBinding {

@ -5,10 +5,17 @@
package web package web
import ( import (
"time"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/model/web"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
"github.com/rocboss/paopao-ce/pkg/convert"
"github.com/sirupsen/logrus"
"github.com/smartwalle/alipay/v3"
) )
var ( var (
@ -21,48 +28,88 @@ var (
) )
type alipayPubSrv struct { type alipayPubSrv struct {
base.BaseServant
api.UnimplementedAlipayPubServant api.UnimplementedAlipayPubServant
*base.DaoServant
} }
type alipayPubBinding struct { type alipayPubBinding struct {
base.BaseBinding
*api.UnimplementedAlipayPubBinding *api.UnimplementedAlipayPubBinding
alipayClient *alipay.Client
} }
type alipayPubRender struct { type alipayPubRender struct {
base.BaseRender
*api.UnimplementedAlipayPubRender *api.UnimplementedAlipayPubRender
} }
type alipayPrivSrv struct { type alipayPrivSrv struct {
base.BaseServant
api.UnimplementedAlipayPrivServant api.UnimplementedAlipayPrivServant
} }
type alipayPrivBinding struct { type alipayPrivBinding struct {
base.BaseBinding
*api.UnimplementedAlipayPrivBinding *api.UnimplementedAlipayPrivBinding
} }
type alipayPrivRender struct { type alipayPrivRender struct {
base.BaseRender
*api.UnimplementedAlipayPrivRender *api.UnimplementedAlipayPrivRender
} }
func (b *alipayPubBinding) BindAlipayNotify(c *gin.Context) (*web.AlipayNotifyReq, mir.Error) {
if err := c.Request.ParseForm(); err != nil {
logrus.Errorf("parse form err: %s", err)
return nil, _errRechargeNotifyError
}
noti, err := b.alipayClient.GetTradeNotification(c.Request)
if err != nil {
logrus.Errorf("alipayClient.GetTradeNotification err: %s form: %v", err, c.Request.Form)
return nil, _errRechargeNotifyError
}
return &web.AlipayNotifyReq{
Ctx: c.Request.Context(),
ID: convert.StrTo(noti.OutTradeNo).MustInt64(),
TradeNo: noti.TradeNo,
TradeStatus: noti.TradeStatus,
}, nil
}
func (s *alipayPubSrv) AlipayNotify(req *web.AlipayNotifyReq) mir.Error {
if req.TradeStatus == alipay.TradeStatusSuccess {
if ok, _ := s.Redis.SetNX(req.Ctx, "PaoPaoRecharge:"+req.TradeNo, 1, time.Second*5).Result(); ok {
recharge, err := s.Ds.GetRechargeByID(req.ID)
if err != nil {
logrus.Errorf("GetRechargeByID id:%d err: %s", req.ID, err)
return _errRechargeNotifyError
}
if recharge.TradeStatus != "TRADE_SUCCESS" {
// 标记为已付款
err := s.Ds.HandleRechargeSuccess(recharge, req.TradeNo)
defer s.Redis.Del(req.Ctx, "PaoPaoRecharge:"+req.TradeNo)
if err != nil {
logrus.Errorf("HandleRechargeSuccess id:%d err: %s", req.ID, err)
return _errRechargeNotifyError
}
}
}
}
return nil
}
func (s *alipayPrivSrv) Chain() gin.HandlersChain { func (s *alipayPrivSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JWT()} return gin.HandlersChain{chain.JWT()}
} }
func newAlipayPubSrv() api.AlipayPub { func newAlipayPubSrv(s *base.DaoServant) api.AlipayPub {
return &alipayPubSrv{} return &alipayPubSrv{
DaoServant: s,
}
} }
func newAlipayPubBinding() api.AlipayPubBinding { func newAlipayPubBinding(alipayClient *alipay.Client) api.AlipayPubBinding {
return &alipayPubBinding{ return &alipayPubBinding{
UnimplementedAlipayPubBinding: &api.UnimplementedAlipayPubBinding{ UnimplementedAlipayPubBinding: &api.UnimplementedAlipayPubBinding{
BindAny: base.BindAny, BindAny: base.BindAny,
}, },
alipayClient: alipayClient,
} }
} }

@ -7,6 +7,7 @@ package web
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/servants/base" "github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/rocboss/paopao-ce/internal/servants/chain" "github.com/rocboss/paopao-ce/internal/servants/chain"
) )
@ -18,17 +19,18 @@ var (
) )
type coreSrv struct { type coreSrv struct {
base.BaseServant
api.UnimplementedCoreServant api.UnimplementedCoreServant
*base.DaoServant
ts core.TweetSearchService
oss core.ObjectStorageService
} }
type coreBinding struct { type coreBinding struct {
base.BaseBinding
*api.UnimplementedCoreBinding *api.UnimplementedCoreBinding
} }
type coreRender struct { type coreRender struct {
base.BaseRender
*api.UnimplementedCoreRender *api.UnimplementedCoreRender
} }
@ -36,8 +38,12 @@ func (s *coreSrv) Chain() gin.HandlersChain {
return gin.HandlersChain{chain.JWT()} return gin.HandlersChain{chain.JWT()}
} }
func newCoreSrv() api.Core { func newCoreSrv(s *base.DaoServant, ts core.TweetSearchService, oss core.ObjectStorageService) api.Core {
return &coreSrv{} return &coreSrv{
DaoServant: s,
ts: ts,
oss: oss,
}
} }
func newCoreBinding() api.CoreBinding { func newCoreBinding() api.CoreBinding {

@ -8,19 +8,32 @@ import (
"github.com/alimy/cfg" "github.com/alimy/cfg"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
api "github.com/rocboss/paopao-ce/auto/api/v1" api "github.com/rocboss/paopao-ce/auto/api/v1"
"github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/dao"
"github.com/rocboss/paopao-ce/internal/servants/base"
"github.com/sirupsen/logrus"
"github.com/smartwalle/alipay/v3"
) )
// RouteWeb register web route // RouteWeb register web route
func RouteWeb(e *gin.Engine) { func RouteWeb(e *gin.Engine) {
api.RegisterAdminServant(e, newAdminSrv(), newAdminBinding(), newAdminRender()) ts := dao.TweetSearchService()
api.RegisterCoreServant(e, newCoreSrv(), newCoreBinding(), newCoreRender()) oss := dao.ObjectStorageService()
ds := &base.DaoServant{
Redis: conf.Redis,
Ds: dao.DataService(),
}
// aways register servants
api.RegisterAdminServant(e, newAdminSrv(ds), newAdminBinding(), newAdminRender())
api.RegisterCoreServant(e, newCoreSrv(ds, ts, oss), newCoreBinding(), newCoreRender())
api.RegisterLooseServant(e, newLooseSrv(), newLooseBinding(), newLooseRender()) api.RegisterLooseServant(e, newLooseSrv(), newLooseBinding(), newLooseRender())
api.RegisterPrivServant(e, newPrivSrv(), newPrivBinding(), newPrivRender()) api.RegisterPrivServant(e, newPrivSrv(), newPrivBinding(), newPrivRender())
api.RegisterPubServant(e, newPubSrv(), newPubBinding(), newPubRender()) api.RegisterPubServant(e, newPubSrv(), newPubBinding(), newPubRender())
// regster servants if needed by configure
cfg.In(cfg.Actions{ cfg.In(cfg.Actions{
"Alipay": func() { "Alipay": func() {
api.RegisterAlipayPubServant(e, newAlipayPubSrv(), newAlipayPubBinding(), newAlipayPubRender()) client := mustAlipayClient()
api.RegisterAlipayPubServant(e, newAlipayPubSrv(ds), newAlipayPubBinding(client), newAlipayPubRender())
api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(), newAlipayPrivBinding(), newAlipayPrivRender()) api.RegisterAlipayPrivServant(e, newAlipayPrivSrv(), newAlipayPrivBinding(), newAlipayPrivRender())
}, },
"Followship": func() { "Followship": func() {
@ -31,3 +44,25 @@ func RouteWeb(e *gin.Engine) {
}, },
}) })
} }
func mustAlipayClient() *alipay.Client {
s := conf.AlipaySetting
// 将 key 的验证调整到初始化阶段
client, err := alipay.New(s.AppID, s.PrivateKey, s.InProduction)
if err != nil {
logrus.Fatalf("alipay.New err: %s", err)
}
// 加载应用公钥证书
if err = client.LoadAppPublicCertFromFile(s.AppPublicCertFile); err != nil {
logrus.Fatalf("client.LoadAppPublicCertFromFile err: %s\n", err)
}
// 加载支付宝根证书
if err = client.LoadAliPayRootCertFromFile(s.RootCertFile); err != nil {
logrus.Fatalf("client.LoadAliPayRootCertFromFile err: %s\n", err)
}
// 加载支付宝公钥证书
if err = client.LoadAliPayPublicCertFromFile(s.PublicCertFile); err != nil {
logrus.Fatalf("client.LoadAliPayPublicCertFromFile err: %s\n", err)
}
return client
}

@ -8,9 +8,13 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
"github.com/alimy/mir/v3"
) )
var ( var (
_ mir.Error = (*Error)(nil)
codes = map[int]string{} codes = map[int]string{}
) )
@ -51,10 +55,10 @@ func NewError(code int, msg string) *Error {
} }
func (e *Error) Error() string { func (e *Error) Error() string {
return fmt.Sprintf("错误码: %d, 错误信息: %s", e.Code(), e.Msg()) return fmt.Sprintf("错误码: %d, 错误信息: %s", e.StatusCode(), e.Msg())
} }
func (e *Error) Code() int { func (e *Error) StatusCode() int {
return e.code return e.code
} }
@ -78,27 +82,26 @@ func (e *Error) WithDetails(details ...string) *Error {
return &newError return &newError
} }
func (e *Error) StatusCode() int { func HttpStatusCode(e mir.Error) int {
switch e.Code() { switch e.StatusCode() {
case Success.Code(): case Success.StatusCode():
return http.StatusOK return http.StatusOK
case ServerError.Code(): case ServerError.StatusCode():
return http.StatusInternalServerError return http.StatusInternalServerError
case InvalidParams.Code(): case InvalidParams.StatusCode():
return http.StatusBadRequest return http.StatusBadRequest
case UnauthorizedAuthNotExist.Code(): case UnauthorizedAuthNotExist.StatusCode():
fallthrough fallthrough
case UnauthorizedAuthFailed.Code(): case UnauthorizedAuthFailed.StatusCode():
fallthrough fallthrough
case UnauthorizedTokenError.Code(): case UnauthorizedTokenError.StatusCode():
fallthrough fallthrough
case UnauthorizedTokenGenerate.Code(): case UnauthorizedTokenGenerate.StatusCode():
fallthrough fallthrough
case UnauthorizedTokenTimeout.Code(): case UnauthorizedTokenTimeout.StatusCode():
return http.StatusUnauthorized return http.StatusUnauthorized
case TooManyRequests.Code(): case TooManyRequests.StatusCode():
return http.StatusTooManyRequests return http.StatusTooManyRequests
} }
return http.StatusInternalServerError return http.StatusInternalServerError
} }

Loading…
Cancel
Save