feature/order_base #1
2
Makefile
2
Makefile
|
@ -61,4 +61,4 @@ mock-gen: # 建立 mock 資料
|
||||||
|
|
||||||
.PHONY: migrate-database
|
.PHONY: migrate-database
|
||||||
migrate-database:
|
migrate-database:
|
||||||
migrate -source file://generate/database/migrations/mongodb -database 'mongodb://127.0.0.1:27017/digimon_order' up
|
migrate -source file://generate/database/mongodb -database 'mongodb://127.0.0.1:27017/digimon_order' up
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
use digimon_order;
|
||||||
|
|
||||||
|
db.order.createIndex({
|
||||||
|
"uid": 1,
|
||||||
|
"order_type": 1,
|
||||||
|
"order_status": 1,
|
||||||
|
"create_time": 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
db.order.createIndex({
|
||||||
|
"business_id": 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 查詢時全部要 1&2 有幾個類用幾個累才會中索引
|
||||||
|
db.order.createIndex({
|
||||||
|
"uid": 1,
|
||||||
|
"direction_type": 1,
|
||||||
|
"crypto_type": 1
|
||||||
|
})
|
|
@ -9,46 +9,159 @@ message OKResp {}
|
||||||
message NoneReq {}
|
message NoneReq {}
|
||||||
|
|
||||||
// 分頁信息
|
// 分頁信息
|
||||||
message Pager
|
message Pager {
|
||||||
{
|
|
||||||
int64 total = 1; // 總數量
|
int64 total = 1; // 總數量
|
||||||
int64 size = 2; // 每頁數量
|
int64 size = 2; // 每頁數量
|
||||||
int64 index = 3; // 當前頁碼
|
int64 index = 3; // 當前頁碼
|
||||||
}
|
}
|
||||||
|
|
||||||
message CreateOrderReq{}
|
message CreateOrderReq {
|
||||||
message CreateOrderResp{}
|
string business_id = 1; // 訂單業務流水號
|
||||||
|
int32 order_type = 2; // 訂單類型
|
||||||
|
int32 order_status = 3; // 訂單狀態
|
||||||
|
string brand = 4; // 下單平台
|
||||||
|
string order_uid = 5; // 下單用戶 UID
|
||||||
|
string reference_id = 6; // 訂單來源
|
||||||
|
string count = 7; // 訂單數量 (decimal to string)
|
||||||
|
string order_fee = 8; // 訂單手續費 (decimal to string)
|
||||||
|
string amount = 9; // 單價 (decimal to string)
|
||||||
|
|
||||||
message CancelOrderReq{}
|
// 以下是可選字段(擴充用)
|
||||||
message ModifyOrderReq{}
|
optional string reference_brand = 10; // 訂單來源平台
|
||||||
message ModifyOrderStatusReq{}
|
optional string reference_uid = 11; // 訂單來源用戶 UID
|
||||||
message DeleteOrderReq{}
|
optional int64 wallet_status = 12; // 交易金額狀態
|
||||||
|
optional int64 three_party_status = 13; // 三方請求狀態
|
||||||
|
optional int64 direction_type = 14; // 交易方向
|
||||||
|
optional string crypto_type = 15; // 交易幣種
|
||||||
|
optional string third_party_fee = 16; // 第三方手續費 (decimal to string)
|
||||||
|
optional string crypto_to_usdt_rate = 17; // 交易幣種對 USDT 匯率 (decimal to string)
|
||||||
|
optional string fiat_to_usd_rate = 18; // 法幣對 USD 匯率 (decimal to string)
|
||||||
|
optional string fee_crypto_to_usdt_rate = 19; // 手續費幣種對 USDT 匯率 (decimal to string)
|
||||||
|
optional string usdt_to_crypto_type_rate = 20; // USDT 對交易幣種匯率 (decimal to string)
|
||||||
|
optional string payment_fiat = 21; // 支付法幣
|
||||||
|
optional string payment_unit_price = 22; // crypto 單價 (decimal to string)
|
||||||
|
optional string payment_template_id = 23; // 支付方式配置 ID
|
||||||
|
optional int64 order_arrival_time = 24; // 訂單到帳時間
|
||||||
|
optional int64 order_payment_time = 25; // 訂單付款時間
|
||||||
|
optional int64 unpaid_timeout_second = 26; // 支付期限秒數
|
||||||
|
optional string chain_type = 27; // 主網類型
|
||||||
|
optional string tx_hash = 28; // 交易哈希
|
||||||
|
optional string from_address = 29; // 來源地址
|
||||||
|
optional string to_address = 30; // 目標地址
|
||||||
|
optional string chain_fee = 31; // 鏈上交易手續費 (decimal to string)
|
||||||
|
optional string chain_fee_crypto = 32; // 鏈上手續費使用幣別
|
||||||
|
optional string memo = 33; // 鏈上備註
|
||||||
|
optional string order_note = 34; // 訂單交易備註
|
||||||
|
}
|
||||||
|
|
||||||
message GetOrderReq{}
|
message CancelOrderReq {
|
||||||
message GetOrderResp{}
|
string business_id = 1;
|
||||||
|
int64 status = 2;
|
||||||
|
}
|
||||||
|
|
||||||
message ListOrderReq{}
|
message ModifyOrderStatusReq {
|
||||||
message ListOrderResp{}
|
string business_id = 1;
|
||||||
|
int64 status = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DeleteOrderReq {
|
||||||
|
string business_id = 1;
|
||||||
|
}
|
||||||
|
|
||||||
message OrderStatusTimeoutReq{}
|
message OrderStatusTimeoutReq {}
|
||||||
|
|
||||||
|
message GetOrderReq {
|
||||||
|
string business_id = 1; // 訂單業務流水號
|
||||||
|
}
|
||||||
|
message GetOrderResp {
|
||||||
|
string business_id = 1; // 訂單業務流水號
|
||||||
|
int32 order_type = 2; // 訂單類型
|
||||||
|
int32 order_status = 3; // 訂單狀態
|
||||||
|
string brand = 4; // 下單平台
|
||||||
|
string order_uid = 5; // 下單用戶 UID
|
||||||
|
string reference_id = 6; // 訂單來源
|
||||||
|
string count = 7; // 訂單數量 (decimal to string)
|
||||||
|
string order_fee = 8; // 訂單手續費 (decimal to string)
|
||||||
|
string amount = 9; // 單價 (decimal to string)
|
||||||
|
|
||||||
|
// 以下是可選字段(擴充用)
|
||||||
|
optional string reference_brand = 10; // 訂單來源平台
|
||||||
|
optional string reference_uid = 11; // 訂單來源用戶 UID
|
||||||
|
optional int64 wallet_status = 12; // 交易金額狀態
|
||||||
|
optional int64 three_party_status = 13; // 三方請求狀態
|
||||||
|
optional int64 direction_type = 14; // 交易方向
|
||||||
|
optional string crypto_type = 15; // 交易幣種
|
||||||
|
optional string third_party_fee = 16; // 第三方手續費 (decimal to string)
|
||||||
|
optional string crypto_to_usdt_rate = 17; // 交易幣種對 USDT 匯率 (decimal to string)
|
||||||
|
optional string fiat_to_usd_rate = 18; // 法幣對 USD 匯率 (decimal to string)
|
||||||
|
optional string fee_crypto_to_usdt_rate = 19; // 手續費幣種對 USDT 匯率 (decimal to string)
|
||||||
|
optional string usdt_to_crypto_type_rate = 20; // USDT 對交易幣種匯率 (decimal to string)
|
||||||
|
optional string payment_fiat = 21; // 支付法幣
|
||||||
|
optional string payment_unit_price = 22; // crypto 單價 (decimal to string)
|
||||||
|
optional string payment_template_id = 23; // 支付方式配置 ID
|
||||||
|
optional int64 order_arrival_time = 24; // 訂單到帳時間
|
||||||
|
optional int64 order_payment_time = 25; // 訂單付款時間
|
||||||
|
optional int64 unpaid_timeout_second = 26; // 支付期限秒數
|
||||||
|
optional string chain_type = 27; // 主網類型
|
||||||
|
optional string tx_hash = 28; // 交易哈希
|
||||||
|
optional string from_address = 29; // 來源地址
|
||||||
|
optional string to_address = 30; // 目標地址
|
||||||
|
optional string chain_fee = 31; // 鏈上交易手續費 (decimal to string)
|
||||||
|
optional string chain_fee_crypto = 32; // 鏈上手續費使用幣別
|
||||||
|
optional string memo = 33; // 鏈上備註
|
||||||
|
optional string order_note = 34; // 訂單交易備註
|
||||||
|
int64 create_time = 35; // 建立時間
|
||||||
|
int64 update_time = 36; // 更新時間
|
||||||
|
}
|
||||||
|
|
||||||
|
message ModifyOrderReq {}
|
||||||
|
|
||||||
|
message ListOrderReq {
|
||||||
|
int64 page_index = 1; // required
|
||||||
|
int64 page_size = 2; // required
|
||||||
|
|
||||||
|
string reference_id = 3;
|
||||||
|
string reference_uid = 4;
|
||||||
|
string business_id = 5;
|
||||||
|
string uid = 6;
|
||||||
|
int32 order_type = 7;
|
||||||
|
repeated int32 direction_type = 8;
|
||||||
|
repeated int32 order_status = 9;
|
||||||
|
|
||||||
|
int64 start_create_time = 10;
|
||||||
|
int64 end_create_time = 11;
|
||||||
|
int64 start_update_time = 12;
|
||||||
|
int64 end_update_time = 13;
|
||||||
|
int64 start_order_arrival_time = 14;
|
||||||
|
int64 end_order_arrival_time = 15;
|
||||||
|
int64 start_order_payment_time = 16;
|
||||||
|
int64 end_order_payment_time = 17;
|
||||||
|
|
||||||
|
string crypto_type = 18;
|
||||||
|
string tx_hash = 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ListOrderResp {
|
||||||
|
repeated GetOrderResp data = 1; // 訂單列表
|
||||||
|
Pager page = 2;
|
||||||
|
}
|
||||||
|
|
||||||
// OrderService 訂單服務(業務邏輯在外面組合)
|
// OrderService 訂單服務(業務邏輯在外面組合)
|
||||||
service OrderService{
|
service OrderService {
|
||||||
// CreateOrder 建立訂單
|
// CreateOrder 建立訂單
|
||||||
rpc CreateOrder(CreateOrderReq)returns(CreateOrderResp);
|
rpc CreateOrder(CreateOrderReq) returns (OKResp);
|
||||||
// CancelOrder 取消訂單
|
// CancelOrder 取消訂單
|
||||||
rpc CancelOrder(CancelOrderReq)returns(OKResp);
|
rpc CancelOrder(CancelOrderReq) returns (OKResp);
|
||||||
// ModifyOrder 修改訂單
|
// ModifyOrder 修改訂單
|
||||||
rpc ModifyOrder(ModifyOrderReq)returns(OKResp);
|
rpc ModifyOrder(ModifyOrderReq) returns (OKResp);
|
||||||
// ModifyOrderStatus 修改訂單狀態
|
// ModifyOrderStatus 修改訂單狀態
|
||||||
rpc ModifyOrderStatus(ModifyOrderStatusReq)returns(OKResp);
|
rpc ModifyOrderStatus(ModifyOrderStatusReq) returns (OKResp);
|
||||||
// DeleteOrder 刪除訂單(軟刪除)
|
// DeleteOrder 刪除訂單(軟刪除)
|
||||||
rpc DeleteOrder(DeleteOrderReq)returns(OKResp);
|
rpc DeleteOrder(DeleteOrderReq) returns (OKResp);
|
||||||
// GetOrder 取得訂單詳情
|
// GetOrder 取得訂單詳情
|
||||||
rpc GetOrder(GetOrderReq)returns(GetOrderResp);
|
rpc GetOrder(GetOrderReq) returns (GetOrderResp);
|
||||||
// ListOrder 取得訂單列表
|
// ListOrder 取得訂單列表
|
||||||
rpc ListOrder(ListOrderReq)returns(ListOrderResp);
|
rpc ListOrder(ListOrderReq) returns (ListOrderResp);
|
||||||
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
||||||
rpc OrderStatusTimeout(OrderStatusTimeoutReq)returns(OKResp);
|
rpc OrderStatusTimeout(OrderStatusTimeoutReq) returns (OKResp);
|
||||||
}
|
}
|
||||||
|
|
18
go.mod
18
go.mod
|
@ -3,7 +3,12 @@ module app-cloudep-order-server
|
||||||
go 1.22.3
|
go 1.22.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
code.30cm.net/digimon/library-go/errs v1.2.5
|
||||||
|
code.30cm.net/digimon/library-go/validator v1.0.0
|
||||||
|
github.com/shopspring/decimal v1.4.0
|
||||||
github.com/zeromicro/go-zero v1.7.2
|
github.com/zeromicro/go-zero v1.7.2
|
||||||
|
go.mongodb.org/mongo-driver v1.16.1
|
||||||
|
go.uber.org/mock v0.4.0
|
||||||
google.golang.org/grpc v1.67.1
|
google.golang.org/grpc v1.67.1
|
||||||
google.golang.org/protobuf v1.34.2
|
google.golang.org/protobuf v1.34.2
|
||||||
)
|
)
|
||||||
|
@ -18,14 +23,19 @@ require (
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||||
github.com/fatih/color v1.17.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/logr v1.4.2 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||||
github.com/go-openapi/swag v0.22.4 // 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/go-playground/validator/v10 v10.22.0 // indirect
|
||||||
github.com/gogo/protobuf v1.3.2 // indirect
|
github.com/gogo/protobuf v1.3.2 // indirect
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
github.com/golang/protobuf v1.5.4 // 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/gnostic-models v0.6.8 // indirect
|
||||||
github.com/google/go-cmp v0.6.0 // indirect
|
github.com/google/go-cmp v0.6.0 // indirect
|
||||||
github.com/google/gofuzz v1.2.0 // indirect
|
github.com/google/gofuzz v1.2.0 // indirect
|
||||||
|
@ -34,11 +44,13 @@ require (
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.17.9 // 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/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
github.com/mattn/go-isatty v0.0.20 // 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/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||||
github.com/modern-go/reflect2 v1.0.2 // 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
@ -48,6 +60,10 @@ require (
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/redis/go-redis/v9 v9.6.1 // indirect
|
github.com/redis/go-redis/v9 v9.6.1 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.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-20201027041543-1326539a0a0a // indirect
|
||||||
go.etcd.io/etcd/api/v3 v3.5.15 // 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/pkg/v3 v3.5.15 // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.15 // indirect
|
go.etcd.io/etcd/client/v3 v3.5.15 // indirect
|
||||||
|
@ -66,8 +82,10 @@ require (
|
||||||
go.uber.org/automaxprocs v1.5.3 // indirect
|
go.uber.org/automaxprocs v1.5.3 // indirect
|
||||||
go.uber.org/multierr v1.9.0 // indirect
|
go.uber.org/multierr v1.9.0 // indirect
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
|
golang.org/x/crypto v0.26.0 // indirect
|
||||||
golang.org/x/net v0.28.0 // indirect
|
golang.org/x/net v0.28.0 // indirect
|
||||||
golang.org/x/oauth2 v0.22.0 // indirect
|
golang.org/x/oauth2 v0.22.0 // indirect
|
||||||
|
golang.org/x/sync v0.8.0 // indirect
|
||||||
golang.org/x/sys v0.24.0 // indirect
|
golang.org/x/sys v0.24.0 // indirect
|
||||||
golang.org/x/term v0.23.0 // indirect
|
golang.org/x/term v0.23.0 // indirect
|
||||||
golang.org/x/text v0.17.0 // indirect
|
golang.org/x/text v0.17.0 // indirect
|
||||||
|
|
|
@ -4,4 +4,13 @@ import "github.com/zeromicro/go-zero/zrpc"
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
zrpc.RpcServerConf
|
zrpc.RpcServerConf
|
||||||
|
|
||||||
|
Mongo struct {
|
||||||
|
Schema string
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
Host string
|
||||||
|
Port string
|
||||||
|
Database string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
"code.30cm.net/digimon/library-go/errs/code"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrorCode uint32
|
||||||
|
|
||||||
|
func (e ErrorCode) ToUint32() uint32 {
|
||||||
|
return uint32(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error Code 統一這邊改
|
||||||
|
const (
|
||||||
|
_ = iota
|
||||||
|
CreateOrderErrorCode ErrorCode = iota
|
||||||
|
CancelOrderErrorCode
|
||||||
|
ModifyOrderErrorCode
|
||||||
|
TimeoutOrderErrorCode
|
||||||
|
)
|
||||||
|
|
||||||
|
func CommentError(ec ErrorCode, s ...string) *ers.LibError {
|
||||||
|
return ers.NewError(code.CloudEPOrder, code.DBError, ec.ToUint32(), strings.Join(s, " "))
|
||||||
|
}
|
||||||
|
|
||||||
|
func CommentErrorL(ec ErrorCode,
|
||||||
|
l logx.Logger, filed []logx.LogField, s ...string) *ers.LibError {
|
||||||
|
e := CommentError(ec, s...)
|
||||||
|
l.WithCallerSkip(1).WithFields(filed...).Error(e.Error())
|
||||||
|
|
||||||
|
return e
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package domain
|
||||||
|
|
||||||
|
type OrderStatus int64
|
||||||
|
|
||||||
|
func (o *OrderStatus) ToInt() int {
|
||||||
|
return int(*o)
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
OrderStatusCreated OrderStatus = 0 // 建立訂單
|
||||||
|
OrderStatusFailed OrderStatus = 1 // 建單失敗
|
||||||
|
OrderStatusReviewing OrderStatus = 2 // 審核中
|
||||||
|
OrderStatusPaying OrderStatus = 3 // 付款中
|
||||||
|
OrderStatusPaid OrderStatus = 4 // 已付款
|
||||||
|
OrderStatusPendingTransfer OrderStatus = 5 // 已付款待轉帳
|
||||||
|
OrderStatusDisputing OrderStatus = 6 // 申訴中
|
||||||
|
OrderStatusCompleted OrderStatus = 7 // 交易完成
|
||||||
|
OrderStatusFailedTrade OrderStatus = 8 // 交易失敗
|
||||||
|
OrderStatusCancelled OrderStatus = 9 // 交易取消
|
||||||
|
OrderStatusAbnormal OrderStatus = 10 // 交易異常
|
||||||
|
OrderStatusTimeout OrderStatus = 11 // 交易超時
|
||||||
|
)
|
|
@ -1,8 +1,12 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-order-server/internal/domain"
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
|
||||||
|
@ -23,9 +27,42 @@ func NewCancelOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Cance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CancelOrderQuery 1.建單失敗 9.交易取消 10.交易異常
|
||||||
|
type CancelOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
Status int64 `json:"status" validate:"required,oneof=1 9 10"`
|
||||||
|
}
|
||||||
|
|
||||||
// CancelOrder 取消訂單
|
// CancelOrder 取消訂單
|
||||||
func (l *CancelOrderLogic) CancelOrder(in *tweeting.CancelOrderReq) (*tweeting.OKResp, error) {
|
func (l *CancelOrderLogic) CancelOrder(in *tweeting.CancelOrderReq) (*tweeting.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&CancelOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := l.svcCtx.OrderModel.UpdateStatus(l.ctx,
|
||||||
|
model.UpdateStatusReq{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-021-02
|
||||||
|
e := domain.CommentErrorL(
|
||||||
|
domain.CancelOrderErrorCode,
|
||||||
|
logx.WithContext(l.ctx),
|
||||||
|
[]logx.LogField{
|
||||||
|
{Key: "req", Value: in},
|
||||||
|
{Key: "func", Value: "OrderModel.UpdateStatus"},
|
||||||
|
{Key: "err", Value: err},
|
||||||
|
},
|
||||||
|
"failed to update order status:").Wrap(err)
|
||||||
|
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
return &tweeting.OKResp{}, nil
|
return &tweeting.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-order-server/internal/domain"
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
@ -23,9 +29,237 @@ func NewCreateOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Creat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrder 建立訂單
|
type createOrderReq struct { // 訂單ID
|
||||||
func (l *CreateOrderLogic) CreateOrder(in *tweeting.CreateOrderReq) (*tweeting.CreateOrderResp, error) {
|
BusinessID string `json:"business_id" validate:"required"` // 訂單業務流水號
|
||||||
// todo: add your logic here and delete this line
|
OrderType int8 `json:"order_type" validate:"required"` // 訂單類型
|
||||||
|
OrderStatus int8 `json:"order_status" validate:"required,oneof=0 1 2 3 4 5 6 7 8 9 10 11"` // 訂單狀態
|
||||||
return &tweeting.CreateOrderResp{}, nil
|
Brand string `json:"brand" validate:"required"` // 下單平台
|
||||||
|
OrderUID string `json:"order_uid" validate:"required"` // 下單用戶 UID
|
||||||
|
ReferenceID string `json:"reference_id" validate:"required"` // 訂單來源
|
||||||
|
Count decimal.Decimal `json:"count" validate:"required,gt=0"` // 訂單數量
|
||||||
|
OrderFee decimal.Decimal `json:"order_fee" validate:"required,gte=0"` // 訂單手續費
|
||||||
|
Amount decimal.Decimal `json:"amount" validate:"required,gte=0"` // 單價
|
||||||
|
ReferenceBrand *string `json:"reference_brand,omitempty" validate:"omitempty"` // 訂單來源平台
|
||||||
|
ReferenceUID *string `json:"reference_uid,omitempty" validate:"omitempty"` // 訂單來源用戶 UID
|
||||||
|
WalletStatus *int64 `json:"wallet_status,omitempty" validate:"omitempty,oneof=1 2 3 4 5 6 7"` // 交易金額狀態
|
||||||
|
ThreePartyStatus *int64 `json:"three_party_status,omitempty" validate:"omitempty,oneof=1 2 3"` // 三方請求狀態
|
||||||
|
DirectionType *int64 `json:"direction_type,omitempty" validate:"omitempty,oneof=1 2"` // 交易方向
|
||||||
|
CryptoType *string `json:"crypto_type,omitempty" validate:"omitempty"` // 交易幣種
|
||||||
|
ThirdPartyFee *decimal.Decimal `json:"third_party_fee,omitempty" validate:"omitempty,gte=0"` // 第三方手續費
|
||||||
|
CryptoToUSDTRate *decimal.Decimal `json:"crypto_to_usdt_rate,omitempty" validate:"omitempty,gte=0"` // 交易幣種對 USDT 匯率
|
||||||
|
FiatToUSDRate *decimal.Decimal `json:"fiat_to_usd_rate,omitempty" validate:"omitempty,gte=0"` // 法幣對 USD 匯率
|
||||||
|
FeeCryptoToUSDTRate *decimal.Decimal `json:"fee_crypto_to_usdt_rate,omitempty" validate:"omitempty,gte=0"` // 手續費幣種對 USDT 匯率
|
||||||
|
USDTToCryptoTypeRate *decimal.Decimal `json:"usdt_to_crypto_type_rate,omitempty" validate:"omitempty,gte=0"` // USDT 對交易幣種匯率
|
||||||
|
PaymentFiat *string `json:"payment_fiat,omitempty" validate:"omitempty"` // 支付法幣
|
||||||
|
PaymentUnitPrice *decimal.Decimal `json:"payment_unit_price,omitempty" validate:"omitempty,gte=0"` // crypto 單價
|
||||||
|
PaymentTemplateID *string `json:"payment_template_id,omitempty" validate:"omitempty"` // 支付方式配置 ID
|
||||||
|
OrderArrivalTime *int64 `json:"order_arrival_time,omitempty" validate:"omitempty"` // 訂單到帳時間
|
||||||
|
OrderPaymentTime *int64 `json:"order_payment_time,omitempty" validate:"omitempty"` // 訂單付款時間
|
||||||
|
UnpaidTimeoutSecond *int64 `json:"unpaid_timeout_second,omitempty" validate:"omitempty,gte=0"` // 支付期限秒數
|
||||||
|
ChainType *string `json:"chain_type,omitempty" validate:"omitempty"` // 主網類型
|
||||||
|
TxHash *string `json:"tx_hash,omitempty" validate:"omitempty"` // 交易哈希
|
||||||
|
FromAddress *string `json:"from_address,omitempty" validate:"omitempty"` // 來源地址
|
||||||
|
ToAddress *string `json:"to_address,omitempty" validate:"omitempty"` // 目標地址
|
||||||
|
ChainFee *decimal.Decimal `json:"chain_fee,omitempty" validate:"omitempty,gte=0"` // 鏈上交易手續費
|
||||||
|
ChainFeeCrypto *string `json:"chain_fee_crypto,omitempty" validate:"omitempty"` // 鏈上手續費使用幣別
|
||||||
|
Memo *string `json:"memo,omitempty" validate:"omitempty"` // 鏈上備註
|
||||||
|
OrderNote *string `json:"order_note,omitempty" validate:"omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateOrder 建立訂單
|
||||||
|
func (l *CreateOrderLogic) CreateOrder(in *tweeting.CreateOrderReq) (*tweeting.OKResp, error) {
|
||||||
|
req, err := buildCreateOrderReq(in)
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&req); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().UTC().UnixNano()
|
||||||
|
// 插入資料庫
|
||||||
|
o := &model.Order{
|
||||||
|
UpdateTime: now,
|
||||||
|
CreateTime: now,
|
||||||
|
BusinessID: req.BusinessID,
|
||||||
|
OrderType: req.OrderType,
|
||||||
|
OrderStatus: req.OrderStatus,
|
||||||
|
Brand: req.Brand,
|
||||||
|
OrderUID: req.OrderUID,
|
||||||
|
ReferenceID: req.ReferenceID,
|
||||||
|
Count: req.Count,
|
||||||
|
OrderFee: req.OrderFee,
|
||||||
|
Amount: req.Amount,
|
||||||
|
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
|
||||||
|
ReferenceBrand: req.ReferenceBrand,
|
||||||
|
ReferenceUID: req.ReferenceUID,
|
||||||
|
WalletStatus: req.WalletStatus,
|
||||||
|
ThreePartyStatus: req.ThreePartyStatus,
|
||||||
|
DirectionType: req.DirectionType,
|
||||||
|
CryptoType: req.CryptoType,
|
||||||
|
ThirdPartyFee: req.ThirdPartyFee,
|
||||||
|
CryptoToUSDTRate: req.CryptoToUSDTRate,
|
||||||
|
FiatToUSDRate: req.FiatToUSDRate,
|
||||||
|
FeeCryptoToUSDTRate: req.FeeCryptoToUSDTRate,
|
||||||
|
USDTToCryptoTypeRate: req.USDTToCryptoTypeRate,
|
||||||
|
PaymentFiat: req.PaymentFiat,
|
||||||
|
PaymentUnitPrice: req.PaymentUnitPrice,
|
||||||
|
PaymentTemplateID: req.PaymentTemplateID,
|
||||||
|
OrderArrivalTime: req.OrderArrivalTime,
|
||||||
|
OrderPaymentTime: req.OrderPaymentTime,
|
||||||
|
UnpaidTimeoutSecond: req.UnpaidTimeoutSecond,
|
||||||
|
ChainType: req.ChainType,
|
||||||
|
TxHash: req.TxHash,
|
||||||
|
FromAddress: req.FromAddress,
|
||||||
|
ToAddress: req.ToAddress,
|
||||||
|
ChainFee: req.ChainFee,
|
||||||
|
ChainFeeCrypto: req.ChainFeeCrypto,
|
||||||
|
Memo: req.Memo,
|
||||||
|
OrderNote: req.OrderNote,
|
||||||
|
}
|
||||||
|
err = l.svcCtx.OrderModel.Insert(l.ctx, o)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-021-01
|
||||||
|
e := domain.CommentErrorL(
|
||||||
|
domain.CreateOrderErrorCode,
|
||||||
|
logx.WithContext(l.ctx),
|
||||||
|
[]logx.LogField{
|
||||||
|
{Key: "req", Value: in},
|
||||||
|
{Key: "func", Value: "OrderModel.Insert"},
|
||||||
|
{Key: "err", Value: err},
|
||||||
|
},
|
||||||
|
"failed to insert order into mongo:").Wrap(err)
|
||||||
|
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tweeting.OKResp{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildCreateOrderReq(in *tweeting.CreateOrderReq) (*createOrderReq, error) {
|
||||||
|
createOrderReq := &createOrderReq{
|
||||||
|
BusinessID: in.BusinessId,
|
||||||
|
OrderType: int8(in.OrderType),
|
||||||
|
OrderStatus: int8(in.OrderStatus),
|
||||||
|
Brand: in.Brand,
|
||||||
|
OrderUID: in.OrderUid,
|
||||||
|
ReferenceID: in.ReferenceId,
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
// 只有當 Count, OrderFee, Amount 不為空時才進行轉換和設置
|
||||||
|
if in.Count != "" {
|
||||||
|
createOrderReq.Count, err = decimal.NewFromString(in.Count)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.OrderFee != "" {
|
||||||
|
createOrderReq.OrderFee, err = decimal.NewFromString(in.OrderFee)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Amount != "" {
|
||||||
|
createOrderReq.Amount, err = decimal.NewFromString(in.Amount)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判斷可選字段,只有不為 nil 才設置
|
||||||
|
if in.ReferenceBrand != nil {
|
||||||
|
createOrderReq.ReferenceBrand = in.ReferenceBrand
|
||||||
|
}
|
||||||
|
if in.ReferenceUid != nil {
|
||||||
|
createOrderReq.ReferenceUID = in.ReferenceUid
|
||||||
|
}
|
||||||
|
if in.WalletStatus != nil {
|
||||||
|
createOrderReq.WalletStatus = in.WalletStatus
|
||||||
|
}
|
||||||
|
if in.ThreePartyStatus != nil {
|
||||||
|
createOrderReq.ThreePartyStatus = in.ThreePartyStatus
|
||||||
|
}
|
||||||
|
if in.DirectionType != nil {
|
||||||
|
createOrderReq.DirectionType = in.DirectionType
|
||||||
|
}
|
||||||
|
if in.CryptoType != nil {
|
||||||
|
createOrderReq.CryptoType = in.CryptoType
|
||||||
|
}
|
||||||
|
if in.ThirdPartyFee != nil && *in.ThirdPartyFee != "" {
|
||||||
|
createOrderReq.ThirdPartyFee = decimalPtrFromString(*in.ThirdPartyFee)
|
||||||
|
}
|
||||||
|
if in.CryptoToUsdtRate != nil && *in.CryptoToUsdtRate != "" {
|
||||||
|
createOrderReq.CryptoToUSDTRate = decimalPtrFromString(*in.CryptoToUsdtRate)
|
||||||
|
}
|
||||||
|
if in.FiatToUsdRate != nil && *in.FiatToUsdRate != "" {
|
||||||
|
createOrderReq.FiatToUSDRate = decimalPtrFromString(*in.FiatToUsdRate)
|
||||||
|
}
|
||||||
|
if in.FeeCryptoToUsdtRate != nil && *in.FeeCryptoToUsdtRate != "" {
|
||||||
|
createOrderReq.FeeCryptoToUSDTRate = decimalPtrFromString(*in.FeeCryptoToUsdtRate)
|
||||||
|
}
|
||||||
|
if in.UsdtToCryptoTypeRate != nil && *in.UsdtToCryptoTypeRate != "" {
|
||||||
|
createOrderReq.USDTToCryptoTypeRate = decimalPtrFromString(*in.UsdtToCryptoTypeRate)
|
||||||
|
}
|
||||||
|
if in.PaymentFiat != nil {
|
||||||
|
createOrderReq.PaymentFiat = in.PaymentFiat
|
||||||
|
}
|
||||||
|
if in.PaymentUnitPrice != nil && *in.PaymentUnitPrice != "" {
|
||||||
|
createOrderReq.PaymentUnitPrice = decimalPtrFromString(*in.PaymentUnitPrice)
|
||||||
|
}
|
||||||
|
if in.PaymentTemplateId != nil {
|
||||||
|
createOrderReq.PaymentTemplateID = in.PaymentTemplateId
|
||||||
|
}
|
||||||
|
if in.OrderArrivalTime != nil {
|
||||||
|
createOrderReq.OrderArrivalTime = in.OrderArrivalTime
|
||||||
|
}
|
||||||
|
if in.OrderPaymentTime != nil {
|
||||||
|
createOrderReq.OrderPaymentTime = in.OrderPaymentTime
|
||||||
|
}
|
||||||
|
if in.UnpaidTimeoutSecond != nil {
|
||||||
|
createOrderReq.UnpaidTimeoutSecond = in.UnpaidTimeoutSecond
|
||||||
|
}
|
||||||
|
if in.ChainType != nil {
|
||||||
|
createOrderReq.ChainType = in.ChainType
|
||||||
|
}
|
||||||
|
if in.TxHash != nil {
|
||||||
|
createOrderReq.TxHash = in.TxHash
|
||||||
|
}
|
||||||
|
if in.FromAddress != nil {
|
||||||
|
createOrderReq.FromAddress = in.FromAddress
|
||||||
|
}
|
||||||
|
if in.ToAddress != nil {
|
||||||
|
createOrderReq.ToAddress = in.ToAddress
|
||||||
|
}
|
||||||
|
if in.ChainFee != nil && *in.ChainFee != "" {
|
||||||
|
createOrderReq.ChainFee = decimalPtrFromString(*in.ChainFee)
|
||||||
|
}
|
||||||
|
if in.ChainFeeCrypto != nil {
|
||||||
|
createOrderReq.ChainFeeCrypto = in.ChainFeeCrypto
|
||||||
|
}
|
||||||
|
if in.Memo != nil {
|
||||||
|
createOrderReq.Memo = in.Memo
|
||||||
|
}
|
||||||
|
if in.OrderNote != nil {
|
||||||
|
createOrderReq.OrderNote = in.OrderNote
|
||||||
|
}
|
||||||
|
|
||||||
|
return createOrderReq, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function for decimal conversion with nil support
|
||||||
|
func decimalPtrFromString(val string) *decimal.Decimal {
|
||||||
|
if val == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
dec, err := decimal.NewFromString(val)
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &dec
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
|
@ -23,9 +24,25 @@ func NewDeleteOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Delet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteOrderQuery 刪除訂單(軟刪除)
|
||||||
|
type DeleteOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteOrder 刪除訂單(軟刪除)
|
// DeleteOrder 刪除訂單(軟刪除)
|
||||||
func (l *DeleteOrderLogic) DeleteOrder(in *tweeting.DeleteOrderReq) (*tweeting.OKResp, error) {
|
func (l *DeleteOrderLogic) DeleteOrder(in *tweeting.DeleteOrderReq) (*tweeting.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&DeleteOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := l.svcCtx.OrderModel.DeleteByBusinessID(l.ctx, in.GetBusinessId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &tweeting.OKResp{}, nil
|
return &tweeting.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/shopspring/decimal"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
@ -23,9 +25,68 @@ func NewGetOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetOrder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetOrderQuery 取得訂單
|
||||||
|
type GetOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetOrder 取得訂單詳情
|
// GetOrder 取得訂單詳情
|
||||||
func (l *GetOrderLogic) GetOrder(in *tweeting.GetOrderReq) (*tweeting.GetOrderResp, error) {
|
func (l *GetOrderLogic) GetOrder(in *tweeting.GetOrderReq) (*tweeting.GetOrderResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&GetOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
return &tweeting.GetOrderResp{}, nil
|
order, err := l.svcCtx.OrderModel.FindOneBusinessID(l.ctx, in.GetBusinessId())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &tweeting.GetOrderResp{
|
||||||
|
UpdateTime: order.UpdateTime,
|
||||||
|
CreateTime: order.CreateTime,
|
||||||
|
BusinessId: order.BusinessID,
|
||||||
|
OrderType: int32(order.OrderType),
|
||||||
|
OrderStatus: int32(order.OrderStatus),
|
||||||
|
Brand: order.Brand,
|
||||||
|
OrderUid: order.OrderUID,
|
||||||
|
ReferenceId: order.ReferenceID,
|
||||||
|
Count: order.Count.String(),
|
||||||
|
OrderFee: order.OrderFee.String(),
|
||||||
|
Amount: order.Amount.String(),
|
||||||
|
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
|
||||||
|
ReferenceBrand: order.ReferenceBrand,
|
||||||
|
ReferenceUid: order.ReferenceUID,
|
||||||
|
WalletStatus: order.WalletStatus,
|
||||||
|
ThreePartyStatus: order.ThreePartyStatus,
|
||||||
|
DirectionType: order.DirectionType,
|
||||||
|
CryptoType: order.CryptoType,
|
||||||
|
ThirdPartyFee: decimalToString(*order.ThirdPartyFee),
|
||||||
|
CryptoToUsdtRate: decimalToString(*order.CryptoToUSDTRate),
|
||||||
|
FiatToUsdRate: decimalToString(*order.FiatToUSDRate),
|
||||||
|
FeeCryptoToUsdtRate: decimalToString(*order.FeeCryptoToUSDTRate),
|
||||||
|
UsdtToCryptoTypeRate: decimalToString(*order.USDTToCryptoTypeRate),
|
||||||
|
PaymentFiat: order.PaymentFiat,
|
||||||
|
PaymentUnitPrice: decimalToString(*order.PaymentUnitPrice),
|
||||||
|
PaymentTemplateId: order.PaymentTemplateID,
|
||||||
|
OrderArrivalTime: order.OrderArrivalTime,
|
||||||
|
OrderPaymentTime: order.OrderPaymentTime,
|
||||||
|
UnpaidTimeoutSecond: order.UnpaidTimeoutSecond,
|
||||||
|
ChainType: order.ChainType,
|
||||||
|
TxHash: order.TxHash,
|
||||||
|
FromAddress: order.FromAddress,
|
||||||
|
ToAddress: order.ToAddress,
|
||||||
|
ChainFee: decimalToString(*order.ChainFee),
|
||||||
|
ChainFeeCrypto: order.ChainFeeCrypto,
|
||||||
|
Memo: order.Memo,
|
||||||
|
OrderNote: order.OrderNote,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func decimalToString(amount decimal.Decimal) *string {
|
||||||
|
a := amount.String()
|
||||||
|
return &a
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
@ -23,9 +26,47 @@ func NewListOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListOrd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GetOrderListReq struct {
|
||||||
|
PageIndex int64 `json:"page_index" validate:"required"`
|
||||||
|
PageSize int64 `json:"page_size" validate:"required"`
|
||||||
|
|
||||||
|
ReferenceID string `json:"reference_id"`
|
||||||
|
ReferenceUID string `json:"reference_uid"`
|
||||||
|
BusinessID string `json:"business_id"`
|
||||||
|
UID string `json:"uid"`
|
||||||
|
OrderType int `json:"order_type"`
|
||||||
|
DirectionType []int64 `json:"direction_type"`
|
||||||
|
OrderStatus []int64 `json:"order_status"`
|
||||||
|
|
||||||
|
StartCreateTime int64 `json:"start_create_time"`
|
||||||
|
EndCreateTime int64 `json:"end_create_time"`
|
||||||
|
StartUpdateTime int64 `json:"start_update_time"`
|
||||||
|
EndUpdateTime int64 `json:"end_update_time"`
|
||||||
|
StartOrderArrivalTime int64 `json:"start_order_arrival_time"`
|
||||||
|
EndOrderArrivalTime int64 `json:"end_order_arrival_time"`
|
||||||
|
StartOrderPaymentTime int64 `json:"start_order_payment_time"`
|
||||||
|
EndOrderPaymentTime int64 `json:"end_order_payment_time"`
|
||||||
|
|
||||||
|
CryptoType string `json:"crypto_type"`
|
||||||
|
TxHash string `json:"tx_hash"`
|
||||||
|
}
|
||||||
|
|
||||||
// ListOrder 取得訂單列表
|
// ListOrder 取得訂單列表
|
||||||
func (l *ListOrderLogic) ListOrder(in *tweeting.ListOrderReq) (*tweeting.ListOrderResp, error) {
|
func (l *ListOrderLogic) ListOrder(in *tweeting.ListOrderReq) (*tweeting.ListOrderResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料,目前只有 Page 必帶,其他要驗證在驗證
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&GetOrderListReq{
|
||||||
|
PageIndex: in.GetPageIndex(),
|
||||||
|
PageSize: in.GetPageSize(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
orders, total, err := l.svcCtx.OrderModel.ListOrder(l.ctx, model.GetOrderListReq{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(orders, total)
|
||||||
return &tweeting.ListOrderResp{}, nil
|
return &tweeting.ListOrderResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-order-server/internal/domain"
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
ers "code.30cm.net/digimon/library-go/errs"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
|
||||||
|
@ -23,9 +27,46 @@ func NewModifyOrderStatusLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ModifyOrderQuery
|
||||||
|
// 0.建立訂單 1.建單失敗 2.審核中 3.付款中 4.已付款
|
||||||
|
// 5.已付款待轉帳 6.申訴中 7.交易完成
|
||||||
|
// 8.交易失敗 9.交易取消 10.交易異常 11.交易超時
|
||||||
|
|
||||||
|
type ModifyOrderQuery struct {
|
||||||
|
BusinessID string `json:"business_id" validate:"required"`
|
||||||
|
Status int64 `json:"status" validate:"required,oneof=2 3 4 5 6 7 8 11"`
|
||||||
|
}
|
||||||
|
|
||||||
// ModifyOrderStatus 修改訂單狀態
|
// ModifyOrderStatus 修改訂單狀態
|
||||||
func (l *ModifyOrderStatusLogic) ModifyOrderStatus(in *tweeting.ModifyOrderStatusReq) (*tweeting.OKResp, error) {
|
func (l *ModifyOrderStatusLogic) ModifyOrderStatus(in *tweeting.ModifyOrderStatusReq) (*tweeting.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證資料
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&ModifyOrderQuery{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
}); err != nil {
|
||||||
|
// 錯誤代碼 06-011-00
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err := l.svcCtx.OrderModel.UpdateStatus(l.ctx,
|
||||||
|
model.UpdateStatusReq{
|
||||||
|
BusinessID: in.GetBusinessId(),
|
||||||
|
Status: in.GetStatus(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-021-02
|
||||||
|
e := domain.CommentErrorL(
|
||||||
|
domain.ModifyOrderErrorCode,
|
||||||
|
logx.WithContext(l.ctx),
|
||||||
|
[]logx.LogField{
|
||||||
|
{Key: "req", Value: in},
|
||||||
|
{Key: "func", Value: "OrderModel.UpdateStatus"},
|
||||||
|
{Key: "err", Value: err},
|
||||||
|
},
|
||||||
|
"failed to update order status:").Wrap(err)
|
||||||
|
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
return &tweeting.OKResp{}, nil
|
return &tweeting.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
package orderservicelogic
|
package orderservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"app-cloudep-order-server/internal/domain"
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
"app-cloudep-order-server/gen_result/pb/tweeting"
|
"app-cloudep-order-server/gen_result/pb/tweeting"
|
||||||
"app-cloudep-order-server/internal/svc"
|
"app-cloudep-order-server/internal/svc"
|
||||||
|
@ -25,7 +28,24 @@ func NewOrderStatusTimeoutLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||||
|
|
||||||
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
// OrderStatusTimeout 訂單超時任務/cron/order-status/timeout
|
||||||
func (l *OrderStatusTimeoutLogic) OrderStatusTimeout(in *tweeting.OrderStatusTimeoutReq) (*tweeting.OKResp, error) {
|
func (l *OrderStatusTimeoutLogic) OrderStatusTimeout(in *tweeting.OrderStatusTimeoutReq) (*tweeting.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
now := time.Now().UTC().UnixNano()
|
||||||
|
_, err := l.svcCtx.OrderModel.UpdateTimeoutOrder(l.ctx, model.UpdateTimeoutReq{
|
||||||
|
CreateTimeBefore: now,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
// 錯誤代碼 06-021-02
|
||||||
|
e := domain.CommentErrorL(
|
||||||
|
domain.TimeoutOrderErrorCode,
|
||||||
|
logx.WithContext(l.ctx),
|
||||||
|
[]logx.LogField{
|
||||||
|
{Key: "now", Value: now},
|
||||||
|
{Key: "func", Value: "OrderModel.UpdateTimeoutOrder"},
|
||||||
|
{Key: "err", Value: err},
|
||||||
|
},
|
||||||
|
"failed to update timeout order").Wrap(err)
|
||||||
|
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
return &tweeting.OKResp{}, nil
|
return &tweeting.OKResp{}, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,16 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import "github.com/zeromicro/go-zero/core/stores/mon"
|
import (
|
||||||
|
"app-cloudep-order-server/internal/domain"
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
var _ OrderModel = (*customOrderModel)(nil)
|
var _ OrderModel = (*customOrderModel)(nil)
|
||||||
|
|
||||||
|
@ -9,11 +19,50 @@ type (
|
||||||
// and implement the added methods in customOrderModel.
|
// and implement the added methods in customOrderModel.
|
||||||
OrderModel interface {
|
OrderModel interface {
|
||||||
orderModel
|
orderModel
|
||||||
|
UpdateStatus(ctx context.Context, data UpdateStatusReq) (*mongo.UpdateResult, error)
|
||||||
|
UpdateTimeoutOrder(ctx context.Context, req UpdateTimeoutReq) (*mongo.UpdateResult, error)
|
||||||
|
DeleteByBusinessID(ctx context.Context, id string) (*mongo.UpdateResult, error)
|
||||||
|
FindOneBusinessID(ctx context.Context, id string) (*Order, error)
|
||||||
|
ListOrder(ctx context.Context, req GetOrderListReq) ([]Order, int64, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
customOrderModel struct {
|
customOrderModel struct {
|
||||||
*defaultOrderModel
|
*defaultOrderModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateStatusReq struct {
|
||||||
|
BusinessID string
|
||||||
|
Status int64
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateTimeoutReq struct {
|
||||||
|
CreateTimeBefore int64
|
||||||
|
}
|
||||||
|
|
||||||
|
GetOrderListReq struct {
|
||||||
|
PageIndex int64 `json:"page_index" validate:"required"`
|
||||||
|
PageSize int64 `json:"page_size" validate:"required"`
|
||||||
|
|
||||||
|
ReferenceID string `json:"reference_id"`
|
||||||
|
ReferenceUID string `json:"reference_uid"`
|
||||||
|
BusinessID string `json:"business_id"`
|
||||||
|
UID string `json:"uid"`
|
||||||
|
OrderType int `json:"order_type"`
|
||||||
|
DirectionType []int64 `json:"direction_type"`
|
||||||
|
OrderStatus []int64 `json:"order_status"`
|
||||||
|
|
||||||
|
StartCreateTime int64 `json:"start_create_time"`
|
||||||
|
EndCreateTime int64 `json:"end_create_time"`
|
||||||
|
StartUpdateTime int64 `json:"start_update_time"`
|
||||||
|
EndUpdateTime int64 `json:"end_update_time"`
|
||||||
|
StartOrderArrivalTime int64 `json:"start_order_arrival_time"`
|
||||||
|
EndOrderArrivalTime int64 `json:"end_order_arrival_time"`
|
||||||
|
StartOrderPaymentTime int64 `json:"start_order_payment_time"`
|
||||||
|
EndOrderPaymentTime int64 `json:"end_order_payment_time"`
|
||||||
|
|
||||||
|
CryptoType string `json:"crypto_type"`
|
||||||
|
TxHash string `json:"tx_hash"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewOrderModel returns a model for the mongo.
|
// NewOrderModel returns a model for the mongo.
|
||||||
|
@ -23,3 +72,163 @@ func NewOrderModel(url, db, collection string) OrderModel {
|
||||||
defaultOrderModel: newDefaultOrderModel(conn),
|
defaultOrderModel: newDefaultOrderModel(conn),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) UpdateStatus(ctx context.Context, data UpdateStatusReq) (*mongo.UpdateResult, error) {
|
||||||
|
// 初始化 updates map
|
||||||
|
updates := make(map[string]any)
|
||||||
|
|
||||||
|
// 更新 update_time 和 status
|
||||||
|
updates["update_time"] = time.Now().UTC().UnixNano()
|
||||||
|
updates["status"] = data.Status
|
||||||
|
|
||||||
|
// 使用 updates map 作為 $set 的內容
|
||||||
|
res, err := m.conn.UpdateOne(ctx,
|
||||||
|
bson.M{
|
||||||
|
"business_id": data.BusinessID,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
bson.M{"$set": updates}, // 使用 updates 而不是整個 data
|
||||||
|
)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) UpdateTimeoutOrder(ctx context.Context, req UpdateTimeoutReq) (*mongo.UpdateResult, error) {
|
||||||
|
// 構建過濾條件,選擇創建時間在指定時間之前且狀態為 0 (創建) 的項目
|
||||||
|
filter := bson.M{
|
||||||
|
"create_time": bson.M{"$lt": req.CreateTimeBefore},
|
||||||
|
"status": domain.OrderStatusCreated,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新內容,將狀態設置為 11,並更新 update_time
|
||||||
|
updates := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"status": domain.OrderStatusTimeout,
|
||||||
|
"update_time": time.Now().UTC().UnixNano(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// 執行更新操作
|
||||||
|
res, err := m.conn.UpdateOne(ctx, filter, updates)
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) DeleteByBusinessID(ctx context.Context, id string) (*mongo.UpdateResult, error) {
|
||||||
|
filter := bson.M{
|
||||||
|
"business_id": id,
|
||||||
|
"$or": []bson.M{
|
||||||
|
{"delete_time": bson.M{"$exists": false}},
|
||||||
|
{"delete_time": 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
updates := bson.M{
|
||||||
|
"$set": bson.M{
|
||||||
|
"delete_time": time.Now().UTC().UnixNano(),
|
||||||
|
"update_time": time.Now().UTC().UnixNano(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// 執行更新操作
|
||||||
|
res, err := m.conn.UpdateOne(ctx, filter, updates)
|
||||||
|
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultOrderModel) FindOneBusinessID(ctx context.Context, id string) (*Order, error) {
|
||||||
|
var data Order
|
||||||
|
|
||||||
|
err := m.conn.FindOne(ctx, &data, bson.M{"business_id": id})
|
||||||
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
return &data, nil
|
||||||
|
case errors.Is(err, mon.ErrNotFound):
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customOrderModel) ListOrder(ctx context.Context, req GetOrderListReq) ([]Order, int64, error) {
|
||||||
|
// 定義查詢過濾器
|
||||||
|
filter := bson.M{}
|
||||||
|
|
||||||
|
// 添加查詢條件
|
||||||
|
if req.ReferenceID != "" {
|
||||||
|
filter["reference_id"] = req.ReferenceID
|
||||||
|
}
|
||||||
|
if req.ReferenceUID != "" {
|
||||||
|
filter["reference_uid"] = req.ReferenceUID
|
||||||
|
}
|
||||||
|
if req.BusinessID != "" {
|
||||||
|
filter["business_id"] = req.BusinessID
|
||||||
|
}
|
||||||
|
if req.UID != "" {
|
||||||
|
filter["order_uid"] = req.UID
|
||||||
|
}
|
||||||
|
if req.OrderType != 0 {
|
||||||
|
filter["order_type"] = req.OrderType
|
||||||
|
}
|
||||||
|
if len(req.DirectionType) > 0 {
|
||||||
|
filter["direction_type"] = bson.M{"$in": req.DirectionType}
|
||||||
|
}
|
||||||
|
if len(req.OrderStatus) > 0 {
|
||||||
|
filter["order_status"] = bson.M{"$in": req.OrderStatus}
|
||||||
|
}
|
||||||
|
// 處理時間範圍
|
||||||
|
if req.StartCreateTime != 0 {
|
||||||
|
filter["create_time"] = bson.M{"$gte": req.StartCreateTime}
|
||||||
|
}
|
||||||
|
if req.EndCreateTime != 0 {
|
||||||
|
filter["create_time"] = bson.M{"$lte": req.EndCreateTime}
|
||||||
|
}
|
||||||
|
if req.StartUpdateTime != 0 {
|
||||||
|
filter["update_time"] = bson.M{"$gte": req.StartUpdateTime}
|
||||||
|
}
|
||||||
|
if req.EndUpdateTime != 0 {
|
||||||
|
filter["update_time"] = bson.M{"$lte": req.EndUpdateTime}
|
||||||
|
}
|
||||||
|
if req.StartOrderArrivalTime != 0 {
|
||||||
|
filter["order_arrival_time"] = bson.M{"$gte": req.StartOrderArrivalTime}
|
||||||
|
}
|
||||||
|
if req.EndOrderArrivalTime != 0 {
|
||||||
|
filter["order_arrival_time"] = bson.M{"$lte": req.EndOrderArrivalTime}
|
||||||
|
}
|
||||||
|
if req.StartOrderPaymentTime != 0 {
|
||||||
|
filter["order_payment_time"] = bson.M{"$gte": req.StartOrderPaymentTime}
|
||||||
|
}
|
||||||
|
if req.EndOrderPaymentTime != 0 {
|
||||||
|
filter["order_payment_time"] = bson.M{"$lte": req.EndOrderPaymentTime}
|
||||||
|
}
|
||||||
|
if req.CryptoType != "" {
|
||||||
|
filter["crypto_type"] = req.CryptoType
|
||||||
|
}
|
||||||
|
if req.TxHash != "" {
|
||||||
|
filter["tx_hash"] = req.TxHash
|
||||||
|
}
|
||||||
|
|
||||||
|
// 計算符合條件的總數量
|
||||||
|
totalCount, err := m.conn.CountDocuments(ctx, filter)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 設定查詢選項,包含分頁
|
||||||
|
findOptions := options.Find()
|
||||||
|
findOptions.SetSkip((req.PageIndex - 1) * req.PageSize)
|
||||||
|
findOptions.SetLimit(req.PageSize)
|
||||||
|
|
||||||
|
// 執行查詢
|
||||||
|
var orders []Order
|
||||||
|
err = m.conn.Find(ctx, &orders, filter, findOptions)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return orders, totalCount, nil
|
||||||
|
}
|
||||||
|
|
|
@ -29,8 +29,8 @@ func newDefaultOrderModel(conn *mon.Model) *defaultOrderModel {
|
||||||
func (m *defaultOrderModel) Insert(ctx context.Context, data *Order) error {
|
func (m *defaultOrderModel) Insert(ctx context.Context, data *Order) error {
|
||||||
if data.ID.IsZero() {
|
if data.ID.IsZero() {
|
||||||
data.ID = primitive.NewObjectID()
|
data.ID = primitive.NewObjectID()
|
||||||
data.CreateAt = time.Now()
|
data.CreateTime = time.Now().UTC().UnixNano()
|
||||||
data.UpdateAt = time.Now()
|
data.UpdateTime = time.Now().UTC().UnixNano()
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := m.conn.InsertOne(ctx, data)
|
_, err := m.conn.InsertOne(ctx, data)
|
||||||
|
@ -57,7 +57,7 @@ func (m *defaultOrderModel) FindOne(ctx context.Context, id string) (*Order, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *defaultOrderModel) Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error) {
|
func (m *defaultOrderModel) Update(ctx context.Context, data *Order) (*mongo.UpdateResult, error) {
|
||||||
data.UpdateAt = time.Now()
|
data.UpdateTime = time.Now().UTC().UnixNano()
|
||||||
|
|
||||||
res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
res, err := m.conn.UpdateOne(ctx, bson.M{"_id": data.ID}, bson.M{"$set": data})
|
||||||
return res, err
|
return res, err
|
||||||
|
|
|
@ -1,14 +1,51 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"github.com/shopspring/decimal"
|
||||||
|
|
||||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Order struct {
|
type Order struct {
|
||||||
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||||
// TODO: Fill your own fields
|
UpdateTime int64 `bson:"update_time"`
|
||||||
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
|
CreateTime int64 `bson:"create_time"`
|
||||||
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
|
BusinessID string `bson:"business_id"` // 訂單業務流水號
|
||||||
|
OrderType int8 `bson:"order_type"` // 訂單類型
|
||||||
|
OrderStatus int8 `bson:"order_status"` // 訂單狀態 0.建立訂單 1.建單失敗 2.審核中 3.付款中 4.已付款 5.已付款待轉帳 6.申訴中 7.交易完成 8.交易失敗 9.交易取消 10.交易異常 11.交易超時
|
||||||
|
Brand string `bson:"brand"` // 下單平台(混合也可用)
|
||||||
|
OrderUID string `bson:"order_uid"` // 下單用戶 UID
|
||||||
|
ReferenceID string `bson:"reference_id"` // 訂單來源(用)
|
||||||
|
Count decimal.Decimal `bson:"count"` // 訂單數量
|
||||||
|
OrderFee decimal.Decimal `bson:"order_fee"` // 訂單手續費
|
||||||
|
Amount decimal.Decimal `bson:"amount"` // 單價
|
||||||
|
// 下面的是未來擴充用,加密貨幣用,或者幣別轉換用,普通訂單用不到
|
||||||
|
ReferenceBrand *string `bson:"reference_brand"` // 訂單來源平台
|
||||||
|
ReferenceUID *string `bson:"reference_uid"` // 訂單來源用戶 UID
|
||||||
|
WalletStatus *int64 `bson:"wallet_status,omitempty"` // 交易金額狀態 1.未凍結 2.已凍結 3.解凍(扣錢) 4.未增加資產 5.已增加資產 6.解凍還原 7.限制(將凍結餘額轉至限制餘額)
|
||||||
|
ThreePartyStatus *int64 `bson:"three_party_status,omitempty"` // 三方請求狀態 1.已發送 2.通知處理中 3.通知已完成
|
||||||
|
DirectionType *int64 `bson:"direction_type,omitempty"` // 交易方向 1.買入 2.賣出
|
||||||
|
CryptoType *string `bson:"crypto_type,omitempty"` // 交易幣種
|
||||||
|
ThirdPartyFee *decimal.Decimal `bson:"third_party_fee,omitempty"` // 第三方手續費
|
||||||
|
CryptoToUSDTRate *decimal.Decimal `bson:"crypto_to_usdt_rate,omitempty"` // 交易幣種 對 USDT 匯率
|
||||||
|
FiatToUSDRate *decimal.Decimal `bson:"fiat_to_usd_rate,omitempty"` // 法幣 對 USD 匯率
|
||||||
|
FeeCryptoToUSDTRate *decimal.Decimal `bson:"fee_crypto_to_usdt_rate,omitempty"` // 手續費幣種 對 USDT 匯率
|
||||||
|
USDTToCryptoTypeRate *decimal.Decimal `bson:"usdt_to_crypto_type_rate,omitempty"` // USDT 對 交易幣種 匯率
|
||||||
|
PaymentFiat *string `bson:"payment_fiat,omitempty"` // 支付法幣
|
||||||
|
PaymentUnitPrice *decimal.Decimal `bson:"payment_unit_price,omitempty"` // crypto 單價
|
||||||
|
PaymentTemplateID *string `bson:"payment_template_id,omitempty"` // 支付方式配置 ID
|
||||||
|
OrderArrivalTime *int64 `bson:"order_arrival_time,omitempty"` // 訂單到帳時間/充值到帳時間
|
||||||
|
OrderPaymentTime *int64 `bson:"order_payment_time,omitempty"` // 訂單付款時間/鏈上成功或失敗時間
|
||||||
|
UnpaidTimeoutSecond *int64 `bson:"unpaid_timeout_second,omitempty"` // 支付期限秒數
|
||||||
|
ChainType *string `bson:"chain_type,omitempty"` // 主網類型
|
||||||
|
TxHash *string `bson:"tx_hash,omitempty"` // 交易哈希
|
||||||
|
FromAddress *string `bson:"from_address,omitempty"` // 來源地址
|
||||||
|
ToAddress *string `bson:"to_address,omitempty"` // 目標地址
|
||||||
|
ChainFee *decimal.Decimal `bson:"chain_fee,omitempty"` // 鏈上交易手續費
|
||||||
|
ChainFeeCrypto *string `bson:"chain_fee_crypto,omitempty"` // 鏈上手續費使用幣別
|
||||||
|
Memo *string `bson:"memo,omitempty"` // 鏈上備註
|
||||||
|
OrderNote *string `bson:"order_note,omitempty"` // 訂單交易備註
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Order) CollectionName() string {
|
||||||
|
return "order"
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ func NewOrderServiceServer(svcCtx *svc.ServiceContext) *OrderServiceServer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateOrder 建立訂單
|
// CreateOrder 建立訂單
|
||||||
func (s *OrderServiceServer) CreateOrder(ctx context.Context, in *tweeting.CreateOrderReq) (*tweeting.CreateOrderResp, error) {
|
func (s *OrderServiceServer) CreateOrder(ctx context.Context, in *tweeting.CreateOrderReq) (*tweeting.OKResp, error) {
|
||||||
l := orderservicelogic.NewCreateOrderLogic(ctx, s.svcCtx)
|
l := orderservicelogic.NewCreateOrderLogic(ctx, s.svcCtx)
|
||||||
return l.CreateOrder(in)
|
return l.CreateOrder(in)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"app-cloudep-order-server/internal/config"
|
||||||
|
model "app-cloudep-order-server/internal/model/mongo"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mustMongoConnectURL(c config.Config) string {
|
||||||
|
return fmt.Sprintf("%s://%s:%s",
|
||||||
|
c.Mongo.Schema,
|
||||||
|
c.Mongo.Host,
|
||||||
|
c.Mongo.Port,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO 思考快取做在那邊
|
||||||
|
|
||||||
|
func MustOrderModel(c config.Config) model.OrderModel {
|
||||||
|
orderCollection := model.Order{}
|
||||||
|
|
||||||
|
return model.NewOrderModel(mustMongoConnectURL(c), c.Mongo.Database, orderCollection.CollectionName())
|
||||||
|
}
|
|
@ -1,13 +1,27 @@
|
||||||
package svc
|
package svc
|
||||||
|
|
||||||
import "app-cloudep-order-server/internal/config"
|
import (
|
||||||
|
"app-cloudep-order-server/internal/config"
|
||||||
|
model "app-cloudep-order-server/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 {
|
type ServiceContext struct {
|
||||||
Config config.Config
|
Config config.Config
|
||||||
|
Validate vi.Validate
|
||||||
|
|
||||||
|
OrderModel model.OrderModel
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewServiceContext(c config.Config) *ServiceContext {
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
ers.Scope = code.CloudEPOrder
|
||||||
|
|
||||||
return &ServiceContext{
|
return &ServiceContext{
|
||||||
Config: c,
|
Config: c,
|
||||||
|
Validate: vi.MustValidator(),
|
||||||
|
OrderModel: MustOrderModel(c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue