feat(self-operated): support selected-day analytics and global quantity sorting
This commit is contained in:
@@ -26,7 +26,7 @@ paths:
|
||||
summary: 单仓固定版本经营总览
|
||||
description: >-
|
||||
平台独立只读权限platform:self-operated-analytics:list。一次一致快照固定销量和库存版本。
|
||||
默认LAST_15_DAYS统一用于趋势、区间出库、日均、互斥分桶及三个Top10;热销按已采集有效量排序并标记覆盖状态,库存评估要求所选区间完整销量及观察资格。
|
||||
默认LAST_15_DAYS统一用于趋势、区间出库、日均、互斥分桶及三个Top10;热销按已采集有效量排序并标记覆盖状态,库存评估要求所选区间完整可信销量和有效库存;商品观察期仅提示。
|
||||
不接受货主、SKU、分页、windowDays、topN或其他额外筛选。仓级趋势不套单SKU观察期。
|
||||
库存严格下钻须携带原版本和drilldownFrom=DASHBOARD;截止时间由服务端根据库存真实观测重算。
|
||||
parameters:
|
||||
@@ -57,7 +57,7 @@ paths:
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sku-sales-summary:
|
||||
get:
|
||||
summary: SKU五周期或历史累计清单
|
||||
description: '候选为两版profile并集,SQL按选定日期聚合后按observedQuantity降序空值末尾、SKU及货主升序,再分页。未知日不填零。 权限platform:self-operated-analytics:list。'
|
||||
description: '候选为两版profile并集,SQL按选定日期聚合后按salesSort指定observedQuantity升降序(默认降序)空值末尾、SKU及货主升序,再分页。未知日不填零。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
@@ -74,6 +74,11 @@ paths:
|
||||
- {$ref: '#/components/parameters/bucket'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
- name: salesSort
|
||||
in: query
|
||||
required: false
|
||||
description: 全量数量排序,默认降序;未知值始终末尾,同值按SKU及货主升序。
|
||||
schema: {type: string, enum: [QUANTITY_ASC, QUANTITY_DESC], default: QUANTITY_DESC}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
@@ -153,8 +158,8 @@ paths:
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/slow-skus:
|
||||
get:
|
||||
summary: 固定完整30日有库存低出库Top100
|
||||
description: '固定30天,不接受windowDays或rangePreset。正品有效新鲜可售量大于零、完整窗口且起点前可靠存在。数量升序、可售量降序、SKU及货主升序。 权限platform:self-operated-analytics:list。'
|
||||
summary: 所选完整时段有库存低出库Top100
|
||||
description: '支持CUSTOM起止日期,1至366天,前端统一为截至昨日的3/7/15/30天或自定义;不接受windowDays。正品有效新鲜可售量大于零、完整窗口且起点前可靠存在。数量升序、可售量降序、SKU及货主升序。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
@@ -165,6 +170,9 @@ paths:
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/rangePreset'}
|
||||
- {$ref: '#/components/parameters/startDate'}
|
||||
- {$ref: '#/components/parameters/endDate'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
@@ -183,7 +191,7 @@ paths:
|
||||
/api/platform/v1/last-leg/self-operated-analytics/inventory-coverage:
|
||||
get:
|
||||
summary: 正品库存与所选窗口可售天数
|
||||
description: '普通库存明细使用10或30天;总览严格下钻须携带drilldownFrom=DASHBOARD及原图CUSTOM起止日期,不得同时携带salesWindowDays/salesWindowEndDate。可售仅品质0可用量,不扣冻结或加在途次品。先UNKNOWN/INVALID/STALE,再有效零库存为0,再校验正库存单位、窗口、观察期;零销量天数为空。 权限platform:self-operated-analytics:list。'
|
||||
description: '普通库存明细使用1至366个完整自然日,由最近3/7/15/30天或自定义区间计算;总览严格下钻须携带drilldownFrom=DASHBOARD及原图CUSTOM起止日期,不得同时携带salesWindowDays/salesWindowEndDate。可售仅品质0可用量,不扣冻结或加在途次品。先UNKNOWN/INVALID/STALE,再有效零库存为0,再校验正库存单位及完整可信窗口;观察期仅提示,不阻断统计;零销量天数为空。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/rangePreset'}
|
||||
- {$ref: '#/components/parameters/startDate'}
|
||||
@@ -195,7 +203,7 @@ paths:
|
||||
- {$ref: '#/components/parameters/attention'}
|
||||
- {$ref: '#/components/parameters/sortBy'}
|
||||
- {$ref: '#/components/parameters/coverageDaysThreshold'}
|
||||
- {name: salesWindowDays, in: query, schema: {type: integer, enum: [10, 30], default: 30}, description: 仅库存明细使用的完整自然日窗口}
|
||||
- {name: salesWindowDays, in: query, schema: {type: integer, minimum: 1, maximum: 366, default: 30}, description: 仅库存明细使用的完整自然日窗口}
|
||||
- {name: salesWindowEndDate, in: query, schema: {type: string, format: date}, description: 含当日的窗口截止日,默认固定查询基准的北京时间昨日;必须早于查询当日,分页须携带原窗口}
|
||||
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
@@ -393,7 +401,7 @@ components:
|
||||
drilldownFrom: {name: drilldownFrom, in: query, description: 必须固定原版本,服务端在真实库存有效期与查询到期较早者阻断并要求刷新总览;不增加权限, schema: {type: string, enum: [DASHBOARD]}}
|
||||
keyword: {name: keyword, in: query, schema: {type: string, minLength: 1, maxLength: 64}, description: 区分大小写的货主编码字面前缀,先过滤去重再分页}
|
||||
attention: {name: attention, in: query, schema: {type: string, default: ALL, enum: [ALL, NO_OUTBOUND_IN_WINDOW, COVERAGE_GT_THRESHOLD, FROZEN_STOCK, DEFECTIVE_STOCK, UNASSESSABLE]}}
|
||||
sortBy: {name: sortBy, in: query, schema: {type: string, default: AVAILABLE_DESC, enum: [AVAILABLE_DESC, COVERAGE_DAYS_DESC, PHYSICAL_DESC, OUTBOUND_ASC]}, description: 完整候选先筛选后按未舍入值排序分页,未知末尾,同值SKU和货主升序}
|
||||
sortBy: {name: sortBy, in: query, schema: {type: string, default: AVAILABLE_DESC, enum: [AVAILABLE_ASC, AVAILABLE_DESC, COVERAGE_DAYS_ASC, COVERAGE_DAYS_DESC, PHYSICAL_ASC, PHYSICAL_DESC, FROZEN_ASC, FROZEN_DESC, DEFECTIVE_ASC, DEFECTIVE_DESC, TRANSIT_ASC, TRANSIT_DESC, OUTBOUND_ASC, OUTBOUND_DESC, AVERAGE_DAILY_ASC, AVERAGE_DAILY_DESC]}, description: 完整候选先筛选后按正式未舍入值排序分页,未知末尾,同值SKU和货主升序;出库和日均按本次实际窗口,已采集小计不参与正式值排序}
|
||||
coverageDaysThreshold: {name: coverageDaysThreshold, in: query, schema: {type: integer, minimum: 1}, description: COVERAGE_GT_THRESHOLD必填,严格大于且未舍入比较,不设置默认经营政策}
|
||||
sourceAccount: {name: sourceAccount, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
warehouseCode: {name: warehouseCode, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
@@ -658,16 +666,17 @@ components:
|
||||
status: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
InventoryMetric:
|
||||
description: 库存窗口响应。windowOutboundQuantity为所选完整窗口销量:普通明细10或30日,总览严格下钻使用原图CUSTOM区间;未知保持null,零销量状态NO_OUTBOUND_IN_WINDOW不除零。无出库关注、出库排序及分组均使用实际窗口。
|
||||
description: 库存窗口响应。windowOutboundQuantity为所选完整窗口销量:普通明细10或30日,总览严格下钻使用原图CUSTOM区间;未知保持null,零销量状态NO_OUTBOUND_IN_WINDOW不除零。无出库关注、出库排序及分组均使用实际窗口;商品观察期仅提示,不阻断完整窗口销量及可售天数。完整可信窗口中无出库行可记零,覆盖不足或数量异常不可补零。
|
||||
type: object
|
||||
properties:
|
||||
customerName: {type: string, nullable: true}
|
||||
defectivePhysicalQuantity: {type: number, nullable: true}
|
||||
windowOutboundQuantity: {type: number, nullable: true}
|
||||
observedWindowOutboundQuantity: {type: number, nullable: true, description: 同一固定销量版及实际窗口中单位有效的已采集出库小计;不代替完整窗口出库,不用于推算日均或可售天数,未知不补零}
|
||||
lastObservedOutboundDate: {type: string, format: date, nullable: true}
|
||||
observedHistoryStartDate: {type: string, format: date, nullable: true}
|
||||
attentionReasons: {type: array, items: {type: string}}
|
||||
quantityStatuses: {type: object, additionalProperties: {type: string, enum: [VALID, UNKNOWN, STALE]}}
|
||||
quantityStatuses: {type: object, additionalProperties: {type: string, enum: [VALID, UNKNOWN, STALE, UNIT_UNKNOWN_OR_CONFLICT, SALES_UNTRUSTED, COVERAGE_INSUFFICIENT]}}
|
||||
sourceAccount: {type: string, nullable: true}
|
||||
customerCode: {type: string, nullable: true}
|
||||
warehouseCode: {type: string, nullable: true}
|
||||
@@ -684,7 +693,7 @@ components:
|
||||
inventoryCoverageDays: {type: number, nullable: true}
|
||||
inventoryQuality: {type: string, nullable: true}
|
||||
salesCoverage: {type: string, nullable: true}
|
||||
observationEligible: {type: boolean, nullable: true}
|
||||
observationEligible: {type: boolean, nullable: true, description: 是否已有不晚于窗口起点的可靠商品记录;false仅用于观察提示,不阻断完整可信窗口出库、日均和可售天数}
|
||||
earliestReliableEvidenceAt: {type: string, format: date-time, nullable: true}
|
||||
status: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
|
||||
+12
-12
@@ -5,10 +5,10 @@ info:
|
||||
description: >-
|
||||
仅PLATFORM、tenantId=0、非代登录及platform:self-operated-analytics:list权限。
|
||||
仓库由服务端受控配置校验;不触发采集,不读取来源订单,不调用领星。
|
||||
三窗为截至endDate的7/15/30个完整北京时间自然日;当前库存独立固定版本。
|
||||
所选窗口为截至endDate的1~366个完整北京时间自然日,并提供7/15/30天辅助对比;当前库存独立固定版本。
|
||||
每次请求使用REPEATABLE_READ。snapshotContext为服务端重建验证的版本与日代表证据,
|
||||
不作为授权凭据;账号、仓库、截止日、基准、queryAsOf、版本对、范围摘要、
|
||||
重建状态及全部30日映射(含缺失日期)逐项重建比较;无效或过期要求整体刷新。
|
||||
重建状态及全部max(30,baseWindowDays)日映射(含缺失日期)逐项重建比较;无效或过期要求整体刷新。
|
||||
历史代表须同范围、正式计划采集、已发布且DAILY_SCHEDULED_FIRST_V1合格标记。
|
||||
上下文有效期最多30分钟;客户端不能直接指定runId。SKU/关注分页不改变概览范围。
|
||||
历史销量完整性不依赖当前库存新鲜度;缺样本不补零、不缩短周转分母。
|
||||
@@ -28,13 +28,13 @@ paths:
|
||||
- {name: sourceAccount, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
- {name: warehouseCode, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
- {name: endDate, in: query, description: '含截止日,默认北京时间昨天,不接受今日或未来', schema: {type: string, format: date}}
|
||||
- {name: baseWindowDays, in: query, schema: {type: integer, enum: [7, 15, 30], default: 30}}
|
||||
- {name: baseWindowDays, in: query, schema: {type: integer, minimum: 1, maximum: 366, default: 30}}
|
||||
- {name: groupBy, in: query, schema: {type: string, enum: [SKU, OWNER], default: SKU}}
|
||||
- {name: customerCode, in: query, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
- {name: sku, in: query, description: SKU分组的精确查询,OWNER禁止传入, schema: {type: string, minLength: 1, maxLength: 128}}
|
||||
- name: focus
|
||||
in: query
|
||||
schema: {type: string, enum: [ALL, NO_OUTBOUND_30D, COVERAGE_GT, COVERAGE_LE, FROZEN, DEFECTIVE, UNASSESSABLE], default: ALL}
|
||||
schema: {type: string, enum: [ALL, NO_OUTBOUND_IN_WINDOW, COVERAGE_GT, COVERAGE_LE, FROZEN, DEFECTIVE, UNASSESSABLE], default: ALL}
|
||||
- {name: coverageDaysThreshold, in: query, description: 'GT/LE必填,其余可选;无默认业务阈值', schema: {type: integer, minimum: 1}}
|
||||
- {name: turnoverStatus, in: query, schema: {type: string, enum: [INSUFFICIENT]}}
|
||||
- name: sortBy
|
||||
@@ -91,7 +91,7 @@ components:
|
||||
type: object
|
||||
required: [days, startDate, endDateExclusive, outboundQuantity, observedQuantity, averageDailyOutboundQuantity, completeDayCount, partialDayCount, unknownDayCount, dataStatus, reasonCodes]
|
||||
properties:
|
||||
days: {type: integer, enum: [7, 15, 30]}
|
||||
days: {type: integer, minimum: 1, maximum: 366}
|
||||
startDate: {type: string, format: date}
|
||||
endDateExclusive: {type: string, format: date}
|
||||
outboundQuantity: {$ref: '#/components/schemas/Quantity'}
|
||||
@@ -110,7 +110,7 @@ components:
|
||||
sourceAccount: {type: string}
|
||||
warehouseCode: {type: string}
|
||||
endDate: {type: string, format: date}
|
||||
baseWindowDays: {type: integer, enum: [7, 15, 30]}
|
||||
baseWindowDays: {type: integer, minimum: 1, maximum: 366}
|
||||
queryAsOf: {type: string, format: date-time}
|
||||
queryExpiresAt: {type: string, format: date-time}
|
||||
analyticsContext: {$ref: './self-operated-analytics-v1.yaml#/components/schemas/Context'}
|
||||
@@ -120,7 +120,7 @@ components:
|
||||
dailySamples:
|
||||
type: array
|
||||
minItems: 30
|
||||
maxItems: 30
|
||||
maxItems: 366
|
||||
items:
|
||||
type: object
|
||||
required: [date, runId]
|
||||
@@ -131,7 +131,7 @@ components:
|
||||
accumulationStartedOn: {type: string, format: date, nullable: true}
|
||||
Row:
|
||||
type: object
|
||||
required: [customerCode, customerName, sku, productName, physicalQuantity, availableQuantity, frozenQuantity, defectiveQuantity, physicalSkuCount, windows, averageDailyOutboundQuantity, inventoryCoverageDays, coverageStatus, averagePhysicalQuantity, quantityTurnoverCount, turnoverStatus, qualifiedSampleDays, requiredSampleDays, missingSampleDates, sampleReasonCodes, lastObservedOutboundDate, attentionReasons, noOutbound30d, slowCoverage, unassessableSkuCount]
|
||||
required: [customerCode, customerName, sku, productName, physicalQuantity, availableQuantity, frozenQuantity, defectiveQuantity, physicalSkuCount, windows, averageDailyOutboundQuantity, inventoryCoverageDays, coverageStatus, averagePhysicalQuantity, quantityTurnoverCount, turnoverStatus, qualifiedSampleDays, requiredSampleDays, missingSampleDates, sampleReasonCodes, lastObservedOutboundDate, attentionReasons, noOutboundInWindow, slowCoverage, unassessableSkuCount]
|
||||
properties:
|
||||
customerCode: {type: string}
|
||||
customerName: {type: string, nullable: true}
|
||||
@@ -142,7 +142,7 @@ components:
|
||||
frozenQuantity: {$ref: '#/components/schemas/Total'}
|
||||
defectiveQuantity: {$ref: '#/components/schemas/Total'}
|
||||
physicalSkuCount: {$ref: '#/components/schemas/Quantity'}
|
||||
windows: {type: array, minItems: 3, maxItems: 3, items: {$ref: '#/components/schemas/Window'}}
|
||||
windows: {type: array, minItems: 3, maxItems: 4, items: {$ref: '#/components/schemas/Window'}}
|
||||
averageDailyOutboundQuantity: {$ref: '#/components/schemas/Quantity'}
|
||||
inventoryCoverageDays: {$ref: '#/components/schemas/Quantity'}
|
||||
coverageStatus: {type: string, enum: [VALID, NOT_APPLICABLE, INVENTORY_UNKNOWN_OR_STALE, NO_AVAILABLE_STOCK, UNASSESSABLE, NO_OUTBOUND_IN_WINDOW]}
|
||||
@@ -150,12 +150,12 @@ components:
|
||||
quantityTurnoverCount: {$ref: '#/components/schemas/Quantity'}
|
||||
turnoverStatus: {type: string, enum: [VALID, INSUFFICIENT, ZERO_AVERAGE_STOCK, SALES_WINDOW_UNAVAILABLE]}
|
||||
qualifiedSampleDays: {type: integer, minimum: 0, maximum: 30}
|
||||
requiredSampleDays: {type: integer, enum: [7, 15, 30]}
|
||||
requiredSampleDays: {type: integer, minimum: 1, maximum: 366}
|
||||
missingSampleDates: {type: array, items: {type: string, format: date}}
|
||||
sampleReasonCodes: {$ref: '#/components/schemas/Reasons'}
|
||||
lastObservedOutboundDate: {type: string, format: date, nullable: true}
|
||||
attentionReasons: {$ref: '#/components/schemas/Reasons'}
|
||||
noOutbound30d: {$ref: '#/components/schemas/Risk'}
|
||||
noOutboundInWindow: {$ref: '#/components/schemas/Risk'}
|
||||
slowCoverage: {$ref: '#/components/schemas/Risk'}
|
||||
unassessableSkuCount: {type: integer, minimum: 0}
|
||||
Overview:
|
||||
@@ -183,7 +183,7 @@ components:
|
||||
customerName: {type: string, nullable: true}
|
||||
physicalQuantity: {$ref: '#/components/schemas/Quantity'}
|
||||
unknownOwnerCount: {type: integer, minimum: 0}
|
||||
averageDaily: {type: array, minItems: 3, maxItems: 3, items: {$ref: '#/components/schemas/Window'}}
|
||||
averageDaily: {type: array, minItems: 3, maxItems: 4, items: {$ref: '#/components/schemas/Window'}}
|
||||
Response:
|
||||
type: object
|
||||
required: [context, summary, charts, rows, total]
|
||||
|
||||
Reference in New Issue
Block a user