From 32f03cd2c14b37585d2c7d988fd52a7381148524 Mon Sep 17 00:00:00 2001 From: huang Date: Thu, 23 Apr 2026 11:43:15 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=80=E6=AC=BE=E6=97=B6?= =?UTF-8?q?=E5=BA=94=E5=BD=93=E5=BF=AB=E7=85=A7=E5=BD=93=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E8=B5=84=E4=BA=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/model/dto/refund_dto.go | 4 +++ internal/model/refund.go | 16 ++++++----- internal/service/refund/service.go | 15 +++++++++++ ..._asset_snapshot_to_refund_request.down.sql | 5 ++++ ...dd_asset_snapshot_to_refund_request.up.sql | 27 +++++++++++++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 migrations/000133_add_asset_snapshot_to_refund_request.down.sql create mode 100644 migrations/000133_add_asset_snapshot_to_refund_request.up.sql diff --git a/internal/model/dto/refund_dto.go b/internal/model/dto/refund_dto.go index 4822020..dab6ecd 100644 --- a/internal/model/dto/refund_dto.go +++ b/internal/model/dto/refund_dto.go @@ -57,6 +57,10 @@ type RefundResponse struct { RefundNo string `json:"refund_no" description:"退款单号"` OrderID uint `json:"order_id" description:"关联订单ID"` OrderNo string `json:"order_no" description:"订单号"` + AssetIdentifier string `json:"asset_identifier,omitempty" description:"下单时资产的标识符快照(ICCID 或 VirtualNo)"` + AssetType string `json:"asset_type,omitempty" description:"资产类型 (card:单卡, device:设备)"` + IotCardID *uint `json:"iot_card_id,omitempty" description:"IoT卡ID"` + DeviceID *uint `json:"device_id,omitempty" description:"设备ID"` PackageUsageID *uint `json:"package_usage_id,omitempty" description:"关联套餐使用记录ID"` ShopID *uint `json:"shop_id,omitempty" description:"店铺ID"` ShopName string `json:"shop_name,omitempty" description:"店铺名称"` diff --git a/internal/model/refund.go b/internal/model/refund.go index 067eabe..56e58f2 100644 --- a/internal/model/refund.go +++ b/internal/model/refund.go @@ -14,12 +14,16 @@ type RefundRequest struct { BaseModel `gorm:"embedded"` // 退款单基础信息 - RefundNo string `gorm:"column:refund_no;type:varchar(50);uniqueIndex:idx_refund_request_refund_no,where:deleted_at IS NULL;not null;comment:退款单号(RF+日期时间+6位随机数)" json:"refund_no"` - OrderID uint `gorm:"column:order_id;index;not null;comment:关联订单ID" json:"order_id"` - OrderNo string `gorm:"column:order_no;type:varchar(30);not null;default:'';comment:关联订单号快照" json:"order_no"` - PackageUsageID *uint `gorm:"column:package_usage_id;comment:关联套餐使用记录ID(可选)" json:"package_usage_id,omitempty"` - ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(从订单获取,用于数据权限过滤)" json:"shop_id,omitempty"` - ShopName string `gorm:"column:shop_name;->" json:"shop_name,omitempty"` + RefundNo string `gorm:"column:refund_no;type:varchar(50);uniqueIndex:idx_refund_request_refund_no,where:deleted_at IS NULL;not null;comment:退款单号(RF+日期时间+6位随机数)" json:"refund_no"` + OrderID uint `gorm:"column:order_id;index;not null;comment:关联订单ID" json:"order_id"` + OrderNo string `gorm:"column:order_no;type:varchar(30);not null;default:'';comment:关联订单号快照" json:"order_no"` + OrderType string `gorm:"column:order_type;type:varchar(20);not null;default:'';comment:订单类型快照(single_card/device)" json:"order_type,omitempty"` + AssetIdentifier string `gorm:"column:asset_identifier;type:varchar(100);not null;default:'';comment:下单时资产标识符快照(ICCID 或 VirtualNo)" json:"asset_identifier,omitempty"` + IotCardID *uint `gorm:"column:iot_card_id;comment:下单时IoT卡ID快照" json:"iot_card_id,omitempty"` + DeviceID *uint `gorm:"column:device_id;comment:下单时设备ID快照" json:"device_id,omitempty"` + PackageUsageID *uint `gorm:"column:package_usage_id;comment:关联套餐使用记录ID(可选)" json:"package_usage_id,omitempty"` + ShopID *uint `gorm:"column:shop_id;index;comment:店铺ID(从订单获取,用于数据权限过滤)" json:"shop_id,omitempty"` + ShopName string `gorm:"column:shop_name;->" json:"shop_name,omitempty"` // 金额信息 ActualReceivedAmount int64 `gorm:"column:actual_received_amount;type:bigint;not null;comment:实收金额(分)" json:"actual_received_amount"` diff --git a/internal/service/refund/service.go b/internal/service/refund/service.go index 23ce474..7ce53fa 100644 --- a/internal/service/refund/service.go +++ b/internal/service/refund/service.go @@ -111,6 +111,10 @@ func (s *Service) Create(ctx context.Context, req *dto.CreateRefundRequest) (*dt RefundNo: generateRefundNo(), OrderID: req.OrderID, OrderNo: order.OrderNo, + OrderType: order.OrderType, + AssetIdentifier: order.AssetIdentifier, + IotCardID: order.IotCardID, + DeviceID: order.DeviceID, PackageUsageID: req.PackageUsageID, ShopID: shopID, ActualReceivedAmount: req.ActualReceivedAmount, @@ -650,11 +654,22 @@ func generateRefundNo() string { // buildRefundResponse 将退款 Model 转换为 DTO 响应 func buildRefundResponse(r *model.RefundRequest) *dto.RefundResponse { + assetType := "" + if r.OrderType == model.OrderTypeSingleCard { + assetType = "card" + } else if r.OrderType == model.OrderTypeDevice { + assetType = "device" + } + resp := &dto.RefundResponse{ ID: r.ID, RefundNo: r.RefundNo, OrderID: r.OrderID, OrderNo: r.OrderNo, + AssetIdentifier: r.AssetIdentifier, + AssetType: assetType, + IotCardID: r.IotCardID, + DeviceID: r.DeviceID, PackageUsageID: r.PackageUsageID, ShopID: r.ShopID, ShopName: r.ShopName, diff --git a/migrations/000133_add_asset_snapshot_to_refund_request.down.sql b/migrations/000133_add_asset_snapshot_to_refund_request.down.sql new file mode 100644 index 0000000..d859ff8 --- /dev/null +++ b/migrations/000133_add_asset_snapshot_to_refund_request.down.sql @@ -0,0 +1,5 @@ +ALTER TABLE tb_refund_request + DROP COLUMN IF EXISTS device_id, + DROP COLUMN IF EXISTS iot_card_id, + DROP COLUMN IF EXISTS asset_identifier, + DROP COLUMN IF EXISTS order_type; diff --git a/migrations/000133_add_asset_snapshot_to_refund_request.up.sql b/migrations/000133_add_asset_snapshot_to_refund_request.up.sql new file mode 100644 index 0000000..6cc76a3 --- /dev/null +++ b/migrations/000133_add_asset_snapshot_to_refund_request.up.sql @@ -0,0 +1,27 @@ +-- 为 tb_refund_request 新增资产快照字段 +-- 创建退款申请时从 tb_order 复制,避免退款列表/详情查询联表订单 +ALTER TABLE tb_refund_request + ADD COLUMN IF NOT EXISTS order_type VARCHAR(20) NOT NULL DEFAULT '', + ADD COLUMN IF NOT EXISTS asset_identifier VARCHAR(100) NOT NULL DEFAULT '', + ADD COLUMN IF NOT EXISTS iot_card_id BIGINT, + ADD COLUMN IF NOT EXISTS device_id BIGINT; + +COMMENT ON COLUMN tb_refund_request.order_type IS '订单类型快照(single_card/device)'; +COMMENT ON COLUMN tb_refund_request.asset_identifier IS '下单时资产标识符快照(ICCID 或 VirtualNo)'; +COMMENT ON COLUMN tb_refund_request.iot_card_id IS '下单时IoT卡ID快照'; +COMMENT ON COLUMN tb_refund_request.device_id IS '下单时设备ID快照'; + +-- 存量数据回填:通过 order_id 关联 tb_order 填充资产快照字段 +UPDATE tb_refund_request r +SET order_type = o.order_type, + asset_identifier = o.asset_identifier, + iot_card_id = o.iot_card_id, + device_id = o.device_id +FROM tb_order o +WHERE r.order_id = o.id + AND ( + r.order_type = '' + OR r.asset_identifier = '' + OR r.iot_card_id IS NULL + OR r.device_id IS NULL + );