feat: 支持展示并复制重置后的密码

- 账号重置接口返回本次使用的默认强密码

- 管理端新增紧凑结果弹窗与复制反馈

- 补充服务测试和中英文文案
This commit is contained in:
2026-07-30 14:17:44 +08:00
parent 766554bf63
commit 5f11219226
8 changed files with 253 additions and 8 deletions

View File

@@ -1,17 +1,26 @@
package tech.easyflow.system.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.mybatisflex.core.query.QueryWrapper;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import tech.easyflow.common.constant.enums.EnumAccountType;
import tech.easyflow.system.config.AccountSecurityProperties;
import tech.easyflow.system.entity.SysAccount;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -51,4 +60,54 @@ public class SysAccountServiceImplTest {
assertEquals("3", displayNameMap.get(BigInteger.valueOf(3)));
verify(service, times(1)).list(any(QueryWrapper.class));
}
/**
* 验证重置密码返回实际明文,同时持久化对应密文并踢出旧登录态。
*
* @throws Exception 注入测试配置失败
*/
@Test
public void shouldReturnPlainPasswordAfterReset() throws Exception {
BigInteger accountId = BigInteger.valueOf(10);
BigInteger operatorId = BigInteger.valueOf(20);
String expectedPassword = "!Reset123";
SysAccountServiceImpl service = spy(new SysAccountServiceImpl());
AccountSecurityProperties properties = new AccountSecurityProperties();
properties.setDefaultResetPassword(expectedPassword);
properties.afterPropertiesSet();
setField(service, "accountSecurityProperties", properties);
SysAccount account = new SysAccount();
account.setId(accountId);
account.setAccountType(EnumAccountType.NORMAL.getCode());
doReturn(account).when(service).getById(accountId);
doReturn(true).when(service).updateById(any(SysAccount.class));
try (MockedStatic<StpUtil> stp = mockStatic(StpUtil.class)) {
String actualPassword = service.resetPassword(accountId, operatorId);
assertEquals(expectedPassword, actualPassword);
ArgumentCaptor<SysAccount> updateCaptor = ArgumentCaptor.forClass(SysAccount.class);
verify(service).updateById(updateCaptor.capture());
SysAccount update = updateCaptor.getValue();
assertTrue(BCrypt.checkpw(expectedPassword, update.getPassword()));
assertEquals(Boolean.TRUE, update.getPasswordResetRequired());
assertEquals(operatorId, update.getModifiedBy());
stp.verify(() -> StpUtil.kickout(accountId), times(1));
}
}
/**
* 设置测试对象的私有字段。
*
* @param target 目标对象
* @param fieldName 字段名
* @param value 字段值
* @throws Exception 字段不存在或不可访问
*/
private void setField(Object target, String fieldName, Object value) throws Exception {
Field field = SysAccountServiceImpl.class.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(target, value);
}
}