feat(t222): add freight ingestion admin flow

This commit is contained in:
QiuSW
2026-07-28 23:26:34 +08:00
parent c524e734fb
commit 6d052b0462
37 changed files with 3397 additions and 101 deletions
@@ -17,23 +17,157 @@ type UsecaseAdapter struct {
tasks *usecase.TaskService
assets *usecase.AssetService
authorizations *usecase.OrderAuthorizationService
freight *usecase.FreightService
}
func NewUsecaseAdapter(
tasks *usecase.TaskService,
assets *usecase.AssetService,
authorizations *usecase.OrderAuthorizationService,
freight ...*usecase.FreightService,
) (*UsecaseAdapter, error) {
if tasks == nil || assets == nil || authorizations == nil {
return nil, errors.New("admin web use cases are required")
}
return &UsecaseAdapter{
adapter := &UsecaseAdapter{
tasks: tasks,
assets: assets,
authorizations: authorizations,
}
if len(freight) > 0 {
adapter.freight = freight[0]
}
return adapter, nil
}
func (adapter *UsecaseAdapter) ListFreightOrders(
ctx context.Context,
limit int,
) ([]FreightOrder, error) {
if adapter.freight == nil {
return nil, ErrUnavailable
}
orders, err := adapter.freight.ListOrders(ctx, localAdminSubject, limit)
if err != nil {
return nil, mapUsecaseError(err)
}
result := make([]FreightOrder, 0, len(orders))
for _, order := range orders {
result = append(result, freightOrderFrom(order))
}
return result, nil
}
func (adapter *UsecaseAdapter) GetFreightOrder(
ctx context.Context,
orderID string,
) (FreightOrderDetail, error) {
if adapter.freight == nil {
return FreightOrderDetail{}, ErrUnavailable
}
detail, err := adapter.freight.GetOrder(
ctx,
localAdminSubject,
orderID,
)
if err != nil {
return FreightOrderDetail{}, mapUsecaseError(err)
}
items := make([]FreightOrderItem, 0, len(detail.Items))
for _, item := range detail.Items {
view := FreightOrderItem{
ID: item.ID,
ExternalItemID: item.ExternalItemID,
Title: item.Title,
ProductSpec: item.ProductSpec,
SKU: item.SKU,
ProductThumbRef: stringValue(item.ProductThumbRef),
PurchaseStatus: stringValue(item.PurchaseStatus),
Revision: item.Revision,
}
if item.Quantity != nil {
view.Quantity = *item.Quantity
}
items = append(items, view)
}
return FreightOrderDetail{
Order: freightOrderFrom(detail.Order),
Items: items,
}, nil
}
func (adapter *UsecaseAdapter) GetFreightSync(
ctx context.Context,
syncID string,
) (FreightSync, error) {
if adapter.freight == nil {
return FreightSync{}, ErrUnavailable
}
run, err := adapter.freight.GetSync(ctx, localAdminSubject, syncID)
if err != nil {
return FreightSync{}, mapUsecaseError(err)
}
return freightSyncFrom(run), nil
}
func (adapter *UsecaseAdapter) CreateFreightSync(
ctx context.Context,
input CreateFreightSyncInput,
) (FreightSync, error) {
if adapter.freight == nil {
return FreightSync{}, ErrUnavailable
}
result, err := adapter.freight.CreateOrderSync(
ctx,
usecase.CreateFreightSyncCommand{
CreatorSubject: localAdminSubject,
ActorUserID: input.ActorUserID,
IdempotencyKey: input.IdempotencyKey,
OrderNumber: input.OrderNumber,
},
)
if err != nil {
return FreightSync{}, mapUsecaseError(err)
}
return freightSyncFrom(result.Run), nil
}
func freightOrderFrom(order domain.FreightOrder) FreightOrder {
result := FreightOrder{
ID: order.ID,
ExternalStockID: order.ExternalStockID,
SourceCode: order.SourceCode,
ShopName: stringValue(order.ShopName),
OrderStatus: stringValue(order.OrderStatus),
PurchaseStatus: stringValue(order.PurchaseStatus),
ItemCount: order.ItemCount,
Revision: order.Revision,
UpdatedAt: order.UpdatedAt,
}
if order.SourceCreatedAt != nil {
result.SourceCreatedAt = *order.SourceCreatedAt
}
if order.IsCanceled != nil {
result.IsCanceled = *order.IsCanceled
}
return result
}
func freightSyncFrom(run domain.FreightSyncRun) FreightSync {
result := FreightSync{
ID: run.ID,
Status: string(run.Status),
ErrorCode: stringValue(run.ErrorCode),
OrderCount: run.OrderCount,
ItemCount: run.ItemCount,
CreatedAt: run.CreatedAt,
}
if run.FinishedAt != nil {
result.FinishedAt = *run.FinishedAt
}
return result
}
func (adapter *UsecaseAdapter) ListTasks(
ctx context.Context,
input ListTasksInput,
@@ -525,3 +659,4 @@ func (err *adapterError) Unwrap() []error {
}
var _ Service = (*UsecaseAdapter)(nil)
var _ FreightService = (*UsecaseAdapter)(nil)