Commit a80757980ef305c968839f232536e897367e00b2

Authored by zichun
1 parent 1cd7a10c

feat(usr): 登录输出 LoginVO 与 UsrCompany 实体 Mapper REQ-USR-004

backend/src/main/java/com/xly/erp/modules/usr/entity/UsrCompany.java 0 → 100644
  1 +package com.xly.erp.modules.usr.entity;
  2 +
  3 +import com.baomidou.mybatisplus.annotation.TableField;
  4 +import com.baomidou.mybatisplus.annotation.TableName;
  5 +import com.xly.erp.common.base.BaseEntity;
  6 +
  7 +/**
  8 + * 公司实体,映射 {@code usr_company}(docs/03 SSoT)。REQ-USR-004 T3。
  9 + *
  10 + * <p>继承 {@link BaseEntity} 复用标准列({@code iIncrement}/{@code sId}/租户列/{@code tCreateDate});
  11 + * 业务列 {@code sCompanyName}(公司名称,登录版本下拉显示来源)、{@code sVersion}(版本/账套标识,可空)。
  12 + * 仅供登录流程只读(companyId 存在性校验 + 公司下拉列表)。</p>
  13 + */
  14 +@TableName("usr_company")
  15 +public class UsrCompany extends BaseEntity {
  16 +
  17 + private static final long serialVersionUID = 1L;
  18 +
  19 + /** 公司名称(登录页版本下拉的显示来源)。 */
  20 + @TableField("sCompanyName")
  21 + private String sCompanyName;
  22 +
  23 + /** 版本 / 账套标识(可空)。 */
  24 + @TableField("sVersion")
  25 + private String sVersion;
  26 +
  27 + public String getSCompanyName() {
  28 + return sCompanyName;
  29 + }
  30 +
  31 + public void setSCompanyName(String sCompanyName) {
  32 + this.sCompanyName = sCompanyName;
  33 + }
  34 +
  35 + public String getSVersion() {
  36 + return sVersion;
  37 + }
  38 +
  39 + public void setSVersion(String sVersion) {
  40 + this.sVersion = sVersion;
  41 + }
  42 +}
... ...
backend/src/main/java/com/xly/erp/modules/usr/mapper/UsrCompanyMapper.java 0 → 100644
  1 +package com.xly.erp.modules.usr.mapper;
  2 +
  3 +import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4 +import com.xly.erp.modules.usr.entity.UsrCompany;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +/**
  8 + * 公司 Mapper(MyBatis-Plus)。REQ-USR-004 T3。
  9 + *
  10 + * <p>无自定义方法,复用 BaseMapper 的 {@code selectById}(companyId 存在性校验)
  11 + * 与 {@code selectList}(公司下拉列表)。</p>
  12 + */
  13 +@Mapper
  14 +public interface UsrCompanyMapper extends BaseMapper<UsrCompany> {
  15 +}
... ...
backend/src/main/java/com/xly/erp/modules/usr/vo/LoginVO.java 0 → 100644
  1 +package com.xly.erp.modules.usr.vo;
  2 +
  3 +import com.fasterxml.jackson.annotation.JsonProperty;
  4 +import java.io.Serializable;
  5 +
  6 +/**
  7 + * 登录输出(spec § 2.2 契约)。REQ-USR-004 T3。
  8 + *
  9 + * <p>{@code token} 为 JWT(不含 {@code Bearer } 前缀);嵌套 {@code user} 为登录用户基础信息。
  10 + * 严格不含 {@code sPassword} / 租户列。匈牙利前缀字段经 {@link JsonProperty} 锁小驼峰键。</p>
  11 + */
  12 +public class LoginVO implements Serializable {
  13 +
  14 + private static final long serialVersionUID = 1L;
  15 +
  16 + /** JWT 令牌(不含 Bearer 前缀,前端自行拼 Authorization 头)。 */
  17 + private String token;
  18 +
  19 + /** 登录用户基础信息(嵌套对象 user{...})。 */
  20 + private UserInfo user;
  21 +
  22 + public String getToken() {
  23 + return token;
  24 + }
  25 +
  26 + public void setToken(String token) {
  27 + this.token = token;
  28 + }
  29 +
  30 + public UserInfo getUser() {
  31 + return user;
  32 + }
  33 +
  34 + public void setUser(UserInfo user) {
  35 + this.user = user;
  36 + }
  37 +
  38 + /**
  39 + * 登录用户基础信息(嵌套于 {@code user}),来源 usr_user,绝不含密码。
  40 + */
  41 + public static class UserInfo implements Serializable {
  42 +
  43 + private static final long serialVersionUID = 1L;
  44 +
  45 + /** 用户主键 iIncrement。 */
  46 + private Integer id;
  47 +
  48 + /** 用户名。 */
  49 + @JsonProperty("sUserName")
  50 + private String sUserName;
  51 +
  52 + /** 用户类型。 */
  53 + @JsonProperty("sUserType")
  54 + private String sUserType;
  55 +
  56 + /** 界面语言。 */
  57 + @JsonProperty("sLanguage")
  58 + private String sLanguage;
  59 +
  60 + public Integer getId() {
  61 + return id;
  62 + }
  63 +
  64 + public void setId(Integer id) {
  65 + this.id = id;
  66 + }
  67 +
  68 + public String getSUserName() {
  69 + return sUserName;
  70 + }
  71 +
  72 + public void setSUserName(String sUserName) {
  73 + this.sUserName = sUserName;
  74 + }
  75 +
  76 + public String getSUserType() {
  77 + return sUserType;
  78 + }
  79 +
  80 + public void setSUserType(String sUserType) {
  81 + this.sUserType = sUserType;
  82 + }
  83 +
  84 + public String getSLanguage() {
  85 + return sLanguage;
  86 + }
  87 +
  88 + public void setSLanguage(String sLanguage) {
  89 + this.sLanguage = sLanguage;
  90 + }
  91 + }
  92 +}
... ...
backend/src/test/java/com/xly/erp/modules/usr/mapper/UsrCompanyMapperTest.java 0 → 100644
  1 +package com.xly.erp.modules.usr.mapper;
  2 +
  3 +import static org.assertj.core.api.Assertions.assertThat;
  4 +
  5 +import com.xly.erp.modules.usr.entity.UsrCompany;
  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 +import org.springframework.transaction.annotation.Transactional;
  11 +
  12 +/**
  13 + * REQ-USR-004 T3:UsrCompanyMapper(BaseMapper)连库验证实体 ↔ usr_company 列映射。
  14 + *
  15 + * <p>@SpringBootTest 连测试库(Flyway 已 apply V1),@Transactional 测试回滚避免污染库。
  16 + * 插 1 条公司 fixture(名前缀 IT4_CO_),验证 selectById / selectList 取回字段正确。</p>
  17 + */
  18 +@SpringBootTest
  19 +@ActiveProfiles("test")
  20 +@Transactional
  21 +class UsrCompanyMapperTest {
  22 +
  23 + @Autowired
  24 + private UsrCompanyMapper usrCompanyMapper;
  25 +
  26 + private UsrCompany insertFixture() {
  27 + UsrCompany c = new UsrCompany();
  28 + c.setSCompanyName("IT4_CO_总部");
  29 + c.setSVersion("企业版");
  30 + usrCompanyMapper.insert(c);
  31 + return c;
  32 + }
  33 +
  34 + @Test
  35 + void selectByIdReturnsCompany() {
  36 + UsrCompany inserted = insertFixture();
  37 + assertThat(inserted.getIIncrement()).isNotNull();
  38 +
  39 + UsrCompany found = usrCompanyMapper.selectById(inserted.getIIncrement());
  40 + assertThat(found).isNotNull();
  41 + assertThat(found.getSCompanyName()).isEqualTo("IT4_CO_总部");
  42 + assertThat(found.getSVersion()).isEqualTo("企业版");
  43 + assertThat(found.getIIncrement()).isEqualTo(inserted.getIIncrement());
  44 + }
  45 +
  46 + @Test
  47 + void selectListReturnsAll() {
  48 + UsrCompany inserted = insertFixture();
  49 + assertThat(usrCompanyMapper.selectList(null))
  50 + .anyMatch(c -> inserted.getIIncrement().equals(c.getIIncrement()));
  51 + }
  52 +}
... ...
backend/src/test/java/com/xly/erp/modules/usr/vo/LoginVOJsonTest.java 0 → 100644
  1 +package com.xly.erp.modules.usr.vo;
  2 +
  3 +import static org.assertj.core.api.Assertions.assertThat;
  4 +
  5 +import com.fasterxml.jackson.databind.ObjectMapper;
  6 +import org.junit.jupiter.api.Test;
  7 +
  8 +/**
  9 + * REQ-USR-004 T3:LoginVO 序列化结构与键名(含嵌套 user,绝不含密码)。
  10 + *
  11 + * <p>验证顶层 {@code token} + 嵌套对象 {@code user{id,sUserName,sUserType,sLanguage}},
  12 + * 匈牙利前缀字段经 {@code @JsonProperty} 锁小驼峰键;响应体不含 {@code sPassword}/{@code password}
  13 + * /大驼峰键 {@code SUserName}(spec § 3 规则 9 / 验收 11)。</p>
  14 + */
  15 +class LoginVOJsonTest {
  16 +
  17 + private final ObjectMapper objectMapper = new ObjectMapper();
  18 +
  19 + @Test
  20 + void serializesTokenAndNestedUserNoPassword() throws Exception {
  21 + LoginVO.UserInfo user = new LoginVO.UserInfo();
  22 + user.setId(1);
  23 + user.setSUserName("admin");
  24 + user.setSUserType("超级管理员");
  25 + user.setSLanguage("中文");
  26 +
  27 + LoginVO vo = new LoginVO();
  28 + vo.setToken("t.t.t");
  29 + vo.setUser(user);
  30 +
  31 + String json = objectMapper.writeValueAsString(vo);
  32 +
  33 + assertThat(json).contains("\"token\":\"t.t.t\"");
  34 + assertThat(json).contains("\"user\":");
  35 + assertThat(json).contains("\"id\":1");
  36 + assertThat(json).contains("\"sUserName\":\"admin\"");
  37 + assertThat(json).contains("\"sUserType\":\"超级管理员\"");
  38 + assertThat(json).contains("\"sLanguage\":\"中文\"");
  39 + assertThat(json).doesNotContain("sPassword");
  40 + assertThat(json).doesNotContain("password");
  41 + assertThat(json).doesNotContain("SUserName");
  42 + }
  43 +}
... ...