# 库存出入库流水（QueryGoodsOutboundReceipt）

> 自动生成于 2026-02-13 | 数据来源：本地 JSON 样本

## 基本信息

| 属性 | 值 |
|------|-----|
| 接口路径 | `GoodsStockManage/QueryGoodsOutboundReceipt` |
| 完整 URL | `https://pc.ficoo.vip/apiprod/admin/v1/GoodsStockManage/QueryGoodsOutboundReceipt` |
| 请求方法 | `POST` |
| Content-Type | `application/json` |
| 鉴权方式 | Bearer Token（`Authorization` 头） |
| ODS 对应表 | `goods_stock_movements` |
| 分页方式 | `page` + `limit`（最大 100） |
| 时间范围 | 需要（startTime / endTime） |

## 请求参数

| 参数名 | 类型 | 示例值 | 说明 |
|--------|------|--------|------|
| `siteId` | int | `2790685415443269` | 门店 ID |
| `stockType` | int | `0` | 库存类型（0=全部） |
| `startTime` | string | `"2026-02-01 08:00:00"` | 查询起始时间 |
| `endTime` | string | `"2026-02-13 08:00:00"` | 查询结束时间 |
| `page` | int | `1` | 页码（从 1 开始） |
| `limit` | int | `100` | 每页条数（最大 100） |

## 响应字段（共 19 个）

| # | 字段名 | 类型 | 示例值 |
|---|--------|------|--------|
| 1 | `siteGoodsStockId` | int | 2957911857581957 |
| 2 | `siteGoodsId` | int | 2793026183532613 |
| 3 | `siteId` | int | 2790685415443269 |
| 4 | `tenantId` | int | 2790683160709957 |
| 5 | `stockType` | int | 1 |
| 6 | `goodsName` | string | '阿萨姆' |
| 7 | `createTime` | string | '2025-11-09 23:23:34' |
| 8 | `startNum` | int | 28 |
| 9 | `endNum` | int | 27 |
| 10 | `changeNum` | int | -1 |
| 11 | `unit` | string | '瓶' |
| 12 | `price` | float | 8.0 |
| 13 | `operatorName` | string | '收银员:郑丽珊' |
| 14 | `changeNumA` | int | 0 |
| 15 | `startNumA` | int | 0 |
| 16 | `endNumA` | int | 0 |
| 17 | `remark` | string | '' |
| 18 | `goodsCategoryId` | int | 2790683528350539 |
| 19 | `goodsSecondCategoryId` | int | 2790683528350540 |

## 详细字段分析

> 以下内容迁移自旧版 `goods_stock_movements-Analysis.md`，包含字段的业务含义、枚举值、跨表关联等详细说明。

二、记录级字段逐一分析（共 19 个）
1. 商品与库存标识 / 关联类字段

siteGoodsStockId

类型：int

含义：门店某个“商品库存记录”的主键 ID。

特点：每条库存变动记录对应一个 siteGoodsStockId，同一个商品可能在不同库存记录中出现（例如不同仓位或不同批次）。

结构用途：

与“库存现状/库存汇总”类表（库存现状.json，文件名 20251110_043308_...）中的主键对应。

用于从“单条变动记录”追溯到该商品当前的整体库存信息。

siteGoodsId

类型：int

含义：门店维度的商品 ID。

特点：

同一种商品（例如“农夫山泉苏打水”）在所有库存变化记录中都会使用同一个 siteGoodsId。

对应商品档案中的主键（门店商品表），在“小票详情.json”和“库存现状.json”等文件中也出现。

结构关联：

库存变化记录.siteGoodsId = 库存现状.siteGoodsId

库存变化记录.siteGoodsId = 小票详情.siteGoodsId

通过此字段，可以把“库存变化”与“销售/出库明细”以及“当前库存”关联起来。

siteId

类型：int

含义：门店 ID。

观测：本文件中所有记录的 siteId 都相同，对应“朗朗桌球”这家门店。

结构作用：

和其他所有 JSON 中的 siteId 一致，用于在多门店场景下按门店过滤。

与 siteProfile.id（出现在其他文件中）一致。

tenantId

类型：int

含义：租户/品牌 ID。

观测：全部记录相同值，说明属于同一商户。

作用：作为上层品牌维度，与其他表（销售、库存、会员等）保持一致。

goodsCategoryId

类型：int

含义：商品一级分类 ID。

观测：当前 100 条样本中约有 5 个不同 ID，对应如“酒水类”“食品小吃类”“香烟类”等大类（仅从命名与商品名推断）。

结构关联：

在其他 JSON（如商品列表/库存现状）中也出现同名字段，作为商品分类维表的外键。

实际的分类名称不在本表体现，需要通过分类表或其他视图查询。

goodsSecondCategoryId

类型：int

含义：商品二级分类 ID。

观测：样本中约有 7 个不同 ID，如饮料中的“矿泉水/功能饮料/碳酸饮料”等。

结构作用：

与商品二级分类维表对应，进一步区分商品细类。

在库存现状或商品档案 JSON 中也出现，用于报表按分类汇总库存。

2. 商品基本信息字段

goodsName

类型：string

含义：商品名称。

示例值：

"农夫山泉苏打水"

"阿萨姆"

"哇哈哈矿泉水"

"鸡翅三个一份"

"普通扑克"

"软玉溪", "钻石荷花"（香烟）

特点：

对应门店商品表中的 goods_name，为当时的名称快照。

与 siteGoodsId 一一对应，但保留在变更记录中便于直接阅读，不用再去商品表查。

unit

类型：string，枚举。

观测值（本样本）：

"瓶"、"包"、"盒"、"根"、"个"、"桶"、"份".

含义：库存计量单位。

说明：库存数量（startNum、endNum、changeNum）均以这里的单位计数。

price

类型：float

含义：商品单价（单位金额）。

观测特征：

常见值：5.0、8.0、15.0、6.0、2.0、10.0、45.0 等。

对同一个 siteGoodsId，所有记录的 price 完全一致——说明这是该商品在门店的当前单价快照。

结构作用：

虽然库存变化记录中并未直接出现金额字段，但通过 price × changeNum 可以算出这次变动对应的金额（如果需要金额层面分析的话）。

在结构上，这是为后续报表（如按进销存金额统计）预留的关键字段。

3. 库存数量变动类字段

startNum

类型：int

含义：变动前（这次出入库之前）的库存数量。

示例：
如记录：startNum = 28, changeNum = -1, endNum = 27。

特点：样本中有 80+ 个不同值，覆盖几十到几百的库存数。

endNum

类型：int

含义：变动后（出入库之后）的库存数量。

结构关系：

全部记录满足：
endNum = startNum + changeNum
这一点在样本中经检验无一例外。

意义：确保库存变动画账逻辑正确，是库存平衡的核心约束。

changeNum

类型：int

含义：本次库存数量变化值。

特点及取值：

常见值：-1、-2、-3、-6、-12、-36 等负数，也有少量正数（如 1、2、12、36 等）。

数据验证：

当 changeNum < 0 时，startNum > endNum；

当 changeNum > 0 时，startNum < endNum。

结构逻辑：

在配合 stockType 使用时，正负号对应该变动是“出库还是入库”：

对 stockType = 1：全部都是负数，代表从库存中扣减（销售或其他出库）。

对 stockType = 4：全部是正数，代表库存增加（入库/调整）。

startNumA

类型：int

观测：所有记录为 0。

含义（推测）：辅助计量单位的起始库存（例如件/箱等第二单位）。

当前门店在样本时间段内没有启用多单位库存管理，因此全部为 0。

endNumA

类型：int

观测：全部为 0。

含义：辅助单位的变动后库存，同样未启用。

changeNumA

类型：int

观测：全部为 0。

含义：辅助单位的变化量（与 changeNum 对应的第二计量单位变化），当前未使用。

结论：
startNumA / endNumA / changeNumA 是为“一个商品有两种计量单位（如箱与瓶）”而设计的预留字段。
目前门店只在单一单位层面管理库存，故全部为 0。

4. 库存变动类型字段

stockType

类型：int，枚举。

观测值（本样本）：

1：89 条

4：11 条

与 changeNum 的联合特征：

(stockType=1, changeNum<0) 出现 89 次；

(stockType=4, changeNum>0) 出现 11 次；

不存在 stockType=1 且 changeNum>0 或 stockType=4 且 changeNum<0 的情况。

含义（基于数据行为推断）：

1：出库类变动
典型情况是销售出库，库存减少 1 或 2；例如顾客点了一瓶饮料，对应一条 stockType=1, changeNum=-1 的记录。

4：入库/盘盈/调整增加
举例：某条记录为 stockType=4, changeNum=2，startNum=13, endNum=15，说明库存被人工或系统增加了 2。

结构意义：

用 stockType 区分变动原因大类（销售/退货/盘点/报损等），再由 changeNum 的正负体现增减。

当前样本里只出现了两个枚举值，但从命名推测，系统中还可能存在其它类型（例如报损出库、盘亏减少等），只是这段时间内未发生。

5. 操作与时间字段

createTime

类型：string，格式 YYYY-MM-DD HH:MM:SS

含义：这条库存变动记录的创建时间，即发生库存变更的时间点。

特点：

样本覆盖 2025-11-09 晚上一段时间，且有多条记录在同一秒内（同桌多商品一起销售时）。

是库存流水的时间轴关键字段，可与小票时间、台费时间等交叉校验。

operatorName

类型：string

含义：执行此次库存变动的操作人。

观测值：

"收银员:郑丽珊"：99 条

"系统"：1 条

说明：

大部分库存变化由前台收银员操作（录入销售单、小票）触发。

个别记录由系统自动生成（如自动盘点调整、系统修正等），操作人显示为“系统”。

6. 备注字段

remark

类型：string

观测：全部为空字符串 ""。

含义：备注信息，用于手工记录本次变更的特殊原因说明（例如“盘点差异调整”“报损”）。

当前样本中没有填入任何备注，但字段已预留，适用于盘点或手工调整场景。

三、与其他 JSON 的结构关联关系（从字段角度）

仅从字段命名和你这批文件中出现的位置来看，“库存变化记录1.json”在整体系统中的结构位置大致如下：

与商品档案 / 库存现状

siteGoodsId：

在 库存现状.json（20251110_043308_...）中同名出现，对应门店商品库存汇总表。

在“小票详情.json”（20251110_035904_...）中也有 siteGoodsId，用于标记每条销售明细对应的商品。

siteGoodsStockId：

是具体库存记录主键，与库存现状中的记录一一对应。

goodsCategoryId / goodsSecondCategoryId：

在商品定义/库存现状 JSON 中同样出现，对应商品分类维表。

结构链路可以概括为：

商品档案/库存现状（siteGoodsId, goodsCategoryId...）
↕
库存变化记录（siteGoodsId, siteGoodsStockId, changeNum...）
↕
小票详情/销售明细（siteGoodsId, 数量）

与门店维度

tenantId / siteId：

与所有业务 JSON 中的同名字段一致，表示这条库存变动属于哪一个品牌、哪一家门店。

对你这批数据来说，这两个字段在所有文件中取值固定，都是“非球科技 · 某门店（朗朗桌球）”。

与操作员/员工信息

operatorName：

以字符串形式记录操作员，“收银员:郑丽珊”与其他 JSON 中的操作员信息（如结账记录、小票记录中的 operator_name）一致。

虽然本表中没有 operatorId，但其他表（如结账记录）有时会记录 ID；可通过姓名+门店，在员工档案或账号表中匹配。

与销售/出库行为

当 stockType = 1, changeNum < 0 时，明显是销售导致的库存减少。

对应的小票/销售明细也会有同一时间点的消费记录（通过 createTime、siteGoodsId、商品名 等组合可以对齐）。

对“盘点增加/入库类”的记录（stockType = 4, changeNum > 0），则可能与采购入库或盘盈记录关联到其他表。

四、结构层面的重要线索（不涉及金额/盈利分析）

从字段设计和样本值可以看出，这个“库存变化记录”表在系统结构上有一些关键特征：

库存平衡公式显式存在

所有记录满足：
endNum = startNum + changeNum。

这意味着系统把每一次增减记录为一条流水，而不是只记录最后库存量。

通过把所有变动记录按时间排序叠加，可以完全重放库存数变化过程。

统一支持双计量单位但本门店未启用

startNumA / endNumA / changeNumA 全为 0，说明目前只使用主单位（瓶/包/盒等）。

但字段已经为“箱/瓶”这种双单位场景预留了结构，可以在未来随时启用。

库存变动类型（stockType）与变化方向强绑定

样本中，stockType=1 永远对应负数 changeNum，stockType=4 永远对应正数。

说明系统在设计时，不是单纯依赖 changeNum 的正负来判断业务含义，而是：

用 stockType 表示业务场景（销售出库/盘点/入库等），

用 changeNum 的正负表达实际的增或减。

其它可能的 stockType（如报损出库/盘亏/退货等）本批样本中未出现，但结构已经预留可扩展。

价格在本表中是“静态快照”，而不是动态计算字段

对同一个 siteGoodsId，所有记录的 price 一致，表明：

price 是当时商品价格的快照副本。

真实的“标准价/进价/零售价”仍以商品档案为准，只是在库存变动记录中复制一份方便报表使用。

这一设计避免了之后价格调整导致历史库存记录无法按当时价格还原的问题。

操作员信息体现“人工 vs 系统”两类来源

大部分记录由“收银员”操作，说明库存减少主要来自前台销售。

个别记录由“系统”操作，说明系统本身会根据某些规则自动生成库存变动记录（例如盘点差异自动入库/出库、库存初始化等）。

结构上不需要额外字段即可从 operatorName 粗略判断记录来源。

与商品分类强绑定，方便结构化报表

通过 goodsCategoryId / goodsSecondCategoryId，这张库存变动明细表可以非常方便地按“饮料/香烟/小食”等分类对库存变动进行结构化分析。

虽然你不希望做“大数据/盈利分析”，但从结构角度看，这两个字段是后续任意统计的关键维度。
