# 资金概览 — 技术方案

> **依据：** 《资金概览功能需求.md》v1.0  
> **关联：** 平台《账务管理.md》v1.0、《提现审核功能需求》v1.0、《提现审核技术方案》v1.0；商家《提现管理功能需求》v1.0、《提现管理技术方案》v1.0、《账户管理功能需求》v1.0、《账户管理技术方案》v1.0；《关联需求分析.md》v1.6、《商家端店铺上下文接口说明》  
> **范围：** 商家端 **财务中心 · 资金概览** — **账户概览**（只读）与 **收支概况流水**（只读分页）；**不含** 写余额/冻结、提现、账户维护。  
> **原则：** `X-Shop-Id` 隔离；**纯查询**；指标 **实时汇总**；流水 **只读**。

---

## 1. 技术架构

| 项 | 选型 |
|----|------|
| 基础框架 | RuoYi **v3.9.2**（`springboot2` 分支） |
| 数据库 | **MySQL 5.7.39**；读 **`biz_shop_wallet`**、**`biz_shop_fund_log`**、**`biz_order`**、**`biz_shop_pay_account`** |
| ORM / 权限 / 响应 | MyBatis；`@PreAuthorize`；`AjaxResult` / `TableDataInfo` |
| 店铺上下文 | `SellerShopContext` + 请求头 **`X-Shop-Id`** |
| 金额 | `BigDecimal`；两位小数 |

### 1.1 与兄弟模块边界

| 维度 | **本模块 · 资金概览** | 提现管理 | 账户管理 | 订单链 |
|------|----------------------|----------|----------|--------|
| 路径 | `/agri/seller/finance/overview` | `/withdraw` | `/payAccount` | C 端 confirmReceive |
| 写操作 | **无** | submit | CRUD | settleOrder |
| 概览余额/冻结 | 读 wallet | 写 wallet | — | 写 wallet（结算） |
| 待结算 | 读 order 汇总 | — | — | 订单状态驱动 |
| 流水 | 读 fund_log | 写（余额提现） | — | 写（订单收支） |
| 银行卡数 | 读 pay_account | — | 写 | — |

### 1.2 数据流与写入来源（只读展示）

```text
【上游写入 · 非本模块】
    订单 confirmReceive → settleOrder
        → fund_log（1 订单收支）；wallet.available ↑
    提现 submit → fund_log（2 余额提现）；wallet 余额↓ 冻结↑
    平台审核 → fund_log（3 提现驳回 / 4 提现完成）；wallet 调整

【待结算 · 不落库】
    SUM(biz_order.pay_amount) WHERE 已支付 AND 待发货/已发货

【本模块 · 只读】
    GET /summary → wallet + 待结算 + countBank + username
    GET /logs    → fund_log 分页，enrich changeReasonText
```

> 详见平台《账务管理.md》：订单与提现 **无表级绑定**；流水 `biz_no` = 订单号/提现编号。

### 1.3 模块落位

**文档目录：** `doc/店铺后台/财务中心/资金概览/`  
**菜单：** 财务中心 → 资金概览（`menu_id=6610`）  
**后端包：** `com.ruoyi.web.modules.finance`

```text
finance/
├── controller/SellerFundOverviewController.java    # 本模块入口
├── service/IShopFundService.java                 # getOverviewSummary / listFundLogs
├── service/impl/ShopFundServiceImpl.java
├── vo/FundOverviewSummaryVO.java
├── vo/FundLogListRowVO.java
├── mapper/BizShopWalletMapper.java               # selectByShopId
├── mapper/BizShopFundLogMapper.java              # selectByShopId
├── mapper/BizShopPayAccountMapper.java           # countBankByShopId
order/mapper/BizOrderMapper.java                  # sumPendingSettleByShopId
├── support/FinanceSupport.java                   # changeReason 文案
resources/mapper/finance/*.xml

sql/biz_shop_finance.sql
sql/biz_shop_finance_menu.sql                     # 6610
```

**前端（建议）：**

| 项 | 值 |
|----|-----|
| 页面 | `ruoyi-ui/src/views/agri/seller/finance/overview/index.vue` |
| API | `ruoyi-ui/src/api/agri/seller/finance/overview.js` |
| 展示格式 | §3.4「变更值+变更后」由 **前端** 格式化 |

---

## 2. 数据库设计

**权威 DDL：** [`sql/biz_shop_finance.sql`](../../../../sql/biz_shop_finance.sql)

本模块 **不建表**；**只读** 下列表。

### 2.1 店铺钱包 `biz_shop_wallet`（概览 · 余额/冻结）

| 字段 | 概览用途 |
|------|----------|
| shop_id | **= X-Shop-Id** |
| available_balance | **可用店铺余额**；无记录 → `0.00` |
| frozen_amount | **冻结金额**；无记录 → `0.00` |

### 2.2 订单 `biz_order`（概览 · 待结算）

**待结算（实时 SQL，不落 wallet）：**

```sql
SELECT IFNULL(SUM(pay_amount), 0)
FROM biz_order
WHERE shop_id = #{shopId}
  AND pay_status = '1'
  AND order_status IN ('1', '2')   -- 待发货、已发货
  AND del_flag = '0'
```

| 口径 | 需求规则 |
|------|----------|
| 计入 | 已支付 + 待发货/已发货 |
| 不计入 | 待支付、已完成、已关闭 |
| 与流水 | **无** 待结算流水；确认收货后写 **订单收支** |

### 2.3 资金流水 `biz_shop_fund_log`（收支概况列表）

| 字段 | 列表用途 |
|------|----------|
| shop_id | 过滤当前店铺 |
| shop_name | 店铺名称列 |
| biz_no | 业务编号（订单号/提现编号） |
| change_reason | 变动原因码 → 文案 |
| balance_change / balance_after | 变动余额 |
| frozen_change / frozen_after | 变动冻结 |
| create_time | 变动时间；**倒序** |

**变动原因枚举：**

| change_reason | 文案 | 写入方 |
|---------------|------|--------|
| `1` | 订单收支 | `settleOrder` |
| `2` | 余额提现 | 提现 submit |
| `3` | 提现驳回 | 平台 reject |
| `4` | 提现完成 | 平台 approve |

**索引：** `idx_shop_time (shop_id, create_time)`。

### 2.4 收款账户 `biz_shop_pay_account`（概览 · 银行卡数）

| 统计 | SQL 条件 |
|------|----------|
| bankAccountCount | `shop_id` + `del_flag='0'` + `account_type='1'` |

> **不含** 支付宝/微信（FIN-A9）。

---

## 3. 接口设计

**基路径：** `/agri/seller/finance/overview`  
**上下文：** 请求头 **`X-Shop-Id`** 必填  
**写接口：** **无**

### 3.1 接口一览

| 方法 | 路径 | 权限 | 说明 |
|------|------|------|------|
| GET | `/summary` | `agri:seller:finance:overview:query` | 账户概览四块 |
| GET | `/logs` | `agri:seller:finance:overview:query` | 收支流水分页 |

### 3.2 概览 `GET /summary`

**响应 data（FundOverviewSummaryVO）：**

| 字段 | 来源 | 说明 |
|------|------|------|
| availableBalance | `biz_shop_wallet` | 可用店铺余额 |
| pendingSettleAmount | `biz_order` 汇总 | 待结算金额 |
| frozenAmount | `biz_shop_wallet` | 冻结金额 |
| username | 当前登录用户 `getUsername()` | 账户信息 · 用户名 |
| bankAccountCount | `biz_shop_pay_account` | 银行卡条数 |

**无 wallet 行时：** `availableBalance`、`frozenAmount` 返回 `0.00`。

### 3.3 收支流水 `GET /logs`

**Query：** `pageNum`, `pageSize`（**无** 筛选参数，非本期）。

**固定条件：** `shop_id = requireShopId()`；`ORDER BY create_time DESC, log_id DESC`。

**行 VO（FundLogListRowVO）：**

| 字段 | 说明 |
|------|------|
| shopName | 店铺名称 |
| changeTime | 变动时间 |
| bizNo | 业务编号 |
| changeReason / changeReasonText | 原因码 + 文案 |
| balanceChange / balanceAfter | 余额变动及变动后 |
| frozenChange / frozenAfter | 冻结变动及变动后 |

**前端展示（需求 §3.4，非后端字段）：**

```text
变动余额：{±balanceChange}（余额：{balanceAfter}）
变动冻结：{±frozenChange}（冻结：{frozenAfter}）
不变侧展示 0 或 —
```

### 3.4 与提现管理 `/balance` 的区别

| 接口 | 返回 | 用途 |
|------|------|------|
| `/overview/summary` | 余额+待结算+冻结+账户信息 | 概览页 |
| `/withdraw/balance` | 仅 availableBalance | 提现提交页辅助 |

口径 **一致**（均读 `biz_shop_wallet.available_balance`）。

---

## 4. 业务规则（实现）

| 编号 | 需求规则 | 实现要点 |
|------|----------|----------|
| FIN-A1 | 只读 | Controller **仅 GET** |
| FIN-A2 | 仅当前店铺 | 全查询带 `shop_id` |
| FIN-A3 | 待结算口径 | `sumPendingSettleByShopId` |
| FIN-A4 | 订单收支时点 | **不写**；由 `settleOrder` 产生 log |
| FIN-A5 | 支付不增余额 | 待结算 **只读 order** |
| FIN-A6 | 提现流水成对 | 本模块 **只展示** 2/3/4 类 log |
| FIN-A7 | 四类原因文案 | `FinanceSupport.toChangeReasonText` |
| FIN-A8 | 变更值+变更后 | 后端返原始 decimal；**前端格式化** |
| FIN-A9 | 仅统计银行卡 | `countBankByShopId` |
| FIN-A11 | 时间倒序 | SQL + PageHelper |

---

## 5. 权限与菜单

| 权限 | 说明 |
|------|------|
| `agri:seller:finance:overview:query` | 概览 + 流水（**无** 分写权限） |

菜单：**财务中心 → 资金概览**（`parent_id=6600`，`menu_id=6610`，`path=overview`）。  
脚本：[`sql/biz_shop_finance_menu.sql`](../../../../sql/biz_shop_finance_menu.sql)。

---

## 6. 测试要点

| 编号 | 场景 | 预期 |
|------|------|------|
| T1 | summary shop 隔离 | 仅本店 wallet/order/count |
| T2 | 无 wallet | 余额/冻结为 0 |
| T3 | 待发货订单 | pendingSettleAmount 含 pay_amount |
| T4 | 确认收货后 | 订单收支 log；待结算减少 |
| T5 | 提现 submit 后 | 余额提现 log；frozen 增 |
| T6 | logs 分页倒序 | 最新在前 |
| T7 | changeReasonText | 四类文案正确 |
| T8 | bankAccountCount | 仅 type=1 未删 |

**建议测试类：** `ShopFundServiceImplTest`（summary/logs）、`SellerFundOverviewControllerTest`（MockMvc）。

---

## 7. 实现状态

| 项 | 状态 |
|----|------|
| DDL（wallet / fund_log） | **已有** |
| `SellerFundOverviewController` / `ShopFundServiceImpl` | **已实现** |
| `BizOrderMapper.sumPendingSettleByShopId` | **已实现** |
| 菜单 SQL 6610 | **已有** |
| ruoyi-ui 资金概览页 | **待建** |
| 流水筛选 / 导出 / 下钻 | **非本期** |

---

## 8. 版本记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版：对齐《资金概览功能需求》v1.0；关联账务/提现/账户/订单链；简练 DB/接口设计 |

---

*文档版本：v1.0 · 依据《资金概览功能需求.md》v1.0*
