# 库存日志 — 前端技术方案

> **依据：** 《库存日志功能需求.md》v1.0、《库存日志技术方案.md》v1.0  
> **前端规范：** `doc/前端设计/前端设计.md`  
> **范围：** 仅 **ruoyi-ui 商家端** 当前店铺库存变化流水 **只读列表**、方向 Tab 筛选、关键词检索；**不含** 写入/编辑/删除、详情页、导出、平台端。  
> **实现状态：** `index.vue`、`api/agri/seller/stock/log.js` **已按 v1.0 落地**；待菜单配置及 `/agri/seller/stock/log` 联调。

---

## 1. 技术栈与写法约定

| 项 | 说明 |
|----|------|
| 框架 | Vue 2 + Element UI |
| 请求 | `@/utils/request` + `sellerShopHeaders()` 携带 **`X-Shop-Id`** |
| 参考页面 | `agri/seller/stock/inbound/index.vue`（检索+页签+列表）、`agri/seller/aftersale/index.vue`（Tab 方向筛选） |
| 布局 | 检索 `el-card` + `<br/>` + 列表 `el-card` + `border` 表格 |
| 店铺切换 | **仅 Navbar**；业务页禁止展示店铺选择器 |

---

## 2. 业务要点（前端需体现）

| 项 | 说明 |
|----|------|
| 只读 | **无** 创建/编辑/删除/跳转单据；日志由入/出库、调整、订单等模块写入 |
| 方向 Tab | 全部 / 入库（`direction=1`）/ 出库（`direction=2`） |
| 关键词 | 模糊匹配 **商品名称**、**商品规格** |
| 「操作」列 | 展示 **变化原因** 文案（`changeReasonText`），**非** 业务按钮 |
| 变化量 | 非负整数展示；**删除产品规格** 可能为 **0** |
| 排序 | 后端固定 **操作时间倒序** |
| 勾选列 | **预留** 导出等非本期能力；**无** 批量操作 |

---

## 3. 文件清单

| 类型 | 路径 | 说明 |
|------|------|------|
| 列表页 | `ruoyi-ui/src/views/agri/seller/stock/log/index.vue` | 关键词检索、方向 Tab、表格、分页 |
| 日志 API | `ruoyi-ui/src/api/agri/seller/stock/log.js` | list（只读） |
| 店铺上下文 | `api/agri/seller/context.js` + `utils/sellerShop.js` | X-Shop-Id |

**组件 name（keep-alive）：** `AgriSellerStockLog`

**不提供：** 详情抽屉、入/出库跳转、导出、时间区间筛选、变化原因下拉。

---

## 4. 菜单与路由

| 菜单名称 | 组件路径 | 路由 path（建议） | 权限标识 |
|----------|----------|-------------------|----------|
| 库存日志 | `agri/seller/stock/log/index` | `seller/stock/log` | `agri:seller:stock:log:list` |

**上级菜单：** 店铺经营管理端 → **库存管理**

| 按钮权限 | 标识 | 说明 |
|----------|------|------|
| 列表查看 | `agri:seller:stock:log:list` | 进入页面、GET /list |

---

## 5. 页面结构（与代码一致）

```text
库存日志 index.vue
├── 检索区 search-card（v-show 受 right-toolbar 控制）
│   ├── 关键词 keyword（商品名称/规格模糊，Enter 或搜索图标）
│   └── 重置
├── 列表区 table-card
│   ├── 方向页签 directionTab：全部(all) | 入库(1) | 出库(2)
│   ├── right-toolbar
│   ├── el-table border（empty-text 动态）
│   │   ├── selection（预留，无批量操作）
│   │   ├── 商品名称（ID + 名称快照）
│   │   ├── 商品规格 specText（空则 —）
│   │   ├── 变化前库存 stockBefore
│   │   ├── 变化后库存 stockAfter
│   │   ├── 变化量 changeQty
│   │   ├── 操作 → changeReasonText（变化原因）
│   │   └── 操作时间 createTime
│   └── pagination
```

---

## 6. 变化原因展示（操作列）

后端 `StockSupport.changeReasonText` 返回完整文案；前端仅对 **`ORDER_CANCEL`** 简写为 **「取消订单返库」**（对齐需求 §3.3 UI 说明）。

| code | 典型文案 |
|------|----------|
| `NEW_SPEC` | 新增商品规格 |
| `PURCHASE_IN` | 采购入库 |
| `RETURN_IN` | 退货入库 |
| `OTHER_IN` | 其他入库 |
| `ORDER_CANCEL` | 取消订单返库（前端简写） |
| `STOCK_EDIT` | 库存编辑 |
| `ORDER_DEDUCT` | 下单扣减库存 |
| `DELETE_SPEC` | 删除产品规格 |
| `MANUAL_ORDER_OUT` | 订单出库 |
| `EXPIRED_OUT` | 过期出库 |
| `OTHER_OUT` | 其他出库 |

---

## 7. 店铺上下文（X-Shop-Id）

| 步骤 | 说明 |
|------|------|
| `created` | `GET /agri/seller/context` → `setSellerShopContext` |
| GET /list | `sellerShopHeaders()` |
| Navbar 切店 | `location.reload()` 整页刷新 |

---

## 8. API 封装

**模块：** `@/api/agri/seller/stock/log.js`

| 方法 | HTTP | 路径 | 权限 |
|------|------|------|------|
| `listSellerStockLog` | GET | `/list` | list |

**Query：** `pageNum`、`pageSize`、`keyword`、`direction`（空=全部，`1`=入库，`2`=出库）。

**Row 字段：** `logId`、`goodsId`、`goodsName`、`specText`、`stockBefore`、`stockAfter`、`changeQty`、`direction`、`changeReason`、`changeReasonText`、`createTime`。

---

## 9. 空状态

| 场景 | 文案 |
|------|------|
| 无流水 | 「暂无库存日志」 |
| 有筛选无结果 | 「未找到符合条件的库存日志」 |

---

## 10. 与兄弟模块边界（前端）

| 模块 | 关系 |
|------|------|
| **商品入库 / 出库** | 确认后写入日志；本页只读展示 |
| **库存调整** | 库存编辑写入日志；本页只读 |
| **库存查询** | 按商品查明细复用同源 `biz_stock_log`；本页为 **全店时间序** |
| **全部订单** | 支付扣减、关单回滚经后端写日志；**非本期** 从日志行跳转订单 |

---

## 11. 联调检查清单

- [ ] 菜单挂载 `agri/seller/stock/log/index`
- [ ] 列表默认按操作时间倒序，仅当前店铺
- [ ] Tab：全部 / 入库 / 出库 与 `direction` 联动
- [ ] 关键词：商品名称、规格组合过滤
- [ ] 「操作」列展示变化原因，无点击行为
- [ ] 勾选列可见但无批量按钮
- [ ] Navbar 切店后列表刷新

---

## 12. 版本记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版：只读列表、方向 Tab、关键词检索、API 封装；对齐需求 v1.0 与 UI 稿 |

---

*文档版本：v1.0 · 依据《库存日志功能需求.md》v1.0、《库存日志技术方案.md》v1.0*
