| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- package com.ruoyi.app.pay;
- import org.apache.ibatis.builder.xml.XMLMapperBuilder;
- import org.apache.ibatis.mapping.Environment;
- import org.apache.ibatis.session.Configuration;
- import org.apache.ibatis.session.SqlSession;
- import org.apache.ibatis.session.SqlSessionFactory;
- import org.apache.ibatis.session.SqlSessionFactoryBuilder;
- import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
- import org.h2.jdbcx.JdbcDataSource;
- import org.junit.jupiter.api.BeforeEach;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.BeanWrapperImpl;
- import java.math.BigDecimal;
- import java.sql.Connection;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.UUID;
- import static org.junit.jupiter.api.Assertions.*;
- class RiderIncomeMapperTest {
- private static final String NS = "com.ruoyi.system.mapper.RiderIncomeMapper.";
- private SqlSessionFactory factory;
- @BeforeEach
- void setUp() throws Exception {
- var source = new JdbcDataSource();
- source.setURL("jdbc:h2:mem:" + UUID.randomUUID() + ";MODE=MySQL;DB_CLOSE_DELAY=-1");
- try (Connection connection = source.getConnection(); var sql = connection.createStatement()) {
- sql.execute("CREATE TABLE user_billing (id BIGINT PRIMARY KEY, user_id BIGINT, user_type VARCHAR(8), "
- + "type VARCHAR(8), state VARCHAR(8), dd_id VARCHAR(64), order_source VARCHAR(16), "
- + "amount DOUBLE, behalf_amount DOUBLE, cretim TIMESTAMP)");
- sql.execute("INSERT INTO user_billing VALUES "
- + "(1,7,'2','0','0','same',NULL,60.10,300,'2026-01-01 00:00:00'),"
- + "(2,7,'2','0','0','same','FLASH',120,0,'2026-01-01 12:00:00'),"
- + "(3,7,'2','0','0','missing','',0,0,'2026-01-01 12:00:00'),"
- + "(4,8,'2','0','0','other','FOOD',999,0,'2026-01-01 12:00:00'),"
- + "(5,7,'2','2','0','withdraw','FOOD',999,0,'2026-01-01 12:00:00'),"
- + "(6,7,'2','0','1','void','FOOD',999,0,'2026-01-01 12:00:00'),"
- + "(7,7,'1','0','0','merchant','FOOD',999,0,'2026-01-01 12:00:00'),"
- + "(8,7,'2','0','0','outside','FOOD',999,0,'2026-01-02 00:00:00'),"
- + "(9,7,'2','0','0',NULL,'FOOD',999,0,'2026-01-01 12:00:00'),"
- + "(10,7,'2','0','0','unknown','OTHER',999,0,'2026-01-01 12:00:00'),"
- + "(11,7,'2','0','0','foreign','FOOD',0.20,0,'2026-01-01 23:59:59'),"
- + "(12,7,'2','0','0','before','FOOD',999,0,'2025-12-31 23:59:59')");
- }
- var configuration = new Configuration(new Environment("test", new JdbcTransactionFactory(), source));
- String resource = "mapper/Billing/RiderIncomeMapper.xml";
- try (var input = getClass().getClassLoader().getResourceAsStream(resource)) {
- assertNotNull(input, "骑手收入 Mapper 尚未实现");
- new XMLMapperBuilder(input, configuration, resource, configuration.getSqlFragments()).parse();
- }
- factory = new SqlSessionFactoryBuilder().build(configuration);
- }
- private Map<String, Object> params(String source) {
- var params = new HashMap<String, Object>();
- params.put("riderId", 7L);
- params.put("startTime", "2026-01-01 00:00:00");
- params.put("endTime", "2026-01-01 23:59:59");
- params.put("orderSource", source);
- params.put("offset", 0L);
- params.put("size", 100);
- return params;
- }
- private Object value(Object row, String field) {
- return new BeanWrapperImpl(row).getPropertyValue(field);
- }
- @Test
- void summaryUsesOnlyOwnValidIncomeAndIgnoresCategoryAndCollection() {
- try (SqlSession session = factory.openSession()) {
- for (String source : List.of("ALL", "FOOD", "FLASH")) {
- Object result = session.selectOne(NS + "summarize", params(source));
- assertEquals(new BigDecimal("180.30"), value(result, "totalIncome"));
- assertEquals(4L, value(result, "totalOrderCount"));
- assertEquals(3L, value(result, "foodOrderCount"));
- assertEquals(1L, value(result, "flashOrderCount"));
- }
- }
- }
- @Test
- void listSeparatesSameOrderNumbersAndPaginatesWithStableTimeAndIdOrder() {
- try (SqlSession session = factory.openSession()) {
- List<Object> all = session.selectList(NS + "selectPage", params("ALL"));
- assertEquals(List.of(11L, 3L, 2L, 1L), all.stream().map(x -> value(x, "billId")).toList());
- assertEquals("foreign", value(all.get(0), "orderNo"));
- assertEquals("missing", value(all.get(1), "orderNo"), "无需订单表也能读取历史账单");
- assertEquals("FOOD", value(all.get(1), "orderSource"));
- assertEquals("same", value(all.get(2), "orderNo"));
- assertEquals("FLASH", value(all.get(2), "orderSource"));
- assertEquals("same", value(all.get(3), "orderNo"));
- assertEquals("FOOD", value(all.get(3), "orderSource"));
- assertEquals(new BigDecimal("300.00"), value(all.get(3), "collectedAmount"));
- List<Object> food = session.selectList(NS + "selectPage", params("FOOD"));
- assertEquals(3, food.size());
- List<Object> flash = session.selectList(NS + "selectPage", params("FLASH"));
- assertEquals(1, flash.size());
- assertEquals(new BigDecimal("120.00"), value(flash.get(0), "incomeAmount"));
- Map<String, Object> page = params("ALL"); page.put("offset", 1L); page.put("size", 2);
- List<Object> rows = session.selectList(NS + "selectPage", page);
- assertEquals(List.of(3L, 2L), rows.stream().map(x -> value(x, "billId")).toList());
- }
- }
- @Test
- void allTimeIncludesHistoryOutsideDailyRangeButStillExcludesOtherAccounts() {
- try (SqlSession session = factory.openSession()) {
- var params = params("ALL"); params.put("startTime", null); params.put("endTime", null);
- Object result = session.selectOne(NS + "summarize", params);
- assertEquals(new BigDecimal("2178.30"), value(result, "totalIncome"));
- assertEquals(6L, value(result, "totalOrderCount"));
- assertEquals(5L, value(result, "foodOrderCount"));
- assertEquals(1L, value(result, "flashOrderCount"));
- assertEquals(6, session.selectList(NS + "selectPage", params).size());
- }
- }
- @Test
- void exactSecondRangeIncludesBothEndpointsWithoutExpandingToWholeDay() {
- try (SqlSession session = factory.openSession()) {
- var params = params("ALL");
- params.put("startTime", "2026-01-01 12:00:00");
- params.put("endTime", "2026-01-01 12:00:00");
- List<Object> rows = session.selectList(NS + "selectPage", params);
- assertEquals(List.of(3L, 2L), rows.stream().map(x -> value(x, "billId")).toList());
- Object sum = session.selectOne(NS + "summarize", params);
- assertEquals(new BigDecimal("120.00"), value(sum, "totalIncome"));
- assertEquals(2L, value(sum, "totalOrderCount"));
- }
- }
- @Test
- void detailScopesByRiderAndRejectsNonIncome() {
- try (SqlSession session = factory.openSession()) {
- for (long id : List.of(4L, 5L, 6L, 7L, 9L, 10L, 999L)) {
- assertNull(session.selectOne(NS + "selectDetail", Map.of("riderId", 7L, "billId", id)));
- }
- Object row = session.selectOne(NS + "selectDetail", Map.of("riderId", 7L, "billId", 1L));
- assertEquals(new BigDecimal("60.10"), value(row, "incomeAmount"));
- assertEquals("same", value(row, "orderNo"));
- }
- }
- @Test
- void noDataReturnsZeroSummaryAndEmptyPage() {
- try (SqlSession session = factory.openSession()) {
- var params = params("ALL"); params.put("riderId", 999L);
- Object result = session.selectOne(NS + "summarize", params);
- assertEquals(new BigDecimal("0.00"), value(result, "totalIncome"));
- assertEquals(0L, value(result, "totalOrderCount"));
- assertEquals(0L, value(result, "foodOrderCount"));
- assertEquals(0L, value(result, "flashOrderCount"));
- assertTrue(session.selectList(NS + "selectPage", params).isEmpty());
- }
- }
- }
|