<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          帶你十天輕松搞定 Go 微服務(wù)系列(六)

          共 14748字,需瀏覽 30分鐘

           ·

          2022-02-26 15:32

          序言

          我們通過一個(gè)系列文章跟大家詳細(xì)展示一個(gè) go-zero 微服務(wù)示例,整個(gè)系列分十篇文章,目錄結(jié)構(gòu)如下:

          1. 環(huán)境搭建:帶你十天輕松搞定 Go 微服務(wù)系列(一)
          2. 服務(wù)拆分:帶你十天輕松搞定 Go 微服務(wù)系列(二)
          3. 用戶服務(wù):帶你十天輕松搞定 Go 微服務(wù)系列(三)
          4. 產(chǎn)品服務(wù):帶你十天輕松搞定 Go 微服務(wù)系列(四)
          5. 訂單服務(wù):帶你十天輕松搞定 Go 微服務(wù)系列(五)
          6. 支付服務(wù)(本文)
          7. RPC 服務(wù) Auth 驗(yàn)證
          8. 服務(wù)監(jiān)控
          9. 鏈路追蹤
          10. 分布式事務(wù)

          期望通過本系列帶你在本機(jī)利用 Docker 環(huán)境利用 go-zero 快速開發(fā)一個(gè)商城系統(tǒng),讓你快速上手微服務(wù)。

          完整示例代碼:https://github.com/nivin-studio/go-zero-mall

          首先,我們來(lái)看一下整體的服務(wù)拆分圖:

          6 支付服務(wù)(pay)

          • 進(jìn)入服務(wù)工作區(qū)
          $?cd?mall/service/pay

          6.1 生成 pay model 模型

          • 創(chuàng)建 sql 文件
          $?vim?model/pay.sql
          • 編寫 sql 文件
          CREATE?TABLE?`pay`?(
          ?`id`?bigint?unsigned?NOT?NULL?AUTO_INCREMENT,
          ?`uid`?bigint?unsigned?NOT?NULL?DEFAULT?'0'?COMMENT?'用戶ID',
          ?`oid`?bigint?unsigned?NOT?NULL?DEFAULT?'0'?COMMENT?'訂單ID',
          ?`amount`?int(10)?unsigned?NOT?NULL?DEFAULT?'0'??COMMENT?'產(chǎn)品金額',
          ?`source`?tinyint(3)?unsigned?NOT?NULL?DEFAULT?'0'?COMMENT?'支付方式',
          ?`status`?tinyint(3)?unsigned?NOT?NULL?DEFAULT?'0'?COMMENT?'支付狀態(tài)',
          ?`create_time`?timestamp?NULL?DEFAULT?CURRENT_TIMESTAMP,
          ?`update_time`?timestamp?NULL?DEFAULT?CURRENT_TIMESTAMP?ON?UPDATE?CURRENT_TIMESTAMP,
          ?PRIMARY?KEY?(`id`),
          ?KEY?`idx_uid`?(`uid`),
          ?KEY?`idx_oid`?(`oid`)
          )?ENGINE=InnoDB??DEFAULT?CHARSET=utf8mb4;
          • 運(yùn)行模板生成命令
          $?goctl?model?mysql?ddl?-src?./model/pay.sql?-dir?./model?-c

          6.2 生成 pay api 服務(wù)

          • 創(chuàng)建 api 文件
          $?vim?api/pay.api
          • 編寫 api 文件
          type?(
          ?//?支付創(chuàng)建
          ?CreateRequest?{
          ??Uid????int64?`json:"uid"`
          ??Oid????int64?`json:"oid"`
          ??Amount?int64?`json:"amount"`
          ?}
          ?CreateResponse?{
          ??Id?int64?`json:"id"`
          ?}
          ?//?支付創(chuàng)建

          ?//?支付詳情
          ?DetailRequest?{
          ??Id?int64?`json:"id"`
          ?}
          ?DetailResponse?{
          ??Id?????int64?`json:"id"`
          ??Uid????int64?`json:"uid"`
          ??Oid????int64?`json:"oid"`
          ??Amount?int64?`json:"amount"`
          ??Source?int64?`json:"source"`
          ??Status?int64?`json:"status"`
          ?}
          ?//?支付詳情

          ?//?支付回調(diào)
          ?CallbackRequest?{
          ??Id?????int64?`json:"id"`
          ??Uid????int64?`json:"uid"`
          ??Oid????int64?`json:"oid"`
          ??Amount?int64?`json:"amount"`
          ??Source?int64?`json:"source"`
          ??Status?int64?`json:"status"`
          ?}
          ?CallbackResponse?{
          ?}
          ?//?支付回調(diào)

          )

          @server(
          ?jwt:?Auth
          )
          service?Pay?{
          ?@handler?Create
          ?post?/api/pay/create(CreateRequest)?returns?(CreateResponse)
          ?
          ?@handler?Detail
          ?post?/api/pay/detail(DetailRequest)?returns?(DetailResponse)
          ?
          ?@handler?Callback
          ?post?/api/pay/callback(CallbackRequest)?returns?(CallbackResponse)
          }
          • 運(yùn)行模板生成命令
          $?goctl?api?go?-api?./api/pay.api?-dir?./api

          6.3 生成 pay rpc 服務(wù)

          • 創(chuàng)建 proto 文件
          $?vim?rpc/pay.proto
          • 編寫 proto 文件
          syntax = "proto3";

          package payclient;

          option go_package = "pay";

          // 支付創(chuàng)建
          message CreateRequest {
          int64 Uid = 1;
          int64 Oid = 2;
          int64 Amount = 3;
          }
          message CreateResponse {
          int64 id = 1;
          }
          // 支付創(chuàng)建

          // 支付詳情
          message DetailRequest {
          int64 id = 1;
          }
          message DetailResponse {
          int64 id = 1;
          int64 Uid = 2;
          int64 Oid = 3;
          int64 Amount = 4;
          int64 Source = 5;
          int64 Status = 6;
          }
          // 支付詳情

          // 支付詳情
          message CallbackRequest {
          int64 id = 1;
          int64 Uid = 2;
          int64 Oid = 3;
          int64 Amount = 4;
          int64 Source = 5;
          int64 Status = 6;
          }
          message CallbackResponse {
          }
          // 支付詳情


          service Pay {
          rpc Create(CreateRequest) returns(CreateResponse);
          rpc Detail(DetailRequest) returns(DetailResponse);
          rpc Callback(CallbackRequest) returns(CallbackResponse);
          }
          • 運(yùn)行模板生成命令
          $?goctl?rpc?proto?-src?./rpc/pay.proto?-dir?./rpc

          6.4 編寫 pay rpc 服務(wù)

          6.4.1 修改配置文件

          • 修改 pay.yaml 配置文件
          $?vim?rpc/etc/pay.yaml
          • 修改服務(wù)監(jiān)聽地址,端口號(hào)為0.0.0.0:9003,Etcd 服務(wù)配置,Mysql 服務(wù)配置,CacheRedis 服務(wù)配置
          Name:?pay.rpc
          ListenOn:?0.0.0.0:9003

          Etcd:
          ??Hosts:
          ??-?etcd:2379
          ??Key:?pay.rpc

          Mysql:
          ??DataSource:?root:123456@tcp(mysql:3306)/mall?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai

          CacheRedis:
          -?Host:?redis:6379
          ??Type:?node
          ??Pass:

          6.4.2 添加 pay model 依賴

          • 添加 Mysql 服務(wù)配置,CacheRedis 服務(wù)配置的實(shí)例化
          $?vim?rpc/internal/config/config.go
          package?config

          import?(
          ?"github.com/tal-tech/go-zero/core/stores/cache"
          ?"github.com/tal-tech/go-zero/zrpc"
          )

          type?Config?struct?{
          ?zrpc.RpcServerConf

          ?Mysql?struct?{
          ??DataSource?string
          ?}
          ????
          ?CacheRedis?cache.CacheConf
          }
          • 注冊(cè)服務(wù)上下文 pay model 的依賴
          $?vim?rpc/internal/svc/servicecontext.go
          package?svc

          import?(
          ?"mall/service/pay/model"
          ?"mall/service/pay/rpc/internal/config"

          ?"github.com/tal-tech/go-zero/core/stores/sqlx"
          )

          type?ServiceContext?struct?{
          ?Config?config.Config
          ????
          ?PayModel?model.PayModel
          }

          func?NewServiceContext(c?config.Config)?*ServiceContext?{
          ?conn?:=?sqlx.NewMysql(c.Mysql.DataSource)
          ?return?&ServiceContext{
          ??Config:???c,
          ??PayModel:?model.NewPayModel(conn,?c.CacheRedis),
          ?}
          }

          6.4.3 添加 user rpc,order rpc 依賴

          • 添加 user rpc, order rpc 服務(wù)配置
          $?vim?rpc/etc/pay.yaml
          Name:?pay.rpc
          ListenOn:?0.0.0.0:9003
          Etcd:
          ??Hosts:
          ??-?etcd:2379
          ??Key:?pay.rpc

          ...

          UserRpc:
          ??Etcd:
          ????Hosts:
          ????-?etcd:2379
          ????Key:?user.rpc

          OrderRpc:
          ??Etcd:
          ????Hosts:
          ????-?etcd:2379
          ????Key:?order.rpc
          • 添加 user rpc, order rpc 服務(wù)配置的實(shí)例化
          $?vim?rpc/internal/config/config.go
          package?config

          import?(
          ?"github.com/tal-tech/go-zero/core/stores/cache"
          ?"github.com/tal-tech/go-zero/zrpc"
          )

          type?Config?struct?{
          ?zrpc.RpcServerConf

          ?Mysql?struct?{
          ??DataSource?string
          ?}
          ????
          ?CacheRedis?cache.CacheConf

          ?UserRpc??zrpc.RpcClientConf
          ?OrderRpc?zrpc.RpcClientConf
          }
          • 注冊(cè)服務(wù)上下文 user rpc, order rpc 的依賴
          $?vim?rpc/internal/svc/servicecontext.go
          package?svc

          import?(
          ?"mall/service/order/rpc/orderclient"
          ?"mall/service/pay/model"
          ?"mall/service/pay/rpc/internal/config"
          ?"mall/service/user/rpc/userclient"

          ?"github.com/tal-tech/go-zero/core/stores/sqlx"
          ?"github.com/tal-tech/go-zero/zrpc"
          )

          type?ServiceContext?struct?{
          ?Config?config.Config
          ????
          ?PayModel?model.PayModel

          ?UserRpc??userclient.User
          ?OrderRpc?orderclient.Order
          }

          func?NewServiceContext(c?config.Config)?*ServiceContext?{
          ?conn?:=?sqlx.NewMysql(c.Mysql.DataSource)
          ?return?&ServiceContext{
          ??Config:???c,
          ??PayModel:?model.NewPayModel(conn,?c.CacheRedis),
          ??UserRpc:??userclient.NewUser(zrpc.MustNewClient(c.UserRpc)),
          ??OrderRpc:?orderclient.NewOrder(zrpc.MustNewClient(c.OrderRpc)),
          ?}
          }

          6.4.4 添加支付創(chuàng)建邏輯 Create

          • 添加根據(jù) oid 查詢訂單支付記錄 PayModel 方法 FindOneByOid
          $?vim?model/paymodel.go
          package?model

          ...

          var?(
          ?...

          ?cachePayIdPrefix??=?"cache:pay:id:"
          ?cachePayOidPrefix?=?"cache:pay:oid:"
          )

          type?(
          ?PayModel?interface?{
          ??Insert(data?*Pay)?(sql.Result,?error)
          ??FindOne(id?int64)?(*Pay,?error)
          ??FindOneByOid(oid?int64)?(*Pay,?error)
          ??Update(data?*Pay)?error
          ??Delete(id?int64)?error
          ?}

          ?...
          )

          ...

          func?(m?*defaultPayModel)?FindOneByOid(oid?int64)?(*Pay,?error)?{
          ?payOidKey?:=?fmt.Sprintf("%s%v",?cachePayOidPrefix,?oid)
          ?var?resp?Pay
          ?err?:=?m.QueryRow(&resp,?payOidKey,?func(conn?sqlx.SqlConn,?v?interface{})?error?{
          ??query?:=?fmt.Sprintf("select?%s?from?%s?where?`oid`?=???limit?1",?payRows,?m.table)
          ??return?conn.QueryRow(v,?query,?oid)
          ?})
          ?switch?err?{
          ?case?nil:
          ??return?&resp,?nil
          ?case?sqlc.ErrNotFound:
          ??return?nil,?ErrNotFound
          ?default:
          ??return?nil,?err
          ?}
          }

          ......
          • 添加支付創(chuàng)建邏輯

            支付流水創(chuàng)建流程,通過調(diào)用 user rpc 服務(wù)查詢驗(yàn)證用戶是否存在,再通過調(diào)用 order rpc 服務(wù)查詢驗(yàn)證訂單是否存在,然后通過查詢庫(kù)判斷此訂單是否已經(jīng)創(chuàng)建過支付流水,最后創(chuàng)建落庫(kù)。

          $?vim?rpc/internal/logic/createlogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/order/rpc/order"
          ?"mall/service/pay/model"
          ?"mall/service/pay/rpc/internal/svc"
          ?"mall/service/pay/rpc/pay"
          ?"mall/service/user/rpc/user"

          ?"github.com/tal-tech/go-zero/core/logx"
          ?"google.golang.org/grpc/status"
          )

          type?CreateLogic?struct?{
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          ?logx.Logger
          }

          func?NewCreateLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?*CreateLogic?{
          ?return?&CreateLogic{
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ??Logger:?logx.WithContext(ctx),
          ?}
          }

          func?(l?*CreateLogic)?Create(in?*pay.CreateRequest)?(*pay.CreateResponse,?error)?{
          ?//?查詢用戶是否存在
          ?_,?err?:=?l.svcCtx.UserRpc.UserInfo(l.ctx,?&user.UserInfoRequest{
          ??Id:?in.Uid,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//?查詢訂單是否存在
          ?_,?err?=?l.svcCtx.OrderRpc.Detail(l.ctx,?&order.DetailRequest{
          ??Id:?in.Oid,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//?查詢訂單是否已經(jīng)創(chuàng)建支付
          ?_,?err?=?l.svcCtx.PayModel.FindOneByOid(in.Oid)
          ?if?err?==?nil?{
          ??return?nil,?status.Error(100,?"訂單已創(chuàng)建支付")
          ?}

          ?newPay?:=?model.Pay{
          ??Uid:????in.Uid,
          ??Oid:????in.Oid,
          ??Amount:?in.Amount,
          ??Source:?0,
          ??Status:?0,
          ?}

          ?res,?err?:=?l.svcCtx.PayModel.Insert(&newPay)
          ?if?err?!=?nil?{
          ??return?nil,?status.Error(500,?err.Error())
          ?}

          ?newPay.Id,?err?=?res.LastInsertId()
          ?if?err?!=?nil?{
          ??return?nil,?status.Error(500,?err.Error())
          ?}

          ?return?&pay.CreateResponse{
          ??Id:?newPay.Id,
          ?},?nil
          }

          6.4.5 添加支付詳情邏輯 Detail

          $?vim?rpc/internal/logic/detaillogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/pay/model"
          ?"mall/service/pay/rpc/internal/svc"
          ?"mall/service/pay/rpc/pay"

          ?"github.com/tal-tech/go-zero/core/logx"
          ?"google.golang.org/grpc/status"
          )

          type?DetailLogic?struct?{
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          ?logx.Logger
          }

          func?NewDetailLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?*DetailLogic?{
          ?return?&DetailLogic{
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ??Logger:?logx.WithContext(ctx),
          ?}
          }

          func?(l?*DetailLogic)?Detail(in?*pay.DetailRequest)?(*pay.DetailResponse,?error)?{
          ?//?查詢支付是否存在
          ?res,?err?:=?l.svcCtx.PayModel.FindOne(in.Id)
          ?if?err?!=?nil?{
          ??if?err?==?model.ErrNotFound?{
          ???return?nil,?status.Error(100,?"支付不存在")
          ??}
          ??return?nil,?status.Error(500,?err.Error())
          ?}

          ?return?&pay.DetailResponse{
          ??Id:?????res.Id,
          ??Uid:????res.Uid,
          ??Oid:????res.Oid,
          ??Amount:?res.Amount,
          ??Source:?res.Source,
          ??Status:?res.Status,
          ?},?nil
          }

          6.4.6 添加支付回調(diào)邏輯 Callback

          支付流水回調(diào)流程,通過調(diào)用 user rpc 服務(wù)查詢驗(yàn)證用戶是否存在,再通過調(diào)用 order rpc 服務(wù)查詢驗(yàn)證訂單是否存在,然后通過查詢庫(kù)判斷此訂單支付流水是否存在,以及回調(diào)支付金額和庫(kù)中流水支付金額是否一致,最后更新支付流水狀態(tài)和通過調(diào)用 order rpc 服務(wù)更新訂單狀態(tài)。

          $?vim?rpc/internal/logic/callbacklogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/order/rpc/order"
          ?"mall/service/pay/model"
          ?"mall/service/pay/rpc/internal/svc"
          ?"mall/service/pay/rpc/pay"
          ?"mall/service/user/rpc/user"

          ?"github.com/tal-tech/go-zero/core/logx"
          ?"google.golang.org/grpc/status"
          )

          type?CallbackLogic?struct?{
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          ?logx.Logger
          }

          func?NewCallbackLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?*CallbackLogic?{
          ?return?&CallbackLogic{
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ??Logger:?logx.WithContext(ctx),
          ?}
          }

          func?(l?*CallbackLogic)?Callback(in?*pay.CallbackRequest)?(*pay.CallbackResponse,?error)?{
          ?//?查詢用戶是否存在
          ?_,?err?:=?l.svcCtx.UserRpc.UserInfo(l.ctx,?&user.UserInfoRequest{
          ??Id:?in.Uid,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//?查詢訂單是否存在
          ?_,?err?=?l.svcCtx.OrderRpc.Detail(l.ctx,?&order.DetailRequest{
          ??Id:?in.Oid,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?//?查詢支付是否存在
          ?res,?err?:=?l.svcCtx.PayModel.FindOne(in.Id)
          ?if?err?!=?nil?{
          ??if?err?==?model.ErrNotFound?{
          ???return?nil,?status.Error(100,?"支付不存在")
          ??}
          ??return?nil,?status.Error(500,?err.Error())
          ?}
          ?//?支付金額與訂單金額不符
          ?if?in.Amount?!=?res.Amount?{
          ??return?nil,?status.Error(100,?"支付金額與訂單金額不符")
          ?}

          ?res.Source?=?in.Source
          ?res.Status?=?in.Status

          ?err?=?l.svcCtx.PayModel.Update(res)
          ?if?err?!=?nil?{
          ??return?nil,?status.Error(500,?err.Error())
          ?}

          ?//?更新訂單支付狀態(tài)
          ?_,?err?=?l.svcCtx.OrderRpc.Paid(l.ctx,?&order.PaidRequest{
          ??Id:?in.Oid,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?status.Error(500,?err.Error())
          ?}

          ?return?&pay.CallbackResponse{},?nil
          }

          6.5 編寫 pay api 服務(wù)

          6.5.1 修改配置文件

          • 修改 pay.yaml 配置文件
          $?vim?api/etc/pay.yaml
          • 修改服務(wù)地址,端口號(hào)為0.0.0.0:8003,Mysql 服務(wù)配置,CacheRedis 服務(wù)配置,Auth 驗(yàn)證配置
          Name:?Pay
          Host:?0.0.0.0
          Port:?8003

          Mysql:
          ??DataSource:?root:123456@tcp(mysql:3306)/mall?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai

          CacheRedis:
          -?Host:?redis:6379
          ??Type:?node
          ??Pass:

          Auth:
          ??AccessSecret:?uOvKLmVfztaXGpNYd4Z0I1SiT7MweJhl
          ??AccessExpire:?86400

          6.5.2 添加 pay rpc 依賴

          • 添加 pay rpc 服務(wù)配置
          $?vim?api/etc/pay.yaml
          Name:?Pay
          Host:?0.0.0.0
          Port:?8003

          ......

          PayRpc:
          ??Etcd:
          ????Hosts:
          ????-?etcd:2379
          ????Key:?pay.rpc
          • 添加 pay rpc 服務(wù)配置的實(shí)例化
          $?vim?api/internal/config/config.go
          package?config

          import?(
          ?"github.com/tal-tech/go-zero/rest"
          ?"github.com/tal-tech/go-zero/zrpc"
          )

          type?Config?struct?{
          ?rest.RestConf

          ?Auth?struct?{
          ??AccessSecret?string
          ??AccessExpire?int64
          ?}

          ?PayRpc?zrpc.RpcClientConf
          }
          • 注冊(cè)服務(wù)上下文 pay rpc 的依賴
          $?vim?api/internal/svc/servicecontext.go
          package?svc

          import?(
          ?"mall/service/pay/api/internal/config"
          ?"mall/service/pay/rpc/payclient"

          ?"github.com/tal-tech/go-zero/zrpc"
          )

          type?ServiceContext?struct?{
          ?Config?config.Config
          ????
          ?PayRpc?payclient.Pay
          }

          func?NewServiceContext(c?config.Config)?*ServiceContext?{
          ?return?&ServiceContext{
          ??Config:?c,
          ??PayRpc:?payclient.NewPay(zrpc.MustNewClient(c.PayRpc)),
          ?}
          }

          6.5.3 添加支付創(chuàng)建邏輯 Create

          $?vim?api/internal/logic/createlogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/pay/api/internal/svc"
          ?"mall/service/pay/api/internal/types"
          ?"mall/service/pay/rpc/pay"

          ?"github.com/tal-tech/go-zero/core/logx"
          )

          type?CreateLogic?struct?{
          ?logx.Logger
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          }

          func?NewCreateLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?CreateLogic?{
          ?return?CreateLogic{
          ??Logger:?logx.WithContext(ctx),
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ?}
          }

          func?(l?*CreateLogic)?Create(req?types.CreateRequest)?(resp?*types.CreateResponse,?err?error)?{
          ?res,?err?:=?l.svcCtx.PayRpc.Create(l.ctx,?&pay.CreateRequest{
          ??Uid:????req.Uid,
          ??Oid:????req.Oid,
          ??Amount:?req.Amount,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?return?&types.CreateResponse{
          ??Id:?res.Id,
          ?},?nil
          }

          6.5.4 添加支付詳情邏輯 Detail

          $?vim?api/internal/logic/detaillogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/pay/api/internal/svc"
          ?"mall/service/pay/api/internal/types"
          ?"mall/service/pay/rpc/pay"

          ?"github.com/tal-tech/go-zero/core/logx"
          )

          type?DetailLogic?struct?{
          ?logx.Logger
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          }

          func?NewDetailLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?DetailLogic?{
          ?return?DetailLogic{
          ??Logger:?logx.WithContext(ctx),
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ?}
          }

          func?(l?*DetailLogic)?Detail(req?types.DetailRequest)?(resp?*types.DetailResponse,?err?error)?{
          ?res,?err?:=?l.svcCtx.PayRpc.Detail(l.ctx,?&pay.DetailRequest{
          ??Id:?req.Id,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?return?&types.DetailResponse{
          ??Id:?????req.Id,
          ??Uid:????res.Uid,
          ??Oid:????res.Oid,
          ??Amount:?res.Amount,
          ??Source:?res.Source,
          ??Status:?res.Status,
          ?},?nil
          }

          6.5.5 添加支付回調(diào)邏輯 Callback

          $?vim?api/internal/logic/callbacklogic.go
          package?logic

          import?(
          ?"context"

          ?"mall/service/pay/api/internal/svc"
          ?"mall/service/pay/api/internal/types"
          ?"mall/service/pay/rpc/pay"

          ?"github.com/tal-tech/go-zero/core/logx"
          )

          type?CallbackLogic?struct?{
          ?logx.Logger
          ?ctx????context.Context
          ?svcCtx?*svc.ServiceContext
          }

          func?NewCallbackLogic(ctx?context.Context,?svcCtx?*svc.ServiceContext)?CallbackLogic?{
          ?return?CallbackLogic{
          ??Logger:?logx.WithContext(ctx),
          ??ctx:????ctx,
          ??svcCtx:?svcCtx,
          ?}
          }

          func?(l?*CallbackLogic)?Callback(req?types.CallbackRequest)?(resp?*types.CallbackResponse,?err?error)?{
          ?_,?err?=?l.svcCtx.PayRpc.Callback(l.ctx,?&pay.CallbackRequest{
          ??Id:?????req.Id,
          ??Uid:????req.Uid,
          ??Oid:????req.Oid,
          ??Amount:?req.Amount,
          ??Source:?req.Source,
          ??Status:?req.Status,
          ?})
          ?if?err?!=?nil?{
          ??return?nil,?err
          ?}

          ?return?&types.CallbackResponse{},?nil
          }

          6.6 啟動(dòng) pay rpc 服務(wù)

          提示:?jiǎn)?dòng)服務(wù)需要在 golang 容器中啟動(dòng)

          $?cd?mall/service/pay/rpc
          $?go?run?pay.go?-f?etc/pay.yaml
          Starting?rpc?server?at?127.0.0.1:9003...

          6.7 啟動(dòng) pay api 服務(wù)

          提示:?jiǎn)?dòng)服務(wù)需要在 golang 容器中啟動(dòng)

          $?cd?mall/service/pay/api
          $?go?run?pay.go?-f?etc/pay.yaml
          Starting?server?at?0.0.0.0:8003...

          項(xiàng)目地址

          https://github.com/zeromicro/go-zero

          歡迎使用 go-zerostar 支持我們!



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù)?ebook?獲取;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 56
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄a免费看 | 国产午夜视频在线观看 | 91成人视频 亚洲一区二区 | 91视频搞靠逼 | 亚洲欧洲一区二区三区 |