d5b11c0943
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JJ1g8XV1YhhmHRzhwWEW7o
144 lines
13 KiB
HTML
144 lines
13 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>出入库明细空字段 × 库存可补 数据统计 — 酒库管理系统</title>
|
||
<style>
|
||
:root{
|
||
--primary:#2563AC; --primary-dark:#154072; --danger:#D14343; --danger-bg:#FDECEC;
|
||
--success:#2E8B57; --success-bg:#E6F3EC; --warn:#B45309; --warn-bg:#FFF4E5; --accent:#8B2331;
|
||
--ink:#232934; --muted:#6E7888; --border:#DCE2EB; --paper:#F5F7FA; --head:#F0F4FF;
|
||
}
|
||
*{box-sizing:border-box;font-family:-apple-system,"PingFang SC","Microsoft YaHei",sans-serif;}
|
||
body{margin:0;background:var(--paper);color:var(--ink);padding:28px;line-height:1.65;max-width:1000px;margin:0 auto;}
|
||
h1{font-size:22px;margin:0 0 4px;}
|
||
h2{font-size:17px;margin:30px 0 10px;color:var(--primary-dark);border-bottom:2px solid var(--head);padding-bottom:6px;}
|
||
h3{font-size:14px;margin:18px 0 6px;color:var(--accent);}
|
||
.sub{color:var(--muted);font-size:13px;margin-bottom:8px;}
|
||
.stats{display:flex;gap:22px;flex-wrap:wrap;font-size:12.5px;color:var(--muted);margin:10px 0;}
|
||
.stats b{color:var(--ink);font-size:16px;}
|
||
.card{background:#fff;border:1px solid var(--border);border-radius:10px;padding:14px 18px;margin:12px 0;}
|
||
table{width:100%;border-collapse:collapse;font-size:13px;margin:6px 0;}
|
||
th{background:var(--head);color:var(--primary-dark);font-weight:600;font-size:12px;text-align:left;padding:8px 10px;border-bottom:1px solid var(--border);}
|
||
td{padding:7px 10px;border-bottom:1px solid #EEF1F6;}
|
||
tr:last-child td{border-bottom:0;}
|
||
td.n{text-align:right;font-family:ui-monospace,Menlo,monospace;}
|
||
.mono{font-family:ui-monospace,Menlo,monospace;font-size:12px;}
|
||
code{font-family:ui-monospace,Menlo,monospace;font-size:12px;background:#EEF2F8;padding:1px 5px;border-radius:4px;color:var(--primary-dark);}
|
||
.hi{color:var(--danger);font-weight:700;}
|
||
.ok{color:var(--success);font-weight:700;}
|
||
.callout{border-left:4px solid var(--primary);background:#F0F6FF;padding:10px 14px;border-radius:4px;margin:12px 0;font-size:13px;}
|
||
.callout.danger{border-color:var(--danger);background:var(--danger-bg);}
|
||
.callout.warn{border-color:var(--warn);background:var(--warn-bg);}
|
||
.callout.ok{border-color:var(--success);background:var(--success-bg);}
|
||
ul{margin:6px 0;padding-left:20px;} li{margin:4px 0;font-size:13px;}
|
||
.tag{display:inline-block;font-size:10px;padding:1px 7px;border-radius:9px;font-weight:600;}
|
||
.tag.fix{background:var(--success-bg);color:var(--success);}
|
||
.tag.no{background:#EEE;color:var(--muted);}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<h1>出入库明细 空字段 × 库存可补 · 数据统计</h1>
|
||
<div class="sub">数据源:生产库每日备份 <code>jiu_db_20260626_020210.sql.gz</code>(2026-06-26 02:02)· 单租户(鼎晟酒行)</div>
|
||
<div class="stats">
|
||
<div>出库明细 <b>26,693</b> 行</div>
|
||
<div>入库明细 <b>28,443</b> 行</div>
|
||
<div>库存批次 <b>13,120</b> 行</div>
|
||
<div>商品 <b>9,525</b> 行</div>
|
||
</div>
|
||
|
||
<div class="callout">
|
||
<b>口径说明:</b>「库存能找到值」= 该字段在库存表的<b>显示值</b>非空,即 <code>COALESCE(NULLIF(sii.batch_no,''), inv.batch_no)</code>(用户在库存页看到的值)。出库明细按 <code>product_id</code> 匹配库存;入库明细按 <code>stock_in_item_id</code> 直连。<br>
|
||
「打印必空白」= 明细行快照为空 <b>且</b> 该行 <code>product</code> 主记录也为空(两者都空,打印才会留白)。
|
||
</div>
|
||
|
||
<h2>一、核心结论</h2>
|
||
<div class="card">
|
||
<ul>
|
||
<li><b>出库单打印空白、且能从库存补回的,只有约 <span class="hi">18~20 行</span>(集中在 <span class="hi">13 张单</span>)</b>,全部是 <b>2026-06-20 ~ 06-24</b> 的近期 App 新建单(含截图 <code>CK20260623000007</code>)。这正是「出库单显示对齐库存口径」能解决的部分。</li>
|
||
<li>出库明细批次号为空共 <b>5,528 行</b>,但其中 <span class="hi">99.7% 在库存里也查不到值</span>(商品已售罄无在库批次 / 源数据本就没录批次)——属源数据缺失,<b>非显示 bug,无法从库存补</b>。</li>
|
||
<li><b>入库单批次/生产日期可补数 = <span class="hi">0</span></b>(库存、product 主记录都补不出)。因为<b>入库是数据录入源头</b>,源头空则下游全空,无上游可回填——与出库不同,<b>不是显示 bug,"显示对齐库存口径"对入库无意义</b>。空批次跨 2023-04~2026-06 整段历史。</li>
|
||
<li>根因复述:批次/生产日期的值真实落在 <code>inventories</code> 表<b>自身的快照列</b>上(不是 stock_in_item、也不是 product 主记录);出库打印却回退读 <code>product</code> 主记录,对不上。详见 <a href="../db-schema.html#inventories">db-schema</a>。</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<h2>二、出库明细 stock_out_items</h2>
|
||
<p class="sub">product_id 全部有值(无占位行)。</p>
|
||
|
||
<h3>① 宽口径:明细字段为空 ÷ 其中库存能找到值</h3>
|
||
<div class="card"><table>
|
||
<thead><tr><th>字段</th><th>明细为空</th><th>占比</th><th>其中库存有值</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>batch_no</code> 批次号</td><td class="n">5,557</td><td class="n">20.8%</td><td class="n">46</td></tr>
|
||
<tr><td><code>production_date</code> 生产日期</td><td class="n">66</td><td class="n">0.25%</td><td class="n">48</td></tr>
|
||
<tr><td><code>product_code</code> 商品编号</td><td class="n">62</td><td class="n">0.23%</td><td class="n">48</td></tr>
|
||
<tr><td><code>series</code> 系列</td><td class="n">63</td><td class="n">0.24%</td><td class="n">48</td></tr>
|
||
<tr><td><code>spec</code> 规格</td><td class="n">63</td><td class="n">0.24%</td><td class="n">48</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h3>② 打印口径:明细空 且 product 主记录也空(= 打印必空白)÷ 库存可补</h3>
|
||
<div class="card"><table>
|
||
<thead><tr><th>字段</th><th>打印空白行</th><th><span class="tag fix">库存可补</span></th><th>涉及出库单</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>batch_no</code> 批次号</td><td class="n">5,528</td><td class="n ok">18</td><td class="n">1,207</td></tr>
|
||
<tr><td><code>production_date</code> 生产日期</td><td class="n">37</td><td class="n ok">20</td><td class="n">22</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h2>三、入库明细 stock_in_items</h2>
|
||
<p class="sub">与出库<b>完全同口径</b>:库存按 <code>product_id</code> 匹配;并额外列出能否从 <code>product</code> 主记录补值。</p>
|
||
<div class="card"><table>
|
||
<thead><tr><th>字段</th><th>明细为空</th><th><span class="tag fix">库存可补</span></th><th>product 主记录可补</th></tr></thead>
|
||
<tbody>
|
||
<tr><td><code>batch_no</code> 批次号</td><td class="n">6,876</td><td class="n hi">0</td><td class="n hi">0</td></tr>
|
||
<tr><td><code>production_date</code> 生产日期</td><td class="n">16</td><td class="n hi">0</td><td class="n hi">0</td></tr>
|
||
<tr><td><code>product_code</code> 商品编号</td><td class="n">25</td><td class="n">10</td><td class="n">25</td></tr>
|
||
<tr><td><code>series</code> 系列</td><td class="n">27</td><td class="n">12</td><td class="n">26</td></tr>
|
||
<tr><td><code>spec</code> 规格</td><td class="n">27</td><td class="n">12</td><td class="n">25</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
<div class="callout warn">
|
||
<b>入库单批次号/生产日期:可补数 = 0(库存、product 主记录都补不出)。</b>这是结构性的——<b>入库是数据录入的源头</b>:批次若在入库时就空着,由它建的 product 也空、由它生成的库存批次同样空,没有任何上游能反过来填。出库之所以能补,是因为出库引用的是「别的、已录过批次的库存批次」。<br>
|
||
入库空批次跨度 <b>2023-04 ~ 2026-06</b>(整段历史都有,非 App 期专属),属源头从未录入,<b>不是显示 bug,与出库的「显示对齐库存口径」无关</b>。商品编号/系列/规格少量空行(25~27)可从 product 主记录补,但属商品身份字段、与本次批次问题无关。</div>
|
||
|
||
<h2>四、受影响(打印空白但库存可补)出库单清单</h2>
|
||
<p class="sub">20 个明细行,13 张单,全部为近期 App 新建单。这些单据打印时批次/生产日期留白,但库存里有值。</p>
|
||
<div class="card"><table>
|
||
<thead><tr><th>出库单号</th><th>日期</th><th>product_id</th><th>库存批次</th><th>库存生产日期</th></tr></thead>
|
||
<tbody>
|
||
<tr><td class="mono">CK20260624000021</td><td>2026-06-24</td><td class="mono">4779</td><td class="mono">2015674600</td><td class="mono">2009-04-16</td></tr>
|
||
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9448</td><td class="mono">2023-003/AI013453</td><td class="mono">2025-02-27</td></tr>
|
||
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">4430</td><td class="mono">1</td><td class="mono">2012-01-01</td></tr>
|
||
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9449</td><td class="mono">2023-003/AI013441</td><td class="mono">2025-02-27</td></tr>
|
||
<tr><td class="mono">CK20260623000001</td><td>2026-06-23</td><td class="mono">9486</td><td class="mono">2006-01/03008</td><td class="mono">2006-12-01</td></tr>
|
||
<tr><td class="mono">CK20260623000003</td><td>2026-06-23</td><td class="mono">4617</td><td class="mono">2026-001/YC025400</td><td class="mono">2026-03-19</td></tr>
|
||
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">9477</td><td class="mono">2025-023/AA007333</td><td class="mono">2025-12-18</td></tr>
|
||
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">9478</td><td class="mono">2025-023/AA007191</td><td class="mono">2025-12-18</td></tr>
|
||
<tr><td class="mono">CK20260623000004</td><td>2026-06-23</td><td class="mono">4722</td><td class="mono">2025-127/441066145489</td><td class="mono">2026-03-14</td></tr>
|
||
<tr><td class="mono"><b>CK20260623000007</b> <span class="tag fix">截图</span></td><td>2026-06-23</td><td class="mono">4382</td><td class="mono">2022-001/AH000108</td><td class="mono">2023-12-28</td></tr>
|
||
<tr><td class="mono">CK20260623000009</td><td>2026-06-23</td><td class="mono">4247</td><td class="mono">(批次空)</td><td class="mono">2024-08-21</td></tr>
|
||
<tr><td class="mono">CK20260623000010</td><td>2026-06-23</td><td class="mono">4717</td><td class="mono">2022-014/664667600053</td><td class="mono">2024-01-31</td></tr>
|
||
<tr><td class="mono">CK20260623000010</td><td>2026-06-23</td><td class="mono">9503</td><td class="mono">2023-004/654105250904</td><td class="mono">2024-07-11</td></tr>
|
||
<tr><td class="mono">CK20260623000013</td><td>2026-06-23</td><td class="mono">4026</td><td class="mono">2022-091/AA019835</td><td class="mono">2023-07-25</td></tr>
|
||
<tr><td class="mono">CK20260623000014</td><td>2026-06-23</td><td class="mono">9499</td><td class="mono">2022-006/AI008438</td><td class="mono">2024-05-11</td></tr>
|
||
<tr><td class="mono">CK20260623000014</td><td>2026-06-23</td><td class="mono">9500</td><td class="mono">2022-005/AH003630</td><td class="mono">2024-03-28</td></tr>
|
||
<tr><td class="mono">CK20260623000015</td><td>2026-06-23</td><td class="mono">4645</td><td class="mono">(批次空)</td><td class="mono">2026-01-19</td></tr>
|
||
<tr><td class="mono">CK20260623000016</td><td>2026-06-23</td><td class="mono">4732</td><td class="mono">2022-030/799689408820</td><td class="mono">2023-02-14</td></tr>
|
||
<tr><td class="mono">CK20260623000017</td><td>2026-06-23</td><td class="mono">4757</td><td class="mono">2025-102/006679240592</td><td class="mono">2026-02-13</td></tr>
|
||
<tr><td class="mono">CK20260620000001</td><td>2026-06-20</td><td class="mono">3510</td><td class="mono">RK20260613000004-01</td><td class="mono">2026-06-09</td></tr>
|
||
</tbody>
|
||
</table></div>
|
||
|
||
<h2>五、对修复方案的指向</h2>
|
||
<div class="callout ok">
|
||
<b>「出库单显示对齐库存口径」(已选方案)足以覆盖真实问题:</b>对近期 App 出库单(上表 13 张)打印时按 <code>product → inventory</code> 取批次/生产日期即可即时补全,无需动数据、无需重发。<br>
|
||
<b>历史海量空批次(5,500+ 行)不在修复范围:</b>它们在 product / 库存 / 入库明细中均无值,属源数据从未录入,任何「显示口径」都补不出来。<br>
|
||
<b>入库单方向收益≈0:</b>入库明细与库存几乎无可用关联,且入库明细空批次同样源数据缺失。
|
||
</div>
|
||
|
||
<p class="sub" style="margin-top:24px;">统计方法:将备份导入临时库 <code>jiu_analyze</code>,按上述口径 SQL 聚合,完成后删除临时库。生成时间 2026-06-26。</p>
|
||
</body>
|
||
</html>
|