Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Failing after 38s
- 字段 outbound_at → first_purchase_at,记录表 tb_asset_outbound_record → tb_asset_first_purchase_record,接口 /outbound-records → /first-purchase-records,筛选参数与导出列同步更名 - 换货后的新资产不因换货写入,在当前世代真正支付套餐订单时才记录;记录来源只保留 order / backfill,去掉换货单字段 - 迁移 000266 重命名列、表、索引与约束;同步 Spec、设计、任务与前端接口变更说明 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
242 lines
22 KiB
Go
242 lines
22 KiB
Go
package model
|
||
|
||
import (
|
||
"time"
|
||
|
||
"gorm.io/datatypes"
|
||
"gorm.io/gorm"
|
||
)
|
||
|
||
// PackageSilenceExtensionPolicy 沉默期延期政策。
|
||
// 匹配优先级:指定套餐 > 套餐系列 > 全部套餐;同一优先级适用范围与生效时间段不得重叠。
|
||
type PackageSilenceExtensionPolicy struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
Name string `gorm:"column:name;type:varchar(100);not null;comment:政策名称" json:"name"`
|
||
ScopeType string `gorm:"column:scope_type;type:varchar(20);not null;comment:适用范围 all/series/package" json:"scope_type"`
|
||
ScopeIDs UintJSONBArray `gorm:"column:scope_ids;type:jsonb;not null;default:'[]';comment:系列或套餐ID列表" json:"scope_ids"`
|
||
UnitPrice int64 `gorm:"column:unit_price;type:bigint;not null;comment:单价(分/月)" json:"unit_price"`
|
||
FreeExtensionLimit int `gorm:"column:free_extension_limit;type:int;not null;default:1;comment:免费延期次数" json:"free_extension_limit"`
|
||
PaidMaxMonths int `gorm:"column:paid_max_months;type:int;not null;default:6;comment:付费延期累计最多月数" json:"paid_max_months"`
|
||
SingleMaxMonths *int `gorm:"column:single_max_months;type:int;comment:单次付费延期最多月数" json:"single_max_months,omitempty"`
|
||
ApprovalExemptTypes StringJSONBArray `gorm:"column:approval_exempt_types;type:jsonb;not null;default:'[]';comment:免审批场景" json:"approval_exempt_types"`
|
||
EffectiveFrom time.Time `gorm:"column:effective_from;not null;comment:生效时间" json:"effective_from"`
|
||
EffectiveTo *time.Time `gorm:"column:effective_to;comment:失效时间" json:"effective_to,omitempty"`
|
||
Status int `gorm:"column:status;type:smallint;not null;default:1;comment:状态 0-停用 1-启用" json:"status"`
|
||
Remark string `gorm:"column:remark;type:varchar(500);not null;default:'';comment:备注" json:"remark"`
|
||
Creator uint `gorm:"column:creator;not null;default:0" json:"creator"`
|
||
Updater uint `gorm:"column:updater;not null;default:0" json:"updater"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||
DeletedAt gorm.DeletedAt `gorm:"column:deleted_at;index" json:"-"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSilenceExtensionPolicy) TableName() string {
|
||
return "tb_package_silence_extension_policy"
|
||
}
|
||
|
||
// PackageSilenceRecord 套餐沉默期变更流水(只新增不修改)。
|
||
type PackageSilenceRecord struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
PackageUsageID uint `gorm:"column:package_usage_id;not null" json:"package_usage_id"`
|
||
EventType string `gorm:"column:event_type;type:varchar(30);not null" json:"event_type"`
|
||
TriggerSource string `gorm:"column:trigger_source;type:varchar(40);not null;default:''" json:"trigger_source"`
|
||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null;default:''" json:"asset_type"`
|
||
AssetID uint `gorm:"column:asset_id;not null;default:0" json:"asset_id"`
|
||
BeforeStatus *string `gorm:"column:before_status;type:varchar(16)" json:"before_status,omitempty"`
|
||
AfterStatus *string `gorm:"column:after_status;type:varchar(16)" json:"after_status,omitempty"`
|
||
BeforeDeadlineAt *time.Time `gorm:"column:before_deadline_at" json:"before_deadline_at,omitempty"`
|
||
AfterDeadlineAt *time.Time `gorm:"column:after_deadline_at" json:"after_deadline_at,omitempty"`
|
||
PeriodDays *int `gorm:"column:period_days" json:"period_days,omitempty"`
|
||
DefaultDaysSnapshot *int `gorm:"column:default_days_snapshot" json:"default_days_snapshot,omitempty"`
|
||
IsAdjusted bool `gorm:"column:is_adjusted;not null;default:false" json:"is_adjusted"`
|
||
ChangeDays int `gorm:"column:change_days;not null;default:0" json:"change_days"`
|
||
OperatorID uint `gorm:"column:operator_id;not null;default:0" json:"operator_id"`
|
||
OperatorType string `gorm:"column:operator_type;type:varchar(20);not null;default:''" json:"operator_type"`
|
||
Reason string `gorm:"column:reason;type:varchar(500);not null;default:''" json:"reason"`
|
||
ApprovalInstanceID *uint `gorm:"column:approval_instance_id" json:"approval_instance_id,omitempty"`
|
||
BatchID *uint `gorm:"column:batch_id" json:"batch_id,omitempty"`
|
||
ExtensionID *uint `gorm:"column:extension_id" json:"extension_id,omitempty"`
|
||
ExchangeOrderID *uint `gorm:"column:exchange_order_id" json:"exchange_order_id,omitempty"`
|
||
ExchangeNo string `gorm:"column:exchange_no;type:varchar(64);not null;default:''" json:"exchange_no"`
|
||
RealnameAt *time.Time `gorm:"column:realname_at" json:"realname_at,omitempty"`
|
||
Extra datatypes.JSON `gorm:"column:extra;type:jsonb;not null;default:'{}'" json:"extra"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSilenceRecord) TableName() string {
|
||
return "tb_package_silence_record"
|
||
}
|
||
|
||
// PackageSilenceExtensionBatch 沉默期申请批次:每次延期或购买时调整都建一个批次,企微审批实例关联批次。
|
||
type PackageSilenceExtensionBatch struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
BatchNo string `gorm:"column:batch_no;type:varchar(40);not null" json:"batch_no"`
|
||
Path string `gorm:"column:path;type:varchar(20);not null" json:"path"`
|
||
ExtensionType string `gorm:"column:extension_type;type:varchar(30);not null" json:"extension_type"`
|
||
ApprovalRequired bool `gorm:"column:approval_required;not null;default:false" json:"approval_required"`
|
||
Reason string `gorm:"column:reason;type:varchar(1000);not null;default:''" json:"reason"`
|
||
EvidenceRefs StringJSONBArray `gorm:"column:evidence_refs;type:jsonb;not null;default:'[]'" json:"evidence_refs"`
|
||
Basis string `gorm:"column:basis;type:varchar(1000);not null;default:''" json:"basis"`
|
||
ImportFileKey string `gorm:"column:import_file_key;type:varchar(500);not null;default:''" json:"import_file_key"`
|
||
PolicyID *uint `gorm:"column:policy_id" json:"policy_id,omitempty"`
|
||
PolicyNameSnapshot string `gorm:"column:policy_name_snapshot;type:varchar(100);not null;default:''" json:"policy_name_snapshot"`
|
||
UnitPriceSnapshot int64 `gorm:"column:unit_price_snapshot;not null;default:0" json:"unit_price_snapshot"`
|
||
ApprovalExemptTypesSnapshot StringJSONBArray `gorm:"column:approval_exempt_types_snapshot;type:jsonb;not null;default:'[]'" json:"approval_exempt_types_snapshot"`
|
||
FreeExtensionLimitSnapshot int `gorm:"column:free_extension_limit_snapshot;not null;default:1" json:"free_extension_limit_snapshot"`
|
||
PaidMaxMonthsSnapshot int `gorm:"column:paid_max_months_snapshot;not null;default:0" json:"paid_max_months_snapshot"`
|
||
SingleMaxMonthsSnapshot *int `gorm:"column:single_max_months_snapshot" json:"single_max_months_snapshot,omitempty"`
|
||
AdjustPackageUsageID *uint `gorm:"column:adjust_package_usage_id" json:"adjust_package_usage_id,omitempty"`
|
||
AdjustDefaultDays *int `gorm:"column:adjust_default_days" json:"adjust_default_days,omitempty"`
|
||
AdjustRequestedDays *int `gorm:"column:adjust_requested_days" json:"adjust_requested_days,omitempty"`
|
||
Amount int64 `gorm:"column:amount;not null;default:0" json:"amount"`
|
||
OfflinePaymentMethodID *uint `gorm:"column:offline_payment_method_id" json:"offline_payment_method_id,omitempty"`
|
||
OfflinePaymentMethodCode *string `gorm:"column:offline_payment_method_code;type:varchar(64)" json:"offline_payment_method_code,omitempty"`
|
||
OfflinePaymentMethodName *string `gorm:"column:offline_payment_method_name;type:varchar(100)" json:"offline_payment_method_name,omitempty"`
|
||
OfflineTradeNo *string `gorm:"column:offline_trade_no;type:varchar(128)" json:"offline_trade_no,omitempty"`
|
||
OfflinePaidAmount *int64 `gorm:"column:offline_paid_amount" json:"offline_paid_amount,omitempty"`
|
||
OfflinePaidAt *time.Time `gorm:"column:offline_paid_at" json:"offline_paid_at,omitempty"`
|
||
PaymentVoucherKeys StringJSONBArray `gorm:"column:payment_voucher_keys;type:jsonb;not null;default:'[]'" json:"payment_voucher_keys"`
|
||
RequestedBy uint `gorm:"column:requested_by;not null;default:0" json:"requested_by"`
|
||
RequestedByType string `gorm:"column:requested_by_type;type:varchar(20);not null;default:''" json:"requested_by_type"`
|
||
RequestedAt time.Time `gorm:"column:requested_at;not null" json:"requested_at"`
|
||
ApprovalInstanceID *uint `gorm:"column:approval_instance_id" json:"approval_instance_id,omitempty"`
|
||
ApprovalStatus string `gorm:"column:approval_status;type:varchar(20);not null;default:''" json:"approval_status"`
|
||
ApprovalFinishedAt *time.Time `gorm:"column:approval_finished_at" json:"approval_finished_at,omitempty"`
|
||
Status string `gorm:"column:status;type:varchar(30);not null" json:"status"`
|
||
RequestedCount int `gorm:"column:requested_count;not null;default:0" json:"requested_count"`
|
||
SucceededCount int `gorm:"column:succeeded_count;not null;default:0" json:"succeeded_count"`
|
||
FailedCount int `gorm:"column:failed_count;not null;default:0" json:"failed_count"`
|
||
CompletedAt *time.Time `gorm:"column:completed_at" json:"completed_at,omitempty"`
|
||
ShopIDTag uint `gorm:"column:shop_id_tag;not null;default:0" json:"shop_id_tag"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSilenceExtensionBatch) TableName() string {
|
||
return "tb_package_silence_extension_batch"
|
||
}
|
||
|
||
// PackageSilenceExtension 沉默期延期明细(延期事实),以明细状态条件更新保证幂等。
|
||
type PackageSilenceExtension struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
BatchID uint `gorm:"column:batch_id;not null" json:"batch_id"`
|
||
RowNo int `gorm:"column:row_no;not null;default:1" json:"row_no"`
|
||
PackageUsageID uint `gorm:"column:package_usage_id;not null" json:"package_usage_id"`
|
||
PackageID uint `gorm:"column:package_id;not null;default:0" json:"package_id"`
|
||
PackageNameSnapshot string `gorm:"column:package_name_snapshot;type:varchar(255);not null;default:''" json:"package_name_snapshot"`
|
||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null;default:''" json:"asset_type"`
|
||
AssetID uint `gorm:"column:asset_id;not null;default:0" json:"asset_id"`
|
||
AssetIdentifierSnapshot string `gorm:"column:asset_identifier_snapshot;type:varchar(100);not null;default:''" json:"asset_identifier_snapshot"`
|
||
ExtensionType string `gorm:"column:extension_type;type:varchar(30);not null" json:"extension_type"`
|
||
InputDays int `gorm:"column:input_days;not null" json:"input_days"`
|
||
Months int `gorm:"column:months;not null" json:"months"`
|
||
ExtensionDays int `gorm:"column:extension_days;not null" json:"extension_days"`
|
||
UnitPriceSnapshot int64 `gorm:"column:unit_price_snapshot;not null;default:0" json:"unit_price_snapshot"`
|
||
Amount int64 `gorm:"column:amount;not null;default:0" json:"amount"`
|
||
ExtensionOrderID *uint `gorm:"column:extension_order_id" json:"extension_order_id,omitempty"`
|
||
BeforeDeadlineAt *time.Time `gorm:"column:before_deadline_at" json:"before_deadline_at,omitempty"`
|
||
AfterDeadlineAt *time.Time `gorm:"column:after_deadline_at" json:"after_deadline_at,omitempty"`
|
||
Status string `gorm:"column:status;type:varchar(20);not null" json:"status"`
|
||
FailureCode string `gorm:"column:failure_code;type:varchar(64);not null;default:''" json:"failure_code"`
|
||
FailureSummary string `gorm:"column:failure_summary;type:varchar(500);not null;default:''" json:"failure_summary"`
|
||
ExecutedAt *time.Time `gorm:"column:executed_at" json:"executed_at,omitempty"`
|
||
HandledBy uint `gorm:"column:handled_by;not null;default:0" json:"handled_by"`
|
||
HandledAt *time.Time `gorm:"column:handled_at" json:"handled_at,omitempty"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSilenceExtension) TableName() string {
|
||
return "tb_package_silence_extension"
|
||
}
|
||
|
||
// PackageSilenceExtensionOrder 沉默期延期订单(交易记录),在线支付复用 tb_payment(order_type = silence_extension)。
|
||
type PackageSilenceExtensionOrder struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
OrderNo string `gorm:"column:order_no;type:varchar(40);not null" json:"order_no"`
|
||
BatchID uint `gorm:"column:batch_id;not null" json:"batch_id"`
|
||
PackageUsageID uint `gorm:"column:package_usage_id;not null" json:"package_usage_id"`
|
||
PackageID uint `gorm:"column:package_id;not null" json:"package_id"`
|
||
PackageNameSnapshot string `gorm:"column:package_name_snapshot;type:varchar(255);not null;default:''" json:"package_name_snapshot"`
|
||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null" json:"asset_type"`
|
||
AssetID uint `gorm:"column:asset_id;not null" json:"asset_id"`
|
||
AssetIdentifierSnapshot string `gorm:"column:asset_identifier_snapshot;type:varchar(100);not null;default:''" json:"asset_identifier_snapshot"`
|
||
ShopID uint `gorm:"column:shop_id;not null;default:0" json:"shop_id"`
|
||
CustomerID *uint `gorm:"column:customer_id" json:"customer_id,omitempty"`
|
||
Source string `gorm:"column:source;type:varchar(20);not null" json:"source"`
|
||
CreatedBy *uint `gorm:"column:created_by" json:"created_by,omitempty"`
|
||
EvidenceRefs StringJSONBArray `gorm:"column:evidence_refs;type:jsonb;not null;default:'[]'" json:"evidence_refs"`
|
||
InputDays int `gorm:"column:input_days;not null" json:"input_days"`
|
||
Months int `gorm:"column:months;not null" json:"months"`
|
||
ExtensionDays int `gorm:"column:extension_days;not null" json:"extension_days"`
|
||
PolicyID *uint `gorm:"column:policy_id" json:"policy_id,omitempty"`
|
||
PolicyNameSnapshot string `gorm:"column:policy_name_snapshot;type:varchar(100);not null;default:''" json:"policy_name_snapshot"`
|
||
UnitPrice int64 `gorm:"column:unit_price;not null" json:"unit_price"`
|
||
ApprovalExemptTypesSnapshot StringJSONBArray `gorm:"column:approval_exempt_types_snapshot;type:jsonb;not null;default:'[]'" json:"approval_exempt_types_snapshot"`
|
||
FreeExtensionLimitSnapshot int `gorm:"column:free_extension_limit_snapshot;not null;default:1" json:"free_extension_limit_snapshot"`
|
||
PaidMaxMonthsSnapshot int `gorm:"column:paid_max_months_snapshot;not null;default:0" json:"paid_max_months_snapshot"`
|
||
SingleMaxMonthsSnapshot *int `gorm:"column:single_max_months_snapshot" json:"single_max_months_snapshot,omitempty"`
|
||
Amount int64 `gorm:"column:amount;not null" json:"amount"`
|
||
BeforeDeadlineAt time.Time `gorm:"column:before_deadline_at;not null" json:"before_deadline_at"`
|
||
ExpectedDeadlineAt time.Time `gorm:"column:expected_deadline_at;not null" json:"expected_deadline_at"`
|
||
Status string `gorm:"column:status;type:varchar(20);not null" json:"status"`
|
||
PaymentMethod string `gorm:"column:payment_method;type:varchar(20);not null" json:"payment_method"`
|
||
OfflinePaymentMethodID *uint `gorm:"column:offline_payment_method_id" json:"offline_payment_method_id,omitempty"`
|
||
OfflinePaymentMethodCode *string `gorm:"column:offline_payment_method_code;type:varchar(64)" json:"offline_payment_method_code,omitempty"`
|
||
OfflinePaymentMethodName *string `gorm:"column:offline_payment_method_name;type:varchar(100)" json:"offline_payment_method_name,omitempty"`
|
||
OfflineTradeNo *string `gorm:"column:offline_trade_no;type:varchar(128)" json:"offline_trade_no,omitempty"`
|
||
PaymentVoucherKeys StringJSONBArray `gorm:"column:payment_voucher_keys;type:jsonb;not null;default:'[]'" json:"payment_voucher_keys"`
|
||
ApprovalRequired bool `gorm:"column:approval_required;not null;default:false" json:"approval_required"`
|
||
ApprovalInstanceID *uint `gorm:"column:approval_instance_id" json:"approval_instance_id,omitempty"`
|
||
PaidPaymentID *uint `gorm:"column:paid_payment_id" json:"paid_payment_id,omitempty"`
|
||
PaidAmount *int64 `gorm:"column:paid_amount" json:"paid_amount,omitempty"`
|
||
PaidAt *time.Time `gorm:"column:paid_at" json:"paid_at,omitempty"`
|
||
ExpireAt *time.Time `gorm:"column:expire_at" json:"expire_at,omitempty"`
|
||
ExtensionID *uint `gorm:"column:extension_id" json:"extension_id,omitempty"`
|
||
CompletedAt *time.Time `gorm:"column:completed_at" json:"completed_at,omitempty"`
|
||
ClosedAt *time.Time `gorm:"column:closed_at" json:"closed_at,omitempty"`
|
||
CloseReason string `gorm:"column:close_reason;type:varchar(200);not null;default:''" json:"close_reason"`
|
||
ExceptionCode string `gorm:"column:exception_code;type:varchar(64);not null;default:''" json:"exception_code"`
|
||
ExceptionSummary string `gorm:"column:exception_summary;type:varchar(500);not null;default:''" json:"exception_summary"`
|
||
RefundNo *string `gorm:"column:refund_no;type:varchar(64)" json:"refund_no,omitempty"`
|
||
RefundAmount *int64 `gorm:"column:refund_amount" json:"refund_amount,omitempty"`
|
||
RefundedAt *time.Time `gorm:"column:refunded_at" json:"refunded_at,omitempty"`
|
||
RefundReason *string `gorm:"column:refund_reason;type:varchar(500)" json:"refund_reason,omitempty"`
|
||
RequestID *string `gorm:"column:request_id;type:varchar(64)" json:"request_id,omitempty"`
|
||
ShopIDTag uint `gorm:"column:shop_id_tag;not null;default:0" json:"shop_id_tag"`
|
||
EnterpriseIDTag *uint `gorm:"column:enterprise_id_tag" json:"enterprise_id_tag,omitempty"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
UpdatedAt time.Time `gorm:"column:updated_at;not null;default:CURRENT_TIMESTAMP" json:"updated_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (PackageSilenceExtensionOrder) TableName() string {
|
||
return "tb_package_silence_extension_order"
|
||
}
|
||
|
||
// AssetFirstPurchaseRecord 资产首次购买套餐记录:每个世代一条,只新增与填写结束信息。
|
||
type AssetFirstPurchaseRecord struct {
|
||
ID uint `gorm:"column:id;primaryKey" json:"id"`
|
||
AssetType string `gorm:"column:asset_type;type:varchar(20);not null" json:"asset_type"`
|
||
AssetID uint `gorm:"column:asset_id;not null" json:"asset_id"`
|
||
AssetIdentifierSnapshot string `gorm:"column:asset_identifier_snapshot;type:varchar(100);not null;default:''" json:"asset_identifier_snapshot"`
|
||
Generation int `gorm:"column:generation;not null" json:"generation"`
|
||
FirstPurchaseAt time.Time `gorm:"column:first_purchase_at;not null" json:"first_purchase_at"`
|
||
Source string `gorm:"column:source;type:varchar(20);not null" json:"source"`
|
||
OrderID *uint `gorm:"column:order_id" json:"order_id,omitempty"`
|
||
OrderNo string `gorm:"column:order_no;type:varchar(40);not null;default:''" json:"order_no"`
|
||
ShopID *uint `gorm:"column:shop_id" json:"shop_id,omitempty"`
|
||
EndedAt *time.Time `gorm:"column:ended_at" json:"ended_at,omitempty"`
|
||
EndReason string `gorm:"column:end_reason;type:varchar(40);not null;default:''" json:"end_reason"`
|
||
CreatedAt time.Time `gorm:"column:created_at;not null;default:CURRENT_TIMESTAMP" json:"created_at"`
|
||
}
|
||
|
||
// TableName 指定表名
|
||
func (AssetFirstPurchaseRecord) TableName() string {
|
||
return "tb_asset_first_purchase_record"
|
||
}
|