refactor: reorganize modules and add Linux build tooling
This commit is contained in:
41
module/ec/address/internal/config/config.go
Normal file
41
module/ec/address/internal/config/config.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/conf"
|
||||
"git.apinb.com/bsm-sdk/core/crypto/encipher"
|
||||
"git.apinb.com/bsm-sdk/core/env"
|
||||
)
|
||||
|
||||
var (
|
||||
Spec SrvConfig
|
||||
)
|
||||
|
||||
type SrvConfig struct {
|
||||
conf.Base `yaml:",inline"`
|
||||
Databases *conf.DBConf `yaml:"Databases"`
|
||||
MicroService *conf.MicroServiceConf `yaml:"MicroService"`
|
||||
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
||||
Gateway *conf.GatewayConf `yaml:"Gateway"`
|
||||
Apm *conf.ApmConf `yaml:"APM"`
|
||||
Etcd *conf.EtcdConf `yaml:"Etcd"`
|
||||
}
|
||||
|
||||
func New(srvKey string) {
|
||||
// 初始化配置 创建一个新的配置实例,用于服务配置
|
||||
conf.New(srvKey, &Spec)
|
||||
|
||||
// 配置校验 服务IP,端口; 端口如果不合规,则随机分配端口
|
||||
Spec.Port = conf.CheckPort(Spec.Port)
|
||||
Spec.BindIP = conf.CheckIP(Spec.BindIP)
|
||||
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
|
||||
|
||||
// 配置校验 服务名称地址及监听地址不能为空
|
||||
conf.NotNil(Spec.Service, Spec.Cache)
|
||||
|
||||
// 初始化加密SecretKey
|
||||
encipher.New(env.Runtime.JwtSecretKey)
|
||||
|
||||
conf.PrintInfo(Spec.Addr)
|
||||
}
|
||||
12
module/ec/address/internal/impl/impl.go
Normal file
12
module/ec/address/internal/impl/impl.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
)
|
||||
|
||||
func NewImpl() {
|
||||
// with activating
|
||||
withRedisCache(vars.ServiceKey) // redis cache
|
||||
withDatabases() // model
|
||||
withEtcd() // etcd
|
||||
}
|
||||
84
module/ec/address/internal/impl/with.go
Normal file
84
module/ec/address/internal/impl/with.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package impl
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"bsm/full/module/ec/address/internal/config"
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
"git.apinb.com/bsm-sdk/core/cache/redis"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
"go.etcd.io/etcd/client/pkg/v3/transport"
|
||||
clientv3 "go.etcd.io/etcd/client/v3"
|
||||
)
|
||||
|
||||
var (
|
||||
RedisCache *redis.RedisClient
|
||||
Etcd *clientv3.Client
|
||||
)
|
||||
|
||||
func withRedisCache(srvKey string) {
|
||||
if config.Spec.Cache != "" {
|
||||
RedisCache = redis.New(config.Spec.Cache, srvKey)
|
||||
}
|
||||
|
||||
// print inform.
|
||||
printer.Info("[BSM - %s] Cache: %s, DBIndex: %d", vars.ServiceKey, config.Spec.Cache, RedisCache.DB)
|
||||
}
|
||||
|
||||
func withDatabases() {
|
||||
if config.Spec.Databases == nil || len(config.Spec.Databases.Source) == 0 {
|
||||
panic("No Database Source Found !")
|
||||
}
|
||||
|
||||
// print inform.
|
||||
printer.Info("[BSM - %s] Databases: %v", vars.ServiceKey, config.Spec.Databases)
|
||||
|
||||
err := models.New(config.Spec.Databases.Driver, config.Spec.Databases.Source, nil)
|
||||
if err != nil {
|
||||
printer.Error("Database Init Failed !")
|
||||
panic(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func withEtcd() {
|
||||
if config.Spec.Etcd != nil {
|
||||
if len(config.Spec.Etcd.Endpoints) == 0 {
|
||||
panic(errcode.ErrNotFound(0, "Etcd Endpoints"))
|
||||
}
|
||||
cfg := clientv3.Config{
|
||||
Endpoints: config.Spec.Etcd.Endpoints,
|
||||
DialTimeout: 5 * time.Second,
|
||||
}
|
||||
if config.Spec.Etcd.Passwd != nil {
|
||||
cfg.Username = config.Spec.Etcd.Passwd.Account
|
||||
cfg.Password = config.Spec.Etcd.Passwd.Password
|
||||
}
|
||||
if config.Spec.Etcd.TLS != nil {
|
||||
tlsInfo := transport.TLSInfo{
|
||||
TrustedCAFile: config.Spec.Etcd.TLS.CaFile,
|
||||
CertFile: config.Spec.Etcd.TLS.CertFile,
|
||||
KeyFile: config.Spec.Etcd.TLS.KeyFile,
|
||||
}
|
||||
tlsConfig, err := tlsInfo.ClientConfig()
|
||||
if err != nil {
|
||||
printer.Error(errcode.ErrEtcd.Error())
|
||||
panic(err)
|
||||
}
|
||||
cfg.TLS = tlsConfig
|
||||
}
|
||||
etcd, err := clientv3.New(cfg)
|
||||
|
||||
if err != nil {
|
||||
printer.Error(errcode.ErrEtcd.Error())
|
||||
panic(err)
|
||||
}
|
||||
|
||||
Etcd = etcd
|
||||
|
||||
// print inform.
|
||||
printer.Info("[BSM - %s] Service Center: %v", vars.ServiceKey, config.Spec.Etcd.Endpoints)
|
||||
}
|
||||
}
|
||||
56
module/ec/address/internal/logic/library/create.go
Normal file
56
module/ec/address/internal/logic/library/create.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
"git.apinb.com/bsm-sdk/core/utils"
|
||||
)
|
||||
|
||||
// 新增地址
|
||||
func Create(ctx context.Context, in *pb.AddressCreateRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
address := &models.AddressLibrary{
|
||||
Country: in.Country,
|
||||
Phone: in.Phone,
|
||||
Province: in.Province,
|
||||
City: in.City,
|
||||
Area: in.Area,
|
||||
Detail: in.Detail,
|
||||
Contact: in.Contact,
|
||||
Name: in.Name,
|
||||
Pics: in.Pics,
|
||||
}
|
||||
address.Identity = utils.UUID()
|
||||
address.OwnerID = auth.ID
|
||||
address.OwnerIdentity = auth.Identity
|
||||
address.Status = int8(in.Status)
|
||||
|
||||
if address.Status == 2 {
|
||||
models.DBService.Model(&models.AddressLibrary{}).Where("owner_id = ? and status=2", auth.ID).UpdateColumn("status", "1")
|
||||
}
|
||||
|
||||
err = models.DBService.Create(address).Error
|
||||
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().UnixNano(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
34
module/ec/address/internal/logic/library/delete.go
Normal file
34
module/ec/address/internal/logic/library/delete.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 删除一个地址
|
||||
func Delete(ctx context.Context, in *pb.AddressDeleteRequest) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = models.DBService.Delete(&models.AddressLibrary{}, "id in ?", in.Id).Error
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().UnixNano(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
60
module/ec/address/internal/logic/library/fetch.go
Normal file
60
module/ec/address/internal/logic/library/fetch.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取地址列表
|
||||
func Fetch(ctx context.Context, in *pb.IdentRequest) (reply *pb.AddressListReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var (
|
||||
address = make([]*models.AddressLibrary, 0)
|
||||
result = make([]*pb.AddressItem, 0)
|
||||
)
|
||||
|
||||
err = models.DBService.Where("owner_identity=?", auth.Identity).Find(&address).Error
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
for _, item := range address {
|
||||
result = append(result, ReflectProtoAddress(item))
|
||||
}
|
||||
|
||||
// TODO: add your logic code & delete this line.
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func ReflectProtoAddress(v *models.AddressLibrary) *pb.AddressItem {
|
||||
if nil == v {
|
||||
return nil
|
||||
}
|
||||
result := &pb.AddressItem{
|
||||
Id: int64(v.ID),
|
||||
Identity: v.Identity,
|
||||
Country: v.Country,
|
||||
Phone: v.Phone,
|
||||
Province: v.Province,
|
||||
City: v.City,
|
||||
Area: v.Area,
|
||||
Detail: v.Detail,
|
||||
Contact: v.Contact,
|
||||
Name: v.Name,
|
||||
Pics: v.Pics,
|
||||
Status: int32(v.Status),
|
||||
}
|
||||
return result
|
||||
}
|
||||
51
module/ec/address/internal/logic/library/get.go
Normal file
51
module/ec/address/internal/logic/library/get.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 获取一条地址
|
||||
func Get(ctx context.Context, in *pb.IdentRequest) (reply *pb.AddressItem, err error) {
|
||||
// parse authorization meta.
|
||||
_, err = service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if in.GetId() == 0 {
|
||||
return nil, errcode.ErrInvalidArgument
|
||||
}
|
||||
|
||||
address := new(models.AddressLibrary)
|
||||
err = models.DBService.Where("id=?", in.Id).First(&address).Error
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, models.ErrNotFound) {
|
||||
return nil, errcode.ErrRecordNotFound
|
||||
}
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.AddressItem{
|
||||
Id: int64(address.ID),
|
||||
Identity: address.Identity,
|
||||
Name: address.Name,
|
||||
Phone: address.Phone,
|
||||
Province: address.Province,
|
||||
City: address.City,
|
||||
Area: address.Area,
|
||||
Detail: address.Detail,
|
||||
Country: address.Country,
|
||||
Pics: address.Pics,
|
||||
Contact: address.Contact,
|
||||
Status: int32(address.Status),
|
||||
}, nil
|
||||
}
|
||||
49
module/ec/address/internal/logic/library/modify.go
Normal file
49
module/ec/address/internal/logic/library/modify.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package library
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"bsm/full/module/ec/address/internal/models"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/errcode"
|
||||
"git.apinb.com/bsm-sdk/core/printer"
|
||||
"git.apinb.com/bsm-sdk/core/service"
|
||||
)
|
||||
|
||||
// 修改地址
|
||||
func Modify(ctx context.Context, in *pb.AddressItem) (reply *pb.StatusReply, err error) {
|
||||
// parse authorization meta.
|
||||
auth, err := service.ParseMetaCtx(ctx, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
address := &models.AddressLibrary{
|
||||
Country: in.Country,
|
||||
Phone: in.Phone,
|
||||
Province: in.Province,
|
||||
City: in.City,
|
||||
Area: in.Area,
|
||||
Detail: in.Detail,
|
||||
Contact: in.Contact,
|
||||
}
|
||||
address.Status = int8(in.Status)
|
||||
|
||||
if address.Status == 2 {
|
||||
models.DBService.Model(&models.AddressLibrary{}).Where("owner_id = ? and status=2", auth.ID).UpdateColumn("status", "1")
|
||||
}
|
||||
|
||||
err = models.DBService.Where("id=?", in.Id).Updates(&address).Error
|
||||
if err != nil {
|
||||
printer.Error(err.Error())
|
||||
return nil, errcode.ErrDB
|
||||
}
|
||||
|
||||
return &pb.StatusReply{
|
||||
Code: 0,
|
||||
Message: "OK",
|
||||
Timeseq: time.Now().UnixNano(),
|
||||
}, nil
|
||||
|
||||
}
|
||||
32
module/ec/address/internal/models/address_library.go
Normal file
32
module/ec/address/internal/models/address_library.go
Normal file
@@ -0,0 +1,32 @@
|
||||
// Models generated by mesh dev cli,@Author: David Yan(david.yan@qq.com).
|
||||
package models
|
||||
|
||||
import (
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
)
|
||||
|
||||
/*
|
||||
* OrderAddress
|
||||
* Comment:
|
||||
* Version: 10
|
||||
* Created: 2022-04-12 18:21:15 , Updated:0001-01-01 00:00:00
|
||||
*/
|
||||
type AddressLibrary struct {
|
||||
types.Std_IICUDS
|
||||
OwnerID uint `gorm:"column:owner_id;Index;" json:"owner_id"`
|
||||
OwnerIdentity string `gorm:"column:owner_identity;type:varchar(36);Index;" json:"owner_identity"` // 用户唯一标识,24位NanoID,36位为UUID
|
||||
Phone string `gorm:"column:phone;type:varchar(20);default:'';" json:"phone"` // 地址电话
|
||||
Country string `gorm:"column:country;type:varchar(255);default:'';" json:"country"` // 国家
|
||||
Province string `gorm:"column:province;type:varchar(255);default:'';" json:"province"` // 省
|
||||
City string `gorm:"column:city;type:varchar(255);default:'';" json:"city"` // 市
|
||||
Area string `gorm:"column:area;type:varchar(255);default:'';" json:"area"` // 区
|
||||
Detail string `gorm:"column:detail;type:varchar(255);default:'';" json:"detail"` // 详细地址
|
||||
Contact string `gorm:"column:contact;type:varchar(20);default:'';" json:"contact"` // 收件人
|
||||
Name string `gorm:"column:name;type:varchar(255);default:'';" json:"name"` // 名称
|
||||
Pics string `gorm:"column:pics;default:'';" json:"pics"` // 图片信息
|
||||
}
|
||||
|
||||
// TableName .
|
||||
func (table *AddressLibrary) TableName() string {
|
||||
return "address_library" //对应数据库表名
|
||||
}
|
||||
84
module/ec/address/internal/models/impl.go
Normal file
84
module/ec/address/internal/models/impl.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"git.apinb.com/bsm-sdk/core/database/sql"
|
||||
"git.apinb.com/bsm-sdk/core/types"
|
||||
"gorm.io/driver/mysql"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var DBService *gorm.DB
|
||||
|
||||
var migrateTables = []any{
|
||||
&AddressLibrary{},
|
||||
}
|
||||
|
||||
func New(driver string, dsn []string, options *types.SqlOptions) (err error) {
|
||||
driver = strings.ToLower(driver)
|
||||
|
||||
switch driver {
|
||||
case "mysql":
|
||||
DBService, err = NewMysql(dsn, options)
|
||||
case "postgres":
|
||||
DBService, err = NewPostgres(dsn, options)
|
||||
default:
|
||||
log.Fatalln("Unsupported database driver:", driver)
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// auto migrate table.
|
||||
err = DBService.AutoMigrate(migrateTables...)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func NewMysql(dsn []string, options *types.SqlOptions) (gormDb *gorm.DB, err error) {
|
||||
//set connection default val.
|
||||
options = sql.SetOptions(options)
|
||||
|
||||
gormDb, err = gorm.Open(mysql.Open(dsn[0]), &gorm.Config{
|
||||
SkipDefaultTransaction: true,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if options.Debug {
|
||||
gormDb = gormDb.Debug()
|
||||
}
|
||||
|
||||
// 获取通用数据库对象 sql.DB ,然后使用其提供的功能
|
||||
sqlDB, _ := gormDb.DB()
|
||||
// SetMaxIdleConns 用于设置连接池中空闲连接的最大数量。
|
||||
sqlDB.SetMaxIdleConns(options.MaxIdleConns)
|
||||
// SetMaxOpenConns 设置打开数据库连接的最大数量。
|
||||
sqlDB.SetMaxOpenConns(options.MaxOpenConns)
|
||||
// SetConnMaxLifetime 设置了连接可复用的最大时间。
|
||||
sqlDB.SetConnMaxLifetime(options.ConnMaxLifetime)
|
||||
|
||||
return gormDb, nil
|
||||
}
|
||||
|
||||
func NewPostgres(dsn []string, options *types.SqlOptions) (gormDb *gorm.DB, err error) {
|
||||
//set connection default val.
|
||||
options = sql.SetOptions(options)
|
||||
|
||||
db, err := sql.NewPostgreSql(dsn[0], options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
db = db.Debug()
|
||||
return db, nil
|
||||
}
|
||||
5
module/ec/address/internal/models/query.go
Normal file
5
module/ec/address/internal/models/query.go
Normal file
@@ -0,0 +1,5 @@
|
||||
package models
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
var ErrNotFound = gorm.ErrRecordNotFound
|
||||
41
module/ec/address/internal/server/library_server.go
Normal file
41
module/ec/address/internal/server/library_server.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"bsm/full/module/ec/address/internal/logic/library"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
)
|
||||
|
||||
type LibraryServer struct {
|
||||
pb.UnimplementedLibraryServer
|
||||
}
|
||||
|
||||
func NewLibraryServer() *LibraryServer {
|
||||
return &LibraryServer{}
|
||||
}
|
||||
|
||||
// 新增地址
|
||||
func (s *LibraryServer) Create(ctx context.Context, in *pb.AddressCreateRequest) (*pb.StatusReply, error) {
|
||||
return library.Create(ctx, in)
|
||||
}
|
||||
|
||||
// 修改地址
|
||||
func (s *LibraryServer) Modify(ctx context.Context, in *pb.AddressItem) (*pb.StatusReply, error) {
|
||||
return library.Modify(ctx, in)
|
||||
}
|
||||
|
||||
// 获取一条地址
|
||||
func (s *LibraryServer) Get(ctx context.Context, in *pb.IdentRequest) (*pb.AddressItem, error) {
|
||||
return library.Get(ctx, in)
|
||||
}
|
||||
|
||||
// 获取地址列表
|
||||
func (s *LibraryServer) Fetch(ctx context.Context, in *pb.IdentRequest) (*pb.AddressListReply, error) {
|
||||
return library.Fetch(ctx, in)
|
||||
}
|
||||
|
||||
// 删除一个地址
|
||||
func (s *LibraryServer) Delete(ctx context.Context, in *pb.AddressDeleteRequest) (*pb.StatusReply, error) {
|
||||
return library.Delete(ctx, in)
|
||||
}
|
||||
71
module/ec/address/internal/server/new.go
Normal file
71
module/ec/address/internal/server/new.go
Normal file
@@ -0,0 +1,71 @@
|
||||
// Code generated by protoc-gen-slc. DO NOT EDIT.
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
pb "bsm/full/module/ec/address/pb"
|
||||
"git.apinb.com/bsm-sdk/core/vars"
|
||||
gwRuntime "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/reflection"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
Grpc *grpc.Server
|
||||
Ctx context.Context
|
||||
Mux *gwRuntime.ServeMux
|
||||
}
|
||||
|
||||
func New(addr string) *Server {
|
||||
srv := &Server{Ctx: context.Background(), Grpc: grpc.NewServer(), Mux: gwRuntime.NewServeMux(
|
||||
gwRuntime.WithForwardResponseRewriter(responseEnvelope),
|
||||
)}
|
||||
|
||||
// register service to grpc.Server
|
||||
pb.RegisterLibraryServer(srv.Grpc, NewLibraryServer())
|
||||
|
||||
reflection.Register(srv.Grpc)
|
||||
|
||||
// 将服务注册到Gateway
|
||||
opts := []grpc.DialOption{grpc.WithInsecure()}
|
||||
pb.RegisterLibraryHandlerFromEndpoint(srv.Ctx, srv.Mux, addr, opts)
|
||||
|
||||
// Register services swagger
|
||||
srv.RegisterSwagger()
|
||||
|
||||
return srv
|
||||
}
|
||||
|
||||
// RegisterSwagger 注册swagger
|
||||
func (s *Server) RegisterSwagger() {
|
||||
srvKey := strings.ToLower(vars.ServiceKey)
|
||||
s.Mux.HandlePath("GET", "/"+srvKey+".swagger.json", func(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
bytes, err := os.ReadFile("./swagger/" + srvKey + ".swagger.json")
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte(err.Error()))
|
||||
return
|
||||
}
|
||||
w.Write(bytes)
|
||||
return
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// response envelope
|
||||
func responseEnvelope(_ context.Context, response proto.Message) (interface{}, error) {
|
||||
name := string(response.ProtoReflect().Descriptor().Name())
|
||||
if name == "Status" || name == "Error" || name == "StatusReply" {
|
||||
return response, nil
|
||||
}
|
||||
return map[string]any{
|
||||
"code": 0,
|
||||
"message": "OK",
|
||||
"result": response,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user