19-查询账户余额接口.md 18 KB

Web端商户账户余额查询接口文档

模块概述

本模块提供账户余额查询功能,包括账户总余额和可提现金额的查询,支持完整的账户资金状态展示。


接口信息

查询账户余额

接口详情

  • 接口名称: 查询账户余额
  • 接口路径: GET /incomeManage/getAccountBalance
  • 请求方式: GET
  • 接口描述: 查询指定门店的账户总余额和可提现金额
  • 登录验证: ✅ 需要(使用 @LoginRequired 注解)

请求参数

参数名 类型 必填 说明 示例值
storeId Integer 门店ID 103

请求示例

GET /incomeManage/getAccountBalance?storeId=103
curl "http://localhost:8080/incomeManage/getAccountBalance?storeId=103" \
  -H "Authorization: Bearer YOUR_TOKEN"

响应参数

成功响应

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "1234.56",
        "cashOutMoney": "567.89"
    },
    "msg": "操作成功"
}

响应字段说明

字段名 类型 说明
data.balance String 账户总余额(单位:元)
data.cashOutMoney String 可提现金额(单位:元)

字段详细说明

balance(账户总余额)

  • 定义: 店铺账户中的总金额
  • 来源: store_user 表的 money 字段
  • 单位: 元(已从分转换)
  • 精度: 保留2位小数
  • 说明: 包含所有收入,不受提现限制影响

cashOutMoney(可提现金额)

  • 定义: 当前可以申请提现的金额
  • 计算规则:

    可提现金额 = 4~27天内收入 - (已提现金额 + 待审核金额)
    
  • 时间范围: 收入创建时间在 [当前时间-27天, 当前时间-4天] 之间

  • 条件: 未绑定提现记录(cash_out_id 为空)

  • 扣除项:

    • 已提现金额(payment_status = 3
    • 待审核金额(payment_status = 1
  • 单位: 元(已从分转换)

  • 精度: 保留2位小数

失败响应

1. 店铺用户不存在

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "查询失败:店铺用户不存在"
}

2. 未登录或登录过期

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "请先登录"
}

3. 系统异常

{
    "code": 500,
    "success": false,
    "data": null,
    "msg": "查询失败:{异常信息}"
}

业务逻辑说明

查询流程

┌─────────────────────────────────────────────┐
│  1. 接收门店ID参数                            │
│  storeId                                     │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  2. 查询店铺用户信息                          │
│  根据 storeId 查询 store_user 表             │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  3. 获取账户总余额                            │
│  balance = money ÷ 100                       │
│  (分→元,保留2位小数)                      │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  4. 查询4~27天内的收入记录                   │
│  条件:                                      │
│  - created_time BETWEEN (now-27天, now-4天)  │
│  - cash_out_id IS NULL                       │
│  - store_id = ?                              │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  5. 计算4~27天内收入总额                     │
│  sum(money)                                  │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  6. 查询已提现和待审核记录                    │
│  条件:                                      │
│  - store_id = ?                              │
│  - payment_status IN (1, 3)                  │
│  - delete_flag = 0                           │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  7. 计算已提现+待审核总额                    │
│  sum(money)                                  │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  8. 计算可提现金额                            │
│  cashOutMoney = 收入总额 - 提现总额          │
│  转换为元(保留2位小数)                     │
└─────────────────┬───────────────────────────┘
                  ↓
┌─────────────────────────────────────────────┐
│  9. 返回结果                                  │
│  { balance, cashOutMoney }                   │
└─────────────────────────────────────────────┘

可提现金额计算规则

时间范围说明

当前时间: 2025-11-17
可提现收入时间范围: 2025-10-21 ~ 2025-11-13

计算公式:
- 开始时间 = 当前时间 - 27天
- 结束时间 = 当前时间 - 4天

为什么是4~27天?

  • 4天: 收入需要经过4天账期才能提现(风险控制期)
  • 27天: 超过27天的收入会自动结算或有其他处理

计算示例

场景1: 正常情况

4~27天内收入总额: 100000分(1000元)
已提现金额: 0分
待审核金额: 0分

可提现金额 = (100000 - 0) ÷ 100 = 1000.00元

场景2: 有待审核提现

4~27天内收入总额: 100000分(1000元)
已提现金额: 0分
待审核金额: 50000分(500元)

可提现金额 = (100000 - 50000) ÷ 100 = 500.00元

场景3: 有已提现记录

4~27天内收入总额: 100000分(1000元)
已提现金额: 30000分(300元)
待审核金额: 20000分(200元)

可提现金额 = (100000 - 30000 - 20000) ÷ 100 = 500.00元

场景4: 收入不足或已全部提现

4~27天内收入总额: 50000分(500元)
已提现金额: 50000分(500元)
待审核金额: 0分

可提现金额 = (50000 - 50000) ÷ 100 = 0.00元

数据库查询

涉及的表

1. store_user(店铺用户表)

查询SQL:

SELECT * FROM store_user
WHERE store_id = ?

说明:

  • 获取账户总余额(money 字段)
  • 单位:分

2. store_income_details_record(收入明细表)

查询SQL:

SELECT * FROM store_income_details_record
WHERE store_id = ?
  AND created_time BETWEEN ? AND ?  -- 4~27天
  AND cash_out_id IS NULL
  AND delete_flag = 0

说明:

  • 查询可提现的收入记录
  • cash_out_id IS NULL: 未绑定提现记录

3. store_cash_out_record(提现记录表)

查询SQL:

SELECT * FROM store_cash_out_record
WHERE store_id = ?
  AND payment_status IN ('1', '3')
  AND delete_flag = '0'

说明:

  • payment_status = 1: 待审核
  • payment_status = 3: 已提现
  • 这两种状态的金额需要从可提现金额中扣除

提现状态说明

payment_status 状态值

Status 说明 是否扣除
0 审核不通过 ❌ 不扣除
1 待审核 ✅ 扣除
2 审核通过待打款 ❌ 不扣除
3 已提现(已打款) ✅ 扣除

扣除规则说明:

  • 待审核(1): 提现申请已提交,资金被锁定,需要扣除
  • 已提现(3): 资金已打款,需要扣除
  • 其他状态: 提现未成功或未完成,不扣除

金额计算规则

金额单位转换

数据库存储(分) 显示(元) 转换公式
100000 1000.00 money ÷ 100
56789 567.89 money ÷ 100
0 0.00 money ÷ 100

转换代码

// 账户总余额转换
String balance = new BigDecimal(storeUser.getMoney())
    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)
    .toString();

// 可提现金额转换
BigDecimal finalCashOutMoney = new BigDecimal(cashOutMoney)
    .subtract(BigDecimal.valueOf(totalCashOutAmount))
    .divide(new BigDecimal(100), 2, RoundingMode.HALF_UP);

转换规则:

  • 使用 BigDecimal 进行精确计算
  • 除以100转换为元
  • 保留2位小数
  • 舍入模式:HALF_UP(四舍五入)

业务场景

场景 1: 新店铺(无收入)

数据状态:

  • 账户余额: 0分
  • 4~27天内收入: 0分
  • 已提现: 0分

响应:

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "0.00",
        "cashOutMoney": "0.00"
    }
}

场景 2: 有收入但未到提现期

数据状态:

  • 账户余额: 50000分(500元)
  • 4~27天内收入: 0分(收入都在4天内)
  • 已提现: 0分

响应:

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "500.00",
        "cashOutMoney": "0.00"
    }
}

说明: 账户有余额,但都是4天内的收入,还未到可提现期


场景 3: 有可提现金额

数据状态:

  • 账户余额: 150000分(1500元)
  • 4~27天内收入: 100000分(1000元)
  • 已提现: 0分

响应:

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "1500.00",
        "cashOutMoney": "1000.00"
    }
}

说明: 账户余额1500元,其中1000元可提现


场景 4: 有待审核提现

数据状态:

  • 账户余额: 150000分(1500元)
  • 4~27天内收入: 100000分(1000元)
  • 待审核提现: 60000分(600元)
  • 已提现: 0分

响应:

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "1500.00",
        "cashOutMoney": "400.00"
    }
}

说明:

  • 账户余额: 1500元(不变)
  • 可提现金额: 1000 - 600 = 400元

场景 5: 全部已提现

数据状态:

  • 账户余额: 50000分(500元)
  • 4~27天内收入: 100000分(1000元)
  • 已提现: 100000分(1000元)

响应:

{
    "code": 200,
    "success": true,
    "data": {
        "balance": "500.00",
        "cashOutMoney": "0.00"
    }
}

说明:

  • 账户余额: 500元(4天内的新收入)
  • 可提现金额: 1000 - 1000 = 0元(4~27天内收入已全部提现)

登录验证

验证机制

接口使用 @LoginRequired 注解进行登录验证,通过AOP切面实现:

  1. Token验证: 从请求中获取JWT Token并解析用户信息
  2. 用户类型验证: 确认用户类型为 storePlatform
  3. Redis Token验证: 检查Token是否在Redis中存在(未过期/未注销)

验证失败场景

场景 返回消息
Token无效或不存在 "请先登录"
用户类型不正确 "请先登录"
Token已过期或已注销 "请先登录"

异常处理

异常场景

异常情况 HTTP状态码 返回code 返回msg
店铺用户不存在 200 500 "查询失败:店铺用户不存在"
未登录 200 500 "请先登录"
系统异常 200 500 "查询失败:{异常信息}"

日志记录

所有请求和异常都会记录详细日志:

// 请求日志
log.info("IncomeManageController.getAccountBalance?storeId={}", storeId);

// 业务日志
log.debug("IncomeManageServiceImpl.getAccountBalance - 账户总余额: {}元", balance);
log.debug("IncomeManageServiceImpl.getAccountBalance - 4~27天内收入总额: {}分", cashOutMoney);

// 异常日志
log.error("IncomeManageController.getAccountBalance ERROR: {}", e.getMessage(), e);

测试用例

测试场景1: 正常查询

请求:

GET /incomeManage/getAccountBalance?storeId=103

预期结果:

  • 返回账户总余额和可提现金额
  • 两个金额都是字符串格式
  • 保留2位小数

测试场景2: 新店铺(无数据)

前置条件:

  • 店铺刚注册
  • 无任何收入记录

预期结果:

{
    "balance": "0.00",
    "cashOutMoney": "0.00"
}

测试场景3: 有待审核提现

前置条件:

  • 有4~27天内的收入
  • 有待审核的提现申请

预期结果:

  • cashOutMoney 应扣除待审核金额
  • balance 不受影响

测试场景4: 店铺不存在

请求:

GET /incomeManage/getAccountBalance?storeId=999999

预期结果:

{
    "code": 500,
    "success": false,
    "msg": "查询失败:店铺用户不存在"
}

注意事项

1. 账期时间范围

  • ⚠️ 可提现时间: 收入创建后4~27天
  • ⚠️ 4天: 最少账期时间(风险控制期)
  • ⚠️ 27天: 最长账期时间(自动结算期)

2. 金额计算

  • ⚠️ 数据库单位: 分(Integer)
  • ⚠️ 接口返回: 元(String)
  • ⚠️ 转换规则: 分 ÷ 100 = 元
  • ⚠️ 精度: 保留2位小数
  • ⚠️ 舍入模式: HALF_UP(四舍五入)

3. 提现状态

  • ⚠️ 扣除状态: 待审核(1)、已提现(3)
  • ⚠️ 不扣除状态: 审核不通过(0)、审核通过待打款(2)

4. 数据一致性

  • ⚠️ balance(账户总余额): 来自 store_user.money
  • ⚠️ cashOutMoney(可提现金额): 计算得出,受多个因素影响
  • ⚠️ 两个金额的关系: balance >= cashOutMoney(总是成立)

5. 登录验证

  • ⚠️ 所有请求必须携带有效Token
  • ⚠️ Token过期需要重新登录
  • ⚠️ 用户类型必须为 storePlatform

性能优化建议

1. 数据库索引

确保以下字段有索引:

-- store_user表
ALTER TABLE store_user ADD INDEX idx_store_id (store_id);

-- store_income_details_record表
ALTER TABLE store_income_details_record 
ADD INDEX idx_store_created_cashout (store_id, created_time, cash_out_id);

-- store_cash_out_record表
ALTER TABLE store_cash_out_record 
ADD INDEX idx_store_status (store_id, payment_status, delete_flag);

2. 查询优化

  • ✅ 使用复合索引加速查询
  • ✅ 时间范围查询使用 BETWEEN
  • ✅ 使用 Stream API 高效计算总和

3. 缓存策略

对于频繁查询的数据,可以考虑:

  • Redis缓存账户余额(TTL: 1分钟)
  • 在余额变更时清除缓存
  • 可提现金额实时计算(不建议缓存)

迁移说明

原接口(app端)

  • 服务: alien-store
  • 路径: /alienStore/storeIncomeDetailsRecord/accountBalance
  • Controller: StoreIncomeDetailsRecordController
  • Service: StoreIncomeDetailsRecordService.accountBalance()

新接口(web端)

  • 服务: alien-store-platform
  • 路径: /incomeManage/getAccountBalance
  • Controller: IncomeManageController
  • Service: IncomeManageService.getAccountBalance()

差异说明

复用的核心组件

  1. Mapper:
    • StoreUserMapper
    • StoreIncomeDetailsRecordMapper
    • StoreCashOutRecordMapper
  2. Entity:
    • StoreUser
    • StoreIncomeDetailsRecord
    • StoreCashOutRecord
  3. Util: DateUtils

更新日志

2025-11-17

新增接口:

  • GET /incomeManage/getAccountBalance - 查询账户余额

核心功能:

  • ✅ 查询账户总余额
  • ✅ 计算可提现金额(4~27天内收入)
  • ✅ 扣除已提现和待审核金额
  • ✅ 金额自动格式化(分→元)
  • ✅ 登录验证(@LoginRequired
  • ✅ 详细日志记录
  • ✅ 完善异常处理

涉及文件:

  • IncomeManageController.java - 更新
  • IncomeManageService.java - 更新
  • IncomeManageServiceImpl.java - 更新

代码质量:

  • ✅ Linter检查:无错误
  • ✅ 日志记录:详细
  • ✅ 异常处理:完善
  • ✅ 代码注释:完整

开发人员: ssk


文档版本: v1.0
最后更新: 2025-11-17
维护人员: ssk

项目 app端 web端 说明
接口路径 /accountBalance /getAccountBalance 更符合web端命名规范
登录验证 ✅ 有(@LoginRequired 增加登录验证
返回类型 Map Map 保持一致
业务逻辑 完全复用
日志记录 基础 详细 增强日志记录