Commit 7986ca8e56fc79e78669dee7f2d52ca98dd4c45e
1 parent
22e97160
feat(usr): sys_permission_category + sys_user_permission_category entity/mapper REQ-USR-002
Showing
6 changed files
with
201 additions
and
4 deletions
backend/src/main/java/com/xly/erp/module/usr/entity/SysPermissionCategory.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.entity; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.annotation.IdType; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 6 | +import lombok.Data; | ||
| 7 | + | ||
| 8 | +import java.time.LocalDateTime; | ||
| 9 | + | ||
| 10 | +@Data | ||
| 11 | +@TableName("sys_permission_category") | ||
| 12 | +public class SysPermissionCategory { | ||
| 13 | + | ||
| 14 | + @TableId(value = "iIncrement", type = IdType.AUTO) | ||
| 15 | + private Integer iIncrement; | ||
| 16 | + | ||
| 17 | + private String sId; | ||
| 18 | + private String sBrandsId; | ||
| 19 | + private String sSubsidiaryId; | ||
| 20 | + private LocalDateTime tCreateDate; | ||
| 21 | + | ||
| 22 | + private String sCategoryName; | ||
| 23 | + private String sCategoryCode; | ||
| 24 | + private String sCategoryDesc; | ||
| 25 | + private Integer iSortOrder; | ||
| 26 | + private Integer iIsDeleted; | ||
| 27 | +} |
backend/src/main/java/com/xly/erp/module/usr/entity/SysUserPermissionCategory.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.entity; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.annotation.IdType; | ||
| 4 | +import com.baomidou.mybatisplus.annotation.TableId; | ||
| 5 | +import com.baomidou.mybatisplus.annotation.TableName; | ||
| 6 | +import lombok.Data; | ||
| 7 | + | ||
| 8 | +import java.time.LocalDateTime; | ||
| 9 | + | ||
| 10 | +@Data | ||
| 11 | +@TableName("sys_user_permission_category") | ||
| 12 | +public class SysUserPermissionCategory { | ||
| 13 | + | ||
| 14 | + @TableId(value = "iIncrement", type = IdType.AUTO) | ||
| 15 | + private Integer iIncrement; | ||
| 16 | + | ||
| 17 | + private String sId; | ||
| 18 | + private String sBrandsId; | ||
| 19 | + private String sSubsidiaryId; | ||
| 20 | + private LocalDateTime tCreateDate; | ||
| 21 | + | ||
| 22 | + private Integer iUserId; | ||
| 23 | + private Integer iPermissionCategoryId; | ||
| 24 | + private String sGrantedBy; | ||
| 25 | +} |
backend/src/main/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapper.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.mapper; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 4 | +import com.xly.erp.module.usr.entity.SysPermissionCategory; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | +import org.apache.ibatis.annotations.Param; | ||
| 7 | +import org.apache.ibatis.annotations.Select; | ||
| 8 | + | ||
| 9 | +import java.util.List; | ||
| 10 | + | ||
| 11 | +@Mapper | ||
| 12 | +public interface SysPermissionCategoryMapper extends BaseMapper<SysPermissionCategory> { | ||
| 13 | + | ||
| 14 | + /** | ||
| 15 | + * 计算给定 ID 集合中有多少行未删除(iIsDeleted=0)。 | ||
| 16 | + * 用于 REQ-USR-002 批量校验 permissionCategoryIds 是否全部存在。 | ||
| 17 | + */ | ||
| 18 | + @Select({ | ||
| 19 | + "<script>", | ||
| 20 | + "SELECT COUNT(*) FROM sys_permission_category ", | ||
| 21 | + "WHERE iIsDeleted = 0 AND iIncrement IN ", | ||
| 22 | + "<foreach item='id' collection='ids' open='(' separator=',' close=')'>#{id}</foreach>", | ||
| 23 | + "</script>" | ||
| 24 | + }) | ||
| 25 | + int countActiveByIds(@Param("ids") List<Integer> ids); | ||
| 26 | +} |
backend/src/main/java/com/xly/erp/module/usr/mapper/SysUserPermissionCategoryMapper.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.mapper; | ||
| 2 | + | ||
| 3 | +import com.baomidou.mybatisplus.core.mapper.BaseMapper; | ||
| 4 | +import com.xly.erp.module.usr.entity.SysUserPermissionCategory; | ||
| 5 | +import org.apache.ibatis.annotations.Mapper; | ||
| 6 | + | ||
| 7 | +@Mapper | ||
| 8 | +public interface SysUserPermissionCategoryMapper extends BaseMapper<SysUserPermissionCategory> { | ||
| 9 | +} |
backend/src/test/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapperTest.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.mapper; | ||
| 2 | + | ||
| 3 | +import com.xly.erp.module.usr.support.LoginTestSeeder; | ||
| 4 | +import org.junit.jupiter.api.BeforeEach; | ||
| 5 | +import org.junit.jupiter.api.Test; | ||
| 6 | +import org.springframework.beans.factory.annotation.Autowired; | ||
| 7 | +import org.springframework.boot.test.context.SpringBootTest; | ||
| 8 | +import org.springframework.test.context.ActiveProfiles; | ||
| 9 | + | ||
| 10 | +import java.util.ArrayList; | ||
| 11 | +import java.util.List; | ||
| 12 | + | ||
| 13 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 14 | + | ||
| 15 | +@SpringBootTest | ||
| 16 | +@ActiveProfiles("test") | ||
| 17 | +class SysPermissionCategoryMapperTest { | ||
| 18 | + | ||
| 19 | + @Autowired private SysPermissionCategoryMapper mapper; | ||
| 20 | + @Autowired private LoginTestSeeder seeder; | ||
| 21 | + | ||
| 22 | + private LoginTestSeeder.Fixture fx; | ||
| 23 | + | ||
| 24 | + @BeforeEach | ||
| 25 | + void setUp() { | ||
| 26 | + fx = seeder.reset(); | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | + @Test | ||
| 30 | + void countActiveByIds_returnsAllActive() { | ||
| 31 | + int n = mapper.countActiveByIds(fx.activePermissionCategoryIds()); | ||
| 32 | + assertEquals(fx.activePermissionCategoryIds().size(), n); | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + @Test | ||
| 36 | + void countActiveByIds_excludesDeleted() { | ||
| 37 | + List<Integer> mixed = new ArrayList<>(fx.activePermissionCategoryIds()); | ||
| 38 | + mixed.add(fx.deletedPermissionCategoryId()); | ||
| 39 | + int n = mapper.countActiveByIds(mixed); | ||
| 40 | + assertEquals(fx.activePermissionCategoryIds().size(), n, | ||
| 41 | + "已软删的分类不应计入"); | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + @Test | ||
| 45 | + void countActiveByIds_excludesUnknown() { | ||
| 46 | + List<Integer> mixed = new ArrayList<>(fx.activePermissionCategoryIds()); | ||
| 47 | + mixed.add(99999); | ||
| 48 | + int n = mapper.countActiveByIds(mixed); | ||
| 49 | + assertEquals(fx.activePermissionCategoryIds().size(), n); | ||
| 50 | + } | ||
| 51 | +} |
backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java
| @@ -2,9 +2,11 @@ package com.xly.erp.module.usr.support; | @@ -2,9 +2,11 @@ package com.xly.erp.module.usr.support; | ||
| 2 | 2 | ||
| 3 | import com.xly.erp.module.usr.entity.SysCompany; | 3 | import com.xly.erp.module.usr.entity.SysCompany; |
| 4 | import com.xly.erp.module.usr.entity.SysEmployee; | 4 | import com.xly.erp.module.usr.entity.SysEmployee; |
| 5 | +import com.xly.erp.module.usr.entity.SysPermissionCategory; | ||
| 5 | import com.xly.erp.module.usr.entity.SysUser; | 6 | import com.xly.erp.module.usr.entity.SysUser; |
| 6 | import com.xly.erp.module.usr.mapper.SysCompanyMapper; | 7 | import com.xly.erp.module.usr.mapper.SysCompanyMapper; |
| 7 | import com.xly.erp.module.usr.mapper.SysEmployeeMapper; | 8 | import com.xly.erp.module.usr.mapper.SysEmployeeMapper; |
| 9 | +import com.xly.erp.module.usr.mapper.SysPermissionCategoryMapper; | ||
| 8 | import com.xly.erp.module.usr.mapper.SysUserMapper; | 10 | import com.xly.erp.module.usr.mapper.SysUserMapper; |
| 9 | import org.springframework.beans.factory.annotation.Autowired; | 11 | import org.springframework.beans.factory.annotation.Autowired; |
| 10 | import org.springframework.jdbc.core.JdbcTemplate; | 12 | import org.springframework.jdbc.core.JdbcTemplate; |
| @@ -12,14 +14,18 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | @@ -12,14 +14,18 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | ||
| 12 | import org.springframework.stereotype.Component; | 14 | import org.springframework.stereotype.Component; |
| 13 | import org.springframework.transaction.annotation.Transactional; | 15 | import org.springframework.transaction.annotation.Transactional; |
| 14 | 16 | ||
| 17 | +import java.util.List; | ||
| 18 | + | ||
| 15 | /** | 19 | /** |
| 16 | * 测试数据种子。在每个集成测试 @BeforeEach 调用 reset()。 | 20 | * 测试数据种子。在每个集成测试 @BeforeEach 调用 reset()。 |
| 17 | - * 复用 BCryptPasswordEncoder 生成密码哈希,避免在 SQL 中硬编码。 | ||
| 18 | * | 21 | * |
| 19 | * 默认账号: | 22 | * 默认账号: |
| 20 | - * - alice / Password1! / 启用 / 关联员工"张三" | 23 | + * - alice / Password1! / 启用 / NORMAL / 关联员工"张三" |
| 24 | + * - admin / Password1! / 启用 / SUPER_ADMIN | ||
| 21 | * - bob_deleted / Password1! / 作废(iIsDeleted=1) | 25 | * - bob_deleted / Password1! / 作废(iIsDeleted=1) |
| 26 | + * | ||
| 22 | * 默认公司:HQ(启用)/ DEL_CO(软删)。 | 27 | * 默认公司:HQ(启用)/ DEL_CO(软删)。 |
| 28 | + * 默认权限分类:PUR-采购管理 / SAL-销售管理(启用)/ HR-人事(软删)。 | ||
| 23 | */ | 29 | */ |
| 24 | @Component | 30 | @Component |
| 25 | public class LoginTestSeeder { | 31 | public class LoginTestSeeder { |
| @@ -28,12 +34,17 @@ public class LoginTestSeeder { | @@ -28,12 +34,17 @@ public class LoginTestSeeder { | ||
| 28 | public static final String COMPANY_OK = "HQ"; | 34 | public static final String COMPANY_OK = "HQ"; |
| 29 | public static final String COMPANY_DELETED = "DEL_CO"; | 35 | public static final String COMPANY_DELETED = "DEL_CO"; |
| 30 | public static final String USER_OK = "alice"; | 36 | public static final String USER_OK = "alice"; |
| 37 | + public static final String USER_ADMIN = "admin"; | ||
| 31 | public static final String USER_DELETED = "bob_deleted"; | 38 | public static final String USER_DELETED = "bob_deleted"; |
| 39 | + public static final String PERMISSION_CATEGORY_PUR = "PUR"; | ||
| 40 | + public static final String PERMISSION_CATEGORY_SAL = "SAL"; | ||
| 41 | + public static final String PERMISSION_CATEGORY_HR_DELETED = "HR"; | ||
| 32 | 42 | ||
| 33 | private final JdbcTemplate jdbc; | 43 | private final JdbcTemplate jdbc; |
| 34 | private final SysCompanyMapper companyMapper; | 44 | private final SysCompanyMapper companyMapper; |
| 35 | private final SysEmployeeMapper employeeMapper; | 45 | private final SysEmployeeMapper employeeMapper; |
| 36 | private final SysUserMapper userMapper; | 46 | private final SysUserMapper userMapper; |
| 47 | + private final SysPermissionCategoryMapper permissionCategoryMapper; | ||
| 37 | private final BCryptPasswordEncoder encoder; | 48 | private final BCryptPasswordEncoder encoder; |
| 38 | 49 | ||
| 39 | @Autowired | 50 | @Autowired |
| @@ -41,11 +52,13 @@ public class LoginTestSeeder { | @@ -41,11 +52,13 @@ public class LoginTestSeeder { | ||
| 41 | SysCompanyMapper companyMapper, | 52 | SysCompanyMapper companyMapper, |
| 42 | SysEmployeeMapper employeeMapper, | 53 | SysEmployeeMapper employeeMapper, |
| 43 | SysUserMapper userMapper, | 54 | SysUserMapper userMapper, |
| 55 | + SysPermissionCategoryMapper permissionCategoryMapper, | ||
| 44 | BCryptPasswordEncoder encoder) { | 56 | BCryptPasswordEncoder encoder) { |
| 45 | this.jdbc = jdbc; | 57 | this.jdbc = jdbc; |
| 46 | this.companyMapper = companyMapper; | 58 | this.companyMapper = companyMapper; |
| 47 | this.employeeMapper = employeeMapper; | 59 | this.employeeMapper = employeeMapper; |
| 48 | this.userMapper = userMapper; | 60 | this.userMapper = userMapper; |
| 61 | + this.permissionCategoryMapper = permissionCategoryMapper; | ||
| 49 | this.encoder = encoder; | 62 | this.encoder = encoder; |
| 50 | } | 63 | } |
| 51 | 64 | ||
| @@ -53,6 +66,7 @@ public class LoginTestSeeder { | @@ -53,6 +66,7 @@ public class LoginTestSeeder { | ||
| 53 | public Fixture reset() { | 66 | public Fixture reset() { |
| 54 | jdbc.update("DELETE FROM sys_user_permission_category"); | 67 | jdbc.update("DELETE FROM sys_user_permission_category"); |
| 55 | jdbc.update("DELETE FROM sys_user"); | 68 | jdbc.update("DELETE FROM sys_user"); |
| 69 | + jdbc.update("DELETE FROM sys_permission_category"); | ||
| 56 | jdbc.update("DELETE FROM sys_employee"); | 70 | jdbc.update("DELETE FROM sys_employee"); |
| 57 | jdbc.update("DELETE FROM sys_department"); | 71 | jdbc.update("DELETE FROM sys_department"); |
| 58 | jdbc.update("DELETE FROM sys_company"); | 72 | jdbc.update("DELETE FROM sys_company"); |
| @@ -97,6 +111,18 @@ public class LoginTestSeeder { | @@ -97,6 +111,18 @@ public class LoginTestSeeder { | ||
| 97 | alice.setSCreatedBy("system"); | 111 | alice.setSCreatedBy("system"); |
| 98 | userMapper.insert(alice); | 112 | userMapper.insert(alice); |
| 99 | 113 | ||
| 114 | + SysUser admin = new SysUser(); | ||
| 115 | + admin.setSUsername(USER_ADMIN); | ||
| 116 | + admin.setSUserCode("U000"); | ||
| 117 | + admin.setSPasswordHash(hash); | ||
| 118 | + admin.setSUserType("SUPER_ADMIN"); | ||
| 119 | + admin.setSLanguage("zh-CN"); | ||
| 120 | + admin.setICanEditDocument(1); | ||
| 121 | + admin.setIIsDeleted(0); | ||
| 122 | + admin.setIFailedLoginCount(0); | ||
| 123 | + admin.setSCreatedBy("system"); | ||
| 124 | + userMapper.insert(admin); | ||
| 125 | + | ||
| 100 | SysUser bob = new SysUser(); | 126 | SysUser bob = new SysUser(); |
| 101 | bob.setSUsername(USER_DELETED); | 127 | bob.setSUsername(USER_DELETED); |
| 102 | bob.setSUserCode("U002"); | 128 | bob.setSUserCode("U002"); |
| @@ -109,8 +135,41 @@ public class LoginTestSeeder { | @@ -109,8 +135,41 @@ public class LoginTestSeeder { | ||
| 109 | bob.setSCreatedBy("system"); | 135 | bob.setSCreatedBy("system"); |
| 110 | userMapper.insert(bob); | 136 | userMapper.insert(bob); |
| 111 | 137 | ||
| 112 | - return new Fixture(alice.getIIncrement(), bob.getIIncrement(), emp.getIIncrement()); | 138 | + SysPermissionCategory pur = new SysPermissionCategory(); |
| 139 | + pur.setSCategoryCode(PERMISSION_CATEGORY_PUR); | ||
| 140 | + pur.setSCategoryName("采购管理"); | ||
| 141 | + pur.setISortOrder(1); | ||
| 142 | + pur.setIIsDeleted(0); | ||
| 143 | + permissionCategoryMapper.insert(pur); | ||
| 144 | + | ||
| 145 | + SysPermissionCategory sal = new SysPermissionCategory(); | ||
| 146 | + sal.setSCategoryCode(PERMISSION_CATEGORY_SAL); | ||
| 147 | + sal.setSCategoryName("销售管理"); | ||
| 148 | + sal.setISortOrder(2); | ||
| 149 | + sal.setIIsDeleted(0); | ||
| 150 | + permissionCategoryMapper.insert(sal); | ||
| 151 | + | ||
| 152 | + SysPermissionCategory hrDel = new SysPermissionCategory(); | ||
| 153 | + hrDel.setSCategoryCode(PERMISSION_CATEGORY_HR_DELETED); | ||
| 154 | + hrDel.setSCategoryName("人事(已删)"); | ||
| 155 | + hrDel.setISortOrder(3); | ||
| 156 | + hrDel.setIIsDeleted(1); | ||
| 157 | + permissionCategoryMapper.insert(hrDel); | ||
| 158 | + | ||
| 159 | + return new Fixture( | ||
| 160 | + alice.getIIncrement(), | ||
| 161 | + admin.getIIncrement(), | ||
| 162 | + bob.getIIncrement(), | ||
| 163 | + emp.getIIncrement(), | ||
| 164 | + List.of(pur.getIIncrement(), sal.getIIncrement()), | ||
| 165 | + hrDel.getIIncrement()); | ||
| 113 | } | 166 | } |
| 114 | 167 | ||
| 115 | - public record Fixture(Integer aliceId, Integer bobDeletedId, Integer employeeId) {} | 168 | + public record Fixture( |
| 169 | + Integer aliceId, | ||
| 170 | + Integer adminId, | ||
| 171 | + Integer bobDeletedId, | ||
| 172 | + Integer employeeId, | ||
| 173 | + List<Integer> activePermissionCategoryIds, | ||
| 174 | + Integer deletedPermissionCategoryId) {} | ||
| 116 | } | 175 | } |