feat(cost-center): 商品与成本按履约载体分区,补充分页与删除能力

- 新增迁移 107_product_catalog_carrier:product_catalog 增加 carrier_type,
  自动发货只认 fulfillment_tasks.executor_key='affiliate_dash' 的履约证据
  (28 个上游 SKU),接单模板商品统一归为 work_order(662 个)
- 页面按「全部 / 自动发货 / 接单平台 / 人工客服 / 共用成本」分区;
  自动发货只展示自动发货 SKU 列表与采购成本,不展示商品目录/渠道映射
- 新增「同步自动发货商品」接口与按钮,按 aff:<skuCode> 幂等补建
- 列表统一接入公共分页 buildAdminTablePagination,支持 10/20/50/100 每页条数
- 标准商品、自动发货 SKU、渠道映射、成本项目、成本版本支持删除,
  带引用保护(映射/版本/快照/订单/接单规则)与生效版本先停用约束
This commit is contained in:
yml2213
2026-10-22 14:05:34 +08:00
parent 8f3babdabe
commit b520a078b0
7 changed files with 1150 additions and 99 deletions
File diff suppressed because it is too large Load Diff
@@ -1,4 +1,4 @@
import { apiGet, apiPatch, apiPost } from '@/lib/http'
import { apiDelete, apiGet, apiPatch, apiPost } from '@/lib/http'
import type {
ChannelProductMapping,
ChannelProductMappingListResult,
@@ -46,6 +46,12 @@ export function createAdminProductCatalog(payload: Record<string, unknown>) {
return apiPost<{ product: ProductCatalogItem }>('/api/v1/admin/cost-center/products', payload)
}
export function syncAdminAffiliateDashProducts() {
return apiPost<{ createdCount: number; updatedCount: number; productCount: number }>(
'/api/v1/admin/cost-center/affiliate-products/sync',
)
}
export function updateAdminProductCatalog(productId: number, payload: Record<string, unknown>) {
return apiPatch<{ product: ProductCatalogItem }>(
`/api/v1/admin/cost-center/products/${productId}`,
@@ -53,6 +59,12 @@ export function updateAdminProductCatalog(productId: number, payload: Record<str
)
}
export function deleteAdminProductCatalog(productId: number) {
return apiDelete<{ deleted: boolean; product: ProductCatalogItem }>(
`/api/v1/admin/cost-center/products/${productId}`,
)
}
export function fetchAdminChannelProductMappings(params?: Record<string, unknown>) {
return apiGet<ChannelProductMappingListResult>('/api/v1/admin/cost-center/mappings', params)
}
@@ -71,6 +83,12 @@ export function updateAdminChannelProductMapping(
)
}
export function deleteAdminChannelProductMapping(mappingId: number) {
return apiDelete<{ deleted: boolean; mappingId: number }>(
`/api/v1/admin/cost-center/mappings/${mappingId}`,
)
}
export function backfillAdminProductMappings(payload: Record<string, unknown>) {
return apiPost<{
updatedCount: number
@@ -104,6 +122,12 @@ export function updateAdminCostItem(costItemId: number, payload: Record<string,
)
}
export function deleteAdminCostItem(costItemId: number) {
return apiDelete<{ deleted: boolean; costItem: CostItem }>(
`/api/v1/admin/cost-center/cost-items/${costItemId}`,
)
}
export function fetchAdminCostVersions(params?: Record<string, unknown>) {
return apiGet<CostVersionListResult>('/api/v1/admin/cost-center/cost-versions', params)
}
@@ -119,6 +143,12 @@ export function retireAdminCostVersion(versionId: number, payload: Record<string
)
}
export function deleteAdminCostVersion(versionId: number) {
return apiDelete<{ deleted: boolean; version: CostVersion }>(
`/api/v1/admin/cost-center/cost-versions/${versionId}`,
)
}
export function fetchAdminCostExceptions(params?: Record<string, unknown>) {
return apiGet<CostExceptionListResult>('/api/v1/admin/cost-center/exceptions', params)
}
@@ -1,3 +1,6 @@
/** 履约载体:自动发货 / 接单平台 / 人工 / 多载体共用。 */
export type CostCarrierType = 'affiliate_dash' | 'work_order' | 'manual' | 'shared'
export interface CostCenterOverview {
productCount: number
mappingCount: number
@@ -5,6 +8,8 @@ export interface CostCenterOverview {
activeVersionCount: number
openExceptionCount: number
unmappedOrderItemCount: number
productCarrierCounts?: Record<string, number>
costItemCarrierCounts?: Record<string, number>
}
export interface ProductCatalogItem {
@@ -12,6 +17,7 @@ export interface ProductCatalogItem {
canonicalSku: string
canonicalName: string
category: string
carrierType: CostCarrierType
rootCategoryId: number | null
rootCategoryName: string
subCategoryId: number | null
@@ -74,6 +80,7 @@ export interface CostVersion {
costItemId: number
costItemCode: string
costItemName: string
carrierType: CostCarrierType
pricingMode: CostItem['pricingMode']
scopeType: 'global' | 'provider' | 'shop' | 'product' | 'rule'
provider: string
@@ -117,6 +124,7 @@ export interface CostCenterOptions {
canonicalSku: string
canonicalName: string
unitName: string
carrierType: CostCarrierType
}>
costItems: Array<{
id: number
@@ -255,6 +263,7 @@ export interface ChannelProductMappingGroup {
canonicalName: string
category: string
unitName: string
carrierType: CostCarrierType
status: 'active' | 'archived'
mappings: ChannelProductMapping[]
}