From 3650ce7f5d42d1bef58abea9693f20d1f209d3b0 Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期六, 10 十月 2026 14:02:27 +0800
Subject: [PATCH] 修改bug

---
 ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java |  218 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 218 insertions(+), 0 deletions(-)

diff --git a/ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java b/ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java
index 44165c6..d86354a 100644
--- a/ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java
+++ b/ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java
@@ -2,17 +2,22 @@
 
 import com.baomidou.mybatisplus.core.MybatisConfiguration;
 import com.baomidou.mybatisplus.core.conditions.Wrapper;
+import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
 import com.ruoyi.account.api.feignClient.AppUserWhitelistClient;
 import com.ruoyi.account.api.feignClient.ChargingCardClient;
+import com.ruoyi.account.api.feignClient.CompanyAllocateRecordClient;
 import com.ruoyi.account.api.feignClient.VinManagementClient;
 import com.ruoyi.account.api.model.TVinManagement;
+import com.ruoyi.account.api.vo.CompanyAllocateSummaryVO;
 import com.ruoyi.common.core.domain.R;
+import com.ruoyi.common.core.exception.ServiceException;
 import com.ruoyi.common.core.web.domain.AjaxResult;
 import com.ruoyi.other.api.domain.TGroupCompany;
 import com.ruoyi.other.api.model.TCompanyRechargeRecord;
 import com.ruoyi.other.mapper.TCompanyRechargeRecordMapper;
 import com.ruoyi.other.mapper.TFleetMapper;
+import com.ruoyi.order.api.feignClient.ChargingOrderClient;
 import com.ruoyi.system.api.domain.SysUser;
 import com.ruoyi.system.api.feignClient.SysRoleClient;
 import com.ruoyi.system.api.feignClient.SysUserClient;
@@ -33,6 +38,7 @@
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
@@ -302,8 +308,11 @@
     void updateAccountModeOnlyUpdatesAccountModeColumn() {
         TGroupCompany company = new TGroupCompany();
         company.setId(2);
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(2)).thenReturn(R.ok(0));
         TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
                 Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
         Mockito.doReturn(true).when(service).updateById(Mockito.any());
 
         assertEquals(200, code(service.updateAccountMode(2, 2)));
@@ -320,6 +329,215 @@
     }
 
     /**
+     * 分配→共享切换成功:加回公司余额、切换模式、远程回收、差额一致无需调整
+     */
+    @Test
+    void switchAllocationToSharedRecyclesBalanceAndWritesRecords() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(2);
+        company.setName("测试公司");
+        company.setAccountMode(2);
+        company.setAvailableBalance(new BigDecimal("100.00"));
+        company.setLockedAmount(new BigDecimal("0.00"));
+
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+        CompanyAllocateSummaryVO summary = new CompanyAllocateSummaryVO();
+        summary.setCompanyId(2);
+        summary.setTotalBalance(new BigDecimal("30.50"));
+        summary.setTotalLocked(new BigDecimal("0.00"));
+        summary.setBalanceUserCount(2);
+        Mockito.when(allocateClient.sumAllocatedBalance(2)).thenReturn(R.ok(summary));
+        Mockito.when(allocateClient.recycleAllocatedBalance(Mockito.eq(2), Mockito.any(), Mockito.eq("测试公司"),
+                Mockito.eq(new BigDecimal("100.00")))).thenReturn(R.ok(new BigDecimal("30.50")));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(2)).thenReturn(R.ok(0));
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+        stubLambdaUpdate(service, true);
+
+        assertEquals(200, code(service.updateAccountMode(2, 1)));
+
+        // 远程回收携带回退前公司余额,写入企业账户正数流水与用户负数流水由 account 侧完成
+        Mockito.verify(allocateClient).recycleAllocatedBalance(2, null, "测试公司", new BigDecimal("100.00"));
+        Mockito.verify(orderClient).countActiveByCompany(2);
+    }
+
+    /**
+     * 存在进行中充电订单:拒绝切换且不触发回收
+     */
+    @Test
+    void switchAllocationToSharedRejectsWhenChargingInProgress() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(3);
+        company.setName("充电中公司");
+        company.setAccountMode(2);
+        company.setAvailableBalance(new BigDecimal("50.00"));
+        company.setLockedAmount(new BigDecimal("0.00"));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(3)).thenReturn(R.ok(2));
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+
+        AjaxResult result = service.updateAccountMode(3, 1);
+
+        assertEquals(500, code(result));
+        assertTrue(String.valueOf(result.get("msg")).contains("正在充电"));
+        Mockito.verify(allocateClient, Mockito.never()).sumAllocatedBalance(Mockito.anyInt());
+        Mockito.verify(allocateClient, Mockito.never()).recycleAllocatedBalance(Mockito.anyInt(), Mockito.any(),
+                Mockito.any(), Mockito.any());
+        Mockito.verify(service, Mockito.never()).updateById(Mockito.any());
+    }
+
+    /**
+     * 存在未释放充电锁定额:拒绝切换且不触发回收
+     */
+    @Test
+    void switchAllocationToSharedRejectsWhenLockedAmountNotReleased() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(4);
+        company.setName("锁定残留公司");
+        company.setAccountMode(2);
+        company.setAvailableBalance(new BigDecimal("50.00"));
+        company.setLockedAmount(new BigDecimal("0.00"));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(4)).thenReturn(R.ok(0));
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+        CompanyAllocateSummaryVO summary = new CompanyAllocateSummaryVO();
+        summary.setCompanyId(4);
+        summary.setTotalBalance(new BigDecimal("10.00"));
+        summary.setTotalLocked(new BigDecimal("3.00"));
+        Mockito.when(allocateClient.sumAllocatedBalance(4)).thenReturn(R.ok(summary));
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+
+        AjaxResult result = service.updateAccountMode(4, 1);
+
+        assertEquals(500, code(result));
+        assertTrue(String.valueOf(result.get("msg")).contains("锁定金额"));
+        Mockito.verify(allocateClient, Mockito.never()).recycleAllocatedBalance(Mockito.anyInt(), Mockito.any(),
+                Mockito.any(), Mockito.any());
+        Mockito.verify(service, Mockito.never()).updateById(Mockito.any());
+    }
+
+    /**
+     * 回收失败:抛业务异常并回滚公司余额与模式(避免资金总账丢失)
+     */
+    @Test
+    void switchAllocationToSharedRollsBackWhenRecycleFails() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(5);
+        company.setName("回滚公司");
+        company.setAccountMode(2);
+        company.setAvailableBalance(new BigDecimal("80.00"));
+        company.setLockedAmount(new BigDecimal("0.00"));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(5)).thenReturn(R.ok(0));
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+        CompanyAllocateSummaryVO summary = new CompanyAllocateSummaryVO();
+        summary.setCompanyId(5);
+        summary.setTotalBalance(new BigDecimal("20.00"));
+        summary.setTotalLocked(new BigDecimal("0.00"));
+        Mockito.when(allocateClient.sumAllocatedBalance(5)).thenReturn(R.ok(summary));
+        Mockito.when(allocateClient.recycleAllocatedBalance(Mockito.eq(5), Mockito.any(), Mockito.any(),
+                Mockito.any())).thenReturn(R.fail("回收失败"));
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+        stubLambdaUpdate(service, true);
+
+        assertThrows(ServiceException.class, () -> service.updateAccountMode(5, 1));
+        // 加回与回滚各一次:第二次(回滚)将模式恢复为分配模式
+        Mockito.verify(service, Mockito.times(2)).lambdaUpdate();
+    }
+
+    /**
+     * 共享→分配无进行中充电订单:通过充电校验后仅切换模式,不做任何资金操作
+     */
+    @Test
+    void switchSharedToAllocationChecksChargingThenOnlyUpdatesMode() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(6);
+        company.setName("切分配公司");
+        company.setAccountMode(1);
+        company.setAvailableBalance(new BigDecimal("60.00"));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(6)).thenReturn(R.ok(0));
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+        Mockito.doReturn(true).when(service).updateById(Mockito.any());
+
+        assertEquals(200, code(service.updateAccountMode(6, 2)));
+
+        Mockito.verify(orderClient).countActiveByCompany(6);
+        Mockito.verify(allocateClient, Mockito.never()).sumAllocatedBalance(Mockito.anyInt());
+        Mockito.verify(allocateClient, Mockito.never()).recycleAllocatedBalance(Mockito.anyInt(), Mockito.any(),
+                Mockito.any(), Mockito.any());
+        Mockito.verify(service).updateById(Mockito.any(TGroupCompany.class));
+    }
+
+    /**
+     * 共享→分配存在进行中充电订单:拒绝切换且不改模式
+     */
+    @Test
+    void switchSharedToAllocationRejectsWhenChargingInProgress() {
+        TGroupCompany company = new TGroupCompany();
+        company.setId(7);
+        company.setName("充电中切分配公司");
+        company.setAccountMode(1);
+        company.setAvailableBalance(new BigDecimal("60.00"));
+
+        ChargingOrderClient orderClient = Mockito.mock(ChargingOrderClient.class);
+        Mockito.when(orderClient.countActiveByCompany(7)).thenReturn(R.ok(3));
+        CompanyAllocateRecordClient allocateClient = Mockito.mock(CompanyAllocateRecordClient.class);
+
+        TGroupCompanyServiceImpl service = buildService(company, Mockito.mock(TFleetMapper.class),
+                Mockito.mock(TCompanyRechargeRecordMapper.class));
+        ReflectionTestUtils.setField(service, "companyAllocateRecordClient", allocateClient);
+        ReflectionTestUtils.setField(service, "chargingOrderClient", orderClient);
+
+        AjaxResult result = service.updateAccountMode(7, 2);
+
+        assertEquals(500, code(result));
+        assertTrue(String.valueOf(result.get("msg")).contains("正在充电"));
+        Mockito.verify(allocateClient, Mockito.never()).sumAllocatedBalance(Mockito.anyInt());
+        Mockito.verify(service, Mockito.never()).updateById(Mockito.any());
+    }
+
+    /**
+     * 打桩 lambdaUpdate 链:eq/setSql/set 返回自身,update 返回指定结果
+     */
+    @SuppressWarnings("unchecked")
+    private void stubLambdaUpdate(TGroupCompanyServiceImpl service, boolean updateResult) {
+        LambdaUpdateChainWrapper<TGroupCompany> chain = Mockito.mock(LambdaUpdateChainWrapper.class);
+        Mockito.when(chain.eq(Mockito.any(), Mockito.any())).thenReturn(chain);
+        Mockito.when(chain.setSql(Mockito.anyString())).thenReturn(chain);
+        Mockito.when(chain.set(Mockito.any(), Mockito.any())).thenReturn(chain);
+        Mockito.when(chain.update()).thenReturn(updateResult);
+        Mockito.doReturn(chain).when(service).lambdaUpdate();
+    }
+
+    /**
      * 构建关注建档字段的 spy:远程账号相关调用全部打桩,不依赖 Spring 容器与数据库
      */
     private TGroupCompanyServiceImpl buildAddCompanyService() {

--
Gitblit v1.7.1