| 项目 | 内容 |
|---|---|
| 接口名称 | 提现记录详情查询 |
| 接口路径 | /incomeManage/getCashOutRecordDetail |
| 请求方式 | GET |
| 接口说明 | 查询指定提现记录的详细信息 |
| 是否需要登录 | 是 |
| 开发者 | ssk |
| 开发日期 | 2025-11-25 |
该接口用于查询单条提现记录的详细信息,包括提现金额、手续费、提现状态、收益时间范围、到账时间、审批信息等完整数据。
/incomeManage/getCashOutRecordList): 分页查询多条提现记录,返回简要信息和统计数据/incomeManage/getCashOutRecordDetail): 查询单条记录的完整详细信息| 参数名 | 类型 | 必填 | 说明 | 示例 |
|---|---|---|---|---|
| id | Integer | 是 | 提现记录ID | 1001 |
| 参数名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| Authorization | String | 是 | JWT Token(格式:Bearer {token}) |
LoginUserUtil 从当前登录用户 Token 中自动获取,用于权限校验{
"code": 200,
"success": true,
"message": "操作成功",
"data": {
"id": 1001,
"storeId": 103,
"money": 10000,
"commission": 500,
"cashOutType": 0,
"orderNo": "TX202511250001",
"aliOrderNo": "2025112522001234567890123456",
"incomeStartTime": "2025-10-28 00:00:00",
"incomeEndTime": "2025-11-24 23:59:59",
"paymentDate": "2025-11-25 15:30:00",
"paymentStatus": 4,
"alertStatus": 1,
"deleteFlag": 0,
"createdTime": "2025-11-25 10:00:00",
"createdUserId": 113,
"updatedTime": "2025-11-25 15:30:00",
"updatedUserId": 1,
"approveTime": "2025-11-25 11:00:00",
"payDate": "2025-11-25 15:30:00",
"failReason": null,
"storeUserId": 113,
"comments": "审核通过",
"settlementAccount": "alipay@example.com",
"approveFailReason": null
}
}
| 字段名 | 类型 | 说明 |
|---|---|---|
| id | Integer | 提现记录ID |
| storeId | Integer | 门店ID |
| money | Integer | 提现金额(单位:分) |
| commission | Integer | 手续费(单位:分) |
| cashOutType | Integer | 提现类型(0-手动,1-自动) |
| orderNo | String | 商户订单号 |
| aliOrderNo | String | 支付宝订单号 |
| incomeStartTime | Date | 收益开始时间 |
| incomeEndTime | Date | 收益结束时间 |
| paymentDate | Date | 到账时间 |
| paymentStatus | Integer | 提现状态 0-进行中 1-待审核 2-审核不通过 3-已通过 4-已打款 5-打款失败 |
| alertStatus | Integer | 已到账期弹窗(0-弹,1-不弹) |
| deleteFlag | Integer | 删除标记(0-未删除,1-已删除) |
| createdTime | Date | 创建时间(申请时间) |
| createdUserId | Integer | 创建人ID(申请人) |
| updatedTime | Date | 修改时间 |
| updatedUserId | Integer | 修改人ID |
| approveTime | Date | 审批时间 |
| payDate | Date | 支付时间 |
| failReason | String | 失败原因(打款失败时) |
| storeUserId | Integer | 申请人ID(store_user表) |
| comments | String | 审批备注 |
| settlementAccount | String | 结算账户(支付宝账号) |
| approveFailReason | String | 拒绝原因(审核不通过时) |
cURL 示例
curl -X GET 'http://localhost:8081/incomeManage/getCashOutRecordDetail?id=1001' \
-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
JavaScript (Axios) 示例
async function getCashOutRecordDetail(id) {
try {
const response = await axios.get(
`/incomeManage/getCashOutRecordDetail?id=${id}`,
{
headers: {
'Authorization': 'Bearer ' + token
}
}
);
console.log('提现记录详情:', response.data);
if (response.data.success) {
const record = response.data.data;
console.log(`提现金额: ${record.money / 100}元`);
console.log(`提现状态: ${getStatusText(record.paymentStatus)}`);
console.log(`结算账户: ${record.settlementAccount}`);
}
} catch (error) {
console.error('查询失败:', error.message);
}
}
function getStatusText(status) {
const statusMap = {
0: '进行中',
1: '待审核',
2: '审核不通过',
3: '已通过',
4: '已打款',
5: '打款失败'
};
return statusMap[status] || '未知状态';
}
// 调用示例
getCashOutRecordDetail(1001);
Java (RestTemplate) 示例
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8081/incomeManage/getCashOutRecordDetail?id=1001";
// 设置请求头
HttpHeaders headers = new HttpHeaders();
headers.set("Authorization", "Bearer " + token);
HttpEntity<Void> requestEntity = new HttpEntity<>(headers);
// 发送请求
ResponseEntity<R> response = restTemplate.exchange(
url,
HttpMethod.GET,
requestEntity,
new ParameterizedTypeReference<R<StoreCashOutRecord>>() {}
);
// 处理响应
R<StoreCashOutRecord> result = response.getBody();
if (result.getSuccess()) {
StoreCashOutRecord record = result.getData();
System.out.println("提现金额: " + record.getMoney() / 100.0 + "元");
System.out.println("提现状态: " + record.getPaymentStatus());
System.out.println("结算账户: " + record.getSettlementAccount());
}
{
"code": 200,
"success": true,
"message": "操作成功",
"data": {
"id": 1001,
"storeId": 103,
"money": 10000,
"commission": 500,
"cashOutType": 0,
"orderNo": "TX202511250001",
"aliOrderNo": "2025112522001234567890123456",
"incomeStartTime": "2025-10-28 00:00:00",
"incomeEndTime": "2025-11-24 23:59:59",
"paymentDate": "2025-11-25 15:30:00",
"paymentStatus": 4,
"alertStatus": 1,
"deleteFlag": 0,
"createdTime": "2025-11-25 10:00:00",
"createdUserId": 113,
"updatedTime": "2025-11-25 15:30:00",
"updatedUserId": 1,
"approveTime": "2025-11-25 11:00:00",
"payDate": "2025-11-25 15:30:00",
"failReason": null,
"storeUserId": 113,
"comments": "审核通过",
"settlementAccount": "alipay@example.com",
"approveFailReason": null
}
}
{
"code": 200,
"success": true,
"message": "操作成功",
"data": {
"id": 1002,
"storeId": 103,
"money": 5000,
"commission": 250,
"cashOutType": 0,
"orderNo": "TX202511250002",
"aliOrderNo": null,
"incomeStartTime": "2025-10-28 00:00:00",
"incomeEndTime": "2025-11-24 23:59:59",
"paymentDate": null,
"paymentStatus": 2,
"alertStatus": 0,
"deleteFlag": 0,
"createdTime": "2025-11-25 12:00:00",
"createdUserId": 113,
"updatedTime": "2025-11-25 13:00:00",
"updatedUserId": 1,
"approveTime": "2025-11-25 13:00:00",
"payDate": null,
"failReason": null,
"storeUserId": 113,
"comments": null,
"settlementAccount": "alipay@example.com",
"approveFailReason": "账户信息有误,请核实后重新申请"
}
}
{
"code": 500,
"success": false,
"message": "查询失败:提现记录不存在",
"data": null
}
{
"code": 500,
"success": false,
"message": "查询失败:无权查看该提现记录",
"data": null
}
{
"code": 500,
"success": false,
"message": "查询失败:提现记录ID不能为空",
"data": null
}
┌─────────────┐
│ 前端发起 │
│ 详情查询 │
└──────┬──────┘
│
▼
┌─────────────────┐
│ 提取 Token │
│ 获取 storeId │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ 参数验证 │
│ - id 非空 │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ 查询提现记录 │
│ 根据 id 查询 │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ 记录存在性检查 │
│ - 记录不存在 │
│ - 已被删除 │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ 权限校验 │
│ 对比 storeId │
└──────┬──────────┘
│
▼
┌─────────────────┐
│ 返回记录详情 │
└─────────────────┘
文件路径: alien-store-platform/src/main/java/shop/alien/storeplatform/controller/IncomeManageController.java
@ApiOperation("提现记录详情查询")
@ApiOperationSupport(order = 5)
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "提现记录ID", dataType = "Integer", paramType = "query", required = true)
})
@GetMapping("/getCashOutRecordDetail")
public R<StoreCashOutRecord> getCashOutRecordDetail(@RequestParam("id") Integer id) {
log.info("IncomeManageController.getCashOutRecordDetail?id={}", id);
try {
StoreCashOutRecord result = incomeManageService.getCashOutRecordDetail(id);
return R.data(result);
} catch (Exception e) {
log.error("IncomeManageController.getCashOutRecordDetail ERROR: {}", e.getMessage(), e);
return R.fail("查询失败:" + e.getMessage());
}
}
文件路径: alien-store-platform/src/main/java/shop/alien/storeplatform/service/IncomeManageService.java
/**
* 提现记录详情查询
*
* @param id 提现记录ID
* @return 提现记录详情
*/
StoreCashOutRecord getCashOutRecordDetail(Integer id);
文件路径: alien-store-platform/src/main/java/shop/alien/storeplatform/service/impl/IncomeManageServiceImpl.java
/**
* 提现记录详情查询
*
* @param id 提现记录ID
* @return 提现记录详情
*/
@Override
public StoreCashOutRecord getCashOutRecordDetail(Integer id) {
log.info("IncomeManageServiceImpl.getCashOutRecordDetail - 开始查询提现记录详情: id={}", id);
// ==================== 1. 参数验证 ====================
if (id == null) {
log.warn("IncomeManageServiceImpl.getCashOutRecordDetail - 提现记录ID为空");
throw new RuntimeException("提现记录ID不能为空");
}
// ==================== 2. 查询提现记录 ====================
StoreCashOutRecord record = storeCashOutRecordMapper.selectById(id);
if (record == null || record.getDeleteFlag() == 1) {
log.warn("IncomeManageServiceImpl.getCashOutRecordDetail - 提现记录不存在: id={}", id);
throw new RuntimeException("提现记录不存在");
}
// ==================== 3. 权限校验(只能查看自己店铺的提现记录) ====================
Integer storeId = LoginUserUtil.getCurrentStoreId();
if (!record.getStoreId().equals(storeId)) {
log.warn("IncomeManageServiceImpl.getCashOutRecordDetail - 无权查看他人提现记录: currentStoreId={}, recordStoreId={}",
storeId, record.getStoreId());
throw new RuntimeException("无权查看该提现记录");
}
log.info("IncomeManageServiceImpl.getCashOutRecordDetail - 查询完成: id={}, storeId={}, money={}, status={}",
id, record.getStoreId(), record.getMoney(), record.getPaymentStatus());
return record;
}
// 从 Token 中获取当前登录用户的店铺ID
Integer storeId = LoginUserUtil.getCurrentStoreId();
// 对比提现记录的店铺ID
if (!record.getStoreId().equals(storeId)) {
throw new RuntimeException("无权查看该提现记录");
}
防止越权访问:
// 验证记录存在性和软删除状态
if (record == null || record.getDeleteFlag() == 1) {
throw new RuntimeException("提现记录不存在");
}
| 状态值 | 状态名称 | 说明 |
|---|---|---|
| 0 | 进行中 | 提现正在处理中 |
| 1 | 待审核 | 等待管理员审核 |
| 2 | 审核不通过 | 审核被拒绝,查看 approveFailReason |
| 3 | 已通过 | 审核通过,等待打款 |
| 4 | 已打款 | 提现成功,已打款到支付宝 |
| 5 | 打款失败 | 打款失败,查看 failReason |
数据库存储的金额单位是分,前端展示时需要转换为元:
// 转换为元(保留两位小数)
const moneyInYuan = record.money / 100;
const commissionInYuan = record.commission / 100;
const actualAmount = (record.money - record.commission) / 100;
console.log(`提现金额: ${moneyInYuan}元`);
console.log(`手续费: ${commissionInYuan}元`);
console.log(`实际到账: ${actualAmount}元`);
┌──────────────────┐
│ 1. 查询列表 │
│ getCashOutRecordList │
│ (分页、筛选) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 2. 选择记录 │
│ 用户点击某条记录 │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 3. 查询详情 │
│ getCashOutRecordDetail │
│ (完整信息) │
└────────┬─────────┘
│
▼
┌──────────────────┐
│ 4. 展示详情页 │
│ 显示所有字段信息 │
└──────────────────┘
// 步骤1: 查询列表
async function loadCashOutList() {
const response = await axios.get('/incomeManage/getCashOutRecordList', {
params: {
page: 1,
size: 10
}
});
// 渲染列表,每条记录有"查看详情"按钮
renderList(response.data.data.cashOutRecordList);
}
// 步骤2: 点击查看详情
function viewDetail(recordId) {
getCashOutRecordDetail(recordId);
}
// 步骤3: 加载详情
async function getCashOutRecordDetail(id) {
const response = await axios.get('/incomeManage/getCashOutRecordDetail', {
params: { id }
});
// 展示详情弹窗或跳转详情页
showDetailModal(response.data.data);
}
@Test
public void testGetCashOutRecordDetail_Success() {
// 准备测试数据
Integer recordId = 1001;
// 执行查询
StoreCashOutRecord result = incomeManageService.getCashOutRecordDetail(recordId);
// 验证结果
assertNotNull(result);
assertEquals(recordId, result.getId());
assertEquals(103, result.getStoreId().intValue());
}
@Test
public void testGetCashOutRecordDetail_NotFound() {
// 查询不存在的记录
assertThrows(RuntimeException.class, () -> {
incomeManageService.getCashOutRecordDetail(99999);
});
}
@Test
public void testGetCashOutRecordDetail_NoPermission() {
// 模拟查询其他店铺的记录
// ... 验证抛出权限异常
}
测试场景1: 正常查询
测试场景2: 记录不存在
测试场景3: 权限校验
A:
A:
A: 不能。系统会自动验证提现记录的 storeId 是否与当前登录用户的店铺ID一致,防止越权访问。
A: 不能。软删除(deleteFlag=1)的记录会被过滤,无法通过详情接口查询。
| 版本号 | 日期 | 修改内容 | 修改人 |
|---|---|---|---|
| v1.0 | 2025-11-25 | 初始版本,新增提现记录详情查询接口 | ssk |
提现记录详情查询接口提供了单条提现记录的完整信息查询功能,配合列表接口使用,为商户提供了完整的提现记录管理体验。接口包含完善的权限控制和数据验证,确保数据安全性。