init: UserBaseService (backend + deploy + scripts)
ci-userbase-service / build-and-push (push) Successful in 40s

This commit is contained in:
chenxing
2026-08-10 14:50:22 +08:00
commit 4ec19486e0
234 changed files with 15604 additions and 0 deletions
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.ClientEnum;
import javax.persistence.AttributeConverter;
/**
* ClientEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。
*
* @author chenx
*/
public class ClientEnumConverter extends CommonIntEnumConverter<ClientEnum> {
public ClientEnumConverter() {
super(ClientEnum.class);
}
}
@@ -0,0 +1,47 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.IEnum;
import javax.persistence.AttributeConverter;
/**
* 通用「int &lt;-&gt; 实现 IEnum&lt;Integer&gt; 的枚举」JPA 转换器抽象基类。<br>
* <p>
* <b>绑定机制(通用做法):</b>为每个枚举写一个极薄的子类,在构造器里传入枚举 class 即可完成绑定,
* 然后实体字段用 {@code @Convert(converter = XxxEnumConverter.class)} 引用该子类。例如:
* <pre>
* public class GroupTypeEnumConverter extends CommonIntEnumConverter&lt;GroupTypeEnum&gt; {
* public GroupTypeEnumConverter() { super(GroupTypeEnum.class); }
* }
* </pre>
* 这样同一套逻辑可服务任意枚举;又因为每个枚举拥有<b>独立的转换器实例</b>,
* 彼此之间不会串类型(标准 JPA 的 @Convert 是按 converter 类创建共享单例的,
* 若让多个不同枚举共用同一个泛型实例,则无法区分各自的枚举 class,故采用「每枚举一子类」的绑定方式)。
* </p>
*
* @param <E> 必须实现 IEnum&lt;Integer&gt; 的枚举类型
* @author chenx
*/
public abstract class CommonIntEnumConverter<E extends Enum<E> & IEnum<Integer>>
implements AttributeConverter<E, Integer> {
private final Class<E> enumCls;
protected CommonIntEnumConverter(Class<E> enumCls) {
this.enumCls = enumCls;
}
@Override
public Integer convertToDatabaseColumn(E enumVal) {
return enumVal == null ? null : enumVal.getKey();
}
@Override
public E convertToEntityAttribute(Integer dbVal) {
if (dbVal == null) {
return null;
}
// 读库安全:无匹配的枚举值返回 null(不抛异常,避免脏数据导致整棵树加载失败)
return IEnum.getByKey(enumCls, dbVal);
}
}
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.GenderEnum;
import javax.persistence.AttributeConverter;
/**
* GenderEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。
*
* @author chenx
*/
public class GenderEnumConverter extends CommonIntEnumConverter<GenderEnum> {
public GenderEnumConverter() {
super(GenderEnum.class);
}
}
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.GroupTypeEnum;
import javax.persistence.AttributeConverter;
/**
* GroupTypeEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可,无需重复转换逻辑。
*
* @author chenx
*/
public class GroupTypeEnumConverter extends CommonIntEnumConverter<GroupTypeEnum> {
public GroupTypeEnumConverter() {
super(GroupTypeEnum.class);
}
}
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.IntegEnum;
import javax.persistence.AttributeConverter;
/**
* IntegEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。
*
* @author chenx
*/
public class IntegEnumConverter extends CommonIntEnumConverter<IntegEnum> {
public IntegEnumConverter() {
super(IntegEnum.class);
}
}
@@ -0,0 +1,50 @@
package com.yunhai.userbase.common.converter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.util.Collections;
import java.util.List;
/**
* @author chenx
* @date 2026/7/14
* @description 将 List<Integer> 与 MySQL JSON 字符串互相转换。
* 使用 Jackson 的 {@link TypeReference} 明确反序列化为 List<Integer>,
* 避免 Hibernate 内置 JSON 类型把数组元素类型读错的问题。
*/
@Converter
public class ListIntegerJsonConverter implements AttributeConverter<List<Integer>, String> {
private static final ObjectMapper MAPPER = new ObjectMapper();
private static final TypeReference<List<Integer>> LIST_INTEGER_TYPE = new TypeReference<List<Integer>>() {
};
@Override
public String convertToDatabaseColumn(List<Integer> attribute) {
if (attribute == null) {
return null;
}
try {
return MAPPER.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("角色列表序列化 JSON 失败: " + attribute, e);
}
}
@Override
public List<Integer> convertToEntityAttribute(String dbData) {
if (dbData == null || dbData.trim().isEmpty()) {
return null;
}
try {
List<Integer> list = MAPPER.readValue(dbData, LIST_INTEGER_TYPE);
return list == null ? Collections.emptyList() : list;
} catch (JsonProcessingException e) {
throw new IllegalArgumentException("角色 JSON 解析失败: " + dbData, e);
}
}
}
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.StatusEnum;
import javax.persistence.AttributeConverter;
/**
* StatusEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。
*
* @author chenx
*/
public class StatusEnumConverter extends CommonIntEnumConverter<StatusEnum> {
public StatusEnumConverter() {
super(StatusEnum.class);
}
}
@@ -0,0 +1,20 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.SysRoleEnum;
import javax.persistence.AttributeConverter;
/**
* SysRoleEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。<br>
* 注意:sys_user.roles 是「角色 key 的 JSON 列表」,使用 ListIntegerJsonConverter,
* 若某处需要「单角色」字段,再引用本转换器即可。
*
* @author chenx
*/
public class SysRoleEnumConverter extends CommonIntEnumConverter<SysRoleEnum> {
public SysRoleEnumConverter() {
super(SysRoleEnum.class);
}
}
@@ -0,0 +1,18 @@
package com.yunhai.userbase.common.converter;
import com.yunhai.userbase.enums.UserTypeEnum;
import javax.persistence.AttributeConverter;
/**
* UserTypeEnum 专用 JPA 转换器(int &lt;-&gt; 枚举)。<br>
* 继承通用基类 CommonIntEnumConverter,仅在构造器绑定枚举 class 即可。
*
* @author chenx
*/
public class UserTypeEnumConverter extends CommonIntEnumConverter<UserTypeEnum> {
public UserTypeEnumConverter() {
super(UserTypeEnum.class);
}
}