本模块提供收入账期查询功能,支持按时间范围、收入类型、账期类型查询店铺的收入明细数据。
GET /incomeManage/getPaymentCycle@LoginRequired 注解)| 参数名 | 类型 | 必填 | 说明 | 示例值 |
|---|---|---|---|---|
| storeId | Integer | 是 | 门店ID | 103 |
| incomeType | Integer | 否 | 收入类型 0:主页(优惠券+团购券) 1:优惠券 2:代金券 3:套餐 4:联名卡 |
0 |
| paymentType | Integer | 否 | 账期类型 0:未到账期 1:已到账期 |
0 |
| startTime | String | 是 | 开始时间(格式:yyyy-MM-dd) | 2025-11-09 |
| endTime | String | 是 | 结束时间(格式:yyyy-MM-dd) | 2025-11-11 |
| page | Integer | 否 | 页码(默认1) | 1 |
| size | Integer | 否 | 每页条数(默认10) | 10 |
GET /incomeManage/getPaymentCycle?storeId=103&incomeType=0&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10
curl "http://localhost:8080/incomeManage/getPaymentCycle?storeId=103&incomeType=0&paymentType=0&startTime=2025-11-09&endTime=2025-11-11&page=1&size=10" \
-H "Authorization: Bearer YOUR_TOKEN"
{
"code": 200,
"success": true,
"data": {
"date": "2025-11-11 ~ 2025-11-14",
"data": {
"records": [
{
"id": 12345,
"storeId": 103,
"userOrderId": 67890,
"incomeType": 1,
"businessId": 111,
"money": 9600,
"moneyStr": "96.00",
"commission": 400,
"cashOutId": null,
"createdTime": "2025-11-11T10:30:00",
"date": "2025-11-11",
"orderTime": "2025-11-11T10:00:00",
"checkTime": "2025-11-11T10:30:00",
"incomeTime": "2025-11-15T10:30:00",
"couponName": "100元代金券"
}
],
"total": 50,
"size": 10,
"current": 1,
"pages": 5
},
"money": "4800.00"
},
"msg": "操作成功"
}
| 字段名 | 类型 | 说明 |
|---|---|---|
| data.date | String | 账期时间范围 |
| data.data | Object | 分页数据对象 |
| data.data.records | Array | 收入明细记录列表 |
| data.data.records[].id | Integer | 收入记录ID |
| data.data.records[].storeId | Integer | 门店ID |
| data.data.records[].userOrderId | Integer | 用户订单ID |
| data.data.records[].incomeType | Integer | 收入类型 1-优惠券 2-团购券 |
| data.data.records[].businessId | Integer | 业务ID(券ID) |
| data.data.records[].money | Integer | 收入金额(分) |
| data.data.records[].moneyStr | String | 收入金额(元,格式化后) |
| data.data.records[].commission | Integer | 抽成金额(分) |
| data.data.records[].cashOutId | Integer | 提现记录ID(null表示未提现) |
| data.data.records[].createdTime | String | 创建时间 |
| data.data.records[].date | String | 日期(格式化) |
| data.data.records[].orderTime | String | 订单时间 |
| data.data.records[].checkTime | String | 核销时间 |
| data.data.records[].incomeTime | String | 到账时间(创建时间+4天) |
| data.data.records[].couponName | String | 券名称 |
| data.data.total | Integer | 总记录数 |
| data.data.size | Integer | 每页条数 |
| data.data.current | Integer | 当前页码 |
| data.data.pages | Integer | 总页数 |
| data.money | String | 汇总金额(元) |
{
"code": 500,
"success": false,
"data": null,
"msg": "查询失败:门店不存在"
}
{
"code": 500,
"success": false,
"data": null,
"msg": "请先登录"
}
{
"code": 500,
"success": false,
"data": null,
"msg": "查询失败:日期格式错误"
}
cash_out_id 为空(未绑定提现记录)cash_out_id 不为空(已绑定提现记录)| incomeType | 名称 | 说明 |
|---|---|---|
| 0 | 主页 | 包含优惠券(1)和团购券(2) |
| 1 | 优惠券 | 仅优惠券收入 |
| 2 | 代金券 | 仅代金券收入 |
| 3 | 套餐 | 仅套餐收入 |
| 4 | 联名卡 | 仅联名卡收入 |
┌─────────────────────────────────────────────┐
│ 1. 接收查询参数 │
│ storeId, incomeType, paymentType, │
│ startTime, endTime, page, size │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 2. 构建查询条件(QueryWrapper) │
│ - 根据 paymentType 设置账期条件 │
│ - 根据 storeId 筛选门店 │
│ - 根据 startTime/endTime 设置时间范围 │
│ - 根据 incomeType 设置收入类型 │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 3. 查询收入明细记录(Mapper) │
│ 调用 selectRecordList(wrapper) │
│ 返回 List<StoreIncomeDetailsRecordVo> │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 4. 查询门店信息 │
│ 获取抽成比例 commissionRate │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 5. 处理列表数据 │
│ - 金额格式化(分→元,保留2位小数) │
│ - 日期格式化(yyyy-MM-dd) │
│ - 设置抽成比例 │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 6. 手动分页 │
│ 使用 ListToPage.setPage(list, page, size) │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 7. 计算汇总金额 │
│ stream().mapToInt(money).sum() │
│ 转换为元并格式化 │
└─────────────────┬───────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 8. 返回结果 │
│ JSONObject包含: date, data, money │
└─────────────────────────────────────────────┘
查询SQL(简化版):
SELECT
sidr.id,
sidr.money,
sidr.commission,
sidr.created_time checkTime,
luo.buy_time orderTime,
ADDDATE(sidr.created_time, 4) incomeTime,
sidr.income_type,
tc.name couponName
FROM store_income_details_record sidr
LEFT JOIN order_coupon_middle ocm ON ocm.id = sidr.user_order_id
LEFT JOIN life_user_order luo ON luo.id = ocm.order_id
LEFT JOIN totalCoupon tc ON tc.id = sidr.business_id
WHERE sidr.store_id = ?
AND sidr.created_time BETWEEN ? AND ?
-- 根据 paymentType 添加条件
AND (sidr.cash_out_id IS NULL OR sidr.cash_out_id IS NOT NULL)
-- 根据 incomeType 添加条件
AND sidr.income_type IN (1, 2) OR sidr.income_type = ?
ORDER BY sidr.created_time DESC
SELECT * FROM store_info WHERE id = ?
| 数据库存储(分) | 显示(元) | 转换公式 |
|---|---|---|
| 9600 | 96.00 | money ÷ 100 |
| 400 | 4.00 | commission ÷ 100 |
// 1. 累加所有记录的金额(分)
int totalMoney = list.stream()
.mapToInt(StoreIncomeDetailsRecord::getMoney)
.sum();
// 2. 转换为元(保留2位小数)
String moneyStr = new BigDecimal(totalMoney)
.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP)
.toString();
示例:
记录1: 9600分
记录2: 8800分
记录3: 10200分
汇总: (9600 + 8800 + 10200) ÷ 100 = 286.00元
使用 ListToPage.setPage() 工具类进行内存分页:
IPage<StoreIncomeDetailsRecordVo> pageResult =
ListToPage.setPage(list, page, size);
总记录数: 50
每页条数: 10
总页数: Math.ceil(50 ÷ 10) = 5
第1页: records[0-9]
第2页: records[10-19]
第3页: records[20-29]
...
{
"records": [...], // 当前页数据
"total": 50, // 总记录数
"size": 10, // 每页条数
"current": 1, // 当前页码
"pages": 5 // 总页数
}
接口使用 @LoginRequired 注解进行登录验证,通过AOP切面实现:
storePlatform| 场景 | 返回消息 |
|---|---|
| Token无效或不存在 | "请先登录" |
| 用户类型不正确 | "请先登录" |
| Token已过期或已注销 | "请先登录" |
| 异常情况 | HTTP状态码 | 返回code | 返回msg |
|---|---|---|---|
| 门店不存在 | 200 | 500 | "查询失败:门店不存在" |
| 日期格式错误 | 200 | 500 | "查询失败:日期格式错误" |
| 未登录 | 200 | 500 | "请先登录" |
| 系统异常 | 200 | 500 | "查询失败:{异常信息}" |
所有请求和异常都会记录详细日志:
// 请求日志
log.info("IncomeManageController.getPaymentCycle?storeId={}, incomeType={}, ...", ...);
// 查询日志
log.info("IncomeManageServiceImpl.getPaymentCycle - 查询到收入记录数: {}", list.size());
// 异常日志
log.error("IncomeManageController.getPaymentCycle ERROR: {}", e.getMessage(), e);
当前时间: 2025-11-14
未到账期范围: 2025-11-11 ~ 2025-11-14
计算公式: [当前时间-3天, 当前时间]
当前时间: 2025-11-14
已到账期范围: 2025-10-18 ~ 2025-11-10
计算公式: [当前时间-27天, 当前时间-4天]
核销时间: 2025-11-11 10:30:00
到账时间: 2025-11-15 10:30:00
计算公式: 核销时间 + 4天
if (incomeType == 0) {
// 主页: 查询优惠券(1) + 团购券(2)
wrapper.in("income_type", 1, 2);
} else if (incomeType != null) {
// 指定类型: 精确匹配
wrapper.eq("income_type", incomeType);
}
// incomeType为null: 不添加类型条件,查询所有
请求:
GET /incomeManage/getPaymentCycle?storeId=103&paymentType=0&startTime=2025-11-09&endTime=2025-11-14&page=1&size=10
预期结果:
请求:
GET /incomeManage/getPaymentCycle?storeId=103&paymentType=1&startTime=2025-10-18&endTime=2025-11-10&page=1&size=10
预期结果:
请求:
GET /incomeManage/getPaymentCycle?storeId=103&incomeType=0&startTime=2025-11-09&endTime=2025-11-14&page=1&size=10
预期结果:
请求:
GET /incomeManage/getPaymentCycle?storeId=103&startTime=2025-11-01&endTime=2025-11-14&page=2&size=5
预期结果:
请求:
GET /incomeManage/getPaymentCycle?storeId=999999&startTime=2025-11-09&endTime=2025-11-14&page=1&size=10
预期结果:
alien-store/alienStore/storeIncomeDetailsRecord/noYetPaymentStoreIncomeDetailsRecordControllerStoreIncomeDetailsRecordService.noYetPayment()alien-store-platform/incomeManage/getPaymentCycleIncomeManageControllerIncomeManageService.getPaymentCycle()| 项目 | app端 | web端 | 说明 |
|---|---|---|---|
| 接口路径 | /noYetPayment |
/getPaymentCycle |
更符合web端命名规范 |
| 登录验证 | 无 | ✅ 有(@LoginRequired) | 增加登录验证 |
| 返回类型 | JSONObject | JSONObject | 保持一致 |
| 业务逻辑 | ✅ | ✅ | 完全复用 |
| 日志记录 | 基础 | 详细 | 增强日志记录 |
StoreIncomeDetailsRecordMapper.selectRecordList()StoreIncomeDetailsRecord, StoreIncomeDetailsRecordVoCouponTypeEnumListToPage, DateUtils确保以下字段有索引:
-- store_income_details_record表
ALTER TABLE store_income_details_record
ADD INDEX idx_store_created (store_id, created_time);
ALTER TABLE store_income_details_record
ADD INDEX idx_cashout_created (cash_out_id, created_time);
ALTER TABLE store_income_details_record
ADD INDEX idx_income_type (income_type);
对于频繁查询的数据,可以考虑:
yyyy-MM-dd 格式(如:2025-11-09)storePlatform新增接口:
GET /incomeManage/getPaymentCycle - 账期查询核心功能:
涉及文件:
IncomeManageController.java - 新建IncomeManageService.java - 新建IncomeManageServiceImpl.java - 新建代码质量:
开发人员: ssk
文档版本: v1.0
最后更新: 2025-11-14
维护人员: ssk