update const

This commit is contained in:
daniel.w 2024-10-31 12:05:22 +08:00
parent 3c1c611f96
commit e9c5818157
26 changed files with 330 additions and 312 deletions

View File

@ -1,32 +0,0 @@
package domain
type OrderStatus int64
func (o *OrderStatus) ToInt64() int64 {
return int64(*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 // 交易超時
)
type OrderType int64
const (
OrderTypeTest OrderType = 0 // 測試訂單
)
func (o *OrderType) ToInt() int {
return int(*o)
}

View File

@ -0,0 +1,25 @@
package order
// Status 表示訂單狀態
type Status int64
// ToInt64 將訂單狀態轉為 int64
func (s Status) ToInt64() int64 {
return int64(s)
}
// 訂單狀態常量
const (
Created Status = iota // 訂單已建立
Failed // 建單失敗
UnderReview // 審核中
Processing // 付款中
Paid // 已付款
AwaitingTransfer // 待轉帳
InDispute // 申訴中
Completed // 交易完成
FailedTrade // 交易失敗
Cancelled // 交易取消
Abnormal // 交易異常
TimedOut // 交易超時
)

View File

@ -0,0 +1,15 @@
package order
// Type 表示訂單類型
type Type int64
// ToInt 將訂單類型轉為 int
func (t Type) ToInt() int {
return int(t)
}
// 訂單類型常量
const (
TestType Type = iota // 測試訂單
)

View File

@ -1,7 +1,7 @@
package repository package repository
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model" "app-cloudep-trade-service/internal/model"
"context" "context"
@ -13,9 +13,9 @@ import (
// UserWalletOperator 針對使用者的錢包基本操作接口 // UserWalletOperator 針對使用者的錢包基本操作接口
type UserWalletOperator interface { type UserWalletOperator interface {
// Balances 取得多種類別餘額 // Balances 取得多種類別餘額
Balances(ctx context.Context, kind []domain.WalletType, opts ...WalletOperatorOption) ([]model.Wallet, error) Balances(ctx context.Context, balanceType []wallet.BalanceType, opts ...WalletOperatorOption) ([]model.Wallet, error)
// LocalBalance 取得本地錢包的數額 // LocalBalance 取得本地錢包的數額
LocalBalance(kind domain.WalletType) decimal.Decimal LocalBalance(balanceType wallet.BalanceType) decimal.Decimal
// GetBalancesByID 取得錢包的數額 ByID // GetBalancesByID 取得錢包的數額 ByID
GetBalancesByID(ctx context.Context, ids []int64, opts ...WalletOperatorOption) ([]model.Wallet, error) GetBalancesByID(ctx context.Context, ids []int64, opts ...WalletOperatorOption) ([]model.Wallet, error)
} }

View File

@ -1,7 +1,7 @@
package repository package repository
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model" "app-cloudep-trade-service/internal/model"
"context" "context"
@ -24,7 +24,7 @@ type WalletRepository interface {
type BalanceReq struct { type BalanceReq struct {
UID []string UID []string
Currency []string Currency []string
Kind []domain.WalletType BalanceType []wallet.BalanceType
} }
type Option func() sqlx.SqlConn type Option func() sqlx.SqlConn

View File

@ -1,7 +1,7 @@
package repository package repository
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"github.com/zeromicro/go-zero/core/stores/sqlx" "github.com/zeromicro/go-zero/core/stores/sqlx"
@ -15,8 +15,8 @@ type WalletOptions struct {
WithLock bool WithLock bool
OrderID string OrderID string
Amount decimal.Decimal Amount decimal.Decimal
Kind domain.WalletType BalanceType wallet.BalanceType
Business domain.BusinessName Business wallet.BusinessLogic
Tx *sqlx.SqlConn Tx *sqlx.SqlConn
} }
@ -48,13 +48,13 @@ func WithAmount(amount decimal.Decimal) WalletOperatorOption {
} }
} }
func WithKind(kind domain.WalletType) WalletOperatorOption { func WithKind(balanceType wallet.BalanceType) WalletOperatorOption {
return func(opts *WalletOptions) { return func(opts *WalletOptions) {
opts.Kind = kind opts.BalanceType = balanceType
} }
} }
func WithBusiness(business domain.BusinessName) WalletOperatorOption { func WithBusiness(business wallet.BusinessLogic) WalletOperatorOption {
return func(opts *WalletOptions) { return func(opts *WalletOptions) {
opts.Business = business opts.Business = business
} }

View File

@ -1,7 +1,7 @@
package usecase package usecase
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"context" "context"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
@ -38,7 +38,7 @@ type ModifyOrderQuery struct {
// CancelOrderQuery 1.建單失敗 9.交易取消 10.交易異常 // CancelOrderQuery 1.建單失敗 9.交易取消 10.交易異常
type CancelOrderQuery struct { type CancelOrderQuery struct {
BusinessID string BusinessID string
Status domain.OrderStatus Status order.Status
} }
// DeleteOrderQuery 刪除訂單(軟刪除) // DeleteOrderQuery 刪除訂單(軟刪除)
@ -53,8 +53,8 @@ type GetOrderQuery struct {
type GetOrderResp struct { type GetOrderResp struct {
BusinessID string // 訂單業務流水號 BusinessID string // 訂單業務流水號
OrderType domain.OrderType `json:"order_type"` // 訂單類型 OrderType order.Type `json:"order_type"` // 訂單類型
OrderStatus domain.OrderStatus `json:"order_status"` // 訂單狀態 OrderStatus order.Status `json:"order_status"` // 訂單狀態
Brand string `json:"brand"` // 下單平台 Brand string `json:"brand"` // 下單平台
OrderUID string `json:"order_uid"` // 下單用戶 UID OrderUID string `json:"order_uid"` // 下單用戶 UID
ReferenceID string `json:"reference_id"` // 訂單來源 ReferenceID string `json:"reference_id"` // 訂單來源
@ -98,7 +98,7 @@ type GetOrderListReq struct {
ReferenceUID string ReferenceUID string
BusinessID string BusinessID string
UID string UID string
OrderType domain.OrderType OrderType order.Type
DirectionType []int64 DirectionType []int64
OrderStatus []int64 OrderStatus []int64
@ -128,8 +128,8 @@ type ListOrderResp struct {
type CreateOrderReq struct { type CreateOrderReq struct {
BusinessID string BusinessID string
OrderType domain.OrderType // 訂單類型 OrderType order.Type // 訂單類型
OrderStatus domain.OrderStatus // 訂單狀態 OrderStatus order.Status // 訂單狀態
Brand string // 下單平台 Brand string // 下單平台
OrderUID string // 下單用戶 UID OrderUID string // 下單用戶 UID
ReferenceID string // 訂單來源 ReferenceID string // 訂單來源

View File

@ -1,7 +1,7 @@
package usecase package usecase
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"context" "context"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
@ -55,11 +55,11 @@ type Transaction struct {
Currency string // 幣別 Currency string // 幣別
Amount decimal.Decimal // 交易金額 Amount decimal.Decimal // 交易金額
BeforeBalance decimal.Decimal // 交易前餘額 BeforeBalance decimal.Decimal // 交易前餘額
Type domain.TxType // 交易種類 Type wallet.TransactionType // 交易種類
BusinessType domain.BusinessName // 商業種類 BusinessType wallet.BusinessLogic // 商業種類
Brand string // 轉帳平台 Brand string // 轉帳平台
From domain.WalletType // 從哪種錢包類型 From wallet.BalanceType // 從哪種錢包類型
To domain.WalletType // 到哪種錢包類型 To wallet.BalanceType // 到哪種錢包類型
} }
type BalanceReq struct { type BalanceReq struct {

View File

@ -1,8 +1,8 @@
package domain package wallet
type WalletStatus int64 type Status int64
func (o *WalletStatus) ToInt() int { func (o *Status) ToInt() int {
return int(*o) return int(*o)
} }

View File

@ -0,0 +1,52 @@
package wallet
// ===================商業邏輯類型===================
type BusinessLogic string
// 定義商業邏輯名稱
const (
// NoLogic 無商業邏輯
NoLogic BusinessLogic = ""
// OrderLogic 訂單相關業務邏輯
OrderLogic BusinessLogic = "order"
// SystemTransferLogic 系統劃轉邏輯
SystemTransferLogic BusinessLogic = "system_transfer"
)
// 定義商業邏輯類型
const (
// NoLogicType 無商業邏輯類型
NoLogicType int8 = iota
// OrderLogicType 訂單業務邏輯類型
OrderLogicType
// SystemTransferLogicType 系統劃轉業務邏輯類型
SystemTransferLogicType
)
// 定義名稱和類型之間的映射
var logicNameToType = map[BusinessLogic]int8{
OrderLogic: OrderLogicType,
SystemTransferLogic: SystemTransferLogicType,
}
var logicTypeToName = map[int8]BusinessLogic{
OrderLogicType: OrderLogic,
SystemTransferLogicType: SystemTransferLogic,
}
// ToInt8 將 BusinessLogic 轉換為對應的 int8 類型
func (b BusinessLogic) ToInt8() int8 {
if val, ok := logicNameToType[b]; ok {
return val
}
return NoLogicType
}
// LogicTypeToName 將 int8 類型轉換為對應的 BusinessLogic 名稱
func LogicTypeToName(b int8) BusinessLogic {
if val, ok := logicTypeToName[b]; ok {
return val
}
return NoLogic
}

View File

@ -0,0 +1,49 @@
package wallet
// ===================交易類型===================
type TransactionType int64
// 定義交易類型
const (
// Deposit 增加可用餘額的充值交易
Deposit TransactionType = iota + 1
// Withdraw 減少可用餘額的提現交易
Withdraw
// Freeze 將可用餘額轉入凍結餘額的凍結交易
Freeze
// Unfreeze 減少凍結餘額的解凍交易
Unfreeze
// RollbackFreeze 回滾凍結:減少凍結餘額並恢復至可用餘額,不指定金額
RollbackFreeze
// Unconfirmed 限制交易:減少凍結餘額並增加他人限制餘額
Unconfirmed
// CancelFreeze 取消凍結:減少凍結餘額並恢復至可用餘額,允許指定金額
CancelFreeze
// DepositToUnconfirmed 增加限制餘額的充值交易
DepositToUnconfirmed
// AppendFreeze 追加凍結:減少可用餘額並增加凍結餘額
AppendFreeze
// RollbackFreezeToAvailable 回滾凍結:指定金額回滾凍結餘額並增加至可用餘額
RollbackFreezeToAvailable
// PlatformDistribution 平台分發交易
PlatformDistribution
// SystemTransfer 系統劃轉交易
SystemTransfer
)
// ToInt 將交易類型轉換為 int64
func (t TransactionType) ToInt() int64 {
return int64(t)
}

View File

@ -0,0 +1,58 @@
package wallet
// ===================錢包餘額類型===================
// BalanceType 表示錢包餘額的類型
type BalanceType int64
// 錢包餘額類型
const (
// AvailableBalanceType 表示可動用的餘額
AvailableBalanceType BalanceType = iota + 1
// FrozenBalanceType 表示在交易過程中凍結的餘額
FrozenBalanceType
// PendingBalanceType 表示已提交但尚未確認完成的交易餘額
PendingBalanceType
// ContractAvailableBalanceType 表示合約或交易可用的餘額
ContractAvailableBalanceType
// ContractFrozenBalanceType 表示合約或交易凍結的餘額
ContractFrozenBalanceType
)
// balanceTypeToName 將餘額類型映射到其名稱
var balanceTypeToName = map[BalanceType]string{
AvailableBalanceType: "available",
FrozenBalanceType: "frozen",
PendingBalanceType: "pending",
ContractAvailableBalanceType: "contract_available",
ContractFrozenBalanceType: "contract_frozen",
}
// nameToBalanceType 將名稱映射到餘額類型
var nameToBalanceType = map[string]BalanceType{
"available": AvailableBalanceType,
"frozen": FrozenBalanceType,
"pending": PendingBalanceType,
"contract_available": ContractAvailableBalanceType,
"contract_frozen": ContractFrozenBalanceType,
}
// Name 返回餘額類型的名稱
func (b BalanceType) Name() string {
return balanceTypeToName[b]
}
// GetBalanceTypeByName 根據名稱返回對應的餘額類型
func GetBalanceTypeByName(name string) BalanceType {
return nameToBalanceType[name]
}
// AllBalanceTypes 包含目前所有的錢包餘額類型
var AllBalanceTypes = []BalanceType{
AvailableBalanceType, FrozenBalanceType, PendingBalanceType,
ContractAvailableBalanceType, ContractFrozenBalanceType,
}

View File

@ -1,52 +0,0 @@
package domain
// ===================交易商業邏輯種類===================
type BusinessName string
const (
// NoBusinessName 非商業邏輯
NoBusinessName BusinessName = ""
// OrderBusinessTypeBusinessName order業務邏輯
OrderBusinessTypeBusinessName BusinessName = "order"
// SystemTransferBusinessTypeBusinessName 系統劃轉
SystemTransferBusinessTypeBusinessName BusinessName = "system_transfer"
)
const (
// NoBusinessType 非商業邏輯
NoBusinessType int8 = iota
// OrderBusinessTypeBusinessType order 業務邏輯
OrderBusinessTypeBusinessType
// SystemTransferBusinessTypeBusinessType 系統劃轉
SystemTransferBusinessTypeBusinessType
)
// 定義兩個map用於名稱和類型的相互映射
var nameToBusinessType = map[BusinessName]int8{
OrderBusinessTypeBusinessName: OrderBusinessTypeBusinessType,
SystemTransferBusinessTypeBusinessName: SystemTransferBusinessTypeBusinessType,
}
var businessTypeToName = map[int8]BusinessName{
OrderBusinessTypeBusinessType: OrderBusinessTypeBusinessName,
SystemTransferBusinessTypeBusinessType: SystemTransferBusinessTypeBusinessName,
}
// ToINT8 converts BusinessName to its corresponding int8 type
func (b BusinessName) ToINT8() int8 {
if val, ok := nameToBusinessType[b]; ok {
return val
}
return NoBusinessType
}
// BusinessTypeToString converts an int8 type to its corresponding BusinessName
func BusinessTypeToString(b int8) BusinessName {
if val, ok := businessTypeToName[b]; ok {
return val
}
return NoBusinessName
}

View File

@ -1,48 +0,0 @@
package domain
// ===================交易種類===================
type TxType int64
// 交易類型
const (
// TxDepositType 充值(增加可用餘額)
TxDepositType TxType = iota + 1
// TxWithdrawType 提現(減少可用餘額)
TxWithdrawType
// TxFreezeType 凍結(減少可用餘額,加在凍結餘額)
TxFreezeType
// TxUnFreezeType 解凍(減少凍結餘額)
TxUnFreezeType
// TxRollbackFreezeType rollback凍結(減少凍結餘額,加回可用餘額,不可指定金額)
TxRollbackFreezeType
// TxUnconfirmedType 限制(減少凍結餘額,加別人限制餘額)
TxUnconfirmedType
// TxCancelFreezeType 取消凍結(減少凍結餘額,加回可用餘額,,可指定金額)
TxCancelFreezeType
// TxDepositUnconfirmedType 充值(增加限制餘額)
TxDepositUnconfirmedType
// TxAppendFreezeType 追加凍結(減少可用餘額,加在凍結餘額)
TxAppendFreezeType
// TxRollbackFreezeAddAvailableType rollback凍結(rollback凍結餘額指定金額加回可用餘額)
TxRollbackFreezeAddAvailableType
// TxDistributionType 平台分發
TxDistributionType
// TxSystemTransfer 系統劃轉
TxSystemTransfer
)
func (t TxType) ToInt() int64 {
return int64(t)
}

View File

@ -1,54 +0,0 @@
package domain
// ===================錢包金額種類===================
type WalletType int64
// 錢包種類
const (
// WalletAvailableType 錢包可動用的金額
WalletAvailableType WalletType = iota + 1
// WalletFreezeType 交易過程,錢包被凍結的金額
WalletFreezeType
// WalletUnconfirmedType 已提交的交易但還未確認完成交易的金額
WalletUnconfirmedType
// WalletContractAvailableType 合約/交易可用餘額
WalletContractAvailableType
// WalletContractFreezeType 合約/交易凍結餘額
WalletContractFreezeType
)
var walletTypeToName = map[WalletType]string{
WalletAvailableType: "available",
WalletFreezeType: "freeze",
WalletUnconfirmedType: "unconfirmed",
WalletContractAvailableType: "contract_available",
WalletContractFreezeType: "contract_freeze",
}
var nameToWalletType = map[string]WalletType{
"available": WalletAvailableType,
"freeze": WalletFreezeType,
"unconfirmed": WalletUnconfirmedType,
"contract_available": WalletContractAvailableType,
"contract_freeze": WalletContractFreezeType,
}
// Name returns the name associated with the WalletType.
func (w WalletType) Name() string {
return walletTypeToName[w]
}
// GetWalletTypeByName returns the WalletType associated with the given name.
func GetWalletTypeByName(name string) WalletType {
return nameToWalletType[name]
}
var AllWalletType = []WalletType{
WalletAvailableType, WalletFreezeType, WalletUnconfirmedType,
WalletContractAvailableType, WalletContractFreezeType,
}

View File

@ -1,7 +1,7 @@
package orderservicelogic package orderservicelogic
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"app-cloudep-trade-service/internal/domain/usecase" "app-cloudep-trade-service/internal/domain/usecase"
"context" "context"
@ -46,7 +46,7 @@ func (l *CancelOrderLogic) CancelOrder(in *trade.CancelOrderReq) (*trade.OKResp,
err := l.svcCtx.OrderUseCase.CancelOrder(l.ctx, usecase.CancelOrderQuery{ err := l.svcCtx.OrderUseCase.CancelOrder(l.ctx, usecase.CancelOrderQuery{
BusinessID: in.GetBusinessId(), BusinessID: in.GetBusinessId(),
Status: domain.OrderStatus(in.GetStatus()), Status: order.Status(in.GetStatus()),
}) })
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -2,7 +2,7 @@ package orderservicelogic
import ( import (
"app-cloudep-trade-service/gen_result/pb/trade" "app-cloudep-trade-service/gen_result/pb/trade"
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"app-cloudep-trade-service/internal/domain/usecase" "app-cloudep-trade-service/internal/domain/usecase"
"app-cloudep-trade-service/internal/svc" "app-cloudep-trade-service/internal/svc"
"context" "context"
@ -169,8 +169,8 @@ func buildCreateOrderReq(in *trade.CreateOrderReq) *createOrderReq {
func toCreateOrderUseCase(req *createOrderReq) usecase.CreateOrderReq { func toCreateOrderUseCase(req *createOrderReq) usecase.CreateOrderReq {
return usecase.CreateOrderReq{ return usecase.CreateOrderReq{
BusinessID: req.BusinessID, BusinessID: req.BusinessID,
OrderType: domain.OrderType(req.OrderType), OrderType: order.Type(req.OrderType),
OrderStatus: domain.OrderStatus(req.OrderStatus), OrderStatus: order.Status(req.OrderStatus),
Brand: req.Brand, Brand: req.Brand,
OrderUID: req.OrderUID, OrderUID: req.OrderUID,
ReferenceID: req.ReferenceID, ReferenceID: req.ReferenceID,

View File

@ -1,7 +1,7 @@
package orderservicelogic package orderservicelogic
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"app-cloudep-trade-service/internal/domain/usecase" "app-cloudep-trade-service/internal/domain/usecase"
"context" "context"
@ -61,7 +61,7 @@ func toGetOrderListReq(req *trade.ListOrderReq) usecase.GetOrderListReq {
ReferenceUID: req.ReferenceUid, ReferenceUID: req.ReferenceUid,
BusinessID: req.BusinessId, BusinessID: req.BusinessId,
UID: req.Uid, UID: req.Uid,
OrderType: domain.OrderType(req.OrderType), OrderType: order.Type(req.OrderType),
DirectionType: i32To64(req.DirectionType), DirectionType: i32To64(req.DirectionType),
OrderStatus: i32To64(req.OrderStatus), OrderStatus: i32To64(req.OrderStatus),
StartCreateTime: req.StartCreateTime, StartCreateTime: req.StartCreateTime,

View File

@ -1,7 +1,7 @@
package model package model
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"context" "context"
"errors" "errors"
"time" "time"
@ -99,7 +99,7 @@ func (m *customOrderModel) UpdateTimeoutOrder(ctx context.Context, req UpdateTim
// 構建過濾條件,選擇創建時間在指定時間之前且狀態為 0 (創建) 的項目 // 構建過濾條件,選擇創建時間在指定時間之前且狀態為 0 (創建) 的項目
filter := bson.M{ filter := bson.M{
"create_time": bson.M{"$lt": req.CreateTimeBefore}, "create_time": bson.M{"$lt": req.CreateTimeBefore},
"status": domain.OrderStatusCreated, "status": order.Cancelled,
"$or": []bson.M{ "$or": []bson.M{
{"delete_time": bson.M{"$exists": false}}, {"delete_time": bson.M{"$exists": false}},
{"delete_time": 0}, {"delete_time": 0},
@ -109,7 +109,7 @@ func (m *customOrderModel) UpdateTimeoutOrder(ctx context.Context, req UpdateTim
// 更新內容,將狀態設置為 11並更新 update_time // 更新內容,將狀態設置為 11並更新 update_time
updates := bson.M{ updates := bson.M{
"$set": bson.M{ "$set": bson.M{
"status": domain.OrderStatusTimeout, "status": order.TimedOut,
"update_time": time.Now().UTC().UnixNano(), "update_time": time.Now().UTC().UnixNano(),
}, },
} }

View File

@ -1,7 +1,7 @@
package model package model
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"github.com/shopspring/decimal" "github.com/shopspring/decimal"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
@ -12,8 +12,8 @@ type Order struct {
UpdateTime int64 `bson:"update_time"` UpdateTime int64 `bson:"update_time"`
CreateTime int64 `bson:"create_time"` CreateTime int64 `bson:"create_time"`
BusinessID string `bson:"business_id"` // 訂單業務流水號 BusinessID string `bson:"business_id"` // 訂單業務流水號
OrderType domain.OrderType `bson:"order_type"` // 訂單類型 OrderType order.Type `bson:"order_type"` // 訂單類型
OrderStatus domain.OrderStatus `bson:"order_status"` // 訂單狀態 OrderStatus order.Status `bson:"order_status"` // 訂單狀態
Brand string `bson:"brand"` // 下單平台 Brand string `bson:"brand"` // 下單平台
OrderUID string `bson:"order_uid"` // 下單用戶 UID OrderUID string `bson:"order_uid"` // 下單用戶 UID
ReferenceID string `bson:"reference_id"` // 訂單來源 ReferenceID string `bson:"reference_id"` // 訂單來源

View File

@ -1,7 +1,7 @@
package model package model
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"context" "context"
"database/sql" "database/sql"
"errors" "errors"
@ -34,7 +34,7 @@ type (
BalanceReq struct { BalanceReq struct {
UID []string UID []string
Currency []string Currency []string
Kind []domain.WalletType Kind []wallet.BalanceType
} }
) )
@ -89,7 +89,7 @@ func (m *customWalletModel) Balances(ctx context.Context, req BalanceReq, isLock
switch { switch {
case err == nil: case err == nil:
return wallets, nil return wallets, nil
case errors.As(sqlc.ErrNotFound, &err): case errors.Is(err, sqlc.ErrNotFound):
return nil, ErrNotFound return nil, ErrNotFound
default: default:
return nil, err return nil, err
@ -117,7 +117,7 @@ func (m *customWalletModel) BalancesByIDs(ctx context.Context, ids []int64, with
switch { switch {
case err == nil: case err == nil:
return wallets, nil return wallets, nil
case errors.As(sqlc.ErrNotFound, &err): case errors.Is(err, sqlc.ErrNotFound):
return nil, ErrNotFound return nil, ErrNotFound
default: default:
return nil, err return nil, err

View File

@ -3,7 +3,7 @@
package model package model
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"context" "context"
"database/sql" "database/sql"
"fmt" "fmt"
@ -44,7 +44,7 @@ type (
Brand string `db:"brand"` // 品牌名稱 Brand string `db:"brand"` // 品牌名稱
Currency string `db:"currency"` // 幣別(或平台點數) Currency string `db:"currency"` // 幣別(或平台點數)
Balance decimal.Decimal `db:"balance"` // 錢包餘額 Balance decimal.Decimal `db:"balance"` // 錢包餘額
WalletType domain.WalletType `db:"wallet_type"` // 錢包種類: 1=可用, 2=凍結, 3=限制(僅出金) WalletType wallet.BalanceType `db:"wallet_type"` // 錢包種類: 1=可用, 2=凍結, 3=限制(僅出金)
CreatedAt int64 `db:"created_at"` // 創建時間 CreatedAt int64 `db:"created_at"` // 創建時間
UpdatedAt int64 `db:"updated_at"` // 更新時間 UpdatedAt int64 `db:"updated_at"` // 更新時間
} }

View File

@ -1,8 +1,8 @@
package repository package repository
import ( import (
"app-cloudep-trade-service/internal/domain"
"app-cloudep-trade-service/internal/domain/repository" "app-cloudep-trade-service/internal/domain/repository"
"app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model" "app-cloudep-trade-service/internal/model"
"context" "context"
@ -19,7 +19,7 @@ type userLocalWallet struct {
currency string currency string
// local wallet 相關計算的餘額存在這裡 // local wallet 相關計算的餘額存在這裡
walletBalance map[domain.WalletType]model.Wallet walletBalance map[wallet.BalanceType]model.Wallet
// local order wallet 相關計算的餘額存在這裡 // local order wallet 相關計算的餘額存在這裡
localOrderBalance map[int64]decimal.Decimal localOrderBalance map[int64]decimal.Decimal
@ -28,6 +28,7 @@ type userLocalWallet struct {
transactions []model.WalletJournal transactions []model.WalletJournal
} }
// GetBalancesByID 使用 Wallet ID 取得餘額,如果需要上鎖,可以在 option 內加上 tx 以及 lock可以參考 TestBalanceUseCase
func (use *userLocalWallet) GetBalancesByID(ctx context.Context, ids []int64, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) { func (use *userLocalWallet) GetBalancesByID(ctx context.Context, ids []int64, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) {
o := repository.ApplyOptions(opts...) o := repository.ApplyOptions(opts...)
tx := use.txConn tx := use.txConn
@ -40,24 +41,25 @@ func (use *userLocalWallet) GetBalancesByID(ctx context.Context, ids []int64, op
return nil, err return nil, err
} }
for _, wallet := range wallets { for _, w := range wallets {
use.walletBalance[wallet.WalletType] = wallet use.walletBalance[w.WalletType] = w
} }
return wallets, nil return wallets, nil
} }
// LocalBalance 內存餘額 // LocalBalance 內存餘額
func (use *userLocalWallet) LocalBalance(kind domain.WalletType) decimal.Decimal { func (use *userLocalWallet) LocalBalance(BalanceType wallet.BalanceType) decimal.Decimal {
wallet, ok := use.walletBalance[kind] w, ok := use.walletBalance[BalanceType]
if !ok { if !ok {
return decimal.Zero return decimal.Zero
} }
return wallet.Balance return w.Balance
} }
func (use *userLocalWallet) Balances(ctx context.Context, kind []domain.WalletType, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) { // Balances 取得餘額如果需要上鎖可以在option 內加上 tx 以及 lock可以參考 TestBalanceUseCase
func (use *userLocalWallet) Balances(ctx context.Context, balanceType []wallet.BalanceType, opts ...repository.WalletOperatorOption) ([]model.Wallet, error) {
o := repository.ApplyOptions(opts...) o := repository.ApplyOptions(opts...)
tx := use.txConn tx := use.txConn
if o.Tx != nil { if o.Tx != nil {
@ -67,7 +69,7 @@ func (use *userLocalWallet) Balances(ctx context.Context, kind []domain.WalletTy
wallets, err := use.wm.Balances(ctx, model.BalanceReq{ wallets, err := use.wm.Balances(ctx, model.BalanceReq{
UID: []string{use.uid}, UID: []string{use.uid},
Currency: []string{use.currency}, Currency: []string{use.currency},
Kind: kind, Kind: balanceType,
}, o.WithLock, tx) }, o.WithLock, tx)
if err != nil { if err != nil {
return nil, err return nil, err
@ -87,7 +89,7 @@ func NewUserWalletOperator(uid, currency string, wm model.WalletModel, txConn sq
uid: uid, uid: uid,
currency: currency, currency: currency,
walletBalance: make(map[domain.WalletType]model.Wallet, len(domain.AllWalletType)), walletBalance: make(map[wallet.BalanceType]model.Wallet, len(wallet.AllBalanceTypes)),
localOrderBalance: make(map[int64]decimal.Decimal, len(domain.AllWalletType)), localOrderBalance: make(map[int64]decimal.Decimal, len(wallet.AllBalanceTypes)),
} }
} }

View File

@ -3,6 +3,7 @@ package repository
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain"
"app-cloudep-trade-service/internal/domain/repository" "app-cloudep-trade-service/internal/domain/repository"
"app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model" "app-cloudep-trade-service/internal/model"
"context" "context"
"database/sql" "database/sql"
@ -88,10 +89,10 @@ func (repo *WalletRepository) GetUserWalletOperator(uid, currency string, opts .
// Create 創建錢包,如果有相同的就跳過不建立 // Create 創建錢包,如果有相同的就跳過不建立
func (repo *WalletRepository) Create(ctx context.Context, uid, currency, brand string) ([]*model.Wallet, error) { func (repo *WalletRepository) Create(ctx context.Context, uid, currency, brand string) ([]*model.Wallet, error) {
wallets := make([]*model.Wallet, 0, len(domain.AllWalletType)) wallets := make([]*model.Wallet, 0, len(wallet.AllBalanceTypes))
// 建立個人所有種類的錢包 // 建立個人所有種類的錢包
now := time.Now().UTC().UnixNano() now := time.Now().UTC().UnixNano()
for _, item := range domain.AllWalletType { for _, item := range wallet.AllBalanceTypes {
balance := decimal.Zero balance := decimal.Zero
wallets = append(wallets, &model.Wallet{ wallets = append(wallets, &model.Wallet{
Brand: brand, Brand: brand,
@ -127,7 +128,7 @@ func (repo *WalletRepository) Balances(ctx context.Context, req repository.Balan
data, err := repo.WalletModel.Balances(ctx, model.BalanceReq{ data, err := repo.WalletModel.Balances(ctx, model.BalanceReq{
UID: req.UID, UID: req.UID,
Currency: req.Currency, Currency: req.Currency,
Kind: req.Kind, Kind: req.BalanceType,
}, false, repo.TxConn) }, false, repo.TxConn)
if err != nil { if err != nil {

View File

@ -1,7 +1,7 @@
package repository package repository
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/wallet"
"app-cloudep-trade-service/internal/model" "app-cloudep-trade-service/internal/model"
"context" "context"
"fmt" "fmt"
@ -22,7 +22,7 @@ func TestByMe(t *testing.T) {
ctx := context.Background() ctx := context.Background()
wo := WalletRepo.GetUserWalletOperator("OOOOOOOK", "USD") wo := WalletRepo.GetUserWalletOperator("OOOOOOOK", "USD")
balances, err := wo.Balances(ctx, domain.AllWalletType) balances, err := wo.Balances(ctx, wallet.AllBalanceTypes)
if err != nil { if err != nil {
return return
} }
@ -77,3 +77,5 @@ func TestByMe(t *testing.T) {
// fmt.Println(balances) // fmt.Println(balances)
} }
func TestBalanceUseCase(t *testing.T) {}

View File

@ -1,7 +1,7 @@
package usecase package usecase
import ( import (
"app-cloudep-trade-service/internal/domain" "app-cloudep-trade-service/internal/domain/order"
"app-cloudep-trade-service/internal/domain/usecase" "app-cloudep-trade-service/internal/domain/usecase"
mockmodel "app-cloudep-trade-service/internal/mock/model" mockmodel "app-cloudep-trade-service/internal/mock/model"
model "app-cloudep-trade-service/internal/model/mongo" model "app-cloudep-trade-service/internal/model/mongo"
@ -30,7 +30,7 @@ func TestOrderUseCase_CancelOrder(t *testing.T) {
cancelOrderQuery := usecase.CancelOrderQuery{ cancelOrderQuery := usecase.CancelOrderQuery{
BusinessID: "business_123", BusinessID: "business_123",
Status: domain.OrderStatusCancelled, // 使用模擬的狀態 Status: order.Cancelled, // 使用模擬的狀態
} }
tests := []struct { tests := []struct {
@ -89,8 +89,8 @@ func TestOrderUseCase_CreateOrder(t *testing.T) {
// 構建測試參數 // 構建測試參數
createOrderReq := usecase.CreateOrderReq{ createOrderReq := usecase.CreateOrderReq{
BusinessID: "business_123", BusinessID: "business_123",
OrderType: domain.OrderTypeTest, OrderType: order.TestType,
OrderStatus: domain.OrderStatusCreated, OrderStatus: order.Created,
Brand: "test_brand", Brand: "test_brand",
OrderUID: "user_123", OrderUID: "user_123",
ReferenceID: "reference_123", ReferenceID: "reference_123",
@ -222,8 +222,8 @@ func TestOrderUseCase_GetOrder(t *testing.T) {
UpdateTime: 123456789, UpdateTime: 123456789,
CreateTime: 123456789, CreateTime: 123456789,
BusinessID: "business_123", BusinessID: "business_123",
OrderType: domain.OrderTypeTest, OrderType: order.TestType,
OrderStatus: domain.OrderStatusCreated, OrderStatus: order.Created,
Brand: "test_brand", Brand: "test_brand",
OrderUID: "user_123", OrderUID: "user_123",
ReferenceID: "reference_123", ReferenceID: "reference_123",
@ -343,14 +343,14 @@ func TestOrderUseCase_ListOrder(t *testing.T) {
PageIndex: 1, PageIndex: 1,
PageSize: 10, PageSize: 10,
BusinessID: "business_123", BusinessID: "business_123",
OrderStatus: []int64{int64(domain.OrderStatusCreated)}, OrderStatus: []int64{int64(order.Created)},
} }
mockOrders := []model.Order{ mockOrders := []model.Order{
{ {
BusinessID: "business_123", BusinessID: "business_123",
OrderUID: "user_123", OrderUID: "user_123",
OrderStatus: domain.OrderStatusCreated, OrderStatus: order.Created,
// 其他欄位根據需要填充 // 其他欄位根據需要填充
}, },
} }
@ -414,7 +414,7 @@ func TestOrderUseCase_ModifyOrderStatus(t *testing.T) {
modifyOrderQuery := &usecase.ModifyOrderQuery{ modifyOrderQuery := &usecase.ModifyOrderQuery{
BusinessID: "business_123", BusinessID: "business_123",
Status: int64(domain.OrderStatusCancelled), Status: int64(order.Cancelled),
} }
tests := []struct { tests := []struct {