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