# 提现汇总 — 技术方案

> **依据：** 《提现汇总功能需求.md》v1.0  
> **关联：** 平台《账务管理.md》v1.0、《提现审核功能需求》v1.0、《提现审核技术方案》v1.0、《资金概览功能需求》v1.0、《资金概览技术方案》v1.0；商家《提现管理功能需求》v1.0、《提现管理技术方案》v1.0、《账户管理功能需求》v1.0；《关联需求分析.md》v1.6  
> **范围：** 平台端 **财务管理 · 提现汇总** — **按店汇总列表**、**单店提现明细**（只读）；**不含** 提现审核、商家提交、账户维护。  
> **原则：** **全平台** 可见；**纯查询**；汇总/明细与 **提现审核、商家提现记录** **同源同口径**。

---

## 1. 技术架构

| 项 | 选型 |
|----|------|
| 基础框架 | RuoYi **v3.9.2**（`springboot2` 分支） |
| 数据库 | **MySQL 5.7.39**；读 **`biz_shop_withdraw`**、**`biz_shop`** |
| ORM / 权限 / 响应 | MyBatis；`@PreAuthorize`；`AjaxResult` / `TableDataInfo` |
| 店铺上下文 | **无** `X-Shop-Id`（平台端全平台） |
| 金额 | `BigDecimal`；两位小数 |

### 1.1 与兄弟模块边界

| 维度 | **本模块 · 提现汇总** | 平台 · 提现审核 | 商家 · 提现管理 | 平台 · 资金概览 |
|------|----------------------|-----------------|-----------------|-----------------|
| 路径 | `/agri/finance/withdrawSummary` | `/withdrawAudit` | `/agri/seller/finance/withdraw` | `/fundOverview` |
| 写操作 | **无** | approve/reject | submit | **无** |
| 列表形态 | **按店汇总** + 单店明细 | **全平台逐单** | **单店逐单** | 余额/冻结排行 |
| 汇总列 | 已提现 / 待审核 | **无** | **无** | **无** |
| 数据源 | `biz_shop_withdraw` | 同左 | 同左 | wallet / order / log |

### 1.2 数据流（只读展示）

```text
【上游写入 · 非本模块】
    商家 POST /withdraw/submit → biz_shop_withdraw（status=1 待审核）
    平台 PUT /withdrawAudit/approve|reject → status=3|2

【本模块 · 只读】
    GET /shops   → biz_shop LEFT JOIN 按店 SUM(withdraw)
    GET /details → biz_shop_withdraw WHERE shop_id = ?（分页+检索）
```

> 汇总 **不缓存**；随 **提现审核** 结果 **实时** 变化。详见《账务管理.md》：**已提现** = 完成态单据；**待审核** = 待审态单据。

### 1.3 模块落位

**文档目录：** `doc/平台后台/财务管理/提现汇总/`  
**菜单：** 财务管理 → 提现汇总（建议 `menu_id=7630`，`parent_id=7600`）  
**后端包：** `com.ruoyi.web.modules.finance`

```text
finance/
├── controller/PlatformWithdrawSummaryController.java   # 本模块入口
├── service/IShopFundService.java                       # 扩展汇总/明细方法
├── service/impl/ShopFundServiceImpl.java
├── dto/PlatformWithdrawSummaryQuery.java
├── dto/PlatformWithdrawSummaryDetailQuery.java
├── vo/PlatformWithdrawSummaryRowVO.java
├── vo/PlatformWithdrawSummaryDetailRowVO.java
├── mapper/BizShopWithdrawMapper.java                   # 扩展汇总/明细 SQL
├── support/FinanceSupport.java                         # 状态/账号文案
resources/mapper/finance/BizShopWithdrawMapper.xml

sql/biz_shop_finance.sql                                # 已有，本模块不增表
sql/biz_platform_withdraw_summary_menu.sql              # 7630 菜单与权限
```

**前端（建议）：**

| 项 | 值 |
|----|-----|
| 页面 | `ruoyi-ui/src/views/agri/finance/withdrawSummary/index.vue` |
| API | `ruoyi-ui/src/api/agri/finance/withdrawSummary.js` |
| 明细弹窗 | 汇总行「查看提现明细」→ 抽屉调 `/details?shopId=` |

---

## 2. 数据库设计

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

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

### 2.1 提现单 `biz_shop_withdraw`（汇总 + 明细）

| 字段 | 用途 |
|------|------|
| shop_id | 按店汇总、明细过滤 |
| shop_name | 明细 **店铺名称** 列（申请快照；汇总列表 **优先** 读 `biz_shop` 当前名） |
| withdraw_amount | 汇总 **求和**、明细 **展示** |
| withdraw_status | `1`待审核 `2`审核不通过 `3`提现完成 |
| apply_time | 明细 **申请时间**；检索、排序 |
| account_type / account_real_name / account_no_mask | 明细 **提现账号** 摘要 |
| remark | 商家备注 |
| process_remark | **提现处理说明** |

**状态常量（`FinanceConstants`）：**

| withdraw_status | 文案 | 计入已提现 | 计入待审核 |
|-----------------|------|------------|------------|
| `1` | 待审核 | 否 | **是** |
| `2` | 审核不通过 | 否 | 否 |
| `3` | 提现完成 | **是** | 否 |

**索引（已有）：** `idx_shop_status_time (shop_id, withdraw_status, apply_time)`、`idx_status_time (withdraw_status, apply_time)` — 满足按店聚合与明细检索。

### 2.2 店铺 `biz_shop`（汇总 · 展示）

| 字段 | 用途 |
|------|------|
| shop_id | 主键 |
| shop_name | 汇总 **店铺名称**；明细检索 **店名** 过滤（汇总列表） |
| shop_avatar | 汇总 **店铺 LOGO** |
| shop_status | `0` 开业 / `1` 停业 |
| del_flag | `0` 正常；`2` 逻辑删除 |

**汇总数据范围：**

```sql
-- 纳入：未删店（含从未提现，金额展示 0）
-- 追加：已逻辑删除 且 存在提现单
WHERE s.del_flag = '0'
   OR EXISTS (SELECT 1 FROM biz_shop_withdraw wd WHERE wd.shop_id = s.shop_id LIMIT 1)
```

### 2.3 按店汇总 SQL 骨架

```sql
SELECT s.shop_id,
       s.shop_name,
       s.shop_avatar,
       s.shop_status,
       s.del_flag,
       IFNULL(wd.withdrawn_amount, 0)     AS withdrawnAmount,
       IFNULL(wd.pending_audit_amount, 0) AS pendingAuditAmount
FROM biz_shop s
LEFT JOIN (
    SELECT shop_id,
           SUM(CASE WHEN withdraw_status = '3' THEN withdraw_amount ELSE 0 END) AS withdrawn_amount,
           SUM(CASE WHEN withdraw_status = '1' THEN withdraw_amount ELSE 0 END) AS pending_audit_amount
    FROM biz_shop_withdraw
    GROUP BY shop_id
) wd ON wd.shop_id = s.shop_id
WHERE (s.del_flag = '0' OR wd.shop_id IS NOT NULL)
  /* 可选：AND s.shop_name LIKE ... */
ORDER BY pending_audit_amount DESC, s.shop_id DESC
```

> **验收（WS-A3/A4）：** 单店 `withdrawnAmount` = 该店 `withdraw_status='3'` 的 `SUM(withdraw_amount)`；`pendingAuditAmount` 同理 `status='1'`。

### 2.4 单店明细 SQL 骨架

```sql
SELECT apply_time,
       shop_name,
       account_type, account_real_name, account_no_mask,
       withdraw_amount, remark, withdraw_status, process_remark
FROM biz_shop_withdraw
WHERE shop_id = #{shopId}
  /* 可选：withdraw_status、apply_time 区间 */
ORDER BY apply_time DESC, withdraw_id DESC
```

> 与 **`selectSellerList`**（商家提现记录）、**`selectPlatformList`**（提现审核）**同一数据源**；本接口 **固定** `shop_id`。

---

## 3. 接口设计

**基路径：** `/agri/finance/withdrawSummary`  
**上下文：** **无** 店铺请求头  
**写接口：** **无**

### 3.1 接口一览

| 方法 | 路径 | 权限 | 说明 |
|------|------|------|------|
| GET | `/shops` | `agri:finance:withdrawSummary:summary` | 店铺提现汇总（分页） |
| GET | `/details` | `agri:finance:withdrawSummary:detail` | 单店提现明细（分页） |

> v1 可合并为 `agri:finance:withdrawSummary:query`；需求允许 **分权**（§8）。

### 3.2 店铺提现汇总 `GET /shops`

**Query（PlatformWithdrawSummaryQuery）：**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |
| shopName | string | 否 | 店铺名称 **模糊** |

**定稿默认排序：** `pendingAuditAmount DESC, shopId DESC`（待审核金额降序，便于运营优先关注）。

**行 VO（PlatformWithdrawSummaryRowVO）：**

| 字段 | 来源 | 说明 |
|------|------|------|
| shopId | `biz_shop` | 下钻明细时传入 |
| shopName | `biz_shop.shop_name` | 当前店名 |
| shopAvatar | `biz_shop.shop_avatar` | LOGO |
| shopStatus | `biz_shop.shop_status` | `0`/`1` |
| shopStatusText | 服务层 | 开业/停业/已删除 |
| deleted | 服务层 | `del_flag='2'` |
| withdrawnAmount | SUM withdraw `status=3` | **已提现金额** |
| pendingAuditAmount | SUM withdraw `status=1` | **待审核金额** |

**无提现记录店：** 两金额返回 `0.00`（WS-A11）。

### 3.3 提现明细 `GET /details`

**Query（PlatformWithdrawSummaryDetailQuery）：**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| pageNum | int | 是 | 页码 |
| pageSize | int | 是 | 每页条数 |
| shopId | long | **是** | 汇总行传入；**固定单店** |
| withdrawStatus | string | 否 | `1`/`2`/`3`；空=全部 |
| beginApplyTime | date | 否 | 申请时间起（含 `00:00:00`） |
| endApplyTime | date | 否 | 申请时间止（含 `23:59:59`） |

**固定排序：** `apply_time DESC, withdraw_id DESC`。

**行 VO（PlatformWithdrawSummaryDetailRowVO）：**

| 字段 | 说明 |
|------|------|
| applyTime | 申请时间 |
| shopName | 店铺名称（快照） |
| accountSummary | 提现账号摘要（`FinanceSupport.buildAccountSummary`） |
| withdrawAmount | 提现金额 |
| remark | 商家备注 |
| withdrawStatus / withdrawStatusText | 状态码 + 文案 |
| processRemark | 提现处理说明；待审核为 **null** 或 **—**（前端） |

**与提现审核列表差异：**

| 字段 | 提现审核 `/withdrawAudit/list` | 本模块 `/details` |
|------|----------------------------------|-------------------|
| withdrawNo | **有** | **非本期**（需求 §10） |
| withdrawId / 操作 | **有** | **无** |
| shopId 过滤 | 全平台 | **必填** |

**与商家 `/withdraw/list` 对账：** 同一 `shopId` + 相同筛选条件下，**申请时间、金额、状态、处理说明、账号摘要** **须一致**（WS-A6）。

### 3.4 与兄弟接口对照

| 能力 | 本模块 | 提现审核 | 商家提现管理 |
|------|--------|----------|--------------|
| 按店已提现/待审 | `/shops` | — | — |
| 全平台逐单 | — | `/list` | — |
| 单店逐单 | `/details` | — | `/list` |
| 审核 | — | `/approve` `/reject` | — |
| 提交 | — | — | `/submit` |

---

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

| 编号 | 需求规则 | 实现要点 |
|------|----------|----------|
| WS-A1 | 只读 | Controller **仅 GET** |
| WS-A2 | 全平台 | `/shops` **无** shopId 限制 |
| WS-A3 | 已提现 = 完成态之和 | SQL `CASE status='3'` |
| WS-A4 | 待审核 = 待审态之和 | SQL `CASE status='1'` |
| WS-A5 | 驳回不计入汇总 | 聚合 **不含** `status='2'` |
| WS-A6 | 明细与审核/商家一致 | 复用 enrich 逻辑（账号/状态文案） |
| WS-A7 | 店名/LOGO 读 shop | 汇总 JOIN `biz_shop` |
| WS-A8 | 明细检索 | `withdrawStatus` + `begin/endApplyTime` |
| WS-A9 | 汇总检索 | `shopName LIKE` |
| WS-A10 | 不写审核 | **无** approve/reject |
| WS-A11 | 无提现店仍展示 | LEFT JOIN 聚合；NULL→0 |

**店铺状态文案：** 复用 `FinanceSupport.toShopStatusText(shopStatus, delFlag)`（与 **资金概览** 一致）。

**明细 enrich（与 `listPlatformWithdraws` 对齐）：**

```text
accountTypeText  ← toAccountTypeText
withdrawStatusText ← toWithdrawStatusText
accountSummary ← buildAccountSummary(type, realName, mask)
```

---

## 5. 权限与菜单

| 权限 | 说明 |
|------|------|
| `agri:finance:withdrawSummary:summary` | 店铺汇总列表 |
| `agri:finance:withdrawSummary:detail` | 提现明细 |

| 菜单 | menu_id | path | 父菜单 |
|------|---------|------|--------|
| 财务管理（平台） | 7600 | finance | — |
| 提现审核 | 7610 | withdrawAudit | 7600 |
| 资金概览 | 7620 | fundOverview | 7600 |
| **提现汇总** | **7630** | **withdrawSummary** | **7600** |

脚本：[`sql/biz_platform_withdraw_summary_menu.sql`](../../../../sql/biz_platform_withdraw_summary_menu.sql)（待建）。

---

## 6. 测试要点

| 编号 | 场景 | 预期 |
|------|------|------|
| T1 | 从未提现的店 | 汇总行存在；两金额 **0** |
| T2 | 提交 100 待审 | 该店 `pendingAuditAmount=100` |
| T3 | 审核通过 | `withdrawnAmount+100`；`pendingAuditAmount-100` |
| T4 | 审核驳回 | 汇总两列 **不变**；明细 **status=2** |
| T5 | shops 店名检索 | 仅匹配店名行 |
| T6 | details shopId 必填 | 缺参 **400/业务提示** |
| T7 | details 时间/状态筛选 | 与 SQL 条件一致 |
| T8 | 与商家 list 对账 | 同 shopId 明细 **一致** |
| T9 | 与 withdrawAudit 对账 | 同店待审金额 = 审核列表该店待审 **SUM** |
| T10 | 已删店有历史单 | 汇总仍展示；`deleted=true` |

**建议测试类：** `ShopFundServiceImplTest`（汇总/明细）、`PlatformWithdrawSummaryControllerTest`（MockMvc）。

---

## 7. 实现状态

| 项 | 状态 |
|----|------|
| DDL（withdraw / shop） | **已有** |
| `PlatformWithdrawSummaryController` | **待建** |
| `IShopFundService` 汇总/明细方法 | **待扩展** |
| `BizShopWithdrawMapper` 汇总/明细 SQL | **待扩展** |
| VO/DTO | **待建** |
| 菜单 SQL 7630 | **待建** |
| ruoyi-ui 提现汇总页 | **待建** |
| 汇总列排序 / 跳转审核 / 导出 | **非本期** |

---

## 8. 版本记录

| 版本 | 说明 |
|------|------|
| **v1.0** | 首版：对齐《提现汇总功能需求》v1.0；关联提现审核/资金概览/商家提现；简练 DB/接口设计；RuoYi v3.9.2 + MySQL 5.7.39 |

---

*文档版本：v1.0 · 依据《提现汇总功能需求.md》v1.0*
