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

---
 ruoyi-service/ruoyi-other/src/test/java/com/ruoyi/other/service/impl/TGroupCompanyServiceImplTest.java |   98 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 96 insertions(+), 2 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 d86354a..c14722c 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
@@ -29,6 +29,7 @@
 import org.springframework.test.util.ReflectionTestUtils;
 
 import java.math.BigDecimal;
+import java.nio.charset.StandardCharsets;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.util.ArrayList;
@@ -48,6 +49,9 @@
 
     /** 编辑公司用例共享的远程账号客户端 mock,供 verify 使用 */
     private SysUserClient editUserClient;
+
+    /** 新增公司用例共享的远程账号客户端 mock,供 verify 使用 */
+    private SysUserClient addUserClient;
 
     @BeforeAll
     static void initTableInfo() {
@@ -247,7 +251,8 @@
     }
 
     /**
-     * 添加/编辑企业弹窗不再配置账户模式:未传账户模式时按共享模式(1)建档
+     * 添加/编辑企业弹窗不再配置账户模式:未传账户模式时按共享模式(1)建档;
+     * 登录账号由系统自动生成(忽略前端传入值),并随返回体回显
      */
     @Test
     void addCompanyDefaultsAccountModeToSharedWhenAbsent() {
@@ -257,11 +262,16 @@
         company.setName("测试公司");
 
         TGroupCompanyServiceImpl service = buildAddCompanyService();
-        assertEquals(200, code(service.addCompany(company)));
+        AjaxResult result = service.addCompany(company);
+        assertEquals(200, code(result));
 
         ArgumentCaptor<TGroupCompany> captor = ArgumentCaptor.forClass(TGroupCompany.class);
         Mockito.verify(service).save(captor.capture());
         assertEquals(1, captor.getValue().getAccountMode());
+        // 账号不可由前端指定:传入值被系统生成值覆盖
+        assertTrue(captor.getValue().getAccount().matches("admin\\d{4}"));
+        assertTrue(!captor.getValue().getAccount().equals("company01"));
+        assertEquals(captor.getValue().getAccount(), String.valueOf(result.get("data")));
     }
 
     /**
@@ -280,6 +290,70 @@
         ArgumentCaptor<TGroupCompany> captor = ArgumentCaptor.forClass(TGroupCompany.class);
         Mockito.verify(service).save(captor.capture());
         assertEquals(2, captor.getValue().getAccountMode());
+        // 账号仍为系统生成值,而非前端传入值
+        assertTrue(captor.getValue().getAccount().matches("admin\\d{4}"));
+        assertTrue(!captor.getValue().getAccount().equals("company02"));
+    }
+
+    /**
+     * 新增公司:登录账号自动生成 admin+4位随机数字,初始密码按登录口径 HMAC-MD5 传输,
+     * 生成账号随返回体回显
+     */
+    @Test
+    void addCompanyGeneratesAccountAndDefaultPassword() {
+        TGroupCompany company = new TGroupCompany();
+        company.setName("测试公司");
+
+        TGroupCompanyServiceImpl service = buildAddCompanyService();
+        AjaxResult result = service.addCompany(company);
+        assertEquals(200, code(result));
+
+        assertTrue(company.getAccount().matches("admin\\d{4}"));
+        assertEquals(company.getAccount(), String.valueOf(result.get("data")));
+
+        ArgumentCaptor<SysUser> userCaptor = ArgumentCaptor.forClass(SysUser.class);
+        Mockito.verify(addUserClient).addSysUser(userCaptor.capture());
+        SysUser created = userCaptor.getValue();
+        assertEquals(company.getAccount(), created.getUserName());
+        // 初始密码 123456:HMAC-MD5(明文, password),与登录/重置链路口径一致
+        assertEquals(hmacMd5Expected("123456", "password"), created.getPassword());
+    }
+
+    /**
+     * 生成候选账号被 sys_user 占用时换号重试,最终以未占用账号建户
+     */
+    @Test
+    void addCompanyRetriesWhenCandidateAccountOccupied() {
+        TGroupCompany company = new TGroupCompany();
+        company.setName("测试公司");
+
+        SysUserClient sysUserClient = Mockito.mock(SysUserClient.class);
+        SysUser occupied = new SysUser();
+        occupied.setUserId(9L);
+        // 首个候选账号被占用,第二个候选通过
+        Mockito.when(sysUserClient.queryUserByUserName(Mockito.any()))
+                .thenReturn(R.ok(occupied), R.ok());
+        Mockito.when(sysUserClient.addSysUser(Mockito.any())).thenReturn(R.ok(100L));
+        Mockito.when(sysUserClient.getSysUser(Mockito.anyLong())).thenReturn(R.ok());
+
+        SysRoleClient sysRoleClient = Mockito.mock(SysRoleClient.class);
+        Mockito.when(sysRoleClient.getRoleIdByRoleKey(Mockito.any())).thenReturn(R.ok(74L));
+
+        TGroupCompanyServiceImpl service = Mockito.spy(new TGroupCompanyServiceImpl());
+        Mockito.doReturn(0L).when(service).count(Mockito.any());
+        Mockito.doReturn(true).when(service).save(Mockito.any());
+        ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient);
+        ReflectionTestUtils.setField(service, "sysRoleClient", sysRoleClient);
+
+        AjaxResult result = service.addCompany(company);
+        assertEquals(200, code(result));
+        assertEquals(company.getAccount(), String.valueOf(result.get("data")));
+
+        // 最终以通过查重的候选账号建户
+        ArgumentCaptor<SysUser> userCaptor = ArgumentCaptor.forClass(SysUser.class);
+        Mockito.verify(sysUserClient).addSysUser(userCaptor.capture());
+        assertEquals(company.getAccount(), userCaptor.getValue().getUserName());
+        assertTrue(userCaptor.getValue().getUserName().matches("admin\\d{4}"));
     }
 
     @Test
@@ -554,10 +628,30 @@
         Mockito.doReturn(true).when(service).save(Mockito.any());
         ReflectionTestUtils.setField(service, "sysUserClient", sysUserClient);
         ReflectionTestUtils.setField(service, "sysRoleClient", sysRoleClient);
+        this.addUserClient = sysUserClient;
         return service;
     }
 
     /**
+     * 按登录口径计算 HMAC-MD5(明文, key) 的期望值(小写 Hex),用于断言初始密码传输值
+     */
+    private String hmacMd5Expected(String text, String key) {
+        try {
+            javax.crypto.Mac mac = javax.crypto.Mac.getInstance("HmacMD5");
+            mac.init(new javax.crypto.spec.SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacMD5"));
+            byte[] bytes = mac.doFinal(text.getBytes(StandardCharsets.UTF_8));
+            StringBuilder hex = new StringBuilder(bytes.length * 2);
+            for (byte b : bytes) {
+                hex.append(Character.forDigit((b >> 4) & 0xF, 16));
+                hex.append(Character.forDigit(b & 0xF, 16));
+            }
+            return hex.toString();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
      * 编辑公司修改登录账号:按旧账号定位用户后把 userName 更新为新账号,
      * 不误走补建分支(避免双账号残留)
      */

--
Gitblit v1.7.1