Commit 80bab78a74682e13647c9837f5fe1d19b1a030e3

Authored by zichun
1 parent 6c46e78b

feat(usr): sys_user/sys_company/sys_employee entity + mapper REQ-USR-001

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 +}
... ...