# Web端商户收入汇总统计接口文档 ## 模块概述 本接口提供收入数据的汇总统计功能,一次性返回可提现金额、今日收益、已入账总数、未入账总数四项关键数据,方便前端首页展示。 --- ## 接口信息 ### 收入汇总统计 #### 接口详情 - **接口名称**: 收入汇总统计 - **接口路径**: `GET /incomeManage/getIncomeSummary` - **请求方式**: GET - **接口描述**: 一次性查询可提现金额、今日收益、已入账金额/数量、未入账金额/数量 - **登录验证**: ✅ 需要(通过 JWT token 自动获取店铺ID) - **数据来源**: 复用三个现有接口的业务逻辑 --- ## 业务逻辑说明 ### 数据来源接口 本接口整合了以下三个app端接口的数据: | 数据项 | app端接口 | 业务逻辑 | |--------|----------|---------| | 可提现金额 | `/alienStore/storeIncomeDetailsRecord/accountBalance` | 4-27天内未绑定提现的收入 - 待审核/已通过的提现金额 | | 今日收益 | `/alienStore/storeIncomeDetailsRecord/todayIncome` | 当天00:00:00 ~ 23:59:59的收入总和 | | 未入账 | `/alienStore/storeIncomeDetailsRecord/noYetPayment?paymentType=0` | 近3天内未绑定提现的收入 | | 已入账 | `/alienStore/storeIncomeDetailsRecord/noYetPayment?paymentType=1` | 4-27天内的收入 | --- ### 数据计算规则 #### **1. 可提现金额** ```java // 查询4-27天内未绑定提现记录的收入 cashOutMoney = SUM(money WHERE created_time BETWEEN (NOW() - 27天) AND (NOW() - 4天) AND cash_out_id IS NULL) // 减去待审核和已通过的提现金额 totalCashOutAmount = SUM(money WHERE payment_status IN (1, 3) AND delete_flag = 0) // 可提现金额 cashOutMoney = cashOutMoney - totalCashOutAmount ``` **说明**: - ✅ 只统计4-27天前的收入(已到提现账期) - ✅ 减去已申请但未到账的提现金额 - ✅ payment_status: 1-待审核, 3-已通过 --- #### **2. 今日收益** ```java // 查询今天的收入总和 todayIncome = SUM(money WHERE created_time BETWEEN '今日 00:00:00' AND '今日 23:59:59') ``` **说明**: - ✅ 统计当天所有收入 - ✅ 包含所有收入类型(优惠券、代金券、团购券等) --- #### **3. 未入账(近3天)** ```java // 查询近3天未绑定提现的收入 notPaidMoney = SUM(money WHERE created_time > (NOW() - 3天) AND cash_out_id IS NULL) notPaidCount = COUNT(*) ``` **说明**: - ✅ 统计近3天的收入 - ✅ 未绑定提现记录 - ✅ 还未到提现账期 --- #### **4. 已入账(4-27天)** ```java // 查询4-27天前的收入 paidMoney = SUM(money WHERE created_time BETWEEN (NOW() - 27天) AND (NOW() - 4天)) paidCount = COUNT(*) ``` **说明**: - ✅ 统计4-27天前的收入 - ✅ 已到提现账期 - ✅ 可以申请提现 --- ## 请求参数 **无参数** 从 JWT token 自动获取店铺ID(`storeId`) --- ## 请求示例 ```http GET /incomeManage/getIncomeSummary Headers: Authorization: Bearer YOUR_JWT_TOKEN ``` ```bash curl -X GET "http://localhost:8080/incomeManage/getIncomeSummary" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` --- ## 响应参数 ### 成功响应 ```json { "code": 200, "success": true, "data": { "balance": "3580.50", "cashOutMoney": "1256.80", "todayIncome": "128.30", "notPaidMoney": "385.60", "notPaidCount": 12, "notPaidDateRange": "2025-11-18 ~ 2025-11-21", "paidMoney": "1580.20", "paidCount": 45, "paidDateRange": "2025-10-25 ~ 2025-11-17" }, "msg": "操作成功" } ``` ### 响应字段说明 | 字段名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200-成功) | | success | Boolean | 是否成功 | | data | Object | 汇总数据 | | msg | String | 提示信息 | #### data 字段详细说明 | 字段名 | 类型 | 单位 | 说明 | |--------|------|------|------| | **balance** | String | 元 | 账户总余额 | | **cashOutMoney** | String | 元 | 可提现金额(4-27天内可提现的收入) | | **todayIncome** | String | 元 | 今日收益(当天所有收入) | | **notPaidMoney** | String | 元 | 未入账金额(近3天的收入) | | **notPaidCount** | Integer | 条 | 未入账记录数 | | **notPaidDateRange** | String | - | 未入账时间范围 | | **paidMoney** | String | 元 | 已入账金额(4-27天的收入) | | **paidCount** | Integer | 条 | 已入账记录数 | | **paidDateRange** | String | - | 已入账时间范围 | --- ### 失败响应 #### 1. 未登录或 token 无效 ```json { "code": 500, "success": false, "data": null, "msg": "请先登录" } ``` #### 2. 查询异常 ```json { "code": 500, "success": false, "data": null, "msg": "查询失败:{异常信息}" } ``` --- ## 业务场景 ### 场景 1: 首页数据展示 **业务需求**: 商户登录后,首页需要展示收入概况的关键数据 **请求**: ```http GET /incomeManage/getIncomeSummary Headers: Authorization: Bearer VALID_TOKEN ``` **响应**: ```json { "code": 200, "success": true, "data": { "balance": "3580.50", "cashOutMoney": "1256.80", "todayIncome": "128.30", "notPaidMoney": "385.60", "notPaidCount": 12, "paidMoney": "1580.20", "paidCount": 45 } } ``` **前端展示**: ``` ┌────────────────────────────────────────┐ │ 收入概况 │ ├────────────────────────────────────────┤ │ 账户余额: ¥3,580.50 │ │ 可提现金额: ¥1,256.80 │ │ 今日收益: ¥128.30 │ │ │ │ 未入账: ¥385.60 (12笔) │ │ 已入账: ¥1,580.20 (45笔) │ └────────────────────────────────────────┘ ``` --- ### 场景 2: 数据刷新 **业务需求**: 用户下拉刷新或手动刷新收入数据 **请求**: ```http GET /incomeManage/getIncomeSummary Headers: Authorization: Bearer VALID_TOKEN ``` **业务逻辑**: - ✅ 重新计算所有统计数据 - ✅ 返回最新的收入概况 - ✅ 前端更新展示 --- ### 场景 3: 定时刷新 **业务需求**: 前端每隔一定时间自动刷新数据 **实现方式**: ```javascript setInterval(() => { fetchIncomeSummary(); }, 60000); // 每分钟刷新一次 ``` --- ## 数据关系说明 ### 金额之间的关系 ``` 账户余额 (balance) = 历史所有收入 - 已提现金额 可提现金额 (cashOutMoney) = 4-27天内未绑定提现的收入 - 待审核的提现金额 - 已通过的提现金额 今日收益 (todayIncome) = 今天所有收入 未入账 (notPaidMoney) = 近3天未绑定提现的收入 (还未到提现账期) 已入账 (paidMoney) = 4-27天的收入 (已到提现账期,可以提现) ``` --- ### 时间范围关系 ``` 时间轴: ←────────────────────────────────→ -27天 -4天 -3天 今天 已入账: ├─────┤ 4-27天 未入账: ├──┤ 3天内 今日收益: │ 今天 ``` --- ## 前端集成示例 ### Vue.js 示例 ```javascript export default { data() { return { summary: { balance: '0.00', cashOutMoney: '0.00', todayIncome: '0.00', notPaidMoney: '0.00', notPaidCount: 0, paidMoney: '0.00', paidCount: 0, notPaidDateRange: '', paidDateRange: '' }, loading: false }; }, methods: { async fetchIncomeSummary() { this.loading = true; try { const response = await this.$axios.get('/incomeManage/getIncomeSummary'); if (response.data.success) { this.summary = response.data.data; this.$message.success('数据加载成功'); } else { this.$message.error(response.data.msg); } } catch (error) { console.error('查询失败:', error); this.$message.error('数据加载失败,请稍后重试'); } finally { this.loading = false; } }, // 格式化金额显示 formatMoney(amount) { return '¥' + parseFloat(amount).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 }); }, // 下拉刷新 onRefresh() { this.fetchIncomeSummary(); } }, mounted() { this.fetchIncomeSummary(); // 每分钟自动刷新 this.timer = setInterval(() => { this.fetchIncomeSummary(); }, 60000); }, beforeDestroy() { if (this.timer) { clearInterval(this.timer); } } } ``` --- ### React 示例 ```javascript import { useState, useEffect } from 'react'; import axios from 'axios'; import { Card, Statistic, Row, Col, Spin } from 'antd'; import { WalletOutlined, DollarOutlined, RiseOutlined } from '@ant-design/icons'; function IncomeSummary() { const [summary, setSummary] = useState({ balance: '0.00', cashOutMoney: '0.00', todayIncome: '0.00', notPaidMoney: '0.00', notPaidCount: 0, paidMoney: '0.00', paidCount: 0 }); const [loading, setLoading] = useState(false); const fetchData = async () => { setLoading(true); try { const response = await axios.get('/incomeManage/getIncomeSummary'); if (response.data.success) { setSummary(response.data.data); } } catch (error) { console.error('查询失败:', error); } finally { setLoading(false); } }; useEffect(() => { fetchData(); // 每分钟自动刷新 const timer = setInterval(fetchData, 60000); return () => clearInterval(timer); }, []); return ( } /> } /> } />

{summary.paidDateRange}

); } ``` --- ## 测试用例 ### 测试场景1: 正常查询 **前置条件**: - 用户已登录 - 店铺ID=103 - 有收入记录 **执行步骤**: 1. 发送请求: `GET /incomeManage/getIncomeSummary` **预期结果**: - 返回成功 - `balance` > 0 - `cashOutMoney` >= 0 - `todayIncome` >= 0 - `notPaidMoney` >= 0, `notPaidCount` >= 0 - `paidMoney` >= 0, `paidCount` >= 0 - 包含时间范围字段 --- ### 测试场景2: 无收入记录 **前置条件**: - 用户已登录 - 新店铺,无任何收入 **执行步骤**: 1. 发送请求: `GET /incomeManage/getIncomeSummary` **预期结果**: - 返回成功 - 所有金额字段 = "0.00" - 所有数量字段 = 0 --- ### 测试场景3: 只有今日收入 **前置条件**: - 用户已登录 - 只有今天有收入记录 **执行步骤**: 1. 发送请求: `GET /incomeManage/getIncomeSummary` **预期结果**: - `todayIncome` > 0 - `notPaidMoney` > 0(今天的收入也在3天内) - `paidMoney` = 0(没有4-27天前的收入) --- ## 常见问题 ### Q1: 为什么可提现金额比已入账金额少? **答案**: - 可提现金额 = 已入账金额 - 待审核的提现 - 已通过的提现 - 如果有提现申请在审核中或已通过,会从可提现金额中扣除 --- ### Q2: 今日收益会计入未入账吗? **答案**: 会的。 - 今日收益统计当天所有收入 - 未入账统计近3天的收入(包括今天) - 所以今日收益会包含在未入账中 --- ### Q3: 账户余额和可提现金额有什么区别? **答案**: - **账户余额**: 所有历史收入 - 已提现金额(总余额) - **可提现金额**: 4-27天内可以立即提现的金额(扣除审核中的提现) --- ### Q4: 已入账的收入一定可以提现吗? **答案**: 不一定。 - 已入账 = 4-27天前的收入(已到账期) - 可提现金额 = 已入账 - 审核中的提现 - 已通过的提现 - 如果已有提现申请,可提现金额会相应减少 --- ### Q5: 时间范围是如何计算的? **答案**: - **未入账**: 当前时间 - 3天 ~ 当前时间 - **已入账**: 当前时间 - 27天 ~ 当前时间 - 4天 - 时间范围会随着查询时间动态变化 --- ## 注意事项 ### 1. 数据实时性 - ⚠️ 数据基于查询时刻实时计算 - ⚠️ 建议前端设置定时刷新(如每分钟) - ⚠️ 或提供手动刷新按钮 ### 2. 金额单位 - ⚠️ 数据库存储单位:**分** - ⚠️ 接口返回单位:**元**(保留2位小数) - ⚠️ 转换公式:元 = 分 / 100 ### 3. 时间范围 - ⚠️ 时间范围是动态的,基于当前时间计算 - ⚠️ 未入账:3天内 - ⚠️ 已入账:4-27天 - ⚠️ 可提现:4-27天内未绑定提现的 ### 4. 性能考虑 - ⚠️ 涉及多次数据库查询 - ⚠️ 建议适当缓存(如Redis,5分钟过期) - ⚠️ 避免频繁调用 --- ## 性能优化建议 ### 1. 缓存方案 ```java @Cacheable(value = "incomeSummary", key = "#storeId", unless = "#result == null") public Map getIncomeSummary(Integer storeId) { // ... 查询逻辑 } ``` **配置**: ```yaml spring: cache: type: redis redis: time-to-live: 300000 # 5分钟过期 ``` --- ### 2. 异步查询 ```java // 使用CompletableFuture并行查询 CompletableFuture balanceFuture = CompletableFuture.supplyAsync(() -> getBalance(storeId)); CompletableFuture todayIncomeFuture = CompletableFuture.supplyAsync(() -> getTodayIncome(storeId)); CompletableFuture notPaidFuture = CompletableFuture.supplyAsync(() -> getNotPaidData(storeId)); CompletableFuture paidFuture = CompletableFuture.supplyAsync(() -> getPaidData(storeId)); // 等待所有查询完成 CompletableFuture.allOf(balanceFuture, todayIncomeFuture, notPaidFuture, paidFuture).join(); ``` --- ## 更新日志 ### 2025-11-21 (v1.0) **新增接口**: - ✅ `GET /incomeManage/getIncomeSummary` - 收入汇总统计 **核心功能**: - ✅ 一次性返回4项关键数据 - ✅ 账户余额 - ✅ 可提现金额 - ✅ 今日收益 - ✅ 已入账/未入账金额和数量 **数据来源**: - 复用三个现有接口的业务逻辑 - `/accountBalance` - 可提现金额 - `/todayIncome` - 今日收益 - `/noYetPayment` - 已入账/未入账 **涉及文件**: - `IncomeManageController.java` - 新增 `getIncomeSummary` 接口 - `IncomeManageService.java` - 新增方法定义 - `IncomeManageServiceImpl.java` - 新增方法实现 **代码质量**: - ✅ Linter检查:无错误 - ✅ 日志记录:详细 - ✅ 异常处理:完善 - ✅ 代码注释:完整 **开发人员**: ssk --- **文档版本**: v1.0 **最后更新**: 2025-11-21 **维护人员**: ssk