Commit b532f99f61a7691e49b477bd48733e512ebe7db3
1 parent
b27400af
feat(usr): tUserPermission 批量写入 + 事务边界 REQ-USR-001
Showing
2 changed files
with
60 additions
and
2 deletions
backend/src/main/java/com/xly/test4/module/usr/service/impl/UserServiceImpl.java
| ... | ... | @@ -10,9 +10,11 @@ import com.xly.test4.module.usr.dto.UserCreateDTO; |
| 10 | 10 | import com.xly.test4.module.usr.entity.Employee; |
| 11 | 11 | import com.xly.test4.module.usr.entity.Permission; |
| 12 | 12 | import com.xly.test4.module.usr.entity.User; |
| 13 | +import com.xly.test4.module.usr.entity.UserPermission; | |
| 13 | 14 | import com.xly.test4.module.usr.mapper.EmployeeMapper; |
| 14 | 15 | import com.xly.test4.module.usr.mapper.PermissionMapper; |
| 15 | 16 | import com.xly.test4.module.usr.mapper.UserMapper; |
| 17 | +import com.xly.test4.module.usr.mapper.UserPermissionMapper; | |
| 16 | 18 | import com.xly.test4.module.usr.service.UserService; |
| 17 | 19 | import com.xly.test4.module.usr.vo.UserCreateVO; |
| 18 | 20 | import org.springframework.beans.factory.annotation.Value; |
| ... | ... | @@ -26,6 +28,7 @@ import java.util.List; |
| 26 | 28 | public class UserServiceImpl implements UserService { |
| 27 | 29 | |
| 28 | 30 | private final UserMapper userMapper; |
| 31 | + private final UserPermissionMapper userPermissionMapper; | |
| 29 | 32 | private final EmployeeMapper employeeMapper; |
| 30 | 33 | private final PermissionMapper permissionMapper; |
| 31 | 34 | private final UserConverter userConverter; |
| ... | ... | @@ -33,12 +36,14 @@ public class UserServiceImpl implements UserService { |
| 33 | 36 | private final String defaultPassword; |
| 34 | 37 | |
| 35 | 38 | public UserServiceImpl(UserMapper userMapper, |
| 39 | + UserPermissionMapper userPermissionMapper, | |
| 36 | 40 | EmployeeMapper employeeMapper, |
| 37 | 41 | PermissionMapper permissionMapper, |
| 38 | 42 | UserConverter userConverter, |
| 39 | 43 | PasswordEncoder passwordEncoder, |
| 40 | 44 | @Value("${app.security.default-password}") String defaultPassword) { |
| 41 | 45 | this.userMapper = userMapper; |
| 46 | + this.userPermissionMapper = userPermissionMapper; | |
| 42 | 47 | this.employeeMapper = employeeMapper; |
| 43 | 48 | this.permissionMapper = permissionMapper; |
| 44 | 49 | this.userConverter = userConverter; |
| ... | ... | @@ -90,6 +95,19 @@ public class UserServiceImpl implements UserService { |
| 90 | 95 | |
| 91 | 96 | userMapper.insert(user); |
| 92 | 97 | |
| 98 | + if (dto.getPermissionIds() != null && !dto.getPermissionIds().isEmpty()) { | |
| 99 | + for (Integer permissionId : dto.getPermissionIds()) { | |
| 100 | + UserPermission up = UserPermission.builder() | |
| 101 | + .iUserId(user.getIIncrement()) | |
| 102 | + .iPermissionId(permissionId) | |
| 103 | + .sGrantedBy(current.getUserName()) | |
| 104 | + .sBrandsId(current.getBrandsId()) | |
| 105 | + .sSubsidiaryId(current.getSubsidiaryId()) | |
| 106 | + .build(); | |
| 107 | + userPermissionMapper.insert(up); | |
| 108 | + } | |
| 109 | + } | |
| 110 | + | |
| 93 | 111 | return userConverter.toVO(user); |
| 94 | 112 | } |
| 95 | 113 | } | ... | ... |
backend/src/test/java/com/xly/test4/module/usr/service/impl/UserServiceImplTest.java
| ... | ... | @@ -6,12 +6,13 @@ import com.xly.test4.common.security.CurrentUser; |
| 6 | 6 | import com.xly.test4.common.security.CurrentUserContext; |
| 7 | 7 | import com.xly.test4.module.usr.converter.UserConverter; |
| 8 | 8 | import com.xly.test4.module.usr.dto.UserCreateDTO; |
| 9 | -import com.xly.test4.module.usr.entity.Employee; | |
| 10 | 9 | import com.xly.test4.module.usr.entity.Permission; |
| 11 | 10 | import com.xly.test4.module.usr.entity.User; |
| 11 | +import com.xly.test4.module.usr.entity.UserPermission; | |
| 12 | 12 | import com.xly.test4.module.usr.mapper.EmployeeMapper; |
| 13 | 13 | import com.xly.test4.module.usr.mapper.PermissionMapper; |
| 14 | 14 | import com.xly.test4.module.usr.mapper.UserMapper; |
| 15 | +import com.xly.test4.module.usr.mapper.UserPermissionMapper; | |
| 15 | 16 | import com.xly.test4.module.usr.vo.UserCreateVO; |
| 16 | 17 | import org.junit.jupiter.api.AfterEach; |
| 17 | 18 | import org.junit.jupiter.api.BeforeEach; |
| ... | ... | @@ -35,6 +36,7 @@ import static org.mockito.Mockito.when; |
| 35 | 36 | class UserServiceImplTest { |
| 36 | 37 | |
| 37 | 38 | private UserMapper userMapper; |
| 39 | + private UserPermissionMapper userPermissionMapper; | |
| 38 | 40 | private EmployeeMapper employeeMapper; |
| 39 | 41 | private PermissionMapper permissionMapper; |
| 40 | 42 | private UserConverter userConverter; |
| ... | ... | @@ -53,11 +55,12 @@ class UserServiceImplTest { |
| 53 | 55 | @BeforeEach |
| 54 | 56 | void setUp() { |
| 55 | 57 | userMapper = mock(UserMapper.class); |
| 58 | + userPermissionMapper = mock(UserPermissionMapper.class); | |
| 56 | 59 | employeeMapper = mock(EmployeeMapper.class); |
| 57 | 60 | permissionMapper = mock(PermissionMapper.class); |
| 58 | 61 | userConverter = mock(UserConverter.class); |
| 59 | 62 | passwordEncoder = new BCryptPasswordEncoder(); |
| 60 | - service = new UserServiceImpl(userMapper, employeeMapper, permissionMapper, | |
| 63 | + service = new UserServiceImpl(userMapper, userPermissionMapper, employeeMapper, permissionMapper, | |
| 61 | 64 | userConverter, passwordEncoder, "666666"); |
| 62 | 65 | ctxMock = mockStatic(CurrentUserContext.class); |
| 63 | 66 | ctxMock.when(CurrentUserContext::current).thenReturn(ADMIN_CONTEXT); |
| ... | ... | @@ -227,4 +230,41 @@ class UserServiceImplTest { |
| 227 | 230 | service.createUser(dto2); |
| 228 | 231 | verify(permissionMapper, never()).selectList(any(Wrapper.class)); |
| 229 | 232 | } |
| 233 | + | |
| 234 | + @Test | |
| 235 | + @SuppressWarnings("unchecked") | |
| 236 | + void createUser_withPermissionIds_insertsOneUserPermissionPerId() { | |
| 237 | + stubConverterReturnsEmptyUser(); | |
| 238 | + when(permissionMapper.selectList(any(Wrapper.class))) | |
| 239 | + .thenReturn(List.of(new Permission(), new Permission(), new Permission())); | |
| 240 | + | |
| 241 | + UserCreateDTO dto = baseDTO(); | |
| 242 | + dto.setPermissionIds(List.of(10, 20, 30)); | |
| 243 | + | |
| 244 | + service.createUser(dto); | |
| 245 | + | |
| 246 | + ArgumentCaptor<UserPermission> captor = ArgumentCaptor.forClass(UserPermission.class); | |
| 247 | + verify(userPermissionMapper, org.mockito.Mockito.times(3)).insert(captor.capture()); | |
| 248 | + | |
| 249 | + List<UserPermission> writes = captor.getAllValues(); | |
| 250 | + assertThat(writes).extracting(UserPermission::getIPermissionId) | |
| 251 | + .containsExactly(10, 20, 30); | |
| 252 | + assertThat(writes).allSatisfy(up -> { | |
| 253 | + assertThat(up.getIUserId()).isEqualTo(42); | |
| 254 | + assertThat(up.getSGrantedBy()).isEqualTo("admin"); | |
| 255 | + assertThat(up.getSBrandsId()).isEqualTo("BR-DEFAULT"); | |
| 256 | + assertThat(up.getSSubsidiaryId()).isEqualTo("SUB-DEFAULT"); | |
| 257 | + }); | |
| 258 | + } | |
| 259 | + | |
| 260 | + @Test | |
| 261 | + void createUser_emptyPermissionIds_doesNotCallUserPermissionInsert() { | |
| 262 | + stubConverterReturnsEmptyUser(); | |
| 263 | + UserCreateDTO dto = baseDTO(); | |
| 264 | + dto.setPermissionIds(List.of()); | |
| 265 | + | |
| 266 | + service.createUser(dto); | |
| 267 | + | |
| 268 | + verify(userPermissionMapper, never()).insert(any(UserPermission.class)); | |
| 269 | + } | |
| 230 | 270 | } | ... | ... |