Commit a80757980ef305c968839f232536e897367e00b2
1 parent
1cd7a10c
feat(usr): 登录输出 LoginVO 与 UsrCompany 实体 Mapper REQ-USR-004
Showing
5 changed files
with
244 additions
and
0 deletions
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 | +} |