feat: 新增提现审计接口与保障用例
This commit is contained in:
@@ -3,6 +3,9 @@ package com.starry.admin.modules.withdraw.controller;
|
|||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.starry.admin.common.exception.CustomException;
|
||||||
|
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
||||||
|
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
|
||||||
import com.starry.admin.modules.withdraw.entity.EarningsBackfillLogEntity;
|
import com.starry.admin.modules.withdraw.entity.EarningsBackfillLogEntity;
|
||||||
import com.starry.admin.modules.withdraw.entity.EarningsLineEntity;
|
import com.starry.admin.modules.withdraw.entity.EarningsLineEntity;
|
||||||
import com.starry.admin.modules.withdraw.entity.WithdrawalLogEntity;
|
import com.starry.admin.modules.withdraw.entity.WithdrawalLogEntity;
|
||||||
@@ -13,6 +16,7 @@ import com.starry.admin.modules.withdraw.service.IEarningsService;
|
|||||||
import com.starry.admin.modules.withdraw.service.ITenantAlipayConfigService;
|
import com.starry.admin.modules.withdraw.service.ITenantAlipayConfigService;
|
||||||
import com.starry.admin.modules.withdraw.service.IWithdrawalLogService;
|
import com.starry.admin.modules.withdraw.service.IWithdrawalLogService;
|
||||||
import com.starry.admin.modules.withdraw.service.IWithdrawalService;
|
import com.starry.admin.modules.withdraw.service.IWithdrawalService;
|
||||||
|
import com.starry.admin.modules.withdraw.vo.ClerkEarningLineVo;
|
||||||
import com.starry.admin.modules.withdraw.vo.EarningsAdminQueryVo;
|
import com.starry.admin.modules.withdraw.vo.EarningsAdminQueryVo;
|
||||||
import com.starry.admin.modules.withdraw.vo.EarningsAdminSummaryVo;
|
import com.starry.admin.modules.withdraw.vo.EarningsAdminSummaryVo;
|
||||||
import com.starry.admin.modules.withdraw.vo.EarningsBackfillRequest;
|
import com.starry.admin.modules.withdraw.vo.EarningsBackfillRequest;
|
||||||
@@ -24,11 +28,15 @@ import io.swagger.annotations.Api;
|
|||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -49,6 +57,8 @@ public class AdminWithdrawalController {
|
|||||||
private IEarningsBackfillService earningsBackfillService;
|
private IEarningsBackfillService earningsBackfillService;
|
||||||
@Resource
|
@Resource
|
||||||
private IEarningsBackfillLogService backfillLogService;
|
private IEarningsBackfillLogService backfillLogService;
|
||||||
|
@Resource
|
||||||
|
private IPlayOrderInfoService orderInfoService;
|
||||||
|
|
||||||
@ApiOperation("分页查询提现请求")
|
@ApiOperation("分页查询提现请求")
|
||||||
@PostMapping("/requests/listByPage")
|
@PostMapping("/requests/listByPage")
|
||||||
@@ -72,6 +82,62 @@ public class AdminWithdrawalController {
|
|||||||
return TypedR.ok(list);
|
return TypedR.ok(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("提现请求审计")
|
||||||
|
@GetMapping("/requests/{id}/audit")
|
||||||
|
public TypedR<List<ClerkEarningLineVo>> getRequestAudit(@PathVariable("id") String id) {
|
||||||
|
String tenantId = SecurityUtils.getTenantId();
|
||||||
|
WithdrawalRequestEntity request = withdrawalService.getById(id);
|
||||||
|
if (request == null || !tenantId.equals(request.getTenantId())) {
|
||||||
|
throw new CustomException("提现申请不存在或无权查看");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EarningsLineEntity> lines = earningsService.lambdaQuery()
|
||||||
|
.eq(EarningsLineEntity::getTenantId, tenantId)
|
||||||
|
.eq(EarningsLineEntity::getWithdrawalId, id)
|
||||||
|
.orderByAsc(EarningsLineEntity::getCreatedTime)
|
||||||
|
.list();
|
||||||
|
if (lines.isEmpty()) {
|
||||||
|
return TypedR.ok(Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> orderIds = lines.stream()
|
||||||
|
.map(EarningsLineEntity::getOrderId)
|
||||||
|
.filter(orderId -> orderId != null && !orderId.isEmpty())
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
Map<String, PlayOrderInfoEntity> orderMap = orderIds.isEmpty()
|
||||||
|
? Collections.emptyMap()
|
||||||
|
: orderInfoService.lambdaQuery()
|
||||||
|
.eq(PlayOrderInfoEntity::getTenantId, tenantId)
|
||||||
|
.in(PlayOrderInfoEntity::getId, orderIds)
|
||||||
|
.list()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(PlayOrderInfoEntity::getId, it -> it));
|
||||||
|
|
||||||
|
List<ClerkEarningLineVo> vos = new ArrayList<>(lines.size());
|
||||||
|
for (EarningsLineEntity line : lines) {
|
||||||
|
ClerkEarningLineVo vo = new ClerkEarningLineVo();
|
||||||
|
vo.setId(line.getId());
|
||||||
|
vo.setAmount(line.getAmount());
|
||||||
|
vo.setStatus(line.getStatus());
|
||||||
|
vo.setEarningType(line.getEarningType());
|
||||||
|
vo.setWithdrawalId(line.getWithdrawalId());
|
||||||
|
vo.setUnlockTime(line.getUnlockTime());
|
||||||
|
vo.setCreatedTime(toLocalDateTime(line.getCreatedTime()));
|
||||||
|
vo.setOrderId(line.getOrderId());
|
||||||
|
if (line.getOrderId() != null) {
|
||||||
|
PlayOrderInfoEntity order = orderMap.get(line.getOrderId());
|
||||||
|
if (order != null) {
|
||||||
|
vo.setOrderNo(order.getOrderNo());
|
||||||
|
vo.setOrderStatus(order.getOrderStatus());
|
||||||
|
vo.setOrderEndTime(toLocalDateTime(order.getOrderEndTime()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vos.add(vo);
|
||||||
|
}
|
||||||
|
return TypedR.ok(vos);
|
||||||
|
}
|
||||||
|
|
||||||
@ApiOperation("分页查询收益明细")
|
@ApiOperation("分页查询收益明细")
|
||||||
@PostMapping("/earnings/listByPage")
|
@PostMapping("/earnings/listByPage")
|
||||||
public TypedR<List<EarningsLineEntity>> listEarnings(@RequestBody EarningsAdminQueryVo vo) {
|
public TypedR<List<EarningsLineEntity>> listEarnings(@RequestBody EarningsAdminQueryVo vo) {
|
||||||
@@ -182,4 +248,17 @@ public class AdminWithdrawalController {
|
|||||||
q.orderByDesc(EarningsLineEntity::getCreatedTime);
|
q.orderByDesc(EarningsLineEntity::getCreatedTime);
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LocalDateTime toLocalDateTime(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value instanceof LocalDateTime) {
|
||||||
|
return (LocalDateTime) value;
|
||||||
|
}
|
||||||
|
if (value instanceof Date) {
|
||||||
|
return ((Date) value).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,292 @@
|
|||||||
|
package com.starry.admin.api;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.nullValue;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||||
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.starry.admin.common.apitest.ApiTestDataSeeder;
|
||||||
|
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
|
||||||
|
import com.starry.admin.modules.order.service.IPlayOrderInfoService;
|
||||||
|
import com.starry.admin.modules.withdraw.entity.EarningsLineEntity;
|
||||||
|
import com.starry.admin.modules.withdraw.entity.WithdrawalRequestEntity;
|
||||||
|
import com.starry.admin.modules.withdraw.enums.EarningsType;
|
||||||
|
import com.starry.admin.modules.withdraw.service.IEarningsService;
|
||||||
|
import com.starry.admin.modules.withdraw.service.IWithdrawalService;
|
||||||
|
import com.starry.admin.utils.SecurityUtils;
|
||||||
|
import com.starry.common.utils.IdUtils;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
|
|
||||||
|
class AdminWithdrawalControllerApiTest extends AbstractApiTest {
|
||||||
|
|
||||||
|
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEarningsService earningsService;
|
||||||
|
@Autowired
|
||||||
|
private IWithdrawalService withdrawalService;
|
||||||
|
@Autowired
|
||||||
|
private IPlayOrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
private final List<String> earningsToCleanup = new ArrayList<>();
|
||||||
|
private final List<String> withdrawalsToCleanup = new ArrayList<>();
|
||||||
|
private final List<String> ordersToCleanup = new ArrayList<>();
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void tearDown() {
|
||||||
|
if (!earningsToCleanup.isEmpty()) {
|
||||||
|
earningsService.removeByIds(earningsToCleanup);
|
||||||
|
earningsToCleanup.clear();
|
||||||
|
}
|
||||||
|
if (!withdrawalsToCleanup.isEmpty()) {
|
||||||
|
withdrawalService.removeByIds(withdrawalsToCleanup);
|
||||||
|
withdrawalsToCleanup.clear();
|
||||||
|
}
|
||||||
|
if (!ordersToCleanup.isEmpty()) {
|
||||||
|
orderInfoService.removeByIds(ordersToCleanup);
|
||||||
|
ordersToCleanup.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditReturnsEarningLinesWithOrderDetails() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
|
||||||
|
PlayOrderInfoEntity order = seedOrder(LocalDateTime.now().minusHours(2));
|
||||||
|
WithdrawalRequestEntity withdrawal = seedWithdrawal(ApiTestDataSeeder.DEFAULT_TENANT_ID, new BigDecimal("88.60"));
|
||||||
|
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
seedEarningLine(withdrawal.getId(), order.getId(), new BigDecimal("50.30"), "withdrawn", now.minusMinutes(30), EarningsType.ORDER);
|
||||||
|
seedEarningLine(withdrawal.getId(), null, new BigDecimal("38.30"), "withdrawing", now.minusMinutes(10), EarningsType.ORDER);
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(get("/admin/withdraw/requests/" + withdrawal.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(200))
|
||||||
|
.andExpect(jsonPath("$.data").isArray())
|
||||||
|
.andExpect(jsonPath("$.data.length()").value(2))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
JsonNode data = objectMapper.readTree(result.getResponse().getContentAsString()).get("data");
|
||||||
|
boolean foundOrder = false;
|
||||||
|
boolean foundMissing = false;
|
||||||
|
for (JsonNode node : data) {
|
||||||
|
String orderNo = node.path("orderNo").isMissingNode() ? null : node.path("orderNo").asText(null);
|
||||||
|
if (order.getOrderNo().equals(orderNo)) {
|
||||||
|
Assertions.assertThat(node.path("orderStatus").asText()).isEqualTo(order.getOrderStatus());
|
||||||
|
Assertions.assertThat(node.path("earningType").asText()).isEqualTo(EarningsType.ORDER.name());
|
||||||
|
foundOrder = true;
|
||||||
|
}
|
||||||
|
if (node.path("orderNo").isNull()) {
|
||||||
|
foundMissing = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assertions.assertThat(foundOrder).isTrue();
|
||||||
|
Assertions.assertThat(foundMissing).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditRejectsMissingRequest() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
|
||||||
|
mockMvc.perform(get("/admin/withdraw/requests/missing-request/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(500))
|
||||||
|
.andExpect(jsonPath("$.message").value("提现申请不存在或无权查看"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditRejectsCrossTenantAccess() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
WithdrawalRequestEntity outsider = seedWithdrawal("tenant-other", new BigDecimal("30.00"));
|
||||||
|
|
||||||
|
mockMvc.perform(get("/admin/withdraw/requests/" + outsider.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(500))
|
||||||
|
.andExpect(jsonPath("$.message").value("提现申请不存在或无权查看"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditReturnsEmptyListWhenNoEarningsFound() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
WithdrawalRequestEntity request = seedWithdrawal(ApiTestDataSeeder.DEFAULT_TENANT_ID, new BigDecimal("22.00"));
|
||||||
|
|
||||||
|
mockMvc.perform(get("/admin/withdraw/requests/" + request.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(200))
|
||||||
|
.andExpect(jsonPath("$.data.length()").value(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditHandlesMissingOrderRecordsGracefully() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
WithdrawalRequestEntity request = seedWithdrawal(ApiTestDataSeeder.DEFAULT_TENANT_ID, new BigDecimal("40.00"));
|
||||||
|
String orphanOrderId = "order-orphan-" + IdUtils.getUuid();
|
||||||
|
seedEarningLine(request.getId(), orphanOrderId, new BigDecimal("15.00"), "withdrawn", LocalDateTime.now().minusMinutes(5), EarningsType.ORDER);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/admin/withdraw/requests/" + request.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(200))
|
||||||
|
.andExpect(jsonPath("$.data[0].orderNo").value(nullValue()))
|
||||||
|
.andExpect(jsonPath("$.data[0].orderId").value(orphanOrderId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditReturnsLinesSortedByCreatedTime() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
PlayOrderInfoEntity order = seedOrder(LocalDateTime.now().minusHours(1));
|
||||||
|
WithdrawalRequestEntity request = seedWithdrawal(ApiTestDataSeeder.DEFAULT_TENANT_ID, new BigDecimal("90.00"));
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
String firstId = seedEarningLine(request.getId(), order.getId(), new BigDecimal("10"), "withdrawn", now.minusMinutes(20), EarningsType.ORDER);
|
||||||
|
Thread.sleep(5L);
|
||||||
|
String secondId = seedEarningLine(request.getId(), null, new BigDecimal("20"), "withdrawn", now.minusMinutes(10), EarningsType.ORDER);
|
||||||
|
Thread.sleep(5L);
|
||||||
|
String thirdId = seedEarningLine(request.getId(), null, new BigDecimal("30"), "withdrawn", now.minusMinutes(5), EarningsType.ORDER);
|
||||||
|
|
||||||
|
MvcResult result = mockMvc.perform(get("/admin/withdraw/requests/" + request.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(200))
|
||||||
|
.andExpect(jsonPath("$.data.length()").value(3))
|
||||||
|
.andReturn();
|
||||||
|
|
||||||
|
JsonNode data = objectMapper.readTree(result.getResponse().getContentAsString()).get("data");
|
||||||
|
List<String> ids = new ArrayList<>();
|
||||||
|
LocalDateTime previous = null;
|
||||||
|
for (JsonNode node : data) {
|
||||||
|
ids.add(node.get("id").asText());
|
||||||
|
String createdText = node.path("createdTime").asText();
|
||||||
|
if (createdText != null && !createdText.isEmpty()) {
|
||||||
|
LocalDateTime created = LocalDateTime.parse(createdText, DATE_TIME_FORMATTER);
|
||||||
|
if (previous != null) {
|
||||||
|
Assertions.assertThat(created.isBefore(previous)).isFalse();
|
||||||
|
}
|
||||||
|
previous = created;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Assertions.assertThat(ids).containsExactlyInAnyOrder(firstId, secondId, thirdId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auditSupportsCommissionEarnings() throws Exception {
|
||||||
|
ensureTenantContext();
|
||||||
|
WithdrawalRequestEntity request = seedWithdrawal(ApiTestDataSeeder.DEFAULT_TENANT_ID, new BigDecimal("55.00"));
|
||||||
|
seedEarningLine(request.getId(), null, new BigDecimal("55.00"), "withdrawn", LocalDateTime.now().minusMinutes(2), EarningsType.COMMISSION);
|
||||||
|
|
||||||
|
mockMvc.perform(get("/admin/withdraw/requests/" + request.getId() + "/audit")
|
||||||
|
.header(USER_HEADER, DEFAULT_USER)
|
||||||
|
.header(TENANT_HEADER, DEFAULT_TENANT))
|
||||||
|
.andExpect(status().isOk())
|
||||||
|
.andExpect(jsonPath("$.code").value(200))
|
||||||
|
.andExpect(jsonPath("$.data[0].earningType").value(EarningsType.COMMISSION.name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
private PlayOrderInfoEntity seedOrder(LocalDateTime endTime) {
|
||||||
|
PlayOrderInfoEntity order = new PlayOrderInfoEntity();
|
||||||
|
String id = "order-audit-" + IdUtils.getUuid();
|
||||||
|
order.setId(id);
|
||||||
|
order.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID);
|
||||||
|
order.setOrderNo("ORD-" + System.currentTimeMillis());
|
||||||
|
order.setOrderStatus("3");
|
||||||
|
order.setOrderType("2");
|
||||||
|
order.setPlaceType("0");
|
||||||
|
order.setRewardType("0");
|
||||||
|
order.setAcceptBy(ApiTestDataSeeder.DEFAULT_CLERK_ID);
|
||||||
|
order.setPurchaserBy(ApiTestDataSeeder.DEFAULT_CUSTOMER_ID);
|
||||||
|
order.setCommodityId(ApiTestDataSeeder.DEFAULT_COMMODITY_ID);
|
||||||
|
order.setOrderMoney(new BigDecimal("120.50"));
|
||||||
|
order.setFinalAmount(order.getOrderMoney());
|
||||||
|
order.setEstimatedRevenue(new BigDecimal("80.25"));
|
||||||
|
order.setOrderSettlementState("1");
|
||||||
|
order.setOrderEndTime(endTime);
|
||||||
|
order.setOrderSettlementTime(endTime);
|
||||||
|
Date nowDate = toDate(LocalDateTime.now());
|
||||||
|
order.setCreatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
order.setCreatedTime(nowDate);
|
||||||
|
order.setUpdatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
order.setUpdatedTime(nowDate);
|
||||||
|
order.setDeleted(false);
|
||||||
|
orderInfoService.save(order);
|
||||||
|
ordersToCleanup.add(id);
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WithdrawalRequestEntity seedWithdrawal(String tenantId, BigDecimal amount) {
|
||||||
|
WithdrawalRequestEntity entity = new WithdrawalRequestEntity();
|
||||||
|
String id = "withdraw-audit-" + IdUtils.getUuid();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setTenantId(tenantId);
|
||||||
|
entity.setClerkId(ApiTestDataSeeder.DEFAULT_CLERK_ID);
|
||||||
|
entity.setAmount(amount);
|
||||||
|
entity.setFee(BigDecimal.ZERO);
|
||||||
|
entity.setNetAmount(amount);
|
||||||
|
entity.setDestAccount("alipay:audit@test.com");
|
||||||
|
entity.setStatus("processing");
|
||||||
|
entity.setPayeeSnapshot("{\"displayName\":\"审计专用\"}");
|
||||||
|
Date nowDate = toDate(LocalDateTime.now());
|
||||||
|
entity.setCreatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
entity.setCreatedTime(nowDate);
|
||||||
|
entity.setUpdatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
entity.setUpdatedTime(nowDate);
|
||||||
|
withdrawalService.save(entity);
|
||||||
|
withdrawalsToCleanup.add(id);
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String seedEarningLine(String withdrawalId, String orderId, BigDecimal amount, String status, LocalDateTime createdAt, EarningsType earningType) {
|
||||||
|
EarningsLineEntity entity = new EarningsLineEntity();
|
||||||
|
String id = "earn-audit-" + IdUtils.getUuid();
|
||||||
|
entity.setId(id);
|
||||||
|
entity.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID);
|
||||||
|
entity.setClerkId(ApiTestDataSeeder.DEFAULT_CLERK_ID);
|
||||||
|
String resolvedOrderId = orderId != null ? orderId : "order-missing-" + IdUtils.getUuid();
|
||||||
|
entity.setOrderId(resolvedOrderId);
|
||||||
|
entity.setAmount(amount);
|
||||||
|
entity.setStatus(status);
|
||||||
|
entity.setEarningType(earningType);
|
||||||
|
entity.setUnlockTime(createdAt.minusHours(1));
|
||||||
|
entity.setWithdrawalId(withdrawalId);
|
||||||
|
Date createdDate = toDate(createdAt);
|
||||||
|
entity.setCreatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
entity.setCreatedTime(createdDate);
|
||||||
|
entity.setUpdatedBy(ApiTestDataSeeder.DEFAULT_ADMIN_USER_ID);
|
||||||
|
entity.setUpdatedTime(createdDate);
|
||||||
|
entity.setDeleted(false);
|
||||||
|
earningsService.save(entity);
|
||||||
|
earningsToCleanup.add(id);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureTenantContext() {
|
||||||
|
SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date toDate(LocalDateTime value) {
|
||||||
|
return Date.from(value.atZone(ZoneId.systemDefault()).toInstant());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user