refactor: 出库时间更名为首次购买套餐时间,换货新资产不再按换货完成时间记录
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>
This commit is contained in:
邹进
2026-10-27 16:47:02 +09:00
parent 909f4d0ec2
commit 62ec94adec
46 changed files with 570 additions and 560 deletions

View File

@@ -1,4 +1,4 @@
// Package packagesilence 提供沉默期延期订单、批次、即将过期 / 已过期套餐与出库记录的只读查询。
// Package packagesilence 提供沉默期延期订单、批次、即将过期 / 已过期套餐与首次购买套餐记录的只读查询。
package packagesilence
import (
@@ -308,13 +308,13 @@ func (q *Query) FetchUsages(ctx context.Context, query *gorm.DB, offset, limit i
return items, nil
}
// ListOutboundRecords 按资产查询各世代出库记录(叠加资产数据范围)。
func (q *Query) ListOutboundRecords(ctx context.Context, assetType string, assetID uint) ([]dto.AssetOutboundRecordResponse, error) {
// ListFirstPurchaseRecords 按资产查询各世代首次购买套餐记录(叠加资产数据范围)。
func (q *Query) ListFirstPurchaseRecords(ctx context.Context, assetType string, assetID uint) ([]dto.AssetFirstPurchaseRecordResponse, error) {
if assetType == "card" {
assetType = constants.OutboundAssetTypeIotCard
assetType = constants.FirstPurchaseAssetTypeIotCard
}
table := "tb_iot_card"
if assetType == constants.OutboundAssetTypeDevice {
if assetType == constants.FirstPurchaseAssetTypeDevice {
table = "tb_device"
}
var count int64
@@ -324,28 +324,26 @@ func (q *Query) ListOutboundRecords(ctx context.Context, assetType string, asset
if count == 0 {
return nil, errors.New(errors.CodeForbidden, "无权限操作该资源或资源不存在")
}
var records []model.AssetOutboundRecord
var records []model.AssetFirstPurchaseRecord
if err := q.db.WithContext(ctx).Where("asset_type = ? AND asset_id = ?", assetType, assetID).Order("generation DESC").Find(&records).Error; err != nil {
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询出库记录失败")
return nil, errors.Wrap(errors.CodeDatabaseError, err, "查询首次购买套餐记录失败")
}
items := make([]dto.AssetOutboundRecordResponse, 0, len(records))
items := make([]dto.AssetFirstPurchaseRecordResponse, 0, len(records))
for _, record := range records {
items = append(items, dto.AssetOutboundRecordResponse{
items = append(items, dto.AssetFirstPurchaseRecordResponse{
ID: record.ID, AssetType: record.AssetType, AssetID: record.AssetID, AssetIdentifier: record.AssetIdentifierSnapshot,
Generation: record.Generation, OutboundAt: record.OutboundAt, Source: record.Source, SourceName: outboundSourceName(record.Source),
OrderNo: record.OrderNo, ExchangeNo: record.ExchangeNo, EndedAt: record.EndedAt, EndReason: record.EndReason, CreatedAt: record.CreatedAt,
Generation: record.Generation, FirstPurchaseAt: record.FirstPurchaseAt, Source: record.Source, SourceName: firstPurchaseSourceName(record.Source),
OrderNo: record.OrderNo, EndedAt: record.EndedAt, EndReason: record.EndReason, CreatedAt: record.CreatedAt,
})
}
return items, nil
}
func outboundSourceName(source string) string {
func firstPurchaseSourceName(source string) string {
switch source {
case constants.OutboundSourceOrder:
case constants.FirstPurchaseSourceOrder:
return "首次购买套餐"
case constants.OutboundSourceExchange:
return "换货新资产"
case constants.OutboundSourceBackfill:
case constants.FirstPurchaseSourceBackfill:
return "历史回填"
default:
return source