|
@@ -353,10 +353,11 @@ public class AlipayBatchPayService {
|
|
|
|
|
|
|
|
/** alipay.fund.trans.render.pay — 生成 PC 支付页链接 */
|
|
/** alipay.fund.trans.render.pay — 生成 PC 支付页链接 */
|
|
|
public Map<String, String> renderPay(String enterpriseId, String outBatchNo) {
|
|
public Map<String, String> renderPay(String enterpriseId, String outBatchNo) {
|
|
|
|
|
+ requireEnterpriseId(enterpriseId);
|
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
|
- .eq(enterpriseId != null && !enterpriseId.isBlank(), BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
|
|
|
|
+ .eq(BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
|
if (!"INIT".equals(order.getStatus()))
|
|
if (!"INIT".equals(order.getStatus()))
|
|
|
throw new BusinessException(400, "仅受理中的批次可支付,当前状态: " + order.getStatus());
|
|
throw new BusinessException(400, "仅受理中的批次可支付,当前状态: " + order.getStatus());
|
|
@@ -381,10 +382,11 @@ public class AlipayBatchPayService {
|
|
|
|
|
|
|
|
/** alipay.fund.batch.detail.query — 查询批次+明细状态并回写 DB */
|
|
/** alipay.fund.batch.detail.query — 查询批次+明细状态并回写 DB */
|
|
|
public Map<String, Object> batchQuery(String enterpriseId, String outBatchNo) {
|
|
public Map<String, Object> batchQuery(String enterpriseId, String outBatchNo) {
|
|
|
|
|
+ requireEnterpriseId(enterpriseId);
|
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
|
- .eq(enterpriseId != null && !enterpriseId.isBlank(), BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
|
|
|
|
+ .eq(BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
|
try {
|
|
try {
|
|
|
AlipayFundBatchDetailQueryModel model = new AlipayFundBatchDetailQueryModel();
|
|
AlipayFundBatchDetailQueryModel model = new AlipayFundBatchDetailQueryModel();
|
|
@@ -437,10 +439,11 @@ public class AlipayBatchPayService {
|
|
|
|
|
|
|
|
/** alipay.fund.batch.close — 主动关闭未支付批次 */
|
|
/** alipay.fund.batch.close — 主动关闭未支付批次 */
|
|
|
public Map<String, String> batchClose(String enterpriseId, String outBatchNo) {
|
|
public Map<String, String> batchClose(String enterpriseId, String outBatchNo) {
|
|
|
|
|
+ requireEnterpriseId(enterpriseId);
|
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
|
- .eq(enterpriseId != null && !enterpriseId.isBlank(), BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
|
|
|
|
+ .eq(BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
|
// 与 renderPay 一致的前置守卫: 仅 INIT 状态可关闭(提前给友好提示而非透传支付宝原文案)
|
|
// 与 renderPay 一致的前置守卫: 仅 INIT 状态可关闭(提前给友好提示而非透传支付宝原文案)
|
|
|
if (!"INIT".equals(order.getStatus()))
|
|
if (!"INIT".equals(order.getStatus()))
|
|
@@ -499,10 +502,10 @@ public class AlipayBatchPayService {
|
|
|
.eq(status != null && !status.isBlank(), BatchOrderEntity::getStatus, status)
|
|
.eq(status != null && !status.isBlank(), BatchOrderEntity::getStatus, status)
|
|
|
.orderByDesc(BatchOrderEntity::getId);
|
|
.orderByDesc(BatchOrderEntity::getId);
|
|
|
if (startTime != null && !startTime.isBlank()) {
|
|
if (startTime != null && !startTime.isBlank()) {
|
|
|
- w.ge(BatchOrderEntity::getCreatedTime, parseTimeFilter(startTime, ":00+08:00"));
|
|
|
|
|
|
|
+ w.ge(BatchOrderEntity::getCreatedTime, parseTimeFilter(startTime, false));
|
|
|
}
|
|
}
|
|
|
if (endTime != null && !endTime.isBlank()) {
|
|
if (endTime != null && !endTime.isBlank()) {
|
|
|
- w.le(BatchOrderEntity::getCreatedTime, parseTimeFilter(endTime, ":59+08:00"));
|
|
|
|
|
|
|
+ w.le(BatchOrderEntity::getCreatedTime, parseTimeFilter(endTime, true));
|
|
|
}
|
|
}
|
|
|
var r = batchOrderMapper.selectPage(new Page<>(pageNo, pageSize), w);
|
|
var r = batchOrderMapper.selectPage(new Page<>(pageNo, pageSize), w);
|
|
|
return PageResult.of(pageNo, pageSize, r.getTotal(), r.getRecords());
|
|
return PageResult.of(pageNo, pageSize, r.getTotal(), r.getRecords());
|
|
@@ -510,26 +513,36 @@ public class AlipayBatchPayService {
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
|
* 时间参数解析: "yyyy-MM-dd HH:mm" 或纯日期 "yyyy-MM-dd" → OffsetDateTime;
|
|
* 时间参数解析: "yyyy-MM-dd HH:mm" 或纯日期 "yyyy-MM-dd" → OffsetDateTime;
|
|
|
- * 10 位纯日期补当天零点(起始)/23:59(结束,与 AccountService.parseDateTime 行为对齐);
|
|
|
|
|
|
|
+ * 10 位纯日期按 endOfDay 补当天 00:00:00 / 23:59:59(与 AccountService.parseDateTime 行为对齐);
|
|
|
* 非法格式抛 400(而非 DateTimeParseException→500)
|
|
* 非法格式抛 400(而非 DateTimeParseException→500)
|
|
|
*/
|
|
*/
|
|
|
- private static OffsetDateTime parseTimeFilter(String time, String suffix) {
|
|
|
|
|
|
|
+ static OffsetDateTime parseTimeFilter(String time, boolean endOfDay) {
|
|
|
try {
|
|
try {
|
|
|
- // 10 位纯日期: 补 " 00:00",结束侧 suffix 会把秒替换为 :59 → 当天 23:59:59
|
|
|
|
|
- String t = time.length() == 10 ? time + " 00:00" : time;
|
|
|
|
|
|
|
+ if (time.length() == 10) {
|
|
|
|
|
+ // 10 位纯日期: 起始补 " 00:00"+":00" → 00:00:00;结束补 " 23:59"+":59" → 23:59:59
|
|
|
|
|
+ String t = time + (endOfDay ? " 23:59" : " 00:00");
|
|
|
|
|
+ return OffsetDateTime.parse(t.replace(' ', 'T') + (endOfDay ? ":59+08:00" : ":00+08:00"));
|
|
|
|
|
+ }
|
|
|
// "yyyy-MM-dd HH:mm" → "yyyy-MM-ddTHH:mm:00+08:00"(ISO 默认模式,无需自定义格式器)
|
|
// "yyyy-MM-dd HH:mm" → "yyyy-MM-ddTHH:mm:00+08:00"(ISO 默认模式,无需自定义格式器)
|
|
|
- return OffsetDateTime.parse(t.replace(' ', 'T') + suffix);
|
|
|
|
|
|
|
+ return OffsetDateTime.parse(time.replace(' ', 'T') + ":00+08:00");
|
|
|
} catch (DateTimeParseException e) {
|
|
} catch (DateTimeParseException e) {
|
|
|
throw new BusinessException(400, "时间参数格式错误:应形如 yyyy-MM-dd HH:mm");
|
|
throw new BusinessException(400, "时间参数格式错误:应形如 yyyy-MM-dd HH:mm");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /** 租户隔离: 企业 ID 是业务必需参数,为空直接拒绝(防御 Controller body 路径的零校验) */
|
|
|
|
|
+ private static void requireEnterpriseId(String enterpriseId) {
|
|
|
|
|
+ if (enterpriseId == null || enterpriseId.isBlank())
|
|
|
|
|
+ throw new BusinessException(400, "缺少企业ID");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
/** 批次详情 + 明细分页(enterprise_id 租户隔离,参照 batchList 过滤写法) */
|
|
/** 批次详情 + 明细分页(enterprise_id 租户隔离,参照 batchList 过滤写法) */
|
|
|
public Map<String, Object> batchDetail(String enterpriseId, String outBatchNo, int pageNo, int pageSize) {
|
|
public Map<String, Object> batchDetail(String enterpriseId, String outBatchNo, int pageNo, int pageSize) {
|
|
|
|
|
+ requireEnterpriseId(enterpriseId);
|
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
BatchOrderEntity order = batchOrderMapper.selectOne(
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchOrderEntity>()
|
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
.eq(BatchOrderEntity::getOutBatchNo, outBatchNo)
|
|
|
- .eq(enterpriseId != null && !enterpriseId.isBlank(), BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
|
|
|
|
+ .eq(BatchOrderEntity::getEnterpriseId, enterpriseId));
|
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
if (order == null) throw new BusinessException(404, "批次不存在");
|
|
|
Page<BatchDetailEntity> detailPage = batchDetailMapper.selectPage(new Page<>(pageNo, pageSize),
|
|
Page<BatchDetailEntity> detailPage = batchDetailMapper.selectPage(new Page<>(pageNo, pageSize),
|
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchDetailEntity>()
|
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<BatchDetailEntity>()
|
|
@@ -547,10 +560,10 @@ public class AlipayBatchPayService {
|
|
|
.eq(status != null && !status.isBlank(), BatchOrderEntity::getStatus, status)
|
|
.eq(status != null && !status.isBlank(), BatchOrderEntity::getStatus, status)
|
|
|
.orderByDesc(BatchOrderEntity::getId);
|
|
.orderByDesc(BatchOrderEntity::getId);
|
|
|
if (startTime != null && !startTime.isBlank()) {
|
|
if (startTime != null && !startTime.isBlank()) {
|
|
|
- w.ge(BatchOrderEntity::getCreatedTime, parseTimeFilter(startTime, ":00+08:00"));
|
|
|
|
|
|
|
+ w.ge(BatchOrderEntity::getCreatedTime, parseTimeFilter(startTime, false));
|
|
|
}
|
|
}
|
|
|
if (endTime != null && !endTime.isBlank()) {
|
|
if (endTime != null && !endTime.isBlank()) {
|
|
|
- w.le(BatchOrderEntity::getCreatedTime, parseTimeFilter(endTime, ":59+08:00"));
|
|
|
|
|
|
|
+ w.le(BatchOrderEntity::getCreatedTime, parseTimeFilter(endTime, true));
|
|
|
}
|
|
}
|
|
|
List<BatchOrderEntity> records = batchOrderMapper.selectList(w);
|
|
List<BatchOrderEntity> records = batchOrderMapper.selectList(w);
|
|
|
// 列: 序号/批次号/支付宝批次号/标题/金额(元)/笔数/状态/创建时间/错误信息
|
|
// 列: 序号/批次号/支付宝批次号/标题/金额(元)/笔数/状态/创建时间/错误信息
|
|
@@ -595,8 +608,6 @@ public class AlipayBatchPayService {
|
|
|
} catch (BusinessException e) {
|
|
} catch (BusinessException e) {
|
|
|
// parseTimeFilter 已抛 400(非法时间),不得被兜底包装成 500
|
|
// parseTimeFilter 已抛 400(非法时间),不得被兜底包装成 500
|
|
|
throw e;
|
|
throw e;
|
|
|
- } catch (DateTimeParseException e) {
|
|
|
|
|
- throw new BusinessException(400, "时间参数格式错误:应形如 yyyy-MM-dd HH:mm");
|
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("导出批次报表失败", e);
|
|
log.error("导出批次报表失败", e);
|
|
|
throw new RuntimeException("导出批次报表失败: " + e.getMessage());
|
|
throw new RuntimeException("导出批次报表失败: " + e.getMessage());
|