RiderIncomeMapperTest.java 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package com.ruoyi.app.pay;
  2. import org.apache.ibatis.builder.xml.XMLMapperBuilder;
  3. import org.apache.ibatis.mapping.Environment;
  4. import org.apache.ibatis.session.Configuration;
  5. import org.apache.ibatis.session.SqlSession;
  6. import org.apache.ibatis.session.SqlSessionFactory;
  7. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  8. import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
  9. import org.h2.jdbcx.JdbcDataSource;
  10. import org.junit.jupiter.api.BeforeEach;
  11. import org.junit.jupiter.api.Test;
  12. import org.springframework.beans.BeanWrapperImpl;
  13. import java.math.BigDecimal;
  14. import java.sql.Connection;
  15. import java.util.HashMap;
  16. import java.util.List;
  17. import java.util.Map;
  18. import java.util.UUID;
  19. import static org.junit.jupiter.api.Assertions.*;
  20. class RiderIncomeMapperTest {
  21. private static final String NS = "com.ruoyi.system.mapper.RiderIncomeMapper.";
  22. private SqlSessionFactory factory;
  23. @BeforeEach
  24. void setUp() throws Exception {
  25. var source = new JdbcDataSource();
  26. source.setURL("jdbc:h2:mem:" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1");
  27. try (Connection connection = source.getConnection(); var sql = connection.createStatement()) {
  28. sql.execute("CREATE TABLE user_billing (id BIGINT PRIMARY KEY, user_id BIGINT, user_type VARCHAR(8), "
  29. + "type VARCHAR(8), state VARCHAR(8), dd_id VARCHAR(64), order_source VARCHAR(16), "
  30. + "amount DOUBLE, behalf_amount DOUBLE, cretim TIMESTAMP)");
  31. sql.execute("INSERT INTO user_billing VALUES "
  32. + "(1,7,'2','0','0','same',NULL,60.10,300,'2026-01-01 00:00:00'),"
  33. + "(2,7,'2','0','0','same','FLASH',120,0,'2026-01-01 12:00:00'),"
  34. + "(3,7,'2','0','0','missing','',0,0,'2026-01-01 12:00:00'),"
  35. + "(4,8,'2','0','0','other','FOOD',999,0,'2026-01-01 12:00:00'),"
  36. + "(5,7,'2','2','0','withdraw','FOOD',999,0,'2026-01-01 12:00:00'),"
  37. + "(6,7,'2','0','1','void','FOOD',999,0,'2026-01-01 12:00:00'),"
  38. + "(7,7,'1','0','0','merchant','FOOD',999,0,'2026-01-01 12:00:00'),"
  39. + "(8,7,'2','0','0','outside','FOOD',999,0,'2026-01-02 00:00:00'),"
  40. + "(9,7,'2','0','0',NULL,'FOOD',999,0,'2026-01-01 12:00:00'),"
  41. + "(10,7,'2','0','0','unknown','OTHER',999,0,'2026-01-01 12:00:00'),"
  42. + "(11,7,'2','0','0','foreign','FOOD',0.20,0,'2026-01-01 23:59:59'),"
  43. + "(12,7,'2','0','0','before','FOOD',999,0,'2025-12-31 23:59:59')");
  44. }
  45. var configuration = new Configuration(new Environment("test", new JdbcTransactionFactory(), source));
  46. String resource = "mapper/Billing/RiderIncomeMapper.xml";
  47. try (var input = getClass().getClassLoader().getResourceAsStream(resource)) {
  48. assertNotNull(input, "骑手收入 Mapper 尚未实现");
  49. new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse();
  50. }
  51. factory = new SqlSessionFactoryBuilder().build(configuration);
  52. }
  53. private Map<String, Object> params(String source) {
  54. var params = new HashMap<String, Object>();
  55. params.put("riderId", 7L);
  56. params.put("startTime", "2026-01-01 00:00:00");
  57. params.put("endTime", "2026-01-01 23:59:59");
  58. params.put("orderSource", source);
  59. params.put("offset", 0L);
  60. params.put("size", 100);
  61. return params;
  62. }
  63. private Object value(Object row, String field) {
  64. return new BeanWrapperImpl(row).getPropertyValue(field);
  65. }
  66. @Test
  67. void summaryUsesOnlyOwnValidIncomeAndIgnoresCategoryAndCollection() {
  68. try (SqlSession session = factory.openSession()) {
  69. for (String source : List.of("ALL", "FOOD", "FLASH")) {
  70. Object result = session.selectOne(NS + "summarize", params(source));
  71. assertEquals(new BigDecimal("180.30"), value(result, "totalIncome"));
  72. assertEquals(4L, value(result, "totalOrderCount"));
  73. assertEquals(3L, value(result, "foodOrderCount"));
  74. assertEquals(1L, value(result, "flashOrderCount"));
  75. }
  76. }
  77. }
  78. @Test
  79. void listSeparatesSameOrderNumbersAndPaginatesWithStableTimeAndIdOrder() {
  80. try (SqlSession session = factory.openSession()) {
  81. List<Object> all = session.selectList(NS + "selectPage", params("ALL"));
  82. assertEquals(List.of(11L, 3L, 2L, 1L), all.stream().map(x -> value(x, "billId")).toList());
  83. assertEquals("foreign", value(all.get(0), "orderNo"));
  84. assertEquals("missing", value(all.get(1), "orderNo"), "无需订单表也能读取历史账单");
  85. assertEquals("FOOD", value(all.get(1), "orderSource"));
  86. assertEquals("same", value(all.get(2), "orderNo"));
  87. assertEquals("FLASH", value(all.get(2), "orderSource"));
  88. assertEquals("same", value(all.get(3), "orderNo"));
  89. assertEquals("FOOD", value(all.get(3), "orderSource"));
  90. assertEquals(new BigDecimal("300.00"), value(all.get(3), "collectedAmount"));
  91. List<Object> food = session.selectList(NS + "selectPage", params("FOOD"));
  92. assertEquals(3, food.size());
  93. List<Object> flash = session.selectList(NS + "selectPage", params("FLASH"));
  94. assertEquals(1, flash.size());
  95. assertEquals(new BigDecimal("120.00"), value(flash.get(0), "incomeAmount"));
  96. Map<String, Object> page = params("ALL"); page.put("offset", 1L); page.put("size", 2);
  97. List<Object> rows = session.selectList(NS + "selectPage", page);
  98. assertEquals(List.of(3L, 2L), rows.stream().map(x -> value(x, "billId")).toList());
  99. }
  100. }
  101. @Test
  102. void allTimeIncludesHistoryOutsideDailyRangeButStillExcludesOtherAccounts() {
  103. try (SqlSession session = factory.openSession()) {
  104. var params = params("ALL"); params.put("startTime", null); params.put("endTime", null);
  105. Object result = session.selectOne(NS + "summarize", params);
  106. assertEquals(new BigDecimal("2178.30"), value(result, "totalIncome"));
  107. assertEquals(6L, value(result, "totalOrderCount"));
  108. assertEquals(5L, value(result, "foodOrderCount"));
  109. assertEquals(1L, value(result, "flashOrderCount"));
  110. assertEquals(6, session.selectList(NS + "selectPage", params).size());
  111. }
  112. }
  113. @Test
  114. void exactSecondRangeIncludesBothEndpointsWithoutExpandingToWholeDay() {
  115. try (SqlSession session = factory.openSession()) {
  116. var params = params("ALL");
  117. params.put("startTime", "2026-01-01 12:00:00");
  118. params.put("endTime", "2026-01-01 12:00:00");
  119. List<Object> rows = session.selectList(NS + "selectPage", params);
  120. assertEquals(List.of(3L, 2L), rows.stream().map(x -> value(x, "billId")).toList());
  121. Object sum = session.selectOne(NS + "summarize", params);
  122. assertEquals(new BigDecimal("120.00"), value(sum, "totalIncome"));
  123. assertEquals(2L, value(sum, "totalOrderCount"));
  124. }
  125. }
  126. @Test
  127. void detailScopesByRiderAndRejectsNonIncome() {
  128. try (SqlSession session = factory.openSession()) {
  129. for (long id : List.of(4L, 5L, 6L, 7L, 9L, 10L, 999L)) {
  130. assertNull(session.selectOne(NS + "selectDetail", Map.of("riderId", 7L, "billId", id)));
  131. }
  132. Object row = session.selectOne(NS + "selectDetail", Map.of("riderId", 7L, "billId", 1L));
  133. assertEquals(new BigDecimal("60.10"), value(row, "incomeAmount"));
  134. assertEquals("same", value(row, "orderNo"));
  135. }
  136. }
  137. @Test
  138. void noDataReturnsZeroSummaryAndEmptyPage() {
  139. try (SqlSession session = factory.openSession()) {
  140. var params = params("ALL"); params.put("riderId", 999L);
  141. Object result = session.selectOne(NS + "summarize", params);
  142. assertEquals(new BigDecimal("0.00"), value(result, "totalIncome"));
  143. assertEquals(0L, value(result, "totalOrderCount"));
  144. assertEquals(0L, value(result, "foodOrderCount"));
  145. assertEquals(0L, value(result, "flashOrderCount"));
  146. assertTrue(session.selectList(NS + "selectPage", params).isEmpty());
  147. }
  148. }
  149. }