diff --git a/backend/src/main/java/com/xly/erp/module/usr/entity/SysPermissionCategory.java b/backend/src/main/java/com/xly/erp/module/usr/entity/SysPermissionCategory.java new file mode 100644 index 0000000..a033449 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/usr/entity/SysPermissionCategory.java @@ -0,0 +1,27 @@ +package com.xly.erp.module.usr.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("sys_permission_category") +public class SysPermissionCategory { + + @TableId(value = "iIncrement", type = IdType.AUTO) + private Integer iIncrement; + + private String sId; + private String sBrandsId; + private String sSubsidiaryId; + private LocalDateTime tCreateDate; + + private String sCategoryName; + private String sCategoryCode; + private String sCategoryDesc; + private Integer iSortOrder; + private Integer iIsDeleted; +} diff --git a/backend/src/main/java/com/xly/erp/module/usr/entity/SysUserPermissionCategory.java b/backend/src/main/java/com/xly/erp/module/usr/entity/SysUserPermissionCategory.java new file mode 100644 index 0000000..3b0e523 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/usr/entity/SysUserPermissionCategory.java @@ -0,0 +1,25 @@ +package com.xly.erp.module.usr.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("sys_user_permission_category") +public class SysUserPermissionCategory { + + @TableId(value = "iIncrement", type = IdType.AUTO) + private Integer iIncrement; + + private String sId; + private String sBrandsId; + private String sSubsidiaryId; + private LocalDateTime tCreateDate; + + private Integer iUserId; + private Integer iPermissionCategoryId; + private String sGrantedBy; +} diff --git a/backend/src/main/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapper.java b/backend/src/main/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapper.java new file mode 100644 index 0000000..1c8c1a8 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapper.java @@ -0,0 +1,26 @@ +package com.xly.erp.module.usr.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xly.erp.module.usr.entity.SysPermissionCategory; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +@Mapper +public interface SysPermissionCategoryMapper extends BaseMapper { + + /** + * 计算给定 ID 集合中有多少行未删除(iIsDeleted=0)。 + * 用于 REQ-USR-002 批量校验 permissionCategoryIds 是否全部存在。 + */ + @Select({ + "" + }) + int countActiveByIds(@Param("ids") List ids); +} diff --git a/backend/src/main/java/com/xly/erp/module/usr/mapper/SysUserPermissionCategoryMapper.java b/backend/src/main/java/com/xly/erp/module/usr/mapper/SysUserPermissionCategoryMapper.java new file mode 100644 index 0000000..733c747 --- /dev/null +++ b/backend/src/main/java/com/xly/erp/module/usr/mapper/SysUserPermissionCategoryMapper.java @@ -0,0 +1,9 @@ +package com.xly.erp.module.usr.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.xly.erp.module.usr.entity.SysUserPermissionCategory; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SysUserPermissionCategoryMapper extends BaseMapper { +} diff --git a/backend/src/test/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapperTest.java b/backend/src/test/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapperTest.java new file mode 100644 index 0000000..044983d --- /dev/null +++ b/backend/src/test/java/com/xly/erp/module/usr/mapper/SysPermissionCategoryMapperTest.java @@ -0,0 +1,51 @@ +package com.xly.erp.module.usr.mapper; + +import com.xly.erp.module.usr.support.LoginTestSeeder; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +@SpringBootTest +@ActiveProfiles("test") +class SysPermissionCategoryMapperTest { + + @Autowired private SysPermissionCategoryMapper mapper; + @Autowired private LoginTestSeeder seeder; + + private LoginTestSeeder.Fixture fx; + + @BeforeEach + void setUp() { + fx = seeder.reset(); + } + + @Test + void countActiveByIds_returnsAllActive() { + int n = mapper.countActiveByIds(fx.activePermissionCategoryIds()); + assertEquals(fx.activePermissionCategoryIds().size(), n); + } + + @Test + void countActiveByIds_excludesDeleted() { + List mixed = new ArrayList<>(fx.activePermissionCategoryIds()); + mixed.add(fx.deletedPermissionCategoryId()); + int n = mapper.countActiveByIds(mixed); + assertEquals(fx.activePermissionCategoryIds().size(), n, + "已软删的分类不应计入"); + } + + @Test + void countActiveByIds_excludesUnknown() { + List mixed = new ArrayList<>(fx.activePermissionCategoryIds()); + mixed.add(99999); + int n = mapper.countActiveByIds(mixed); + assertEquals(fx.activePermissionCategoryIds().size(), n); + } +} diff --git a/backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java b/backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java index 3fe8cb1..4f1e355 100644 --- a/backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java +++ b/backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java @@ -2,9 +2,11 @@ package com.xly.erp.module.usr.support; import com.xly.erp.module.usr.entity.SysCompany; import com.xly.erp.module.usr.entity.SysEmployee; +import com.xly.erp.module.usr.entity.SysPermissionCategory; import com.xly.erp.module.usr.entity.SysUser; import com.xly.erp.module.usr.mapper.SysCompanyMapper; import com.xly.erp.module.usr.mapper.SysEmployeeMapper; +import com.xly.erp.module.usr.mapper.SysPermissionCategoryMapper; import com.xly.erp.module.usr.mapper.SysUserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; @@ -12,14 +14,18 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; +import java.util.List; + /** * 测试数据种子。在每个集成测试 @BeforeEach 调用 reset()。 - * 复用 BCryptPasswordEncoder 生成密码哈希,避免在 SQL 中硬编码。 * * 默认账号: - * - alice / Password1! / 启用 / 关联员工"张三" + * - alice / Password1! / 启用 / NORMAL / 关联员工"张三" + * - admin / Password1! / 启用 / SUPER_ADMIN * - bob_deleted / Password1! / 作废(iIsDeleted=1) + * * 默认公司:HQ(启用)/ DEL_CO(软删)。 + * 默认权限分类:PUR-采购管理 / SAL-销售管理(启用)/ HR-人事(软删)。 */ @Component public class LoginTestSeeder { @@ -28,12 +34,17 @@ public class LoginTestSeeder { public static final String COMPANY_OK = "HQ"; public static final String COMPANY_DELETED = "DEL_CO"; public static final String USER_OK = "alice"; + public static final String USER_ADMIN = "admin"; public static final String USER_DELETED = "bob_deleted"; + public static final String PERMISSION_CATEGORY_PUR = "PUR"; + public static final String PERMISSION_CATEGORY_SAL = "SAL"; + public static final String PERMISSION_CATEGORY_HR_DELETED = "HR"; private final JdbcTemplate jdbc; private final SysCompanyMapper companyMapper; private final SysEmployeeMapper employeeMapper; private final SysUserMapper userMapper; + private final SysPermissionCategoryMapper permissionCategoryMapper; private final BCryptPasswordEncoder encoder; @Autowired @@ -41,11 +52,13 @@ public class LoginTestSeeder { SysCompanyMapper companyMapper, SysEmployeeMapper employeeMapper, SysUserMapper userMapper, + SysPermissionCategoryMapper permissionCategoryMapper, BCryptPasswordEncoder encoder) { this.jdbc = jdbc; this.companyMapper = companyMapper; this.employeeMapper = employeeMapper; this.userMapper = userMapper; + this.permissionCategoryMapper = permissionCategoryMapper; this.encoder = encoder; } @@ -53,6 +66,7 @@ public class LoginTestSeeder { public Fixture reset() { jdbc.update("DELETE FROM sys_user_permission_category"); jdbc.update("DELETE FROM sys_user"); + jdbc.update("DELETE FROM sys_permission_category"); jdbc.update("DELETE FROM sys_employee"); jdbc.update("DELETE FROM sys_department"); jdbc.update("DELETE FROM sys_company"); @@ -97,6 +111,18 @@ public class LoginTestSeeder { alice.setSCreatedBy("system"); userMapper.insert(alice); + SysUser admin = new SysUser(); + admin.setSUsername(USER_ADMIN); + admin.setSUserCode("U000"); + admin.setSPasswordHash(hash); + admin.setSUserType("SUPER_ADMIN"); + admin.setSLanguage("zh-CN"); + admin.setICanEditDocument(1); + admin.setIIsDeleted(0); + admin.setIFailedLoginCount(0); + admin.setSCreatedBy("system"); + userMapper.insert(admin); + SysUser bob = new SysUser(); bob.setSUsername(USER_DELETED); bob.setSUserCode("U002"); @@ -109,8 +135,41 @@ public class LoginTestSeeder { bob.setSCreatedBy("system"); userMapper.insert(bob); - return new Fixture(alice.getIIncrement(), bob.getIIncrement(), emp.getIIncrement()); + SysPermissionCategory pur = new SysPermissionCategory(); + pur.setSCategoryCode(PERMISSION_CATEGORY_PUR); + pur.setSCategoryName("采购管理"); + pur.setISortOrder(1); + pur.setIIsDeleted(0); + permissionCategoryMapper.insert(pur); + + SysPermissionCategory sal = new SysPermissionCategory(); + sal.setSCategoryCode(PERMISSION_CATEGORY_SAL); + sal.setSCategoryName("销售管理"); + sal.setISortOrder(2); + sal.setIIsDeleted(0); + permissionCategoryMapper.insert(sal); + + SysPermissionCategory hrDel = new SysPermissionCategory(); + hrDel.setSCategoryCode(PERMISSION_CATEGORY_HR_DELETED); + hrDel.setSCategoryName("人事(已删)"); + hrDel.setISortOrder(3); + hrDel.setIIsDeleted(1); + permissionCategoryMapper.insert(hrDel); + + return new Fixture( + alice.getIIncrement(), + admin.getIIncrement(), + bob.getIIncrement(), + emp.getIIncrement(), + List.of(pur.getIIncrement(), sal.getIIncrement()), + hrDel.getIIncrement()); } - public record Fixture(Integer aliceId, Integer bobDeletedId, Integer employeeId) {} + public record Fixture( + Integer aliceId, + Integer adminId, + Integer bobDeletedId, + Integer employeeId, + List activePermissionCategoryIds, + Integer deletedPermissionCategoryId) {} }