cangku/backend/src/config/pickingBinSalesAnalysis.js
youruo 817cc74a40 feat: 拣选库位动销分析默认按近 30 天销量划分等级
- 默认统计窗口 15 天 -> 30 天(后端 PICKING_BIN_DEFAULT_DAYS 与前端常量同步)
- 可切换窗口补充近 60 天(7 / 15 / 30 / 60)
- 等级阈值不变:爆款≥20 / 热卖 10-20 / 平销 3-10 / 滞销-1 1-3 / 滞销-2 (0,1) / 销售=0
- 单测断言同步更新;实测 30 天窗口:7091 个拣选库位,日销=销量÷30
2026-10-07 17:41:17 +08:00

67 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 拣选库位动销分析 —— 口径配置(纯规则,不含业务数值)
*
* 一级菜单:大货库存监控
* 二级菜单:拣选库位动销分析
*
* 表头(需求表原列为 所在仓库 | 仓位 | 数量 | 类型 | 动销等级,这里做了扩充与优化):
* 仓库 | 仓位 | 类型 | 库存数量 | SKU数 | 近N天销量 | 日销 | 动销等级
*
* 口径:
* 库存数量:rpt.jst_packInventoryInfo 按 wms_co_id + 仓位 汇总 qty
* 仓位类型:bin_group 为空 → 拣选位;bin_group = '存货' → 存货位
* 销量: rpt.jst_Orders × rpt.jst_OrderItem,按 send_date,排除 Delete/Cancelled
* 日销: 库位销量 / 窗口天数
*
* 【关键】同一 SKU 常常同时占用多个同类型仓位(崔桥工厂仓实测 3290 个拣选 SKU 中
* 1431 个跨多个拣选位,最多 24 个)。若直接把 SKU 销量累加到每个仓位,
* 销量会被放大数倍。因此这里按「SKU 销量在其占用的同类型仓位数之间平均分摊」:
* 库位销量 = Σ(该库位内各 SKU 的窗口销量 ÷ 该 SKU 占用的同类型仓位数)
* 恒等式(已实测校验,差异 0):全部库位销量之和 = 有库位记录的那些 SKU 的销量之和。
* 注意它小于「全仓销量」:jst_packInventoryInfo 只覆盖部分 SKU 的仓位数据,
* 没有仓位记录的 SKU 的销量不会体现在任何库位上。
*/
const PICKING_BIN_LEVEL1 = '大货库存监控';
const PICKING_BIN_LEVEL2 = '拣选库位动销分析';
/** 可选的统计窗口天数;默认 30 天(需求指定按近 30 天销量划分动销等级) */
const PICKING_BIN_WINDOW_OPTIONS = [7, 15, 30, 60];
const PICKING_BIN_DEFAULT_DAYS = 30;
/** 仓位类型:业务库 bin_group 为空视为拣选位 */
const BIN_TYPE_PICKING = '拣选';
const BIN_TYPE_STORAGE = '存货';
const BIN_TYPES = [BIN_TYPE_PICKING, BIN_TYPE_STORAGE];
/** 默认只看拣选位(本功能的核心是拣货位动销) */
const PICKING_BIN_DEFAULT_TYPES = [BIN_TYPE_PICKING];
/**
* 动销等级(顺序即展示顺序)。
* lower 为日销下界(含),upper 为日销上界(不含);null 表示不限制。
* zero 档为「窗口内无销量」,由 salesQty <= 0 兜底。
*/
const PICKING_BIN_GRADE_RULES = [
{ key: 'hot', label: '爆款:日销≥20', lower: 20, upper: null, tip: '库位日均销量 ≥ 20 件' },
{ key: 'best', label: '热卖款:10≤日销<20', lower: 10, upper: 20, tip: '库位日均销量 10 ~ 20 件(含 10,不含 20)' },
{ key: 'normal', label: '平销款:3≤日销<10', lower: 3, upper: 10, tip: '库位日均销量 3 ~ 10 件(含 3,不含 10)' },
{ key: 'slow1', label: '滞销款-1:1≤日销<3', lower: 1, upper: 3, tip: '库位日均销量 1 ~ 3 件(含 1,不含 3)' },
{ key: 'slow2', label: '滞销款-2:0<日销<1', lower: 0, upper: 1, tip: '库位日均销量大于 0 且小于 1 件' },
{ key: 'zero', label: '销售=0', lower: 0, upper: 0, tip: '统计窗口内该库位所有 SKU 均无销量(仍占用库存)' },
];
const PICKING_BIN_TOTAL_LABEL = '汇总';
module.exports = {
PICKING_BIN_LEVEL1,
PICKING_BIN_LEVEL2,
PICKING_BIN_WINDOW_OPTIONS,
PICKING_BIN_DEFAULT_DAYS,
BIN_TYPE_PICKING,
BIN_TYPE_STORAGE,
BIN_TYPES,
PICKING_BIN_DEFAULT_TYPES,
PICKING_BIN_GRADE_RULES,
PICKING_BIN_TOTAL_LABEL,
};