# Web端商户已入账/未入账详情查询接口文档 ## 模块概述 本接口用于查询商户的收入明细,支持查询已入账和未入账的收益详情。可以按时间范围、收入类型进行筛选,并提供分页功能。 --- ## 接口信息 ### 已入账/未入账详情查询 #### 接口详情 - **接口名称**: 已入账/未入账详情查询 - **接口路径**: `GET /incomeManage/getPaymentDetails` - **请求方式**: GET - **接口描述**: 查询商户的收入明细,区分已入账和未入账状态 - **登录验证**: ✅ 需要(通过 JWT token 自动获取店铺ID) - **数据来源**: app端 `/alienStore/storeIncomeDetailsRecord/noYetPayment` 接口 --- ## 业务逻辑说明 ### 入账规则 #### **未入账 (paymentType=0)**: - **时间范围**: 当前时间-3天内的记录 - **条件**: `cash_out_id IS NULL`(未绑定提现记录) - **说明**: 3天内的收入还未到账期,不能提现 #### **已入账 (paymentType=1)**: - **时间范围**: 当前时间-4天 至 当前时间-27天的记录 - **条件**: 创建时间在4~27天之间 - **说明**: 4-27天前的收入已到账期,可以提现 ### 收入类型说明 | incomeType | 说明 | 备注 | |-----------|------|------| | 0 | 主页 | 包含优惠券(1)和团购券(2) | | 1 | 优惠券 | 单独查询优惠券收入 | | 2 | 代金券 | 单独查询代金券收入 | | 3 | 套餐 | 单独查询套餐收入 | | 4 | 联名卡 | 单独查询联名卡收入 | --- ## 请求参数 ### Query 参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | incomeType | Integer | 否 | - | 收入类型, 0:主页, 1:优惠券, 2:代金券, 3:套餐, 4:联名卡 | | paymentType | Integer | 是 | - | 账期类型, 0:未入账, 1:已入账 | | startTime | String | 是 | - | 开始时间(格式:yyyy-MM-dd) | | endTime | String | 是 | - | 结束时间(格式:yyyy-MM-dd) | | page | Integer | 否 | 1 | 页码(从1开始) | | size | Integer | 否 | 10 | 每页条数 | **说明**: - `storeId` 从 JWT token 自动获取,无需传参 - `startTime` 和 `endTime` 用于自定义查询时间范围 - 系统会根据 `paymentType` 自动计算默认时间范围 --- ## 请求示例 ### 示例1: 查询未入账收入 ```http GET /incomeManage/getPaymentDetails?paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer YOUR_JWT_TOKEN ``` ```bash curl -X GET "http://localhost:8080/incomeManage/getPaymentDetails?paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` --- ### 示例2: 查询已入账的优惠券收入 ```http GET /incomeManage/getPaymentDetails?incomeType=1&paymentType=1&startTime=2025-10-01&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer YOUR_JWT_TOKEN ``` ```bash curl -X GET "http://localhost:8080/incomeManage/getPaymentDetails?incomeType=1&paymentType=1&startTime=2025-10-01&endTime=2025-11-11&page=1&size=10" \ -H "Authorization: Bearer YOUR_JWT_TOKEN" ``` --- ### 示例3: 查询主页(优惠券+团购券)未入账收入 ```http GET /incomeManage/getPaymentDetails?incomeType=0&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer YOUR_JWT_TOKEN ``` --- ## 响应参数 ### 成功响应 ```json { "code": 200, "success": true, "data": { "date": "2025-11-08 ~ 2025-11-11", "money": "128.50", "data": { "records": [ { "id": 1001, "storeId": 103, "money": 5000, "moneyStr": "50.00", "commission": 150, "commissionStr": "1.50", "incomeMoney": "51.50", "incomeType": 1, "couponName": "50元优惠券", "cashOutId": null, "date": "2025-11-10", "commissionRate": "3", "createdTime": "2025-11-10 14:30:00" }, { "id": 1002, "storeId": 103, "money": 7800, "moneyStr": "78.00", "commission": 234, "commissionStr": "2.34", "incomeMoney": "80.34", "incomeType": 2, "couponName": "100元团购券", "cashOutId": null, "date": "2025-11-09", "commissionRate": "3", "createdTime": "2025-11-09 16:20:00" } ], "total": 25, "size": 10, "current": 1, "pages": 3 } }, "msg": "操作成功" } ``` ### 响应字段说明 #### 顶层字段 | 字段名 | 类型 | 说明 | |--------|------|------| | code | Integer | 状态码(200-成功) | | success | Boolean | 是否成功 | | data | JSONObject | 返回数据 | | msg | String | 提示信息 | #### data 字段 | 字段名 | 类型 | 说明 | |--------|------|------| | date | String | 账期时间范围 | | money | String | 总金额(元,保留2位小数) | | data | Page | 分页数据 | #### data.data 分页字段 | 字段名 | 类型 | 说明 | |--------|------|------| | records | Array | 收入明细列表 | | total | Integer | 总记录数 | | size | Integer | 每页条数 | | current | Integer | 当前页码 | | pages | Integer | 总页数 | #### records 明细字段 | 字段名 | 类型 | 说明 | |--------|------|------| | id | Integer | 收入记录ID | | storeId | Integer | 店铺ID | | money | Integer | 收益金额(分) | | moneyStr | String | 收益金额(元,格式化) | | commission | Integer | 手续费(分) | | commissionStr | String | 手续费(元,格式化) | | incomeMoney | String | 售价(收益+手续费,元) | | incomeType | Integer | 收入类型 | | couponName | String | 优惠券名称 | | cashOutId | Integer | 提现记录ID(null表示未提现) | | date | String | 日期(yyyy-MM-dd) | | commissionRate | String | 抽成比例 | | createdTime | String | 创建时间 | --- ### 失败响应 #### 1. 未登录或 token 无效 ```json { "code": 500, "success": false, "data": null, "msg": "请先登录" } ``` #### 2. 参数错误 ```json { "code": 500, "success": false, "data": null, "msg": "查询失败:时间格式错误" } ``` #### 3. 查询异常 ```json { "code": 500, "success": false, "data": null, "msg": "查询失败:{异常信息}" } ``` --- ## 业务场景 ### 场景 1: 查询未入账收入(近3天) **业务需求**: 商户想查看最近3天内产生的收入,这些收入还未到提现账期 **请求**: ```http GET /incomeManage/getPaymentDetails?paymentType=0&startTime=2025-11-08&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer VALID_TOKEN ``` **响应**: ```json { "code": 200, "success": true, "data": { "date": "2025-11-08 ~ 2025-11-11", "money": "256.80", "data": { "records": [...], "total": 15, "current": 1, "pages": 2 } } } ``` **业务逻辑**: - ✅ 查询 `created_time > (当前时间 - 3天)` 的记录 - ✅ 且 `cash_out_id IS NULL`(未绑定提现) - ✅ 按创建时间倒序排列 - ✅ 返回汇总金额和明细列表 --- ### 场景 2: 查询已入账收入(4-27天前) **业务需求**: 商户想查看可以提现的收入,这些收入已到账期 **请求**: ```http GET /incomeManage/getPaymentDetails?paymentType=1&startTime=2025-10-15&endTime=2025-11-07&page=1&size=10 Headers: Authorization: Bearer VALID_TOKEN ``` **响应**: ```json { "code": 200, "success": true, "data": { "date": "2025-10-15 ~ 2025-11-07", "money": "1580.50", "data": { "records": [...], "total": 42, "current": 1, "pages": 5 } } } ``` **业务逻辑**: - ✅ 查询 `created_time BETWEEN (当前时间-27天) AND (当前时间-4天)` 的记录 - ✅ 按创建时间倒序排列 - ✅ 这些收入可以申请提现 --- ### 场景 3: 按收入类型筛选(优惠券) **业务需求**: 商户只想查看优惠券产生的收入 **请求**: ```http GET /incomeManage/getPaymentDetails?incomeType=1&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer VALID_TOKEN ``` **响应**: ```json { "code": 200, "success": true, "data": { "date": "2025-11-08 ~ 2025-11-11", "money": "86.20", "data": { "records": [ { "incomeType": 1, "couponName": "50元优惠券", "moneyStr": "50.00", ... } ], "total": 5, "current": 1, "pages": 1 } } } ``` --- ### 场景 4: 查询主页收入(优惠券+团购券) **业务需求**: 商户想查看主页展示的收入汇总(包含优惠券和团购券) **请求**: ```http GET /incomeManage/getPaymentDetails?incomeType=0&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10 Headers: Authorization: Bearer VALID_TOKEN ``` **响应**: ```json { "code": 200, "success": true, "data": { "date": "2025-11-08 ~ 2025-11-11", "money": "328.60", "data": { "records": [ {"incomeType": 1, "couponName": "50元优惠券", ...}, {"incomeType": 2, "couponName": "100元团购券", ...} ], "total": 18, "current": 1, "pages": 2 } } } ``` **业务逻辑**: - ✅ `incomeType=0` 会自动查询 `income_type IN (1, 2)` - ✅ 包含优惠券和团购券的收入 --- ## 数据库查询逻辑 ### SQL 示例(未入账) ```sql SELECT sidr.* FROM store_income_details_record sidr WHERE sidr.store_id = ? AND sidr.cash_out_id IS NULL AND sidr.created_time > DATE_SUB(NOW(), INTERVAL 3 DAY) AND sidr.created_time BETWEEN ? AND ? AND sidr.income_type IN (1, 2) -- 如果 incomeType=0 ORDER BY sidr.created_time DESC ``` --- ### SQL 示例(已入账) ```sql SELECT sidr.* FROM store_income_details_record sidr WHERE sidr.store_id = ? AND sidr.created_time BETWEEN DATE_SUB(NOW(), INTERVAL 27 DAY) AND DATE_SUB(NOW(), INTERVAL 4 DAY) AND sidr.created_time BETWEEN ? AND ? AND sidr.income_type = ? ORDER BY sidr.created_time DESC ``` --- ## 金额计算逻辑 ### 单条记录计算 ```java // 1. 收益(分转元) moneyStr = money / 100 // 例: 5000分 = 50.00元 // 2. 手续费(分转元) commissionStr = commission / 100 // 例: 150分 = 1.50元 // 3. 售价(收益 + 手续费) incomeMoney = (money + commission) / 100 // 例: (5000 + 150) / 100 = 51.50元 ``` ### 汇总计算 ```java // 所有记录的收益总和(分转元) totalMoney = SUM(money) / 100 ``` --- ## 前端集成示例 ### Vue.js 示例 ```javascript export default { data() { return { paymentType: 0, // 0-未入账, 1-已入账 incomeType: null, startTime: '2025-11-09', endTime: '2025-11-11', page: 1, size: 10, loading: false, tableData: [], totalMoney: '0.00', dateRange: '', total: 0 }; }, methods: { async fetchPaymentDetails() { this.loading = true; try { const params = { paymentType: this.paymentType, startTime: this.startTime, endTime: this.endTime, page: this.page, size: this.size }; if (this.incomeType !== null) { params.incomeType = this.incomeType; } const response = await this.$axios.get('/incomeManage/getPaymentDetails', { params }); if (response.data.success) { const data = response.data.data; this.tableData = data.data.records; this.totalMoney = data.money; this.dateRange = data.date; this.total = data.data.total; this.$message.success('查询成功'); } else { this.$message.error(response.data.msg); } } catch (error) { console.error('查询失败:', error); this.$message.error('查询失败,请稍后重试'); } finally { this.loading = false; } }, handlePageChange(page) { this.page = page; this.fetchPaymentDetails(); }, switchPaymentType(type) { this.paymentType = type; this.page = 1; this.fetchPaymentDetails(); } }, mounted() { this.fetchPaymentDetails(); } } ``` --- ### React 示例 ```javascript import { useState, useEffect } from 'react'; import axios from 'axios'; import { Table, Radio, DatePicker, Select } from 'antd'; function PaymentDetails() { const [paymentType, setPaymentType] = useState(0); const [incomeType, setIncomeType] = useState(null); const [dateRange, setDateRange] = useState(['2025-11-09', '2025-11-11']); const [page, setPage] = useState(1); const [size, setSize] = useState(10); const [loading, setLoading] = useState(false); const [tableData, setTableData] = useState([]); const [totalMoney, setTotalMoney] = useState('0.00'); const [total, setTotal] = useState(0); const fetchData = async () => { setLoading(true); try { const params = { paymentType, startTime: dateRange[0], endTime: dateRange[1], page, size }; if (incomeType !== null) { params.incomeType = incomeType; } const response = await axios.get('/incomeManage/getPaymentDetails', { params }); if (response.data.success) { const data = response.data.data; setTableData(data.data.records); setTotalMoney(data.money); setTotal(data.data.total); } } catch (error) { console.error('查询失败:', error); } finally { setLoading(false); } }; useEffect(() => { fetchData(); }, [paymentType, dateRange, page, incomeType]); return (
setPaymentType(e.target.value)}> 未入账 已入账
总金额: ¥{totalMoney}
); } ``` --- ## 测试用例 ### 测试场景1: 查询未入账收入 **前置条件**: - 用户已登录 - 店铺ID=103 - 近3天有5笔收入记录 **执行步骤**: 1. 发送请求: `GET /incomeManage/getPaymentDetails?paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10` **预期结果**: - 返回成功 - `date` = "2025-11-08 ~ 2025-11-11" - `money` = 所有记录的收益总和 - `data.total` = 5 - 所有记录的 `cashOutId` = null --- ### 测试场景2: 查询已入账收入 **前置条件**: - 用户已登录 - 4-27天前有10笔收入记录 **执行步骤**: 1. 发送请求: `GET /incomeManage/getPaymentDetails?paymentType=1&startTime=2025-10-15&endTime=2025-11-07&page=1&size=10` **预期结果**: - 返回成功 - `date` = "2025-10-15 ~ 2025-11-07" - `data.total` = 10 - 记录的创建时间在4-27天之间 --- ### 测试场景3: 按收入类型筛选 **前置条件**: - 近3天有优惠券收入3笔、团购券收入2笔 **执行步骤**: 1. 发送请求: `GET /incomeManage/getPaymentDetails?incomeType=1&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10` **预期结果**: - 返回成功 - 只返回优惠券收入(incomeType=1) - `data.total` = 3 --- ## 常见问题 ### Q1: 未入账和已入账的时间范围是固定的吗? **答案**: 是的。 - **未入账**: 固定为当前时间-3天内 - **已入账**: 固定为当前时间-4天至-27天 - `startTime` 和 `endTime` 用于进一步筛选时间范围 --- ### Q2: incomeType=0 和不传 incomeType 有什么区别? **答案**: - **incomeType=0**: 查询优惠券(1)和团购券(2)的收入 - **不传**: 查询所有类型的收入 --- ### Q3: money 和 incomeMoney 有什么区别? **答案**: - **money**: 商户实际收益(已扣除手续费) - **incomeMoney**: 售价(收益 + 手续费) - 关系: `incomeMoney = money + commission` --- ### Q4: 为什么有些记录有 cashOutId,有些没有? **答案**: - **有 cashOutId**: 已绑定提现记录,收益已申请提现 - **无 cashOutId**: 未绑定提现记录,收益还未提现 --- ### Q5: 分页查询时,total 是指什么? **答案**: `total` 是符合查询条件的总记录数,不是总页数。 - 总页数 = `pages` 字段 - 当前页 = `current` 字段 --- ## 注意事项 ### 1. 时间范围理解 - ⚠️ 系统自动根据 `paymentType` 计算默认时间范围 - ⚠️ `startTime` 和 `endTime` 用于进一步筛选 - ⚠️ 实际查询是两个时间范围的交集 ### 2. 金额单位 - ⚠️ 数据库存储单位:**分** - ⚠️ 接口返回单位:**元**(保留2位小数) - ⚠️ 转换公式:元 = 分 / 100 ### 3. 收入类型 - ⚠️ `incomeType=0` 是特殊值,表示主页(优惠券+团购券) - ⚠️ 其他值直接对应具体的收入类型 - ⚠️ 不传表示查询所有类型 ### 4. 分页注意 - ⚠️ 使用内存分页(ListToPage) - ⚠️ 先查询所有符合条件的记录,再分页 - ⚠️ 数据量大时可能影响性能 --- ## 更新日志 ### 2025-11-21 (v1.0) **新增接口**: - ✅ `GET /incomeManage/getPaymentDetails` - 已入账/未入账详情查询 **核心功能**: - ✅ 区分未入账(3天内)和已入账(4-27天) - ✅ 支持按收入类型筛选 - ✅ 支持自定义时间范围 - ✅ 支持分页查询 - ✅ 返回汇总金额和明细列表 - ✅ 金额自动转换(分转元) - ✅ 自动计算售价、手续费 **数据来源**: - app端 `/alienStore/storeIncomeDetailsRecord/noYetPayment` 接口 - 完全复用业务逻辑 **涉及文件**: - `IncomeManageController.java` - 新增 `getPaymentDetails` 接口 - `IncomeManageService.java` - 新增方法定义 - `IncomeManageServiceImpl.java` - 新增方法实现 **代码质量**: - ✅ Linter检查:无错误(1个警告可忽略) - ✅ 日志记录:详细 - ✅ 异常处理:完善 - ✅ 代码注释:完整 **开发人员**: ssk --- **文档版本**: v1.0 **最后更新**: 2025-11-21 **维护人员**: ssk