Commit 80bab78a74682e13647c9837f5fe1d19b1a030e3
1 parent
6c46e78b
feat(usr): sys_user/sys_company/sys_employee entity + mapper REQ-USR-001
Showing
8 changed files
with
298 additions
and
0 deletions
backend/src/main/java/com/xly/erp/module/usr/entity/SysCompany.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 | +/** | |
| 11 | + * 公司表实体(只需登录用到的字段)。docs/03 § sys_company。 | |
| 12 | + */ | |
| 13 | +@Data | |
| 14 | +@TableName("sys_company") | |
| 15 | +public class SysCompany { | |
| 16 | + | |
| 17 | + @TableId(value = "iIncrement", type = IdType.AUTO) | |
| 18 | + private Integer iIncrement; | |
| 19 | + | |
| 20 | + private String sId; | |
| 21 | + private String sBrandsId; | |
| 22 | + private String sSubsidiaryId; | |
| 23 | + private LocalDateTime tCreateDate; | |
| 24 | + | |
| 25 | + private String sCompanyName; | |
| 26 | + private String sCompanyCode; | |
| 27 | + private Integer iSortOrder; | |
| 28 | + private Integer iIsDeleted; | |
| 29 | +} | ... | ... |
backend/src/main/java/com/xly/erp/module/usr/entity/SysEmployee.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 | +/** | |
| 11 | + * 职员表实体(只读 join,含登录返回 employeeName 所需的最小字段)。 | |
| 12 | + * docs/03 § sys_employee。 | |
| 13 | + */ | |
| 14 | +@Data | |
| 15 | +@TableName("sys_employee") | |
| 16 | +public class SysEmployee { | |
| 17 | + | |
| 18 | + @TableId(value = "iIncrement", type = IdType.AUTO) | |
| 19 | + private Integer iIncrement; | |
| 20 | + | |
| 21 | + private String sId; | |
| 22 | + private String sBrandsId; | |
| 23 | + private String sSubsidiaryId; | |
| 24 | + private LocalDateTime tCreateDate; | |
| 25 | + | |
| 26 | + private String sEmployeeName; | |
| 27 | + private String sEmployeeCode; | |
| 28 | + private Integer iDepartmentId; | |
| 29 | + private String sPhone; | |
| 30 | + private String sEmail; | |
| 31 | + private Integer iIsDeleted; | |
| 32 | +} | ... | ... |
backend/src/main/java/com/xly/erp/module/usr/entity/SysUser.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 | +/** | |
| 11 | + * 用户表实体。docs/03 § sys_user。 | |
| 12 | + */ | |
| 13 | +@Data | |
| 14 | +@TableName("sys_user") | |
| 15 | +public class SysUser { | |
| 16 | + | |
| 17 | + @TableId(value = "iIncrement", type = IdType.AUTO) | |
| 18 | + private Integer iIncrement; | |
| 19 | + | |
| 20 | + private String sId; | |
| 21 | + private String sBrandsId; | |
| 22 | + private String sSubsidiaryId; | |
| 23 | + private LocalDateTime tCreateDate; | |
| 24 | + | |
| 25 | + private String sUsername; | |
| 26 | + private String sUserCode; | |
| 27 | + private String sPasswordHash; | |
| 28 | + | |
| 29 | + private Integer iEmployeeId; | |
| 30 | + private String sUserType; | |
| 31 | + private String sLanguage; | |
| 32 | + private Integer iCanEditDocument; | |
| 33 | + private Integer iIsDeleted; | |
| 34 | + private Integer iFailedLoginCount; | |
| 35 | + private LocalDateTime tLockUntil; | |
| 36 | + private LocalDateTime tLastLoginDate; | |
| 37 | + private String sCreatedBy; | |
| 38 | + private String sUpdatedBy; | |
| 39 | + private LocalDateTime tUpdatedDate; | |
| 40 | +} | ... | ... |
backend/src/main/java/com/xly/erp/module/usr/mapper/SysCompanyMapper.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.SysCompany; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | +import org.apache.ibatis.annotations.Select; | |
| 7 | + | |
| 8 | +@Mapper | |
| 9 | +public interface SysCompanyMapper extends BaseMapper<SysCompany> { | |
| 10 | + | |
| 11 | + @Select("SELECT * FROM sys_company WHERE sCompanyCode = #{code} LIMIT 1") | |
| 12 | + SysCompany selectByCode(String code); | |
| 13 | +} | ... | ... |
backend/src/main/java/com/xly/erp/module/usr/mapper/SysEmployeeMapper.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.SysEmployee; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | + | |
| 7 | +@Mapper | |
| 8 | +public interface SysEmployeeMapper extends BaseMapper<SysEmployee> { | |
| 9 | +} | ... | ... |
backend/src/main/java/com/xly/erp/module/usr/mapper/SysUserMapper.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.SysUser; | |
| 5 | +import org.apache.ibatis.annotations.Mapper; | |
| 6 | +import org.apache.ibatis.annotations.Select; | |
| 7 | + | |
| 8 | +@Mapper | |
| 9 | +public interface SysUserMapper extends BaseMapper<SysUser> { | |
| 10 | + | |
| 11 | + @Select("SELECT * FROM sys_user WHERE sUsername = #{username} LIMIT 1") | |
| 12 | + SysUser selectByUsername(String username); | |
| 13 | +} | ... | ... |
backend/src/test/java/com/xly/erp/module/usr/mapper/SysUserMapperTest.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.mapper; | |
| 2 | + | |
| 3 | +import com.xly.erp.module.usr.entity.SysUser; | |
| 4 | +import com.xly.erp.module.usr.support.LoginTestSeeder; | |
| 5 | +import org.junit.jupiter.api.BeforeEach; | |
| 6 | +import org.junit.jupiter.api.Test; | |
| 7 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 8 | +import org.springframework.boot.test.context.SpringBootTest; | |
| 9 | +import org.springframework.test.context.ActiveProfiles; | |
| 10 | + | |
| 11 | +import static org.junit.jupiter.api.Assertions.*; | |
| 12 | + | |
| 13 | +@SpringBootTest | |
| 14 | +@ActiveProfiles("test") | |
| 15 | +class SysUserMapperTest { | |
| 16 | + | |
| 17 | + @Autowired | |
| 18 | + private SysUserMapper userMapper; | |
| 19 | + | |
| 20 | + @Autowired | |
| 21 | + private LoginTestSeeder seeder; | |
| 22 | + | |
| 23 | + @BeforeEach | |
| 24 | + void setUp() { | |
| 25 | + seeder.reset(); | |
| 26 | + } | |
| 27 | + | |
| 28 | + @Test | |
| 29 | + void selectByUsername_returnsUserWithAllFields() { | |
| 30 | + SysUser user = userMapper.selectByUsername(LoginTestSeeder.USER_OK); | |
| 31 | + assertNotNull(user); | |
| 32 | + assertEquals(LoginTestSeeder.USER_OK, user.getSUsername()); | |
| 33 | + assertEquals("U001", user.getSUserCode()); | |
| 34 | + assertNotNull(user.getSPasswordHash()); | |
| 35 | + assertEquals("NORMAL", user.getSUserType()); | |
| 36 | + assertEquals("zh-CN", user.getSLanguage()); | |
| 37 | + assertEquals(0, user.getIIsDeleted()); | |
| 38 | + assertEquals(0, user.getIFailedLoginCount()); | |
| 39 | + } | |
| 40 | + | |
| 41 | + @Test | |
| 42 | + void selectByUsername_returnsNullWhenNotFound() { | |
| 43 | + SysUser user = userMapper.selectByUsername("nobody"); | |
| 44 | + assertNull(user); | |
| 45 | + } | |
| 46 | +} | ... | ... |
backend/src/test/java/com/xly/erp/module/usr/support/LoginTestSeeder.java
0 → 100644
| 1 | +package com.xly.erp.module.usr.support; | |
| 2 | + | |
| 3 | +import com.xly.erp.module.usr.entity.SysCompany; | |
| 4 | +import com.xly.erp.module.usr.entity.SysEmployee; | |
| 5 | +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.SysEmployeeMapper; | |
| 8 | +import com.xly.erp.module.usr.mapper.SysUserMapper; | |
| 9 | +import org.springframework.beans.factory.annotation.Autowired; | |
| 10 | +import org.springframework.jdbc.core.JdbcTemplate; | |
| 11 | +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; | |
| 12 | +import org.springframework.stereotype.Component; | |
| 13 | +import org.springframework.transaction.annotation.Transactional; | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * 测试数据种子。在每个集成测试 @BeforeEach 调用 reset()。 | |
| 17 | + * 复用 BCryptPasswordEncoder 生成密码哈希,避免在 SQL 中硬编码。 | |
| 18 | + * | |
| 19 | + * 默认账号: | |
| 20 | + * - alice / Password1! / 启用 / 关联员工"张三" | |
| 21 | + * - bob_deleted / Password1! / 作废(iIsDeleted=1) | |
| 22 | + * 默认公司:HQ(启用)/ DEL_CO(软删)。 | |
| 23 | + */ | |
| 24 | +@Component | |
| 25 | +public class LoginTestSeeder { | |
| 26 | + | |
| 27 | + public static final String DEFAULT_PASSWORD = "Password1!"; | |
| 28 | + public static final String COMPANY_OK = "HQ"; | |
| 29 | + public static final String COMPANY_DELETED = "DEL_CO"; | |
| 30 | + public static final String USER_OK = "alice"; | |
| 31 | + public static final String USER_DELETED = "bob_deleted"; | |
| 32 | + | |
| 33 | + private final JdbcTemplate jdbc; | |
| 34 | + private final SysCompanyMapper companyMapper; | |
| 35 | + private final SysEmployeeMapper employeeMapper; | |
| 36 | + private final SysUserMapper userMapper; | |
| 37 | + private final BCryptPasswordEncoder encoder; | |
| 38 | + | |
| 39 | + @Autowired | |
| 40 | + public LoginTestSeeder(JdbcTemplate jdbc, | |
| 41 | + SysCompanyMapper companyMapper, | |
| 42 | + SysEmployeeMapper employeeMapper, | |
| 43 | + SysUserMapper userMapper, | |
| 44 | + BCryptPasswordEncoder encoder) { | |
| 45 | + this.jdbc = jdbc; | |
| 46 | + this.companyMapper = companyMapper; | |
| 47 | + this.employeeMapper = employeeMapper; | |
| 48 | + this.userMapper = userMapper; | |
| 49 | + this.encoder = encoder; | |
| 50 | + } | |
| 51 | + | |
| 52 | + @Transactional | |
| 53 | + public Fixture reset() { | |
| 54 | + jdbc.update("DELETE FROM sys_user_permission_category"); | |
| 55 | + jdbc.update("DELETE FROM sys_user"); | |
| 56 | + jdbc.update("DELETE FROM sys_employee"); | |
| 57 | + jdbc.update("DELETE FROM sys_department"); | |
| 58 | + jdbc.update("DELETE FROM sys_company"); | |
| 59 | + | |
| 60 | + SysCompany hq = new SysCompany(); | |
| 61 | + hq.setSCompanyCode(COMPANY_OK); | |
| 62 | + hq.setSCompanyName("总部"); | |
| 63 | + hq.setIIsDeleted(0); | |
| 64 | + companyMapper.insert(hq); | |
| 65 | + | |
| 66 | + SysCompany del = new SysCompany(); | |
| 67 | + del.setSCompanyCode(COMPANY_DELETED); | |
| 68 | + del.setSCompanyName("已删公司"); | |
| 69 | + del.setIIsDeleted(1); | |
| 70 | + companyMapper.insert(del); | |
| 71 | + | |
| 72 | + jdbc.update("INSERT INTO sys_department (sDepartmentName, sDepartmentCode, iIsDeleted) VALUES (?,?,0)", | |
| 73 | + "技术部", "TECH"); | |
| 74 | + Integer deptId = jdbc.queryForObject( | |
| 75 | + "SELECT iIncrement FROM sys_department WHERE sDepartmentCode='TECH'", | |
| 76 | + Integer.class); | |
| 77 | + | |
| 78 | + SysEmployee emp = new SysEmployee(); | |
| 79 | + emp.setSEmployeeName("张三"); | |
| 80 | + emp.setSEmployeeCode("E001"); | |
| 81 | + emp.setIDepartmentId(deptId); | |
| 82 | + emp.setIIsDeleted(0); | |
| 83 | + employeeMapper.insert(emp); | |
| 84 | + | |
| 85 | + String hash = encoder.encode(DEFAULT_PASSWORD); | |
| 86 | + | |
| 87 | + SysUser alice = new SysUser(); | |
| 88 | + alice.setSUsername(USER_OK); | |
| 89 | + alice.setSUserCode("U001"); | |
| 90 | + alice.setSPasswordHash(hash); | |
| 91 | + alice.setIEmployeeId(emp.getIIncrement()); | |
| 92 | + alice.setSUserType("NORMAL"); | |
| 93 | + alice.setSLanguage("zh-CN"); | |
| 94 | + alice.setICanEditDocument(0); | |
| 95 | + alice.setIIsDeleted(0); | |
| 96 | + alice.setIFailedLoginCount(0); | |
| 97 | + alice.setSCreatedBy("system"); | |
| 98 | + userMapper.insert(alice); | |
| 99 | + | |
| 100 | + SysUser bob = new SysUser(); | |
| 101 | + bob.setSUsername(USER_DELETED); | |
| 102 | + bob.setSUserCode("U002"); | |
| 103 | + bob.setSPasswordHash(hash); | |
| 104 | + bob.setSUserType("NORMAL"); | |
| 105 | + bob.setSLanguage("zh-CN"); | |
| 106 | + bob.setICanEditDocument(0); | |
| 107 | + bob.setIIsDeleted(1); | |
| 108 | + bob.setIFailedLoginCount(0); | |
| 109 | + bob.setSCreatedBy("system"); | |
| 110 | + userMapper.insert(bob); | |
| 111 | + | |
| 112 | + return new Fixture(alice.getIIncrement(), bob.getIIncrement(), emp.getIIncrement()); | |
| 113 | + } | |
| 114 | + | |
| 115 | + public record Fixture(Integer aliceId, Integer bobDeletedId, Integer employeeId) {} | |
| 116 | +} | ... | ... |