钱包流水新增资产信息
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m59s
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 7m59s
This commit is contained in:
@@ -5740,6 +5740,16 @@ components:
|
||||
amount:
|
||||
description: 变动金额(分,正数为入账,负数为扣款)
|
||||
type: integer
|
||||
asset_id:
|
||||
description: 资产ID(仅套餐扣款流水有值)
|
||||
minimum: 0
|
||||
type: integer
|
||||
asset_identifier:
|
||||
description: 资产标识快照(ICCID、IMEI或虚拟号,仅套餐扣款流水有值)
|
||||
type: string
|
||||
asset_type:
|
||||
description: 资产类型(iot_card:物联网卡, device:设备,仅套餐扣款流水有值)
|
||||
type: string
|
||||
balance_after:
|
||||
description: 变动后余额(分)
|
||||
type: integer
|
||||
|
||||
@@ -50,6 +50,9 @@ type AgentWalletTransaction struct {
|
||||
ReferenceType *string `gorm:"column:reference_type;type:varchar(50);comment:关联业务类型(order | commission | withdrawal | topup)" json:"reference_type,omitempty"`
|
||||
ReferenceID *uint `gorm:"column:reference_id;comment:关联业务ID" json:"reference_id,omitempty"`
|
||||
RelatedShopID *uint `gorm:"column:related_shop_id;comment:关联店铺ID(代购时记录下级店铺)" json:"related_shop_id,omitempty"`
|
||||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null;default:'';comment:资产类型(iot_card-物联网卡 | device-设备)" json:"asset_type,omitempty"`
|
||||
AssetID uint `gorm:"column:asset_id;not null;default:0;comment:资产ID快照(卡ID或设备ID)" json:"asset_id,omitempty"`
|
||||
AssetIdentifier string `gorm:"column:asset_identifier;type:varchar(100);not null;default:'';comment:资产标识快照(ICCID、IMEI或虚拟号)" json:"asset_identifier,omitempty"`
|
||||
Remark *string `gorm:"column:remark;type:text;comment:备注" json:"remark,omitempty"`
|
||||
Metadata *string `gorm:"column:metadata;type:jsonb;comment:扩展信息(如手续费、支付方式等)" json:"metadata,omitempty"`
|
||||
Creator uint `gorm:"column:creator;not null;comment:创建人ID" json:"creator"`
|
||||
|
||||
@@ -60,6 +60,9 @@ type MainWalletTransactionItem struct {
|
||||
Amount int64 `json:"amount" description:"变动金额(分,正数为入账,负数为扣款)"`
|
||||
BalanceBefore int64 `json:"balance_before" description:"变动前余额(分)"`
|
||||
BalanceAfter int64 `json:"balance_after" description:"变动后余额(分)"`
|
||||
AssetType string `json:"asset_type" description:"资产类型(iot_card:物联网卡, device:设备,仅套餐扣款流水有值)"`
|
||||
AssetID uint `json:"asset_id" description:"资产ID(仅套餐扣款流水有值)"`
|
||||
AssetIdentifier string `json:"asset_identifier" description:"资产标识快照(ICCID、IMEI或虚拟号,仅套餐扣款流水有值)"`
|
||||
Remark string `json:"remark" description:"备注(可为空)"`
|
||||
CreatedAt string `json:"created_at" description:"流水时间"`
|
||||
}
|
||||
|
||||
@@ -728,6 +728,7 @@ func (s *Service) CreateH5Order(ctx context.Context, req *dto.CreateOrderRequest
|
||||
BuyerID: orderBuyerID,
|
||||
IotCardID: req.IotCardID,
|
||||
DeviceID: req.DeviceID,
|
||||
AssetIdentifier: buildOrderAssetIdentifier(validationResult),
|
||||
TotalAmount: totalAmount,
|
||||
PaymentMethod: paymentMethod,
|
||||
PaymentStatus: paymentStatus,
|
||||
@@ -988,11 +989,11 @@ func (s *Service) getCostPrice(ctx context.Context, shopID uint, packageID uint)
|
||||
// ctx: 上下文
|
||||
// tx: 事务对象
|
||||
// wallet: 扣款前的钱包快照
|
||||
// orderID: 订单ID
|
||||
// order: 订单快照
|
||||
// amount: 扣款金额(正数)
|
||||
// purchaseRole: 订单角色
|
||||
// relatedShopID: 关联店铺ID(代购场景填充下级店铺ID)
|
||||
func (s *Service) createWalletTransaction(ctx context.Context, tx *gorm.DB, wallet *model.AgentWallet, orderID uint, amount int64, purchaseRole string, relatedShopID *uint) error {
|
||||
func (s *Service) createWalletTransaction(ctx context.Context, tx *gorm.DB, wallet *model.AgentWallet, order *model.Order, amount int64, purchaseRole string, relatedShopID *uint) error {
|
||||
var subtype *string
|
||||
remark := "购买套餐"
|
||||
if purchaseRole == "" {
|
||||
@@ -1021,6 +1022,7 @@ func (s *Service) createWalletTransaction(ctx context.Context, tx *gorm.DB, wall
|
||||
}
|
||||
|
||||
userID := middleware.GetUserIDFromContext(ctx)
|
||||
assetType, assetID, assetIdentifier := buildAgentWalletTransactionAssetSnapshot(order)
|
||||
|
||||
// 创建钱包流水记录
|
||||
transaction := &model.AgentWalletTransaction{
|
||||
@@ -1034,8 +1036,11 @@ func (s *Service) createWalletTransaction(ctx context.Context, tx *gorm.DB, wall
|
||||
BalanceAfter: wallet.Balance - amount,
|
||||
Status: constants.TransactionStatusSuccess,
|
||||
ReferenceType: strPtr(constants.ReferenceTypeOrder),
|
||||
ReferenceID: &orderID,
|
||||
ReferenceID: &order.ID,
|
||||
RelatedShopID: relatedShopID,
|
||||
AssetType: assetType,
|
||||
AssetID: assetID,
|
||||
AssetIdentifier: assetIdentifier,
|
||||
Remark: &remark,
|
||||
Creator: userID,
|
||||
ShopIDTag: wallet.ShopIDTag,
|
||||
@@ -1049,6 +1054,51 @@ func (s *Service) createWalletTransaction(ctx context.Context, tx *gorm.DB, wall
|
||||
return nil
|
||||
}
|
||||
|
||||
// buildAgentWalletTransactionAssetSnapshot 从订单中生成代理钱包扣款流水的资产快照。
|
||||
func buildAgentWalletTransactionAssetSnapshot(order *model.Order) (string, uint, string) {
|
||||
if order == nil {
|
||||
return "", 0, ""
|
||||
}
|
||||
switch order.OrderType {
|
||||
case model.OrderTypeSingleCard:
|
||||
if order.IotCardID == nil {
|
||||
return constants.AssetTypeIotCard, 0, order.AssetIdentifier
|
||||
}
|
||||
return constants.AssetTypeIotCard, *order.IotCardID, order.AssetIdentifier
|
||||
case model.OrderTypeDevice:
|
||||
if order.DeviceID == nil {
|
||||
return constants.AssetTypeDevice, 0, order.AssetIdentifier
|
||||
}
|
||||
return constants.AssetTypeDevice, *order.DeviceID, order.AssetIdentifier
|
||||
default:
|
||||
return "", 0, order.AssetIdentifier
|
||||
}
|
||||
}
|
||||
|
||||
// buildOrderAssetIdentifier 生成订单资产标识快照。
|
||||
// 后台按标识下单时保留请求标识;按ID下单时用卡ICCID或设备IMEI/虚拟号兜底。
|
||||
func buildOrderAssetIdentifier(result *purchase_validation.PurchaseValidationResult) string {
|
||||
if result == nil {
|
||||
return ""
|
||||
}
|
||||
if result.Card != nil {
|
||||
return result.Card.ICCID
|
||||
}
|
||||
if result.Device != nil {
|
||||
return firstNonEmpty(result.Device.IMEI, result.Device.VirtualNo)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func firstNonEmpty(values ...string) string {
|
||||
for _, value := range values {
|
||||
if value != "" {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// strPtr 字符串指针辅助函数
|
||||
func strPtr(s string) *string {
|
||||
return &s
|
||||
@@ -1113,7 +1163,7 @@ func (s *Service) createOrderWithWalletPayment(ctx context.Context, order *model
|
||||
if order.PurchaseRole == model.PurchaseRolePurchaseForSubordinate {
|
||||
relatedShopID = &buyerShopID
|
||||
}
|
||||
if err := s.createWalletTransaction(ctx, tx, wallet, order.ID, actualAmount, order.PurchaseRole, relatedShopID); err != nil {
|
||||
if err := s.createWalletTransaction(ctx, tx, wallet, order, actualAmount, order.PurchaseRole, relatedShopID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1593,7 +1643,7 @@ func (s *Service) WalletPay(ctx context.Context, orderID uint, buyerType string,
|
||||
return errors.New(errors.CodeInsufficientBalance, "余额不足或并发冲突")
|
||||
}
|
||||
|
||||
if err := s.createWalletTransaction(ctx, tx, wallet, order.ID, order.TotalAmount, order.PurchaseRole, nil); err != nil {
|
||||
if err := s.createWalletTransaction(ctx, tx, wallet, order, order.TotalAmount, order.PurchaseRole, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -739,6 +739,9 @@ func (s *Service) ListMainWalletTransactions(ctx context.Context, shopID uint, r
|
||||
Amount: t.Amount,
|
||||
BalanceBefore: t.BalanceBefore,
|
||||
BalanceAfter: t.BalanceAfter,
|
||||
AssetType: t.AssetType,
|
||||
AssetID: t.AssetID,
|
||||
AssetIdentifier: t.AssetIdentifier,
|
||||
Remark: remark,
|
||||
CreatedAt: t.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
})
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE tb_agent_wallet_transaction
|
||||
DROP COLUMN IF EXISTS asset_identifier,
|
||||
DROP COLUMN IF EXISTS asset_id,
|
||||
DROP COLUMN IF EXISTS asset_type;
|
||||
@@ -0,0 +1,10 @@
|
||||
-- 为代理钱包流水新增消费资产快照字段
|
||||
-- 仅新产生的套餐扣款流水在消费发生时写入,存量历史流水不回填。
|
||||
ALTER TABLE tb_agent_wallet_transaction
|
||||
ADD COLUMN IF NOT EXISTS asset_type VARCHAR(20) NOT NULL DEFAULT '',
|
||||
ADD COLUMN IF NOT EXISTS asset_id BIGINT NOT NULL DEFAULT 0,
|
||||
ADD COLUMN IF NOT EXISTS asset_identifier VARCHAR(100) NOT NULL DEFAULT '';
|
||||
|
||||
COMMENT ON COLUMN tb_agent_wallet_transaction.asset_type IS '消费资产类型快照:iot_card-物联网卡 | device-设备';
|
||||
COMMENT ON COLUMN tb_agent_wallet_transaction.asset_id IS '消费资产ID快照(卡ID或设备ID)';
|
||||
COMMENT ON COLUMN tb_agent_wallet_transaction.asset_identifier IS '消费资产标识快照(ICCID、IMEI或虚拟号)';
|
||||
Reference in New Issue
Block a user