选择原材料库存批次出库/);
+ assert.match(mainCss, /\.production-out-source-lot-panel/);
+});
+
+it("keeps production ledger inbound settlement controls paper-native", () => {
+ assert.match(source, /production-ledger-inbound-paper-grid/);
+ assert.match(source, /production-ledger-inbound-summary/);
+ assert.match(source, /production-ledger-inbound-metrics/);
+ assert.doesNotMatch(source, /
[\s\S]*?productionWorkOrderInboundForm\.finished_qty/);
+ assert.match(mainCss, /\.production-ledger-inbound-metrics/);
+});
+```
+
+- [ ] **Step 2: Run test to verify it fails**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: FAIL because the P0 class names are not in `InventoryLedgerView.vue` or CSS yet.
+
+## Task 6: Convert Special Inbound / Special Outbound Paper Form
+
+**Files:**
+- Modify: `frontend/src/views/InventoryLedgerView.vue`
+- Modify: `frontend/src/styles/main.css`
+
+- [ ] **Step 1: Replace the special adjustment warning and header fields**
+
+In the `specialAdjustmentDrawerOpen` drawer, replace:
+
+```vue
+
+ 特殊调整会直接改变库存明细
+ 保存后写入库存流水和特殊调整记录,请仅在补录、纠错、线下已处理等特殊场景使用。
+
+
+
+
+ 调整说明
+
+
+
+ 仓库
+
+ 请选择仓库
+
+ {{ warehouse.warehouse_name }}
+
+
+
+
+```
+
+with:
+
+```vue
+
+ 特殊调整会直接改变库存明细
+ 保存后写入库存流水和特殊调整记录,请仅在补录、纠错、线下已处理等特殊场景使用。
+
+
+
+
+ 调整说明
+
+
+
+ 仓库
+
+ 请选择仓库
+
+ {{ warehouse.warehouse_name }}
+
+
+
+
+```
+
+- [ ] **Step 2: Replace add-line action area**
+
+Replace:
+
+```vue
+
+
+ 添加调整明细
+
+ 请先填写调整说明
+
+```
+
+with:
+
+```vue
+
+
+ 添加调整明细
+
+ 请先填写调整说明
+ 每条明细都会写入库存流水,调整说明会同步进入变更记录。
+
+```
+
+- [ ] **Step 3: Rename special adjustment line containers**
+
+Replace class names:
+
+```vue
+class="special-adjustment-lines"
+class="special-adjustment-line-card"
+```
+
+with:
+
+```vue
+class="special-adjustment-paper-lines special-adjustment-lines"
+class="special-adjustment-paper-line-card special-adjustment-line-card"
+```
+
+Keep existing child classes such as `special-adjustment-card-grid`, `special-adjustment-card-field`, and `special-adjustment-card-preview` for now because they already use a paper-grid look.
+
+- [ ] **Step 4: Add CSS aliases**
+
+Add near the existing special adjustment styles:
+
+```css
+.special-adjustment-paper-warning {
+ display: grid;
+ gap: 5px;
+ color: #78350f;
+ background:
+ linear-gradient(90deg, rgba(180, 83, 9, 0.13), transparent 50%),
+ rgba(255, 250, 240, 0.64);
+}
+
+.special-adjustment-paper-warning strong {
+ color: #78350f;
+ font-size: 15px;
+}
+
+.special-adjustment-paper-warning span,
+.special-adjustment-paper-toolbar span {
+ font-size: 12px;
+ font-weight: 900;
+}
+
+.special-adjustment-paper-grid {
+ grid-template-columns: repeat(4, minmax(0, 1fr));
+}
+
+.special-adjustment-paper-toolbar {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 12px;
+}
+
+.special-adjustment-paper-lines {
+ display: grid;
+ grid-column: 1 / -1;
+ gap: 14px;
+ min-width: 0;
+}
+
+.special-adjustment-paper-line-card {
+ position: relative;
+ overflow: hidden;
+ border: 1.5px solid rgba(20, 14, 6, 0.72);
+ background:
+ linear-gradient(90deg, rgba(31, 122, 74, 0.06), transparent 44%),
+ rgba(255, 250, 240, 0.72);
+ box-shadow:
+ inset 0 0 0 1px rgba(255, 255, 255, 0.5),
+ 0 8px 18px rgba(52, 39, 15, 0.08);
+}
+```
+
+- [ ] **Step 5: Run focused test**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: special adjustment test passes; production out and production ledger inbound tests still fail.
+
+## Task 7: Convert Production Out Paper Form
+
+**Files:**
+- Modify: `frontend/src/views/InventoryLedgerView.vue`
+- Modify: `frontend/src/styles/main.css`
+
+- [ ] **Step 1: Replace production out tip and product selector**
+
+In the `productionDrawerOpen` drawer, replace:
+
+```vue
+
选择原材料库存批次出库,后续小程序报工按库存批次号推进。
+
+
+ 产品
+
+ 请选择产品
+
+ {{ formatProductLabel(product) }}
+
+
+
+```
+
+with:
+
+```vue
+
+ 选择原材料库存批次出库,后续小程序报工按库存批次号推进。一次生产出库只能选择一个材料库存批次。
+
+
+
+
+ 产品
+
+ 请选择产品
+
+ {{ formatProductLabel(product) }}
+
+
+
+
+```
+
+- [ ] **Step 2: Replace production stock lot selector**
+
+Replace:
+
+```vue
+
+ 库存批次号
+
+
+```
+
+with:
+
+```vue
+
+
+ 库存批次号
+ 搜索并选择一个材料库存批次号
+
+
+
+
+
+```
+
+- [ ] **Step 3: Replace selected lot table wrapper**
+
+Change:
+
+```vue
+
+```
+
+to:
+
+```vue
+
+```
+
+- [ ] **Step 4: Replace issue weight/reference quantity group**
+
+Replace the production out `double-field` group with:
+
+```vue
+
+
+ 本次生产出库重量(kg)
+
+
+
+ 参考生产数量
+
+
+
+```
+
+- [ ] **Step 5: Add CSS**
+
+Add:
+
+```css
+.production-out-paper-tip {
+ color: #145c39;
+}
+
+.production-out-paper-grid,
+.production-out-source-lot-panel,
+.production-out-source-lot-table {
+ grid-column: 1 / -1;
+}
+
+.production-out-source-lot-panel .stock-lot-control {
+ min-height: 50px;
+ border: 0;
+ border-radius: 0;
+ background: rgba(255, 255, 255, 0.32);
+ box-shadow: inset 0 0 0 1.5px rgba(31, 122, 74, 0.28);
+}
+
+.production-out-source-lot-table {
+ margin: 0;
+ overflow-x: auto;
+ border-top: 2px solid rgba(20, 14, 6, 0.88);
+ border-left: 2px solid rgba(20, 14, 6, 0.88);
+ border-radius: 0;
+ background: rgba(255, 250, 240, 0.46);
+ box-shadow: none;
+}
+```
+
+- [ ] **Step 6: Run focused test**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: special adjustment and production out tests pass; production ledger inbound test still fails.
+
+## Task 8: Convert Production Ledger Inbound Settlement Paper Form
+
+**Files:**
+- Modify: `frontend/src/views/InventoryLedgerView.vue`
+- Modify: `frontend/src/styles/main.css`
+
+- [ ] **Step 1: Replace settlement workflow tip and ledger select**
+
+In `productionWorkOrderInboundDrawerOpen`, replace:
+
+```vue
+
+ 选择生产台账后,系统按领料重量、单件毛重和已入库成品数量填入理论余料、理论废料。理论值只是辅助参考,实际称重可修改;偏差超过上下15%时需要填写说明。
+
+
+
+ 生产台账
+
+ 请选择在生产的生产台账
+
+ {{ formatProductionWorkOrderInboundOption(workOrder) }}
+
+
+
+```
+
+with:
+
+```vue
+
+ 选择生产台账后,系统按领料重量、单件毛重和已入库成品数量填入理论余料、理论废料。理论值只是辅助参考,实际称重可修改;偏差超过上下15%时需要填写说明。
+
+
+
+
+ 生产台账
+
+ 请选择在生产的生产台账
+
+ {{ formatProductionWorkOrderInboundOption(workOrder) }}
+
+
+
+
+```
+
+- [ ] **Step 2: Add settlement summary class to preview grid**
+
+Change:
+
+```vue
+
+```
+
+to:
+
+```vue
+
+```
+
+- [ ] **Step 3: Replace the triple-field input group**
+
+Replace:
+
+```vue
+
+
+ 成品入库数量
+
+
+
+ 余料入库重量(kg)
+
+
+
+ 废料重量(kg)
+
+
+
+```
+
+with:
+
+```vue
+
+
+ 成品入库数量
+
+
+
+ 余料入库重量(kg)
+
+
+
+ 废料重量(kg)
+
+
+
+```
+
+- [ ] **Step 4: Replace theoretical metric grid class**
+
+Change:
+
+```vue
+
+```
+
+to:
+
+```vue
+
+```
+
+Then change each nested `
` to use:
+
+```vue
+
+```
+
+Keep the labels and computed values unchanged.
+
+- [ ] **Step 5: Add CSS**
+
+Add:
+
+```css
+.production-ledger-inbound-tip,
+.production-ledger-inbound-paper-grid,
+.production-ledger-inbound-summary,
+.production-ledger-inbound-metrics {
+ grid-column: 1 / -1;
+}
+
+.production-ledger-inbound-tip {
+ color: #145c39;
+}
+
+.production-ledger-inbound-metrics {
+ border-top: 2px solid rgba(20, 14, 6, 0.88);
+ border-left: 2px solid rgba(20, 14, 6, 0.88);
+}
+```
+
+- [ ] **Step 6: Run focused test**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: all `InventoryLedgerView` tests pass.
+
+## Task 9: Full Verification
+
+**Files:**
+- Test: `frontend/src/components/documentForms/documentForms.test.js`
+- Test: `frontend/src/views/InventoryLedgerView.test.js`
+- Build: `frontend/package.json`
+
+- [ ] **Step 1: Run document component tests**
+
+Run:
+
+```bash
+cd frontend
+node --test src/components/documentForms/documentForms.test.js
+```
+
+Expected: PASS.
+
+- [ ] **Step 2: Run warehouse view tests**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: PASS.
+
+- [ ] **Step 3: Run frontend build**
+
+Run:
+
+```bash
+cd frontend
+npm run build
+```
+
+Expected: build succeeds. Existing Vite chunk-size warning is acceptable.
+
+- [ ] **Step 4: Browser verify P0 documents**
+
+Using the in-app browser at `http://localhost:5173/inventory-ledger`, verify:
+
+- `原材料库 -> 特殊入库`: warning, reason, warehouse, add-line toolbar, and line cards visually belong to the paper document.
+- `原材料库 -> 特殊出库`: same as special inbound.
+- `原材料库 -> 生产出库`: product selector, source lot selector, selected lot table, and issue weight/reference quantity are paper-native.
+- `工具 -> 生产台账入库`: ledger selector, preview summary, finished/surplus/scrap inputs, theoretical metrics, settle checkbox, and abnormal explanation area are paper-native.
+- `原材料库 -> 客料入库`: approved template does not regress.
+- `采购订单` and `销售订单`: existing paper documents still render.
+
+## Task 10: Completion Review
+
+**Files:**
+- Inspect: `git diff --stat`
+- Inspect: `git status --short`
+
+- [ ] **Step 1: Check whitespace**
+
+Run:
+
+```bash
+git diff --check
+```
+
+Expected: no output.
+
+- [ ] **Step 2: Check changed files**
+
+Run:
+
+```bash
+git status --short
+```
+
+Expected changed files should be limited to:
+
+```text
+frontend/src/components/documentForms/DocumentActionBar.vue
+frontend/src/components/documentForms/DocumentField.vue
+frontend/src/components/documentForms/DocumentFormShell.vue
+frontend/src/components/documentForms/DocumentInlineSummary.vue
+frontend/src/components/documentForms/DocumentPaper.vue
+frontend/src/components/documentForms/DocumentSection.vue
+frontend/src/components/documentForms/DocumentSelectorPanel.vue
+frontend/src/components/documentForms/DocumentSettlePanel.vue
+frontend/src/components/documentForms/WarehouseDocumentActionBar.vue
+frontend/src/components/documentForms/WarehouseDocumentFormShell.vue
+frontend/src/components/documentForms/WarehouseDocumentSection.vue
+frontend/src/components/documentForms/documentForms.test.js
+frontend/src/styles/main.css
+frontend/src/views/InventoryLedgerView.test.js
+frontend/src/views/InventoryLedgerView.vue
+```
+
+Plus any already-existing dirty files that predated execution.
+
+- [ ] **Step 3: Summarize residual risks**
+
+Report:
+
+- Which P0 documents were browser-verified.
+- Whether build passed.
+- Whether any browser verification was limited by narrow viewport.
+- That backend APIs and business logic were intentionally not changed.
+
+## Self-Review
+
+- Spec coverage: covers Phase 0 generic foundation and Phase 1 P0 warehouse documents from `2026-06-13-system-wide-paper-document-unification-design.md`.
+- Placeholder scan: no placeholder markers or fill-later wording.
+- Type consistency: component names are consistently `DocumentFormShell`, `DocumentSection`, `DocumentActionBar`, `DocumentField`, `DocumentSelectorPanel`, `DocumentInlineSummary`, `DocumentSettlePanel`.
+- Scope guard: does not alter backend archive routes, inventory calculation, production calculation, or database schema.
diff --git a/docs/superpowers/plans/2026-06-13-warehouse-paper-form-unification-phase1.md b/docs/superpowers/plans/2026-06-13-warehouse-paper-form-unification-phase1.md
new file mode 100644
index 0000000..67fdd52
--- /dev/null
+++ b/docs/superpowers/plans/2026-06-13-warehouse-paper-form-unification-phase1.md
@@ -0,0 +1,212 @@
+# Warehouse Paper Form Unification Phase 1 Implementation Plan
+
+> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
+
+**Goal:** Make warehouse operation documents use one cohesive paper-form visual language, starting with the production-ledger controlled inbound forms that currently mix modern web controls into the paper sheet.
+
+**Architecture:** Keep all business state, computed values, validation, and submit payloads in `InventoryLedgerView.vue` unchanged. Introduce paper-specific wrappers/classes around the existing controls so selectors, selected-lot tables, live summaries, remarks, and settle controls visually belong to the same document grid as the approved “客料入库单”. Avoid global restyling of `.form-field`, `.double-field`, `.table-wrap`, or shared controls used outside paper documents.
+
+**Tech Stack:** Vue 3 SFC, Vite, project CSS in `frontend/src/styles/main.css`, Node built-in test runner.
+
+---
+
+## File Structure
+
+- Modify `frontend/src/views/InventoryLedgerView.vue`: convert the generic warehouse drawer’s production-ledger controlled inbound branch to paper-specific markup while preserving existing bindings and branch conditions.
+- Modify `frontend/src/styles/main.css`: add reusable paper document classes for control grids, inline summary rows, source-lot selector/table panels, and settle confirmation rows.
+- Modify `frontend/src/views/InventoryLedgerView.test.js`: add regression coverage that production surplus/scrap inbound forms use the paper-specific classes and that the old naked modern classes are not the only visual contract.
+
+## Design Direction
+
+- Aesthetic: “工业纸质单据”.
+- Purpose: Support fast warehouse entry while making each operation feel like a formal business document, not a demo web form.
+- Differentiation anchor: Thick ledger grid lines, label/value cells, stamped meta strips, and paper-native control panels.
+- DFII: 13. Impact 4, fit 5, feasibility 5, performance 4, consistency risk 5. This is strong because it reuses the approved客料入库 visual system, but must be scoped to avoid touching unrelated app forms.
+
+## Task 1: Lock The Regression Tests
+
+**Files:**
+- Modify: `frontend/src/views/InventoryLedgerView.test.js`
+- Read: `frontend/src/views/InventoryLedgerView.vue`
+- Read: `frontend/src/styles/main.css`
+
+- [ ] **Step 1: Add paper-form assertions for production-ledger controlled inbound**
+
+Add a test that checks the generic drawer contains production-ledger paper classes and keeps the old branch visually wrapped:
+
+```js
+it("wraps production-ledger controlled inbound forms in the shared paper control language", () => {
+ assert.match(source, /warehouse-paper-control-grid/);
+ assert.match(source, /warehouse-paper-source-lot-panel/);
+ assert.match(source, /warehouse-paper-source-lot-table/);
+ assert.match(source, /warehouse-paper-inline-summary/);
+ assert.match(source, /warehouse-paper-settle-panel/);
+ assert.match(source, /warehouse-paper-settle-toggle/);
+ assert.match(source, /warehouse-paper-settle-grid/);
+ assert.match(source, /warehouse-paper-settle-remark/);
+ assert.match(mainCss, /\.warehouse-document-section-grid > \.warehouse-paper-control-grid\s*\{[\s\S]*grid-column: 1 \/ -1;/);
+ assert.match(mainCss, /\.warehouse-paper-control-grid\s*\{[\s\S]*grid-template-columns: repeat\(4, minmax\(0, 1fr\)\);/);
+ assert.match(mainCss, /\.warehouse-paper-source-lot-table/);
+ assert.match(mainCss, /\.warehouse-paper-settle-toggle/);
+});
+```
+
+- [ ] **Step 2: Run the test and confirm it fails before implementation**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected before implementation: failure mentioning one or more missing `warehouse-paper-*` classes.
+
+## Task 2: Convert Production Controlled Inbound Markup
+
+**Files:**
+- Modify: `frontend/src/views/InventoryLedgerView.vue`
+
+- [ ] **Step 1: Replace the naked production work-order block**
+
+Replace the `isProductionWorkOrderControlledInbound` `stack-form` block with paper-grid fields:
+
+```vue
+
+
+ {{ isReworkScrapInbound ? "返工工单" : "生产台账" }}
+
+ {{ isReworkScrapInbound ? "请选择返工工单" : "请选择生产台账" }}
+
+ {{ formatWorkOrderLedgerOption(workOrder, activeOperation?.bizType) }}
+
+
+
+
+
+
+ 产品
+ {{ selectedGenericWorkOrder.product_code }} · {{ selectedGenericWorkOrder.product_name }}
+
+
+ 材料库存批次号
+ {{ selectedGenericWorkOrder.source_lot_summary || selectedGenericWorkOrder.material_lot_no || "-" }}
+
+
+ 库外未闭环重量
+ {{ formatWeight(selectedGenericWorkOrder.outside_weight_kg || selectedGenericWorkOrder.limits?.max_scrap_inbound_weight_kg) }}
+
+
+ 库外未闭环重量
+ {{ formatWeight(selectedGenericWorkOrder.outside_weight_kg || selectedGenericWorkOrder.limits?.max_surplus_inbound_weight_kg) }}
+
+
+
+```
+
+- [ ] **Step 2: Convert the core fields to a paper grid**
+
+Replace the main `double-field` and `triple-field` groups in the generic drawer with `warehouse-paper-control-grid`, using the existing exact conditions and v-models. Keep field order: item, warehouse, location, measure basis, weight, quantity, unit cost.
+
+- [ ] **Step 3: Wrap source-lot selector and tables in paper panels**
+
+Keep `StockLotTagSelect` unchanged, but place it inside:
+
+```vue
+
+
+ 来源库存批次号
+ {{ genericSourceLotSelectPlaceholder }}
+
+
+
+```
+
+For selected lot tables, keep the same columns and inputs but add `warehouse-paper-source-lot-table` to the wrapping table container so CSS can remove the ordinary web-card feel.
+
+- [ ] **Step 4: Convert summaries and settle controls**
+
+Replace `inventory-live-summary` display with `warehouse-paper-inline-summary`, and replace `work-order-settle-panel` / `work-order-settle-toggle` with paper-specific classes. Keep `genericForm.settle_work_order`, deviation values, and `genericForm.settle_remark` unchanged.
+
+## Task 3: Add Paper-Specific CSS
+
+**Files:**
+- Modify: `frontend/src/styles/main.css`
+
+- [ ] **Step 1: Add grid spanning rules**
+
+Add the new paper containers beside existing `.warehouse-paper-grid` rules:
+
+```css
+.warehouse-document-section-grid > .warehouse-paper-control-grid,
+.warehouse-document-section-grid > .warehouse-paper-source-lot-panel,
+.warehouse-document-section-grid > .warehouse-paper-source-lot-table,
+.warehouse-document-section-grid > .warehouse-paper-inline-summary,
+.warehouse-document-section-grid > .warehouse-paper-settle-panel {
+ grid-column: 1 / -1;
+}
+```
+
+- [ ] **Step 2: Reuse approved paper field and summary cells**
+
+Make `.warehouse-paper-control-grid` visually match `.warehouse-paper-grid`, with four columns on desktop, two on tablet, and one on mobile. Make `.warehouse-paper-control-grid-compact` allow summary cards to live in the same grid.
+
+- [ ] **Step 3: Style selector/table/settle panels as document rows**
+
+Style:
+
+```css
+.warehouse-paper-source-lot-panel
+.warehouse-paper-source-lot-heading
+.warehouse-paper-source-lot-table
+.warehouse-paper-inline-summary
+.warehouse-paper-settle-panel
+.warehouse-paper-settle-toggle
+.warehouse-paper-settle-grid
+.warehouse-paper-settle-remark
+```
+
+They should use document borders, paper backgrounds, Songti/Simsun value text where appropriate, and no floating modern-card shadows.
+
+## Task 4: Verify
+
+**Files:**
+- Test: `frontend/src/views/InventoryLedgerView.test.js`
+- Build: `frontend/package.json`
+
+- [ ] **Step 1: Run focused view tests**
+
+Run:
+
+```bash
+cd frontend
+node --test src/views/InventoryLedgerView.test.js
+```
+
+Expected: all tests pass.
+
+- [ ] **Step 2: Run production build**
+
+Run:
+
+```bash
+cd frontend
+npm run build
+```
+
+Expected: Vite build succeeds. Existing chunk-size warning is acceptable if it remains the same non-blocking warning.
+
+- [ ] **Step 3: Browser verification**
+
+Open `http://localhost:5173/inventory-ledger`, then inspect:
+
+- 原材料库 · 客料入库 remains unchanged and approved.
+- 原材料库 · 生产余料入库 uses the same paper-grid visual language.
+- The source-lot multi-select, selected-lot table, remark field, and “该批材料余料结单” no longer look like separate modern web cards pasted onto paper.
+- Existing submit button and drawer behavior still work.
+
+## Self-Review
+
+- Spec coverage: covers the user’s requested recommended approach by converting the most visible mixed-UI warehouse document first and creating reusable paper classes for subsequent warehouse forms.
+- Placeholder scan: no TBD/TODO/implement-later placeholders.
+- Type consistency: class names in tests, markup, and CSS use the same `warehouse-paper-*` prefix.
diff --git a/docs/superpowers/specs/2026-06-13-system-wide-paper-document-unification-design.md b/docs/superpowers/specs/2026-06-13-system-wide-paper-document-unification-design.md
new file mode 100644
index 0000000..525947a
--- /dev/null
+++ b/docs/superpowers/specs/2026-06-13-system-wide-paper-document-unification-design.md
@@ -0,0 +1,341 @@
+# 全系统纸质单据统一改造设计
+
+## 背景
+
+系统已经开始从普通后台表单向正式业务单据升级:销售订单、采购订单已经接入 `DocumentPaper` 纸质单据和 PDF 归档;仓库中的 `原材料库 · 客料入库单` 已被用户认可为“模板级别”;`生产余料入库单 / 生产废料入库单` 第一阶段也已经开始改成同一套纸质单据语言。
+
+用户明确补充:这不是仓库专属改造,而是全系统所有“单据型业务”都要采用统一纸质单据体系。为了避免仓库、采购、销售、生产各自长出不同样式,本设计把目标升级为“全系统业务单据纸质化 + PDF 归档统一体系”。
+
+## 单据边界
+
+### 纳入纸质化的对象
+
+满足任一条件就纳入:
+
+- 会创建正式业务凭证:销售订单、采购订单、到货入库单、质量校验单、发货单、退货/返工单。
+- 会改变库存或形成库存流水:各库入库、出库、特殊调整、盘库。
+- 会形成生产追溯闭环:生产出库、生产台账入库、生产入库结算、生产领料出库。
+- 用户后续需要预览、下载、批量下载或审计留档。
+
+### 不纳入纸质化的对象
+
+这些仍按系统管理/主数据维护表单处理,不强行改成纸质单据:
+
+- 供应商名录、客户名录、人员管理、设备管理。
+- 原材料名录、产品管理、产品需规清单、BOM、工艺路线。
+- 系统权限、系统拓展、导入工具、基础配置。
+
+原因:这些是主数据或配置记录,不是业务凭证。强行纸质化会降低维护效率,也会把“单据”的正式感稀释掉。
+
+## 现状清单
+
+### 已基本纸质化且已有 PDF 归档
+
+| 模块 | 页面 | 单据 | 前端状态 | 后端归档类型 | 备注 |
+| --- | --- | --- | --- | --- | --- |
+| 订单与计划 | `SalesPlanningView.vue` | 销售订单 | 使用 `DocumentPaper`、`DocumentLineTable`、`DocumentArchiveActions` | `销售订单` | 已有预览、下载、重新生成、批量下载 |
+| 采购与库存 | `PurchaseOrderView.vue` | 采购订单 | 使用 `DocumentPaper`、`DocumentArchiveActions` | `采购订单` | 已有预览、下载、重新生成、批量下载 |
+| 采购与库存 | `PurchaseReceiptView.vue` | 到货入库单 | 使用 `DocumentPaper`、`DocumentArchiveActions` | `到货入库单` | 新增到货入库已纸质化 |
+| 采购与库存 | `QualityInspectionView.vue` | 质量校验单 | 使用 `DocumentPaper`、`DocumentLineTable`、`DocumentArchiveActions` | `质量校验单` | 质检放行弹窗仍需继续统一交互 |
+| 生产执行 | `ProductionLedgerView.vue` | 生产领料出库单 | 列表详情有 `DocumentArchiveActions` | `生产领料出库单` | 主要是归档入口,填单发生在仓库生产出库 |
+| 生产执行 | `ProductionLedgerView.vue` | 生产入库结算单 | 列表详情有 `DocumentArchiveActions` | `生产入库结算单` | 对应生产台账入库 |
+
+### 已套纸质外壳但仍有混用 UI
+
+| 模块 | 页面 | 单据 | 当前问题 | 优先级 |
+| --- | --- | --- | --- | --- |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 特殊入库单 / 特殊出库单 | 明细编辑区仍像现代卡片控件,和纸质单据割裂 | P0 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产出库单 | 已使用纸质外壳,但来源批次选择、产品/BOM信息仍需统一纸质表格语言 | P0 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产台账入库结算单 | 已有纸质外壳和摘要格,但三库联动字段、异常说明区域仍需与纸质单据模板对齐 | P0 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 生产入库单 / 返工入库单 | 结单区和摘要区仍有旧卡片感 | P1 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 销售出库单 | 已套纸质外壳,但销售订单关联、包装备注、发货明细区域需统一 | P1 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 原材料退货出库单、退货入库单、退货废料入库单、返工出库单 | 已套纸质外壳,但字段区仍有普通表单/表格痕迹 | P1 |
+| 嘉恒仓库 | `InventoryLedgerView.vue` | 期初入库、委外入库/出库、报废出库、售卖出库等通用分支 | 通用分支第一阶段只统一了生产余料/废料一部分,仍需逐个验收 | P1 |
+
+### 需要补充纸质化或确认是否作为单据
+
+| 模块 | 页面 | 业务 | 判断 | 优先级 |
+| --- | --- | --- | --- | --- |
+| 发货概览 | `DeliveryManagementView.vue` | 发货台账/发货明细 | 如果存在独立发货动作,应形成发货单;若发货统一走成品库销售出库,则只保留流水归档入口 | P1 |
+| 发货概览 | `ReturnManagementView.vue` | 退货/返工/废料处置 | 属于业务凭证,需要与退货库单据闭环统一 | P1 |
+| 发货概览 | `ScrapReworkView.vue` | 报废返工处理 | 若仍在使用,应按退货/返工处置单统一;若已被仓库/退货库替代,应清理或降级为台账 | P2 |
+| 生产执行 | `CompletionReceiptView.vue` | 成品入库 | 旧入口如果仍可用,需要和仓库生产入库/生产台账入库统一;如果已被新流程替代,应标记为旧入口 | P2 |
+| 嘉恒仓库 | `StocktakeDialog.vue` | 盘库单 | 盘库会改库存,应纳入纸质盘库单和 PDF 归档,但可排在特殊出入库之后 | P2 |
+
+## 推荐方案
+
+### 方案 A:继续逐页局部改造
+
+每个页面自己套 `DocumentPaper` 和单独 CSS。
+
+优点:
+
+- 单次改动小。
+- 速度快。
+
+缺点:
+
+- 很容易再次出现“仓库一套、采购一套、销售一套”。
+- 样式复制越来越多。
+- 后续 PDF、预览、下载、异常说明、签核栏会重复实现。
+
+结论:不推荐作为长期方案,只适合救急。
+
+### 方案 B:沉淀全系统单据底座,分批迁移
+
+把现在的 `DocumentPaper`、`DocumentGrid`、`DocumentLineTable`、`WarehouseDocumentFormShell` 抽象成全系统单据组件。仓库继续推进,但所有新样式都进入通用单据层。
+
+优点:
+
+- 风格统一。
+- 后续新增单据成本低。
+- 能保留现有业务逻辑,不需要一次性大重构。
+- 适合当前系统已经上线、仍在快速迭代的状态。
+
+缺点:
+
+- 第一批需要先做组件抽象和兼容层。
+- 每个单据仍要逐个检查字段和业务交互。
+
+结论:推荐。
+
+### 方案 C:一次性全系统重构
+
+一次把所有单据型页面、归档、PDF 重新设计和重写。
+
+优点:
+
+- 最终一致性最高。
+
+缺点:
+
+- 风险大。
+- 容易影响已经可用的采购、销售、仓库主流程。
+- 验收压力大。
+
+结论:当前不推荐。
+
+## 目标架构
+
+### 前端组件层
+
+保留现有组件并向通用命名演进:
+
+- `DocumentPaper`:纸张、标题、编号章、签核栏、留存联。
+- `DocumentGrid`:只读/展示型字段格。
+- `DocumentLineTable`:明细表。
+- `DocumentArchiveActions`:预览、下载、重新生成。
+
+新增或演进:
+
+- `DocumentFormShell`:全系统通用填单外壳,替代仓库专属 `WarehouseDocumentFormShell`。
+- `DocumentSection`:通用单据分区,替代仓库专属 `WarehouseDocumentSection`。
+- `DocumentActionBar`:通用底部操作区,替代仓库专属 `WarehouseDocumentActionBar`。
+- `DocumentField`:纸质输入格,承载 input、select、textarea、readonly。
+- `DocumentSelectorPanel`:纸质风格的下拉、多选、来源批次选择、关联订单选择。
+- `DocumentInlineSummary`:纸质风格的金额/数量/重量汇总条。
+- `DocumentSettlePanel`:结单、异常说明、偏差确认等正式确认区。
+
+兼容规则:
+
+- 第一阶段不删除 `WarehouseDocument*` 组件。
+- 新通用组件先复用当前纸质 CSS 变量和视觉语言。
+- 仓库页面逐步从 `warehouse-paper-*` 类迁移到 `document-paper-*` 类。
+- 老类名保留一段时间作为兼容,避免正在使用的仓库单据被打断。
+
+### 前端页面层
+
+每个单据页面遵循同一结构:
+
+1. `DocumentFormShell`
+2. 单据头:标题、单据编号、业务日期、公司/模块名。
+3. 基础信息区:客户/供应商/仓库/经办人/业务日期/关联单据。
+4. 明细区:物料/产品/批次/数量/重量/单价/金额。
+5. 辅助信息区:照片、运单号、运费、包装备注、用途、说明。
+6. 汇总区:数量、重量、金额、差异、异常说明。
+7. 签核区:制单、经办、审核、仓库/财务。
+8. 操作区:保存、保存并归档、归档状态动作。
+
+### 后端归档层
+
+继续使用现有 `document_archives` 表和统一路由:
+
+- `POST /document-archives/{document_type_key}/{business_id}/generate`
+- `GET /document-archives/{document_type_key}/{business_id}/latest/preview`
+- `GET /document-archives/{document_type_key}/{business_id}/latest/download`
+- `POST /document-archives/batch-download`
+
+现有支持的归档类型:
+
+- `销售订单`
+- `采购订单`
+- `到货入库单`
+- `质量校验单`
+- `生产领料出库单`
+- `生产入库结算单`
+- `仓库出入库单`
+
+新增归档类型只在确实不是现有类型能表达时添加。优先复用:
+
+- 普通仓库动作统一走 `仓库出入库单`。
+- 生产出库走 `生产领料出库单`。
+- 生产台账入库走 `生产入库结算单`。
+- 采购流程走 `采购订单 / 到货入库单 / 质量校验单`。
+- 销售下单走 `销售订单`。
+
+### PDF 规则
+
+PDF 是保存后的数据库事实快照,不从前端表单二次推导。
+
+PDF 必须遵守:
+
+- 不显示英文状态。
+- 不显示前端省略号。
+- 长文本完整换行,不超格。
+- 制单、经办人默认使用当前登录账号或后端记录的操作人。
+- 库存批次号使用业务认可的原材料库存批次号,不使用无业务意义的每库内部批次号。
+- PDF 样式和前端纸质单据属于同一视觉体系,但不要求像素完全一致。
+
+## 分期执行
+
+### 第 0 期:全系统清单和统一底座
+
+目标:
+
+- 固化本文档的单据清单。
+- 新增通用 `DocumentFormShell / DocumentSection / DocumentActionBar / DocumentField / DocumentSelectorPanel`。
+- 把仓库当前纸质样式抽象为通用 `document-paper-*`,保留 `warehouse-paper-*` 兼容层。
+
+验收:
+
+- 销售订单、采购订单、客料入库单视觉不退化。
+- 新通用组件有基础测试或源码断言。
+
+### 第 1 期:仓库 P0 单据
+
+目标:
+
+- 特殊入库 / 特殊出库。
+- 生产出库。
+- 生产台账入库结算单。
+
+原因:
+
+- 这些单据业务风险最高,且当前混用 UI 最明显。
+- 改完能沉淀“多行明细类单据”“生产闭环类单据”“异常说明类单据”三类模板。
+
+验收:
+
+- 不再出现普通卡片/普通表格突兀嵌在纸里。
+- 特殊出入库说明、明细行、调整前后数据完整显示。
+- 生产台账入库三库联动显示为一张结算单,不误写成只属于成品库。
+
+### 第 2 期:仓库 P1 单据
+
+目标:
+
+- 生产入库 / 返工入库。
+- 销售出库。
+- 原材料退货出库、退货入库、退货废料入库、返工出库。
+- 期初、委外、报废、售卖等通用分支。
+
+验收:
+
+- 6 大库所有出入库抽屉都统一纸质化。
+- 流水里 PDF 预览、下载、重新生成入口完整。
+
+### 第 3 期:采购、销售、质检细节统一
+
+目标:
+
+- 销售订单、采购订单、到货入库、质量校验页面继续消除残留普通控件。
+- 关联销售订单、采购明细、质检备注弹窗等改成统一纸质选择/说明面板。
+
+验收:
+
+- 已有 PDF 归档能力不回退。
+- 纸质字段、明细表、按钮区和仓库单据保持同一套视觉语言。
+
+### 第 4 期:发货、退货、返工闭环
+
+目标:
+
+- 发货台账按销售订单聚合后的明细留档入口统一。
+- 退货、返工、废料处置相关页面和退货库单据闭环。
+- 若旧页面被新仓库流程替代,则标记为只读台账或移除入口,避免双流程。
+
+验收:
+
+- 用户能从销售订单、发货台账、退货库流水追溯到同一套 PDF 单据。
+
+### 第 5 期:盘库与批量导出
+
+目标:
+
+- 盘库单纸质化和 PDF 归档。
+- 各业务台账按时间/筛选条件批量导出单据或流水 Excel。
+
+验收:
+
+- 盘库调整说明进入 PDF。
+- Excel 导出不使用省略号,长字段完整输出。
+
+## 测试策略
+
+### 前端测试
+
+每批至少增加源码断言或组件测试:
+
+- 单据页面使用通用 `DocumentFormShell` 或兼容的纸质单据组件。
+- 不在纸质单据主体中裸露旧 `form-field / double-field / triple-field / workflow-tip` 作为主要布局。
+- 归档按钮使用 `DocumentArchiveActions`。
+- 保存按钮位于单据底部操作区,不悬在单据中间。
+
+### 后端测试
+
+继续沿用现有归档测试风格:
+
+- 归档生成成功写入 `document_archives`。
+- PDF 文件以 `%PDF` 开头。
+- 归档失败不阻断业务保存。
+- 列表返回最新 PDF 归档状态。
+- 不同业务类型映射到正确 `document_type`。
+
+### 浏览器验收
+
+每批至少手动/浏览器验证:
+
+- 典型桌面宽度。
+- 当前内置浏览器窄视口。
+- 单据可滚动、按钮位置合理。
+- 长文本不挤坏单据。
+- PDF 预览/下载入口可见。
+
+## 设计约束
+
+- 纸质化是表现层和归档层升级,不借机删字段。
+- 不改变现有业务计算和提交语义。
+- 不把主数据维护表单改成纸质单据。
+- 不把 PDF 归档失败作为库存/订单保存失败。
+- 不新增英文状态、英文备注或英文系统标志。
+- 不在 PDF 中使用省略号。
+- 不把仓库特有样式继续扩散到全系统,新增能力进入通用 `documentForms`。
+
+## 下一步推荐
+
+推荐进入第 0 期 + 第 1 期合并执行:
+
+1. 先抽象通用单据底座,保留现有仓库兼容层。
+2. 接着改 `特殊入库 / 特殊出库`。
+3. 再改 `生产出库`。
+4. 再改 `生产台账入库结算单`。
+
+这样能最快解决用户当前肉眼最不舒服的仓库混 UI 问题,同时保证做出来的能力可以继续给采购、销售、质检、发货复用。
+
+## 自检
+
+- 无占位项。
+- 已明确哪些页面纳入,哪些页面不纳入。
+- 已避免把仓库纸质化做成孤岛。
+- 已给出分期和优先级。
+- 已保持“先视觉/交互统一,不改变业务逻辑”的边界。
diff --git a/frontend/src/components/documentForms/DocumentActionBar.vue b/frontend/src/components/documentForms/DocumentActionBar.vue
new file mode 100644
index 0000000..f3406a8
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentActionBar.vue
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentField.vue b/frontend/src/components/documentForms/DocumentField.vue
new file mode 100644
index 0000000..307778f
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentField.vue
@@ -0,0 +1,55 @@
+
+
+ {{ label }}
+
+ {{ value || "-" }}
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentFormShell.vue b/frontend/src/components/documentForms/DocumentFormShell.vue
new file mode 100644
index 0000000..718a35f
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentFormShell.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentInlineSummary.vue b/frontend/src/components/documentForms/DocumentInlineSummary.vue
new file mode 100644
index 0000000..30e42d0
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentInlineSummary.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentPaper.vue b/frontend/src/components/documentForms/DocumentPaper.vue
index 92baf5b..efb60ea 100644
--- a/frontend/src/components/documentForms/DocumentPaper.vue
+++ b/frontend/src/components/documentForms/DocumentPaper.vue
@@ -43,7 +43,11 @@
-
+
diff --git a/frontend/src/components/documentForms/DocumentSection.vue b/frontend/src/components/documentForms/DocumentSection.vue
new file mode 100644
index 0000000..6ed3eb7
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentSection.vue
@@ -0,0 +1,25 @@
+
+
+
+ {{ index }}
+ {{ title }}
+
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentSelectorPanel.vue b/frontend/src/components/documentForms/DocumentSelectorPanel.vue
new file mode 100644
index 0000000..9fedc31
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentSelectorPanel.vue
@@ -0,0 +1,24 @@
+
+
+
+ {{ label }}
+ {{ hint }}
+
+
+
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/DocumentSettlePanel.vue b/frontend/src/components/documentForms/DocumentSettlePanel.vue
new file mode 100644
index 0000000..aca9e27
--- /dev/null
+++ b/frontend/src/components/documentForms/DocumentSettlePanel.vue
@@ -0,0 +1,5 @@
+
+
+
diff --git a/frontend/src/components/documentForms/WarehouseDocumentActionBar.vue b/frontend/src/components/documentForms/WarehouseDocumentActionBar.vue
index f7a903b..a094193 100644
--- a/frontend/src/components/documentForms/WarehouseDocumentActionBar.vue
+++ b/frontend/src/components/documentForms/WarehouseDocumentActionBar.vue
@@ -1,47 +1,12 @@
-
-
-
-
-
+
+
+
+
+
+
diff --git a/frontend/src/components/documentForms/WarehouseDocumentFormShell.vue b/frontend/src/components/documentForms/WarehouseDocumentFormShell.vue
index d91c1c4..eacc97a 100644
--- a/frontend/src/components/documentForms/WarehouseDocumentFormShell.vue
+++ b/frontend/src/components/documentForms/WarehouseDocumentFormShell.vue
@@ -1,32 +1,23 @@
-
+
+
+
diff --git a/frontend/src/components/documentForms/WarehouseDocumentSection.vue b/frontend/src/components/documentForms/WarehouseDocumentSection.vue
index bec8dc5..86111ee 100644
--- a/frontend/src/components/documentForms/WarehouseDocumentSection.vue
+++ b/frontend/src/components/documentForms/WarehouseDocumentSection.vue
@@ -1,17 +1,16 @@
-
-
- {{ index }}
- {{ title }}
-
-
-
-
-
-
+
+
+