# Web端商户提现记录查询接口文档 ## 模块概述 本模块提供提现记录查询功能,支持按时间范围、提现状态等条件筛选提现记录,并提供分页查询和统计信息。 --- ## 接口信息 ### 提现记录查询 #### 接口详情 - **接口名称**: 提现记录查询 - **接口路径**: `GET /incomeManage/getCashOutRecordList` - **请求方式**: GET - **接口描述**: 查询指定门店的提现记录,支持按时间范围和提现状态筛选,返回分页数据和统计信息 - **登录验证**: ✅ 需要(使用 `@LoginRequired` 注解) --- ## 请求参数 | 参数名 | 类型 | 必填 | 说明 | 示例值 | |--------|------|------|------|--------| | storeId | Integer | 是 | 门店ID | 103 | | cashOutStartTime | String | 否 | 开始时间(格式:yyyy-MM-dd) | 2025-11-10 | | cashOutEndTime | String | 否 | 结束时间(格式:yyyy-MM-dd) | 2025-11-11 | | paymentStatus | String | 否 | 提现状态 | 1 | | page | Integer | 否 | 页码,默认1 | 1 | | size | Integer | 否 | 每页条数,默认10 | 10 | ### 参数说明 #### paymentStatus(提现状态) - `1`: 待审核 - `2`: 审核不通过 - `3`: 已通过 - `4`: 已打款 - `5`: 打款失败 - 不传:查询所有状态 #### 时间范围 - **cashOutStartTime**: 查询此日期(含)之后创建的提现记录 - **cashOutEndTime**: 查询此日期(含)之前创建的提现记录 - 不传时间参数:查询所有时间的记录 --- ## 请求示例 ### 示例1: 查询所有提现记录 ```http GET /incomeManage/getCashOutRecordList?storeId=103&page=1&size=10 ``` ```bash curl "http://localhost:8080/incomeManage/getCashOutRecordList?storeId=103&page=1&size=10" \ -H "Authorization: Bearer YOUR_TOKEN" ``` --- ### 示例2: 按时间范围查询 ```http GET /incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-10&cashOutEndTime=2025-11-11&page=1&size=10 ``` ```bash curl "http://localhost:8080/incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-10&cashOutEndTime=2025-11-11&page=1&size=10" \ -H "Authorization: Bearer YOUR_TOKEN" ``` --- ### 示例3: 查询待审核记录 ```http GET /incomeManage/getCashOutRecordList?storeId=103&paymentStatus=1&page=1&size=10 ``` ```bash curl "http://localhost:8080/incomeManage/getCashOutRecordList?storeId=103&paymentStatus=1&page=1&size=10" \ -H "Authorization: Bearer YOUR_TOKEN" ``` --- ### 示例4: 组合查询 ```http GET /incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-10&cashOutEndTime=2025-11-11&paymentStatus=4&page=1&size=10 ``` --- ## 响应参数 ### 成功响应 ```json { "code": 200, "success": true, "data": { "cashOutRecordList": [ { "id": 1001, "storeId": 103, "storeUserId": 114, "money": 50000, "commission": 0, "cashOutType": 0, "paymentStatus": 1, "orderNo": "TX20251119001", "aliOrderNo": null, "paymentDate": "2025-11-19 10:30:00", "payDate": "2025-11-19 10:30:00", "settlementAccount": "13800138000", "failReason": null, "deleteFlag": 0, "createdTime": "2025-11-19 10:30:00", "updatedTime": "2025-11-19 10:30:00" }, { "id": 1000, "storeId": 103, "storeUserId": 114, "money": 30000, "commission": 0, "cashOutType": 0, "paymentStatus": 4, "orderNo": "TX20251118001", "aliOrderNo": "2025111822001234567890123456", "paymentDate": "2025-11-18 15:20:00", "payDate": "2025-11-18 15:25:00", "settlementAccount": "alipay@example.com", "failReason": null, "deleteFlag": 0, "createdTime": "2025-11-18 15:20:00", "updatedTime": "2025-11-18 15:25:00" } ], "cashOutAllMoney": 800.00, "cashOutNum": 15 }, "msg": "操作成功" } ``` ### 响应字段说明 #### 外层字段 | 字段名 | 类型 | 说明 | |--------|------|------| | data.cashOutRecordList | Array | 提现记录列表(当前页) | | data.cashOutAllMoney | BigDecimal | 提现总金额(仅统计待审核状态,单位:元) | | data.cashOutNum | Integer | 提现记录总数 | #### cashOutRecordList 字段 | 字段名 | 类型 | 说明 | |--------|------|------| | id | Long | 提现记录ID | | storeId | Integer | 门店ID | | storeUserId | Integer | 用户ID | | money | Integer | 提现金额(单位:分) | | commission | Integer | 手续费(单位:分) | | cashOutType | Integer | 提现类型(0-全部提现) | | paymentStatus | Integer | 提现状态 | | orderNo | String | 提现订单号 | | aliOrderNo | String | 支付宝订单号 | | paymentDate | Date | 申请时间 | | payDate | Date | 打款时间 | | failReason | String | 失败原因 | | settlementAccount | String | 结算账户(支付宝账号或手机号) | | deleteFlag | Integer | 删除标识 | | createdTime | Date | 创建时间 | | updatedTime | Date | 更新时间 | **⚠️ 重要字段说明**: - `settlementAccount`: 通过 LEFT JOIN `store_user` 表查询得到 - 优先使用商户的支付宝账号(`alipay_account`) - 如果没有支付宝账号,则使用手机号(`phone`) --- ### 失败响应 #### 1. 参数错误 ```json { "code": 500, "success": false, "data": null, "msg": "查询失败:门店ID不能为空" } ``` #### 2. 未登录或登录过期 ```json { "code": 500, "success": false, "data": null, "msg": "请先登录" } ``` #### 3. 系统异常 ```json { "code": 500, "success": false, "data": null, "msg": "查询失败:{异常信息}" } ``` --- ## 业务逻辑说明 ### 查询流程 ``` ┌─────────────────────────────────────────────┐ │ 1. 接收查询参数 │ │ - storeId (必填) │ │ - cashOutStartTime (可选) │ │ - cashOutEndTime (可选) │ │ - paymentStatus (可选) │ │ - page, size (分页) │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 2. 构建查询条件 │ │ wrapper.eq(storeId) │ │ IF paymentStatus != null │ │ wrapper.eq(paymentStatus) │ │ IF cashOutEndTime != null │ │ wrapper.le(createdTime, endTime 23:59:59) │ │ IF cashOutStartTime != null │ │ wrapper.ge(createdTime, startTime 00:00:00)│ │ wrapper.orderByDesc(createdTime) │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 3. 查询所有符合条件的记录 │ │ List recordList │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 4. 手动分页 │ │ IPage page = ListToPage.setPage(list, p, s)│ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 5. 构建返回VO │ │ vo.cashOutRecordList = page.getRecords() │ │ vo.cashOutAllMoney = sum(money[status=1]) ÷ 100 │ │ vo.cashOutNum = list.size() │ └─────────────────┬───────────────────────────┘ ↓ ┌─────────────────────────────────────────────┐ │ 6. 返回结果 │ │ 返回分页数据和统计信息 │ └─────────────────────────────────────────────┘ ``` ### 查询条件说明 #### 1. 必填条件 - **storeId**: 门店ID(必须) #### 2. 可选条件(AND关系) - **paymentStatus**: 提现状态筛选 - **cashOutStartTime**: 开始时间(含当天 00:00:00) - **cashOutEndTime**: 结束时间(含当天 23:59:59) #### 3. 排序规则 - 按创建时间倒序排序(最新的在前) --- ## 数据库查询 ### 查询SQL ```sql -- 使用自定义Mapper方法 selectCashoutRecordList SELECT scor.*, IF(su.alipay_account IS NOT NULL, su.alipay_account, su.phone) AS settlement_account FROM store_cash_out_record scor LEFT JOIN store_user su ON su.store_id = scor.store_id AND su.delete_flag = 0 WHERE scor.store_id = ? AND scor.delete_flag = 0 AND (scor.payment_status = ? OR ? IS NULL) AND (scor.created_time <= ? OR ? IS NULL) AND (scor.created_time >= ? OR ? IS NULL) ORDER BY scor.created_time DESC ``` **SQL说明**: - 🔔 使用 LEFT JOIN 关联 `store_user` 表获取结算账户信息 - 📌 `settlement_account` 字段逻辑: - 优先返回 `alipay_account`(支付宝账号) - 如果为空,返回 `phone`(手机号) - 🔄 表别名:`scor` = store_cash_out_record,`su` = store_user ### 索引建议 ```sql -- store_cash_out_record 表索引 ALTER TABLE store_cash_out_record ADD INDEX idx_store_status_time (store_id, payment_status, created_time); -- store_user 表索引(用于LEFT JOIN) ALTER TABLE store_user ADD INDEX idx_store_id_delete (store_id, delete_flag); ``` --- ## 提现状态说明 ### payment_status 状态值 | Status | 名称 | 描述 | 可查询 | |--------|------|------|--------| | 1 | 待审核 | 提现申请已提交,等待管理员审核 | ✅ | | 2 | 审核不通过 | 管理员拒绝提现申请 | ✅ | | 3 | 已通过 | 管理员审核通过,等待打款 | ✅ | | 4 | 已打款 | 支付宝转账成功 | ✅ | | 5 | 打款失败 | 支付宝转账失败 | ✅ | ### 状态流转 ``` 1(待审核) ──审核通过──→ 3(已通过) ──打款成功──→ 4(已打款) │ │ │ └──打款失败──→ 5(打款失败) │ └──审核拒绝──→ 2(审核不通过) ``` --- ## 金额计算规则 ### 金额单位转换 | 数据库存储(分) | 显示(元) | 转换公式 | |------------------|-----------|----------| | 50000 | 500.00 | money ÷ 100 | | 30000 | 300.00 | money ÷ 100 | | 80000 | 800.00 | money ÷ 100 | ### cashOutAllMoney 计算 ```java // 仅统计状态为1-待审核的记录总金额 int totalMoney = recordList.stream() .filter(item -> "1".equals(item.getPaymentStatus().toString())) .mapToInt(StoreCashOutRecord::getMoney) .sum(); // 转换为元(向下取整) BigDecimal cashOutAllMoney = new BigDecimal(totalMoney) .divide(new BigDecimal(100), 2, RoundingMode.DOWN); ``` **说明**: - 🔔 **重要变更(2025-11-20)**: 仅统计 `paymentStatus = 1`(待审核)状态的记录总金额 - ⚠️ 统计的是所有符合条件且状态为待审核的记录,不是当前页 - 使用 `RoundingMode.DOWN`(向下取整) --- ## 业务场景 ### 场景 1: 查询所有提现记录 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&page=1&size=10 ``` **响应**: ```json { "code": 200, "data": { "cashOutRecordList": [...], // 第1页,10条记录 "cashOutAllMoney": 500.00, // 所有待审核记录总金额 "cashOutNum": 25 // 所有记录总数 } } ``` **说明**: - 不传任何筛选条件,返回该门店的所有提现记录 - `cashOutAllMoney` 仅统计状态为"待审核"的记录总金额 --- ### 场景 2: 查询指定时间范围 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-10&cashOutEndTime=2025-11-11&page=1&size=10 ``` **响应**: ```json { "code": 200, "data": { "cashOutRecordList": [...], "cashOutAllMoney": 200.00, // 2025-11-10至2025-11-11期间待审核记录的总金额 "cashOutNum": 5 // 期间的总记录数 } } ``` **说明**: - 只返回指定时间范围内的提现记录 - `cashOutAllMoney` 仅统计该时间范围内待审核状态的记录 --- ### 场景 3: 查询待审核记录 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&paymentStatus=1&page=1&size=10 ``` **响应**: ```json { "code": 200, "data": { "cashOutRecordList": [...], "cashOutAllMoney": 300.00, // 待审核记录总金额 "cashOutNum": 3 // 待审核记录总数 } } ``` **说明**: 只返回待审核状态的提现记录,`cashOutAllMoney` 统计所有待审核记录的总金额 --- ### 场景 4: 组合查询 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-01&cashOutEndTime=2025-11-30&paymentStatus=4&page=1&size=10 ``` **响应**: ```json { "code": 200, "data": { "cashOutRecordList": [...], "cashOutAllMoney": 0.00, // 11月已打款记录中待审核的总金额(0元,因为已打款状态不是待审核) "cashOutNum": 10 // 11月已打款记录总数 } } ``` **说明**: - 查询11月已打款的提现记录 - ⚠️ **注意**: 由于 `cashOutAllMoney` 只统计待审核状态,而查询条件是已打款状态,所以 `cashOutAllMoney` 为0 --- ### 场景 5: 空结果 **前置条件**: 指定条件下无记录 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&paymentStatus=5&page=1&size=10 ``` **响应**: ```json { "code": 200, "data": { "cashOutRecordList": [], "cashOutAllMoney": 0.00, "cashOutNum": 0 } } ``` --- ## 分页说明 ### 分页逻辑 1. **查询全部**: 首先查询所有符合条件的记录 2. **手动分页**: 使用 `ListToPage.setPage()` 进行内存分页 3. **返回当前页**: `cashOutRecordList` 只包含当前页的记录 4. **统计全部**: `cashOutNum` 统计所有记录,`cashOutAllMoney` 仅统计待审核状态的记录 ### 分页参数 - **page**: 页码,从1开始 - **size**: 每页条数,默认10 - **total**: 总记录数(返回值中的 `cashOutNum`) ### 分页示例 **场景**: 共25条记录,每页10条 - **第1页** (page=1, size=10): 显示第1-10条 - **第2页** (page=2, size=10): 显示第11-20条 - **第3页** (page=3, size=10): 显示第21-25条 **统计信息**: - `cashOutNum = 25` (所有页的总记录数) - `cashOutAllMoney` = 所有25条记录中待审核状态的总金额 --- ## 前端集成示例 ### Vue.js 示例 ```javascript export default { data() { return { storeId: 103, cashOutStartTime: '', cashOutEndTime: '', paymentStatus: '', page: 1, size: 10, cashOutRecordList: [], cashOutAllMoney: 0, cashOutNum: 0 }; }, methods: { async getCashOutRecordList() { try { const params = { storeId: this.storeId, page: this.page, size: this.size }; // 可选参数 if (this.cashOutStartTime) { params.cashOutStartTime = this.cashOutStartTime; } if (this.cashOutEndTime) { params.cashOutEndTime = this.cashOutEndTime; } if (this.paymentStatus) { params.paymentStatus = this.paymentStatus; } const response = await this.$axios.get('/incomeManage/getCashOutRecordList', { params }); if (response.data.success) { const data = response.data.data; this.cashOutRecordList = data.cashOutRecordList; this.cashOutAllMoney = data.cashOutAllMoney; this.cashOutNum = data.cashOutNum; } } catch (error) { console.error('查询失败:', error); this.$message.error('查询失败'); } }, // 翻页 handlePageChange(page) { this.page = page; this.getCashOutRecordList(); } }, mounted() { this.getCashOutRecordList(); } } ``` --- ### React 示例 ```javascript import { useState, useEffect } from 'react'; import axios from 'axios'; function CashOutRecordList() { const [storeId] = useState(103); const [cashOutStartTime, setCashOutStartTime] = useState(''); const [cashOutEndTime, setCashOutEndTime] = useState(''); const [paymentStatus, setPaymentStatus] = useState(''); const [page, setPage] = useState(1); const [size] = useState(10); const [data, setData] = useState({ cashOutRecordList: [], cashOutAllMoney: 0, cashOutNum: 0 }); const getCashOutRecordList = async () => { try { const params = { storeId, page, size, ...(cashOutStartTime && { cashOutStartTime }), ...(cashOutEndTime && { cashOutEndTime }), ...(paymentStatus && { paymentStatus }) }; const response = await axios.get('/incomeManage/getCashOutRecordList', { params }); if (response.data.success) { setData(response.data.data); } } catch (error) { console.error('查询失败:', error); } }; useEffect(() => { getCashOutRecordList(); }, [page, cashOutStartTime, cashOutEndTime, paymentStatus]); return (

提现记录

总记录数: {data.cashOutNum}

总金额: ¥{data.cashOutAllMoney}

); } ``` --- ## 测试用例 ### 测试场景1: 正常查询 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&page=1&size=10 ``` **预期结果**: - 返回提现记录列表 - 包含统计信息(总金额、总数) - 按创建时间倒序排序 --- ### 测试场景2: 时间范围查询 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&cashOutStartTime=2025-11-10&cashOutEndTime=2025-11-11 ``` **预期结果**: - 只返回2025-11-10至2025-11-11的记录 - 包含这两天 00:00:00 到 23:59:59 的记录 --- ### 测试场景3: 状态筛选 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&paymentStatus=1 ``` **预期结果**: - 只返回待审核状态的记录 - 其他状态的记录不返回 --- ### 测试场景4: 空结果 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=999999&page=1&size=10 ``` **预期结果**: ```json { "cashOutRecordList": [], "cashOutAllMoney": 0.00, "cashOutNum": 0 } ``` --- ### 测试场景5: 分页测试 **前置条件**: 共25条记录 **请求**: ```http GET /incomeManage/getCashOutRecordList?storeId=103&page=3&size=10 ``` **预期结果**: - 返回第21-25条记录(5条) - `cashOutNum` 仍为25 - `cashOutAllMoney` 为所有25条记录中待审核状态的总金额 --- ## 注意事项 ### 1. 时间范围 - ⚠️ **时间格式**: 必须是 `yyyy-MM-dd` - ⚠️ **开始时间**: 自动补充 `00:00:00` - ⚠️ **结束时间**: 自动补充 `23:59:59` - ⚠️ **时区**: 使用服务器时区 ### 2. 分页逻辑 - ⚠️ **查询全部**: 先查询所有符合条件的记录 - ⚠️ **内存分页**: 在内存中进行分页 - ⚠️ **性能考虑**: 大数据量时可能影响性能 - ⚠️ **统计准确**: `cashOutNum` 统计所有记录,`cashOutAllMoney` 仅统计待审核状态 ### 3. 金额单位 - ⚠️ **数据库**: 分(Integer) - ⚠️ **接口返回**: 元(BigDecimal,保留2位小数) - ⚠️ **舍入模式**: DOWN(向下取整) ### 4. 提现状态 - ⚠️ **状态值**: 字符串类型 - ⚠️ **可选参数**: 不传则查询所有状态 - ⚠️ **多状态**: 目前不支持,需多次调用 ### 5. 查询性能 - ⚠️ **索引**: 确保有合适的索引 - ⚠️ **数据量**: 建议限制时间范围 - ⚠️ **缓存**: 考虑使用Redis缓存热点数据 --- ## 性能优化建议 ### 1. 数据库索引 ```sql -- 推荐的复合索引 ALTER TABLE store_cash_out_record ADD INDEX idx_store_status_time (store_id, payment_status, created_time); -- 好处: -- 1. 覆盖最常用的查询条件 -- 2. 支持排序优化 -- 3. 提升查询速度 ``` ### 2. 分页优化 **现状**: 内存分页(查全部->分页) **优化方案**: ```java // 使用MyBatis-Plus的分页插件 IPage page = new Page<>(pageNum, pageSize); IPage result = storeCashOutRecordMapper.selectPage(page, wrapper); ``` **优点**: - 数据库层面分页 - 只查询当前页数据 - 性能更好 ### 3. 缓存策略 ```java // Redis缓存热点数据 @Cacheable(value = "cashOutRecordList", key = "#storeId + ':' + #page + ':' + #size") public Object getCashOutRecordList(...) { // ... } ``` --- ## 迁移说明 ### 原接口(app端) - **服务**: `alien-store` - **路径**: `/alienStore/storeCashOutRecord/getCashOutRecordList` - **Controller**: `StoreCashOutRecordController` - **Service**: `StoreCashOutRecordService.getCashOutRecordList()` ### 新接口(web端) - **服务**: `alien-store-platform` - **路径**: `/incomeManage/getCashOutRecordList` - **Controller**: `IncomeManageController` - **Service**: `IncomeManageService.getCashOutRecordList()` ### 差异说明 | 项目 | app端 | web端 | 说明 | |------|-------|-------|------| | 接口路径 | `/getCashOutRecordList` | `/getCashOutRecordList` | 保持一致 | | 请求方式 | GET | GET | 保持一致 | | 参数名称 | 一致 | 一致 | 完全相同 | | 返回格式 | StoreCashOutRecordVo | StoreCashOutRecordVo | 保持一致 | | 业务逻辑 | ✅ | ✅ | 完全复用 | | 登录验证 | ❌ 无 | ✅ 有 | 增加验证 | | 日志记录 | 基础 | 详细 | 增强日志 | ### 复用的核心组件 1. **Mapper**: - `StoreCashOutRecordMapper.selectCashoutRecordList()` - 自定义查询方法,LEFT JOIN store_user 2. **Entity**: - `StoreCashOutRecord` - 提现记录实体(包含 settlementAccount 字段) - `StoreCashOutRecordVo` - 提现记录VO 3. **Util**: - `ListToPage` - 手动分页工具 ### 自定义Mapper SQL ```java @Select("select scor.*, If(su.alipay_account is not null,su.alipay_account,su.phone) settlementAccount\n" + "from store_cash_out_record scor\n" + "left join store_user su on su.store_id = scor.store_id and su.delete_flag = 0\n" + "${ew.customSqlSegment}") List selectCashoutRecordList(@Param(Constants.WRAPPER) QueryWrapper wrapper); ``` **说明**: - 使用 `@Select` 注解定义SQL - LEFT JOIN `store_user` 获取结算账户 - `${ew.customSqlSegment}` 动态拼接WHERE、ORDER BY等条件 --- ## 常见问题 ### Q1: cashOutAllMoney 是当前页还是所有记录的总金额? **答案**: 所有符合条件且状态为"待审核"(paymentStatus=1)记录的总金额,不是当前页。 **注意**: 从2025-11-20开始,只统计待审核状态的提现金额,与app端逻辑保持一致。 --- ### Q2: 如何查询多个状态的记录? **答案**: 目前不支持,需要多次调用接口分别查询。 --- ### Q3: 时间参数必须都传吗? **答案**: 不需要。可以只传开始时间、只传结束时间,或都不传。 --- ### Q4: 分页是数据库分页还是内存分页? **答案**: 内存分页。先查询所有记录,再在内存中分页。 --- ### Q5: 如何获取总页数? **答案**: `totalPages = Math.ceil(cashOutNum / size)` --- ### Q6: 金额为什么使用DOWN舍入模式? **答案**: 向下取整更保守,避免显示金额大于实际金额。 --- ### Q7: settlementAccount 是什么?如何获取的? **答案**: - **settlementAccount** 是结算账户,用于显示商户的提现账户信息 - 获取逻辑: 1. 通过 LEFT JOIN `store_user` 表查询 2. 优先使用 `alipay_account`(支付宝账号) 3. 如果支付宝账号为空,使用 `phone`(手机号) - SQL: `IF(su.alipay_account IS NOT NULL, su.alipay_account, su.phone)` --- ### Q8: 为什么要用 QueryWrapper 而不是 LambdaQueryWrapper? **答案**: - `selectCashoutRecordList` 是自定义Mapper方法,使用了表别名(`scor`) - 需要使用 `QueryWrapper` 配合字符串字段名(如 `"scor.store_id"`) - `LambdaQueryWrapper` 无法使用表别名 --- ## 更新日志 ### 2025-11-20 **逻辑更新(重要)**: - 🔄 修改查询方法,使用 `selectCashoutRecordList` 代替 `selectList` - ✅ 添加 LEFT JOIN `store_user` 表,获取结算账户信息(`settlementAccount`) - ✅ 修改 `QueryWrapper` 使用表别名 `scor`(以配合自定义SQL) - ✅ 添加 `delete_flag = 0` 条件(软删除过滤) - 🔄 修改 `cashOutAllMoney` 计算逻辑,仅统计 `paymentStatus = 1`(待审核)状态的记录 **变更原因**: - 同步app端完整业务逻辑 - 提现记录需要显示结算账户信息(支付宝账号或手机号) - 需要过滤已删除的记录 **影响范围**: - 响应字段新增 `settlementAccount`(结算账户) - 查询会关联 `store_user` 表,可能影响性能(建议添加索引) - `cashOutAllMoney` 仅统计待审核状态的提现总金额 **涉及文件**: - `IncomeManageServiceImpl.java` - 更新 `getCashOutRecordList` 方法(line 352-390) - `StoreCashOutRecordMapper.java` - 使用 `selectCashoutRecordList` 方法 --- ### 2025-11-19 **新增接口**: - ✅ `GET /incomeManage/getCashOutRecordList` - 提现记录查询 **核心功能**: - ✅ 按门店ID查询提现记录 - ✅ 支持时间范围筛选 - ✅ 支持提现状态筛选 - ✅ 分页查询 - ✅ 统计总金额和总数 - ✅ 按创建时间倒序排序 - ✅ 详细日志记录 - ✅ 完善异常处理 **涉及文件**: - `IncomeManageController.java` - 更新 - `IncomeManageService.java` - 更新 - `IncomeManageServiceImpl.java` - 更新 **代码质量**: - ✅ Linter检查:无错误 - ✅ 日志记录:详细 - ✅ 异常处理:完善 - ✅ 代码注释:完整 **与原接口一致性**: - ✅ 请求参数:完全相同 - ✅ 返回格式:完全相同 - ✅ 业务逻辑:完全复用 **开发人员**: ssk --- **文档版本**: v1.0 **最后更新**: 2025-11-19 **维护人员**: ssk