| | |
| | | import java.util.Map; |
| | | |
| | | import com.talentcard.server.business.PageResult; |
| | | import com.talentcard.server.business.admin.AdminBusinessService; |
| | | import com.talentcard.server.business.admin.MerchantSettlementAdminService; |
| | | import com.talentcard.server.business.merchant.auth.MerchantPrincipal; |
| | | import org.junit.jupiter.api.BeforeEach; |
| | |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | import org.springframework.jdbc.core.JdbcTemplate; |
| | | import org.springframework.test.context.ActiveProfiles; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | /** |
| | | * 提现状态可见性 seam:商户端和后台都只能看到「处理中 / 已到账 / 提现失败」三种状态, |
| | |
| | | |
| | | @Autowired |
| | | private MerchantSettlementAdminService adminService; |
| | | |
| | | @Autowired |
| | | private AdminBusinessService adminBusinessService; |
| | | |
| | | private Long merchantId; |
| | | private Long storeId; |
| | |
| | | } |
| | | |
| | | @Test |
| | | void theAdminPageReturnsAnEmptyPageWhenNoWithdrawalsMatch() { |
| | | PageResult<Map<String, Object>> page = adminService.withdrawals( |
| | | 1, 20, merchantName + " no matching merchant", null, null, null, null, null); |
| | | |
| | | assertThat(page.records()).isEmpty(); |
| | | assertThat(page.total()).isZero(); |
| | | } |
| | | |
| | | @Test |
| | | @Transactional |
| | | void theAdminRefreshLoadsWithdrawalsAndTracksStuckWithdrawalNotices() { |
| | | // 刷新页面还会调用布局中的全局待办接口;只验证提现列表无法覆盖缺少提现关联表的错误。 |
| | | assertThat(adminService.withdrawals(1, 20, merchantName, null, null, null, null, null).records()) |
| | | .hasSize(4); |
| | | Map<String, Object> originalNotice = stuckWithdrawalNotice(); |
| | | long originalCount = originalNotice.isEmpty() ? 0 |
| | | : Long.parseLong(String.valueOf(originalNotice.get("content")).replaceAll("\\D", "")); |
| | | String orderNo = "NOTICE-" + suffix; |
| | | jdbc.update(""" |
| | | insert into benefit_order(order_no, talent_id, merchant_id, store_id, order_type, |
| | | pay_amount, order_status, verify_status, withdrawal_status, deleted) |
| | | values (?, 9701, ?, ?, 'GROUP_BUY', 2000, 1, 1, 1, 0) |
| | | """, orderNo, merchantId, storeId); |
| | | Long orderId = jdbc.queryForObject("select id from benefit_order where order_no = ?", Long.class, orderNo); |
| | | Long withdrawalId = jdbc.queryForObject( |
| | | "select id from merchant_withdrawal where merchant_id = ? and status = 'failed'", Long.class, merchantId); |
| | | jdbc.update("insert into merchant_withdrawal_order(withdrawal_id, order_id, amount_cents) values (?, ?, 2000)", |
| | | withdrawalId, orderId); |
| | | |
| | | assertThat(stuckWithdrawalNotice()) |
| | | .containsEntry("content", "您有 %d 笔提现失败且金额已停止自动重试".formatted(originalCount + 1)) |
| | | .containsEntry("path", "/merchant-settlement?kind=withdrawals"); |
| | | |
| | | jdbc.update("update merchant_withdrawal_order set released_at = now() where order_id = ?", orderId); |
| | | assertThat(stuckWithdrawalNotice()).isEqualTo(originalNotice); |
| | | } |
| | | |
| | | private Map<String, Object> stuckWithdrawalNotice() { |
| | | return adminBusinessService.pendingNotices().stream() |
| | | .filter(notice -> "merchant-withdrawal-stuck".equals(notice.get("id"))) |
| | | .findFirst().orElse(Map.of()); |
| | | } |
| | | |
| | | @Test |
| | | void theAdminStatusFilterUsesTheThreeDisplayStates() { |
| | | // 筛「处理中」要同时命中库里还没提交的 pending 和已提交的 processing。 |
| | | PageResult<Map<String, Object>> processing = adminService.withdrawals( |