init mongo
This commit is contained in:
parent
69746285ae
commit
9e667c83f3
|
@ -0,0 +1,148 @@
|
|||
run:
|
||||
timeout: 3m
|
||||
# Exit code when at least one issue was found.
|
||||
# Default: 1
|
||||
issues-exit-code: 2
|
||||
# Include test files or not.
|
||||
# Default: true
|
||||
tests: false
|
||||
|
||||
# Reference URL: https://golangci-lint.run/usage/linters/
|
||||
linters:
|
||||
# Disable everything by default so upgrades to not include new - default
|
||||
# enabled- linters.
|
||||
disable-all: true
|
||||
# Specifically enable linters we want to use.
|
||||
enable:
|
||||
# - depguard
|
||||
- errcheck
|
||||
# - godot
|
||||
- gofmt
|
||||
- goimports
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- misspell
|
||||
- revive
|
||||
# - staticcheck
|
||||
- typecheck
|
||||
- unused
|
||||
# - wsl
|
||||
- asasalint
|
||||
- asciicheck
|
||||
- bidichk
|
||||
- bodyclose
|
||||
# - containedctx
|
||||
- contextcheck
|
||||
# - cyclop
|
||||
# - varnamelen
|
||||
# - gci
|
||||
- wastedassign
|
||||
- whitespace
|
||||
# - wrapcheck
|
||||
- thelper
|
||||
- tparallel
|
||||
- unconvert
|
||||
- unparam
|
||||
- usestdlibvars
|
||||
- tenv
|
||||
- testableexamples
|
||||
- stylecheck
|
||||
- sqlclosecheck
|
||||
- nosprintfhostport
|
||||
- paralleltest
|
||||
- prealloc
|
||||
- predeclared
|
||||
- promlinter
|
||||
- reassign
|
||||
- rowserrcheck
|
||||
- nakedret
|
||||
- nestif
|
||||
- nilerr
|
||||
- nilnil
|
||||
- nlreturn
|
||||
- noctx
|
||||
- nolintlint
|
||||
- nonamedreturns
|
||||
- decorder
|
||||
- dogsled
|
||||
# - dupl
|
||||
- dupword
|
||||
- durationcheck
|
||||
- errchkjson
|
||||
- errname
|
||||
- errorlint
|
||||
# - execinquery
|
||||
- exhaustive
|
||||
- exportloopref
|
||||
- forbidigo
|
||||
- forcetypeassert
|
||||
# - gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
# - godox
|
||||
# - goerr113
|
||||
# - gofumpt
|
||||
- goheader
|
||||
- gomoddirectives
|
||||
# - gomodguard always failed
|
||||
- goprintffuncname
|
||||
- gosec
|
||||
- grouper
|
||||
- importas
|
||||
- interfacebloat
|
||||
# - ireturn
|
||||
- lll
|
||||
- loggercheck
|
||||
- maintidx
|
||||
- makezero
|
||||
|
||||
issues:
|
||||
exclude-rules:
|
||||
- path: _test\.go
|
||||
linters:
|
||||
- funlen
|
||||
- goconst
|
||||
- interfacer
|
||||
- dupl
|
||||
- lll
|
||||
- goerr113
|
||||
- errcheck
|
||||
- gocritic
|
||||
- cyclop
|
||||
- wrapcheck
|
||||
- gocognit
|
||||
- contextcheck
|
||||
|
||||
exclude-dirs:
|
||||
- internal/model
|
||||
|
||||
exclude-files:
|
||||
- .*_test.go
|
||||
|
||||
|
||||
|
||||
linters-settings:
|
||||
gci:
|
||||
sections:
|
||||
- standard # Standard section: captures all standard packages.
|
||||
- default # Default section: contains all imports that could not be matched to another section type.
|
||||
gocognit:
|
||||
# Minimal code complexity to report.
|
||||
# Default: 30 (but we recommend 10-20)
|
||||
min-complexity: 40
|
||||
nestif:
|
||||
# Minimal complexity of if statements to report.
|
||||
# Default: 5
|
||||
min-complexity: 10
|
||||
lll:
|
||||
# Max line length, lines longer will be reported.
|
||||
# '\t' is counted as 1 character by default, and can be changed with the tab-width option.
|
||||
# Default: 120.
|
||||
line-length: 200
|
||||
# Tab width in spaces.
|
||||
# Default: 1
|
||||
tab-width: 1
|
|
@ -4,3 +4,26 @@ Etcd:
|
|||
Hosts:
|
||||
- 127.0.0.1:2379
|
||||
Key: trade.rpc
|
||||
|
||||
mongodb:
|
||||
hosts: [ 127.0.0.1:27017 ]
|
||||
username:
|
||||
password:
|
||||
databaseName: "cnx_commission"
|
||||
minPoolSize: 10
|
||||
maxPoolSize: 30
|
||||
maxConnIdleTime: 30m
|
||||
replicaName: ""
|
||||
|
||||
Mongo:
|
||||
Schema: mongodb
|
||||
Host: 127.0.0.1
|
||||
User: ""
|
||||
Password: ""
|
||||
Port: "27017"
|
||||
Database: digimon_order
|
||||
ReplicaName: "order"
|
||||
MaxStaleness: 30m
|
||||
MaxPoolSize: 30
|
||||
MinPoolSize: 10
|
||||
MaxConnIdleTime: 30m
|
||||
|
|
17
go.mod
17
go.mod
|
@ -3,7 +3,12 @@ module app-cloudep-trade-service
|
|||
go 1.22.3
|
||||
|
||||
require (
|
||||
code.30cm.net/digimon/library-go/errs v1.2.5
|
||||
code.30cm.net/digimon/library-go/validator v1.0.0
|
||||
github.com/go-playground/validator/v10 v10.22.0
|
||||
github.com/shopspring/decimal v1.4.0
|
||||
github.com/zeromicro/go-zero v1.7.3
|
||||
go.mongodb.org/mongo-driver v1.17.1
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/protobuf v1.35.1
|
||||
)
|
||||
|
@ -18,14 +23,18 @@ require (
|
|||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/fatih/color v1.17.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
|
@ -34,11 +43,13 @@ require (
|
|||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/montanaflynn/stats v0.7.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
|
@ -48,6 +59,10 @@ require (
|
|||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.7.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.15 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.15 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.15 // indirect
|
||||
|
@ -66,8 +81,10 @@ require (
|
|||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.28.0 // indirect
|
||||
golang.org/x/net v0.30.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/sync v0.8.0 // indirect
|
||||
golang.org/x/sys v0.26.0 // indirect
|
||||
golang.org/x/term v0.25.0 // indirect
|
||||
golang.org/x/text v0.19.0 // indirect
|
||||
|
|
|
@ -1,7 +1,27 @@
|
|||
package config
|
||||
|
||||
import "github.com/zeromicro/go-zero/zrpc"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/zrpc"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
zrpc.RpcServerConf
|
||||
|
||||
Mongo struct {
|
||||
Schema string
|
||||
User string
|
||||
Password string
|
||||
Host string
|
||||
Port string
|
||||
Database string
|
||||
ReplicaName string
|
||||
MaxStaleness time.Duration
|
||||
MaxPoolSize uint64
|
||||
MinPoolSize uint64
|
||||
MaxConnIdleTime time.Duration
|
||||
// Compressors []string
|
||||
// EnableStandardReadWriteSplitMode bool
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/bson/bsonrw"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type MgoDecimal struct{}
|
||||
|
||||
var (
|
||||
_ bsoncodec.ValueEncoder = &MgoDecimal{}
|
||||
_ bsoncodec.ValueDecoder = &MgoDecimal{}
|
||||
)
|
||||
|
||||
func (dc *MgoDecimal) EncodeValue(_ bsoncodec.EncodeContext, w bsonrw.ValueWriter, value reflect.Value) error {
|
||||
// TODO 待確認是否有非decimal.Decimal type而導致error的場景
|
||||
dec, ok := value.Interface().(decimal.Decimal)
|
||||
if !ok {
|
||||
return fmt.Errorf("value %v to encode is not of type decimal.Decimal", value)
|
||||
}
|
||||
|
||||
// Convert decimal.Decimal to primitive.Decimal128.
|
||||
primDec, err := primitive.ParseDecimal128(dec.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting decimal.Decimal %v to primitive.Decimal128 error: %w", dec, err)
|
||||
}
|
||||
|
||||
return w.WriteDecimal128(primDec)
|
||||
}
|
||||
|
||||
func (dc *MgoDecimal) DecodeValue(_ bsoncodec.DecodeContext, r bsonrw.ValueReader, value reflect.Value) error {
|
||||
primDec, err := r.ReadDecimal128()
|
||||
if err != nil {
|
||||
return fmt.Errorf("reading primitive.Decimal128 from ValueReader error: %w", err)
|
||||
}
|
||||
|
||||
// Convert primitive.Decimal128 to decimal.Decimal.
|
||||
dec, err := decimal.NewFromString(primDec.String())
|
||||
if err != nil {
|
||||
return fmt.Errorf("converting primitive.Decimal128 %v to decimal.Decimal error: %w", primDec, err)
|
||||
}
|
||||
|
||||
// set as decimal.Decimal type
|
||||
value.Set(reflect.ValueOf(dec))
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func MustMongoConnectURL(c config.Config) string {
|
||||
return fmt.Sprintf("%s://%s:%s",
|
||||
c.Mongo.Schema,
|
||||
c.Mongo.Host,
|
||||
c.Mongo.Port,
|
||||
)
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package mongo
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
"reflect"
|
||||
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/bsoncodec"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
type TypeCodec struct {
|
||||
ValueType reflect.Type
|
||||
Encoder bsoncodec.ValueEncoder
|
||||
Decoder bsoncodec.ValueDecoder
|
||||
}
|
||||
|
||||
// WithTypeCodec registers TypeCodecs to convert custom types.
|
||||
func WithTypeCodec(typeCodecs ...TypeCodec) mon.Option {
|
||||
return func(c *options.ClientOptions) {
|
||||
registry := bson.NewRegistry()
|
||||
for _, v := range typeCodecs {
|
||||
registry.RegisterTypeEncoder(v.ValueType, v.Encoder)
|
||||
registry.RegisterTypeDecoder(v.ValueType, v.Decoder)
|
||||
}
|
||||
c.SetRegistry(registry)
|
||||
}
|
||||
}
|
||||
|
||||
// SetCustomDecimalType force convert primitive.Decimal128 to decimal.Decimal.
|
||||
func SetCustomDecimalType() mon.Option {
|
||||
return WithTypeCodec(TypeCodec{
|
||||
ValueType: reflect.TypeOf(decimal.Decimal{}),
|
||||
Encoder: &MgoDecimal{},
|
||||
Decoder: &MgoDecimal{},
|
||||
})
|
||||
}
|
||||
|
||||
func InitMongoOptions(cfg config.Config) mon.Option {
|
||||
return func(opts *options.ClientOptions) {
|
||||
opts.SetMaxPoolSize(cfg.Mongo.MaxPoolSize)
|
||||
opts.SetMinPoolSize(cfg.Mongo.MinPoolSize)
|
||||
opts.SetMaxConnIdleTime(cfg.Mongo.MaxConnIdleTime)
|
||||
opts.SetCompressors([]string{"snappy"})
|
||||
// opts.SetReplicaSet(cfg.Mongo.ReplicaName)
|
||||
// opts.SetWriteConcern(writeconcern.W1())
|
||||
// opts.SetReadPreference(readpref.Primary())
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNotFound = mon.ErrNotFound
|
||||
ErrInvalidObjectId = errors.New("invalid objectId")
|
||||
)
|
|
@ -0,0 +1,27 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
)
|
||||
|
||||
var _ OrderModel = (*customOrderModel)(nil)
|
||||
|
||||
type (
|
||||
// OrderModel is an interface to be customized, add more methods here,
|
||||
// and implement the added methods in customOrderModel.
|
||||
OrderModel interface {
|
||||
orderModel
|
||||
}
|
||||
|
||||
customOrderModel struct {
|
||||
*defaultOrderModel
|
||||
}
|
||||
)
|
||||
|
||||
// NewOrderModel returns a model for the mongo.
|
||||
func NewOrderModel(url, db, collection string, opts ...mon.Option) OrderModel {
|
||||
conn := mon.MustNewModel(url, db, collection, opts...)
|
||||
return &customOrderModel{
|
||||
defaultOrderModel: newDefaultOrderModel(conn),
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
// Code generated by goctl. DO NOT EDIT.
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
)
|
||||
|
||||
type orderModel interface {
|
||||
Insert(ctx context.Context, data *Order) error
|
||||
FindOne(ctx context.Context, id string) (*Order, error)
|
||||
Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error)
|
||||
Delete(ctx context.Context, id string) (int64, error)
|
||||
}
|
||||
|
||||
type defaultOrderModel struct {
|
||||
conn *mon.Model
|
||||
}
|
||||
|
||||
func newDefaultOrderModel(conn *mon.Model) *defaultOrderModel {
|
||||
return &defaultOrderModel{conn: conn}
|
||||
}
|
||||
|
||||
func (m *defaultOrderModel) Insert(ctx context.Context, data *Order) error {
|
||||
if data.ID.IsZero() {
|
||||
data.ID = primitive.NewObjectID()
|
||||
data.CreateAt = time.Now()
|
||||
data.UpdateAt = time.Now()
|
||||
}
|
||||
|
||||
_, err := m.conn.InsertOne(ctx, data)
|
||||
return err
|
||||
}
|
||||
|
||||
func (m *defaultOrderModel) FindOne(ctx context.Context, id string) (*Order, error) {
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return nil, ErrInvalidObjectId
|
||||
}
|
||||
|
||||
var data Order
|
||||
|
||||
err = m.conn.FindOne(ctx, &data, bson.M{"_id": oid})
|
||||
switch err {
|
||||
case nil:
|
||||
return &data, nil
|
||||
case mon.ErrNotFound:
|
||||
return nil, ErrNotFound
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
func (m *defaultOrderModel) Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error) {
|
||||
data.UpdateAt = time.Now()
|
||||
|
||||
res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (m *defaultOrderModel) Delete(ctx context.Context, id string) (int64, error) {
|
||||
oid, err := primitive.ObjectIDFromHex(id)
|
||||
if err != nil {
|
||||
return 0, ErrInvalidObjectId
|
||||
}
|
||||
|
||||
res, err := m.conn.DeleteOne(ctx, bson.M{"_id": oid})
|
||||
return res, err
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
)
|
||||
|
||||
type Order struct {
|
||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||
// TODO: Fill your own fields
|
||||
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
|
||||
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
|
||||
}
|
||||
|
||||
func (p *Order) CollectionName() string {
|
||||
return "order"
|
||||
}
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/couponservice"
|
||||
couponservicelogic "app-cloudep-trade-service/internal/logic/couponservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/inventoryservice"
|
||||
inventoryservicelogic "app-cloudep-trade-service/internal/logic/inventoryservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/orderservice"
|
||||
orderservicelogic "app-cloudep-trade-service/internal/logic/orderservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/productservice"
|
||||
productservicelogic "app-cloudep-trade-service/internal/logic/productservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/subscriptionservice"
|
||||
subscriptionservicelogic "app-cloudep-trade-service/internal/logic/subscriptionservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"context"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/logic/walletservice"
|
||||
walletservicelogic "app-cloudep-trade-service/internal/logic/walletservice"
|
||||
"app-cloudep-trade-service/internal/svc"
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package svc
|
||||
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
mgo "app-cloudep-trade-service/internal/lib/mongo"
|
||||
model "app-cloudep-trade-service/internal/model/mongo"
|
||||
)
|
||||
|
||||
// MustOrderModel 連線 order mongo 時
|
||||
func MustOrderModel(c config.Config) model.OrderModel {
|
||||
orderCollection := model.Order{}
|
||||
|
||||
return model.NewOrderModel(
|
||||
mgo.MustMongoConnectURL(c),
|
||||
c.Mongo.Database,
|
||||
orderCollection.CollectionName(),
|
||||
mgo.SetCustomDecimalType(),
|
||||
mgo.InitMongoOptions(c),
|
||||
)
|
||||
}
|
|
@ -1,13 +1,30 @@
|
|||
package svc
|
||||
|
||||
import "app-cloudep-trade-service/internal/config"
|
||||
import (
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
model "app-cloudep-trade-service/internal/model/mongo"
|
||||
|
||||
ers "code.30cm.net/digimon/library-go/errs"
|
||||
"code.30cm.net/digimon/library-go/errs/code"
|
||||
vi "code.30cm.net/digimon/library-go/validator"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
Config config.Config
|
||||
Validate vi.Validate
|
||||
OrderModel model.OrderModel
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
// TODO 改成 Trade
|
||||
ers.Scope = code.CloudEPOrder
|
||||
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
Validate: vi.MustValidator(
|
||||
WithDecimalGt(),
|
||||
WithDecimalGte(),
|
||||
),
|
||||
OrderModel: MustOrderModel(c),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
package svc
|
||||
|
||||
import (
|
||||
vi "code.30cm.net/digimon/library-go/validator"
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
// WithDecimalGt 是否大於等於
|
||||
func WithDecimalGt() vi.Option {
|
||||
return vi.Option{
|
||||
ValidatorName: "decimalGt",
|
||||
ValidatorFunc: func(fl validator.FieldLevel) bool {
|
||||
if val, ok := fl.Field().Interface().(string); ok {
|
||||
value, err := decimal.NewFromString(val)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
conditionValue, err := decimal.NewFromString(fl.Param())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return value.GreaterThan(conditionValue)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// WithDecimalGte 是否大於等於
|
||||
func WithDecimalGte() vi.Option {
|
||||
return vi.Option{
|
||||
ValidatorName: "decimalGte",
|
||||
ValidatorFunc: func(fl validator.FieldLevel) bool {
|
||||
if val, ok := fl.Field().Interface().(string); ok {
|
||||
value, err := decimal.NewFromString(val)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
conditionValue, err := decimal.NewFromString(fl.Param())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return value.GreaterThanOrEqual(conditionValue)
|
||||
}
|
||||
|
||||
return true
|
||||
},
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package svc
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
vi "code.30cm.net/digimon/library-go/validator"
|
||||
)
|
||||
|
||||
func TestWithDecimalGte(t *testing.T) {
|
||||
validate := vi.MustValidator(WithDecimalGt(), WithDecimalGte())
|
||||
|
||||
type TestStruct struct {
|
||||
Value string `validate:"decimalGte=10.50"`
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input TestStruct
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid - equal",
|
||||
input: TestStruct{Value: "10.50"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "valid - greater",
|
||||
input: TestStruct{Value: "15.00"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - less",
|
||||
input: TestStruct{Value: "9.99"},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid - not a decimal",
|
||||
input: TestStruct{Value: "abc"},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid - empty string",
|
||||
input: TestStruct{Value: ""},
|
||||
wantErr: true, // Assuming empty string is valid
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validate.ValidateAll(tt.input)
|
||||
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("TestWithDecimalGte() %s = error %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithDecimalGt(t *testing.T) {
|
||||
validate := vi.MustValidator(WithDecimalGt(), WithDecimalGt())
|
||||
|
||||
type TestStruct struct {
|
||||
Value string `validate:"decimalGt=10.50"`
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input TestStruct
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "valid - greater",
|
||||
input: TestStruct{Value: "10.51"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - equal",
|
||||
input: TestStruct{Value: "10.50"},
|
||||
wantErr: true, // should fail because the value is equal to the condition
|
||||
},
|
||||
{
|
||||
name: "invalid - less",
|
||||
input: TestStruct{Value: "9.99"},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "invalid - not a decimal",
|
||||
input: TestStruct{Value: "abc"},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid - empty string",
|
||||
input: TestStruct{Value: ""},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := validate.ValidateAll(tt.input)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("TestWithDecimalGt() %s = error %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
5
trade.go
5
trade.go
|
@ -2,7 +2,8 @@ package main
|
|||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
||||
"app-cloudep-trade-service/gen_result/pb/trade"
|
||||
"app-cloudep-trade-service/internal/config"
|
||||
|
@ -44,6 +45,6 @@ func main() {
|
|||
})
|
||||
defer s.Stop()
|
||||
|
||||
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
|
||||
logx.Infof("Starting rpc server at %s...\n", c.ListenOn)
|
||||
s.Start()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue