longz
2026-07-15 a77ef9eab5658fc5488d6e62f75ca6a55f05289b
合作商分账编辑fix
4个文件已添加
2个文件已修改
162 ■■■■■ 已修改文件
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/test/java/com/ruoyi/chargingPile/controller/SiteControllerTest.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/test/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImplTest.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/ChargingOrderShareConfigurationTest.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-payment/src/test/java/com/ruoyi/payment/icbc/service/impl/IcbcPayServiceImplTest.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImpl.java
@@ -158,14 +158,6 @@
        if (isInvalidShareRatio(partner.getServiceShareRatio())) {
            return AjaxResult.error("服务费分成比例必须为0-100且最多两位小数");
        }
        if (partner.getElectricityShareRatio() != null || partner.getServiceShareRatio() != null) {
            if (StringUtils.isEmpty(partner.getIcbcSubMerId())) {
                return AjaxResult.error("填写分成比例时工行二级商户编号不能为空");
            }
            if (StringUtils.isEmpty(partner.getIcbcSubMerPrtclNo())) {
                return AjaxResult.error("填写分成比例时工行二级商户协议编号不能为空");
            }
        }
        return AjaxResult.success();
    }
ruoyi-service/ruoyi-chargingPile/src/test/java/com/ruoyi/chargingPile/controller/SiteControllerTest.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.chargingPile.controller;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.ruoyi.chargingPile.api.model.Site;
import com.ruoyi.chargingPile.service.ISiteService;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.domain.R;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Collections;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class SiteControllerTest {
    @Test
    void getSiteByIdsReturnsEmptyListWithoutQueryingWhenIdsAreEmpty() {
        SiteController controller = new SiteController();
        ISiteService siteService = mock(ISiteService.class);
        when(siteService.list(any(Wrapper.class))).thenThrow(new AssertionError("empty ids must not query database"));
        ReflectionTestUtils.setField(controller, "siteService", siteService);
        R<List<Site>> result = controller.getSiteByIds(Collections.emptyList());
        assertEquals(Constants.SUCCESS, result.getCode());
        assertNotNull(result.getData());
        assertTrue(result.getData().isEmpty());
        verify(siteService, never()).list(any(Wrapper.class));
    }
}
ruoyi-service/ruoyi-chargingPile/src/test/java/com/ruoyi/chargingPile/service/impl/PartnerServiceImplTest.java
New file
@@ -0,0 +1,25 @@
package com.ruoyi.chargingPile.service.impl;
import com.ruoyi.chargingPile.api.model.Partner;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.assertTrue;
class PartnerServiceImplTest {
    @Test
    void acceptsShareRatioWithoutIcbcSubMerchantConfiguration() {
        Partner partner = new Partner();
        partner.setId(1);
        partner.setCode("PARTNER001");
        partner.setName("测试合作商");
        partner.setPartnerType(1);
        partner.setPhoneOne("13800000000");
        partner.setElectricityShareRatio(new BigDecimal("20.00"));
        partner.setServiceShareRatio(new BigDecimal("30.00"));
        assertTrue(new PartnerServiceImpl().addPartnerParameterCheck(partner).isSuccess());
    }
}
ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -1209,6 +1209,12 @@
        List<IcbcAdminSubOrderVO> result = new ArrayList<>();
        for (TChargingOrderShareRecord record : records) {
            IcbcAdminSubOrderVO item = buildIcbcAdminSubOrderVO(record);
            if (!Boolean.TRUE.equals(record.getNeedOnlineShare())) {
                item.setQueryStatus("SKIP");
                item.setErrorMessage(record.getFailReason());
                result.add(item);
                continue;
            }
            try {
                IcbcSubOrderQueryReq query = IcbcAdminFundOperationSupport.buildSubOrderQueryRequest(order, record);
                item.applyQuery(requireFeignData(icbcPaymentClient.querySubOrder(query), "工行子订单查询失败"));
@@ -6927,8 +6933,6 @@
        record.setElectricityShareAmount(electricityShareAmount);
        record.setServiceShareAmount(serviceShareAmount);
        record.setShareAmount(electricityShareAmount.add(serviceShareAmount).setScale(2, RoundingMode.HALF_UP));
        record.setNeedOnlineShare("ICBC".equals(payChannel) && record.getShareAmount().compareTo(BigDecimal.ZERO) > 0);
        record.setOnlineShareStatus(Boolean.TRUE.equals(record.getNeedOnlineShare()) ? "INIT" : "RECORDED");
        if ("ICBC".equals(payChannel)) {
            record.setSeqNo(chargingOrder.getCode());
            record.setBusiType("1");
@@ -6938,7 +6942,12 @@
        if ("ICBC".equals(payChannel) && partner != null) {
            record.setSubMerId(partner.getIcbcSubMerId());
            record.setSubMerPrtclNo(partner.getIcbcSubMerPrtclNo());
            record.setMerAcct(partner.getIcbcMerAcct());
        }
        boolean needOnlineShare = shouldProcessIcbcOnlineShare(payChannel, record.getShareAmount(), partner);
        record.setNeedOnlineShare(needOnlineShare);
        record.setOnlineShareStatus(needOnlineShare ? "INIT" : "RECORDED");
        if ("ICBC".equals(payChannel) && record.getShareAmount().compareTo(BigDecimal.ZERO) > 0 && !needOnlineShare) {
            record.setFailReason("未配置完整工行二级商户参数,仅记录本地分账");
        }
        record.setRetryCount(0);
        record.setDelFlag(false);
@@ -7107,6 +7116,15 @@
        return amount.multiply(ratio).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
    }
    static boolean shouldProcessIcbcOnlineShare(String payChannel, BigDecimal shareAmount, Partner partner) {
        return "ICBC".equals(payChannel)
                && shareAmount != null
                && shareAmount.compareTo(BigDecimal.ZERO) > 0
                && partner != null
                && StringUtils.hasLength(partner.getIcbcSubMerId())
                && StringUtils.hasLength(partner.getIcbcSubMerPrtclNo());
    }
    private IcbcSubOrderSplitReq buildIcbcSubOrderSplitReq(TChargingOrderShareRecord record) {
        IcbcSubOrderSplitReq req = new IcbcSubOrderSplitReq();
        req.setChargingOrderCode(record.getChargingOrderCode());
@@ -7118,7 +7136,6 @@
        req.setSubMerId(record.getSubMerId());
        req.setSubMerPrtclNo(record.getSubMerPrtclNo());
        req.setClassifyAmt(record.getShareAmount());
        req.setMerAcct(record.getMerAcct());
        req.setMerSpInfor("充电订单分账:" + record.getChargingOrderCode());
        return req;
    }
@@ -7153,7 +7170,6 @@
        data.put("icbcPartnerId", partner.getIcbcPartnerId());
        data.put("icbcSubMerId", partner.getIcbcSubMerId());
        data.put("icbcSubMerPrtclNo", partner.getIcbcSubMerPrtclNo());
        data.put("icbcMerAcct", partner.getIcbcMerAcct());
        if (partner.getElectricityShareRatio() != null) {
            data.put("electricityShareRatio", partner.getElectricityShareRatio());
        }
ruoyi-service/ruoyi-order/src/test/java/com/ruoyi/order/service/impl/ChargingOrderShareConfigurationTest.java
New file
@@ -0,0 +1,25 @@
package com.ruoyi.order.service.impl;
import com.ruoyi.chargingPile.api.model.Partner;
import org.junit.jupiter.api.Test;
import java.math.BigDecimal;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class ChargingOrderShareConfigurationTest {
    @Test
    void onlyEnablesIcbcOnlineShareWithCompleteSubMerchantConfiguration() {
        Partner partner = new Partner();
        partner.setIcbcSubMerId("231011990055");
        assertFalse(TChargingOrderServiceImpl.shouldProcessIcbcOnlineShare("ICBC", new BigDecimal("1.00"), partner));
        partner.setIcbcSubMerPrtclNo("2310119900550201");
        assertTrue(TChargingOrderServiceImpl.shouldProcessIcbcOnlineShare("ICBC", new BigDecimal("1.00"), partner));
        assertFalse(TChargingOrderServiceImpl.shouldProcessIcbcOnlineShare("ICBC", BigDecimal.ZERO, partner));
        assertFalse(TChargingOrderServiceImpl.shouldProcessIcbcOnlineShare("BALANCE", new BigDecimal("1.00"), partner));
    }
}
ruoyi-service/ruoyi-payment/src/test/java/com/ruoyi/payment/icbc/service/impl/IcbcPayServiceImplTest.java
New file
@@ -0,0 +1,39 @@
package com.ruoyi.payment.icbc.service.impl;
import com.ruoyi.payment.icbc.config.IcbcPayProperties;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertTrue;
class IcbcPayServiceImplTest {
    @Test
    void verifiesRealPaymentCallbackWithConfiguredNotifyPath() {
        IcbcPayProperties properties = new IcbcPayProperties();
        properties.setCharset("UTF-8");
        properties.setSignType("RSA2");
        properties.setNotifyUrl("https://www.lyt18.cn/payment/icbc/callBack");
        properties.setIcbcPublicKey(
                "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMpjaWjngB4E3ATh+G1DVAmQnIpiPEFAEDqRfNGAVvvH35yDetqewKi0l7OEceTMN1C6NPym3zStvSoQayjYV+eIcZERkx31KhtFu9clZKgRTyPjdKMIth/wBtPKjL/5+PYalLdomM4ONthrPgnkN4x4R0+D4+EBpXo8gNiAFsNwIDAQAB");
        Map<String, String> params = new HashMap<>();
        params.put("api", "/api/cardbusiness/aggregatepay/b2c/online/consumepurchase/V1");
        params.put("app_id", "11000000000000096526");
        params.put("biz_content", "{\"access_type\":\"9\",\"attach\":\"1\",\"bank_disc_amt\":\"0\",\"card_flag\":\"\",\"card_kind\":\"\",\"card_no\":\"\",\"coupon_amt\":\"0\",\"cust_id\":\"\",\"decr_flag\":\"\",\"ecoupon_amt\":\"0\",\"mer_disc_amt\":\"0\",\"mer_id\":\"231011990056\",\"msg_id\":\"050200106196883020737106827\",\"open_id\":\"ow8NuxGF2KZlxu2sOd_bD44hacJI\",\"order_id\":\"231011990056000552607150002085\",\"out_trade_no\":\"CD10920260715105437088\",\"pay_time\":\"20260715105446\",\"pay_type\":\"9\",\"payment_amt\":\"50\",\"point_amt\":\"0\",\"return_code\":\"0\",\"return_msg\":\"\u4ea4\u6613\u6210\u529f\",\"third_party_coupon_amt\":\"0\",\"third_party_discount_amt\":\"0\",\"third_trade_no\":\"4500000314202607153746388432\",\"total_amt\":\"50\",\"total_disc_amt\":\"0\"}");
        params.put("charset", "UTF-8");
        params.put("format", "json");
        params.put("from", "icbc-api");
        params.put("sign", "ImWNkGh6yx2UB40+bH+nNcqLDv1C8qyGnO/3FVw4wv9/AI53PEuIoTO22UlPg0lP4QJb6z25vJ4O5YVRxaT8pInGW00izoKArF2nOtWka7wEFWdnRVJ8vBNRZfQ5+bXR1lRc7lqQyNXIorFN79z3BY9bjVzSlbuQJPDweVCkV+o=");
        params.put("sign_type", "RSA");
        params.put("timestamp", "2026-07-15 10:54:47");
        IcbcPayServiceImpl service = new IcbcPayServiceImpl();
        ReflectionTestUtils.setField(service, "properties", properties);
        assertTrue(Boolean.TRUE.equals(ReflectionTestUtils.invokeMethod(service, "verifyNotify", params)));
    }
}