diff --git a/enlish-framework/enlish-common/pom.xml b/enlish-framework/enlish-common/pom.xml
new file mode 100644
index 0000000..43c642e
--- /dev/null
+++ b/enlish-framework/enlish-common/pom.xml
@@ -0,0 +1,69 @@
+
+ 4.0.0
+
+
+ com.yinlihupo
+ enlish-framework
+ ${revision}
+
+
+
+ jar
+
+ enlish-common
+ ${project.artifactId}
+ 平台通用模块,如一些通用枚举、工具类等等
+
+
+
+
+ org.projectlombok
+ lombok
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+
+
+
+ com.fasterxml.jackson.core
+ jackson-core
+
+
+
+
+ com.fasterxml.jackson.datatype
+ jackson-datatype-jsr310
+
+
+
+
+ jakarta.validation
+ jakarta.validation-api
+
+
+ org.hibernate.validator
+ hibernate-validator
+
+
+
+
+ com.google.guava
+ guava
+
+
+
+ cn.hutool
+ hutool-all
+
+
+
+ org.apache.commons
+ commons-lang3
+
+
+
+
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/DateConstants.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/DateConstants.java
new file mode 100644
index 0000000..af882d7
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/DateConstants.java
@@ -0,0 +1,38 @@
+package com.yinlihupo.framework.common.constant;
+
+import java.time.format.DateTimeFormatter;
+
+
+public interface DateConstants {
+
+ /**
+ * DateTimeFormatter:年-月-日 时:分:秒
+ */
+ DateTimeFormatter DATE_FORMAT_Y_M_D_H_M_S = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * DateTimeFormatter:年-月-日
+ */
+ DateTimeFormatter DATE_FORMAT_Y_M_D = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+
+ /**
+ * DateTimeFormatter:时:分:秒
+ */
+ DateTimeFormatter DATE_FORMAT_H_M_S = DateTimeFormatter.ofPattern("HH:mm:ss");
+
+ /**
+ * DateTimeFormatter:年-月
+ */
+ DateTimeFormatter DATE_FORMAT_Y_M = DateTimeFormatter.ofPattern("yyyy-MM");
+
+ /**
+ * DateTimeFormatter:月-日
+ */
+ DateTimeFormatter DATE_FORMAT_M_D = DateTimeFormatter.ofPattern("MM-dd");
+
+
+ /**
+ * DateTimeFormatter:时:分
+ */
+ DateTimeFormatter DATE_FORMAT_H_M = DateTimeFormatter.ofPattern("HH:mm");
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/GlobalConstants.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/GlobalConstants.java
new file mode 100644
index 0000000..9210d1d
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/constant/GlobalConstants.java
@@ -0,0 +1,12 @@
+package com.yinlihupo.framework.common.constant;
+
+
+
+
+public interface GlobalConstants {
+
+ /**
+ * 用户 ID
+ */
+ String USER_ID = "userId";
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/DeletedEnum.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/DeletedEnum.java
new file mode 100644
index 0000000..a4e66fd
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/DeletedEnum.java
@@ -0,0 +1,15 @@
+package com.yinlihupo.framework.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+@Getter
+@AllArgsConstructor
+public enum DeletedEnum {
+
+ YES(true),
+ NO(false);
+
+ private final Boolean value;
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/StatusEnum.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/StatusEnum.java
new file mode 100644
index 0000000..089e6ae
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/enums/StatusEnum.java
@@ -0,0 +1,16 @@
+package com.yinlihupo.framework.common.enums;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+@Getter
+@AllArgsConstructor
+public enum StatusEnum {
+ // 启用
+ ENABLE(0),
+ // 禁用
+ DISABLED(1);
+
+ private final Integer value;
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BaseExceptionInterface.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BaseExceptionInterface.java
new file mode 100644
index 0000000..957f263
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BaseExceptionInterface.java
@@ -0,0 +1,9 @@
+package com.yinlihupo.framework.common.exception;
+
+
+public interface BaseExceptionInterface {
+
+ String getErrorCode();
+
+ String getErrorMessage();
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BizException.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BizException.java
new file mode 100644
index 0000000..9fc454d
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/exception/BizException.java
@@ -0,0 +1,19 @@
+package com.yinlihupo.framework.common.exception;
+
+import lombok.Getter;
+import lombok.Setter;
+
+
+@Getter
+@Setter
+public class BizException extends RuntimeException {
+ // 异常码
+ private String errorCode;
+ // 错误信息
+ private String errorMessage;
+
+ public BizException(BaseExceptionInterface baseExceptionInterface) {
+ this.errorCode = baseExceptionInterface.getErrorCode();
+ this.errorMessage = baseExceptionInterface.getErrorMessage();
+ }
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/PageResponse.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/PageResponse.java
new file mode 100644
index 0000000..d7bf3d5
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/PageResponse.java
@@ -0,0 +1,69 @@
+package com.yinlihupo.framework.common.response;
+
+
+import lombok.Data;
+
+import java.util.List;
+
+
+@Data
+public class PageResponse extends Response> {
+
+ // 当前页码
+ private long pageNo;
+ // 总数据量
+ private long totalCount;
+ // 每页展示的数据量
+ private long pageSize;
+ // 总页数
+ private long totalPage;
+
+
+ public static PageResponse success(List data, long pageNo, long totalCount) {
+ PageResponse pageResponse = new PageResponse<>();
+ pageResponse.setSuccess(true);
+ pageResponse.setData(data);
+ pageResponse.setPageNo(pageNo);
+ pageResponse.setTotalCount(totalCount);
+ // 每页展示的数据量
+ long pageSize = 10L;
+ pageResponse.setPageSize(pageSize);
+ // 计算总页数
+ long totalPage = (totalCount + pageSize - 1) / pageSize;
+ pageResponse.setTotalPage(totalPage);
+ return pageResponse;
+ }
+
+
+ public static PageResponse success(List data, long pageNo, long totalCount, long pageSize) {
+ PageResponse pageResponse = new PageResponse<>();
+ pageResponse.setSuccess(true);
+ pageResponse.setData(data);
+ pageResponse.setPageNo(pageNo);
+ pageResponse.setTotalCount(totalCount);
+ pageResponse.setPageSize(pageSize);
+ // 计算总页数
+ long totalPage = pageSize == 0 ? 0 : (totalCount + pageSize - 1) / pageSize;
+ pageResponse.setTotalPage(totalPage);
+ return pageResponse;
+ }
+
+ /**
+ * 获取总页数
+ */
+ public static long getTotalPage(long totalCount, long pageSize) {
+
+ return pageSize == 0 ? 0 : (totalCount + pageSize - 1) / pageSize;
+ }
+
+ /**
+ * 计算分页查询的 offset
+ */
+ public static long getOffset(long pageNo, long pageSize) {
+ // 如果页码小于 1,默认返回第一页的 offset
+ if (pageNo < 1) {
+ pageNo = 1;
+ }
+ return (pageNo - 1) * pageSize;
+ }
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/Response.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/Response.java
new file mode 100644
index 0000000..19c6254
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/response/Response.java
@@ -0,0 +1,73 @@
+package com.yinlihupo.framework.common.response;
+
+
+import com.yinlihupo.framework.common.exception.BaseExceptionInterface;
+import com.yinlihupo.framework.common.exception.BizException;
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+@Data
+public class Response implements Serializable {
+
+ // 是否成功,默认为 true
+ private boolean success = true;
+ // 响应消息
+ private String message;
+ // 异常码
+ private String errorCode;
+ // 响应数据
+ private T data;
+
+ // =================================== 成功响应 ===================================
+ public static Response success() {
+ Response response = new Response<>();
+ return response;
+ }
+
+ public static Response success(T data) {
+ Response response = new Response<>();
+ response.setData(data);
+ return response;
+ }
+
+ // =================================== 失败响应 ===================================
+ public static Response fail() {
+ Response response = new Response<>();
+ response.setSuccess(false);
+ return response;
+ }
+
+ public static Response fail(String errorMessage) {
+ Response response = new Response<>();
+ response.setSuccess(false);
+ response.setMessage(errorMessage);
+ return response;
+ }
+
+ public static Response fail(String errorCode, String errorMessage) {
+ Response response = new Response<>();
+ response.setSuccess(false);
+ response.setErrorCode(errorCode);
+ response.setMessage(errorMessage);
+ return response;
+ }
+
+ public static Response fail(BizException bizException) {
+ Response response = new Response<>();
+ response.setSuccess(false);
+ response.setErrorCode(bizException.getErrorCode());
+ response.setMessage(bizException.getErrorMessage());
+ return response;
+ }
+
+ public static Response fail(BaseExceptionInterface baseExceptionInterface) {
+ Response response = new Response<>();
+ response.setSuccess(false);
+ response.setErrorCode(baseExceptionInterface.getErrorCode());
+ response.setMessage(baseExceptionInterface.getErrorMessage());
+ return response;
+ }
+
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/DateUtils.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/DateUtils.java
new file mode 100644
index 0000000..f8b186f
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/DateUtils.java
@@ -0,0 +1,81 @@
+package com.yinlihupo.framework.common.util;
+
+
+
+
+import com.yinlihupo.framework.common.constant.DateConstants;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
+import java.time.temporal.ChronoUnit;
+import java.util.Date;
+
+/**
+ * @author lbwxxc
+ * @date 2025/6/2 16:24
+ * @description: 日期工具类
+ */
+public class DateUtils {
+
+ public static long localDateTime2Timestamp(LocalDateTime localDateTime) {
+ return localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
+ }
+
+ public static long dateTime2Timestamp(Date date) {
+ return date.toInstant().toEpochMilli();
+ }
+
+ /**
+ * LocalDateTime 转 String 字符串
+ */
+ public static String localDateTime2String(LocalDateTime time) {
+ return time.format(DateConstants.DATE_FORMAT_Y_M_D_H_M_S);
+ }
+
+ /**
+ * LocalDateTime 转友好的相对时间字符串
+ */
+ public static String formatRelativeTime(LocalDateTime dateTime) {
+ // 当前时间
+ LocalDateTime now = LocalDateTime.now();
+
+ // 计算与当前时间的差距
+ long daysDiff = ChronoUnit.DAYS.between(dateTime, now);
+ long hoursDiff = ChronoUnit.HOURS.between(dateTime, now);
+ long minutesDiff = ChronoUnit.MINUTES.between(dateTime, now);
+
+ if (daysDiff < 1) { // 如果是今天
+ if (hoursDiff < 1) { // 如果是几分钟前
+ return minutesDiff + "分钟前";
+ } else { // 如果是几小时前
+ return hoursDiff + "小时前";
+ }
+ } else if (daysDiff == 1) { // 如果是昨天
+ return "昨天 " + dateTime.format(DateConstants.DATE_FORMAT_H_M);
+ } else if (daysDiff < 7) { // 如果是最近一周
+ return daysDiff + "天前";
+ } else if (dateTime.getYear() == now.getYear()) { // 如果是今年
+ return dateTime.format(DateConstants.DATE_FORMAT_M_D);
+ } else { // 如果是去年或更早
+ return dateTime.format(DateConstants.DATE_FORMAT_Y_M_D);
+ }
+ }
+
+ /**
+ * 计算年龄
+ * @param birthDate 出生日期(LocalDate)
+ * @return 计算得到的年龄(以年为单位)
+ */
+ public static int calculateAge(LocalDate birthDate) {
+ // 获取当前日期
+ LocalDate currentDate = LocalDate.now();
+
+ // 计算出生日期到当前日期的 Period 对象
+ Period period = Period.between(birthDate, currentDate);
+
+ // 返回完整的年份(即年龄)
+ return period.getYears();
+ }
+}
diff --git a/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/JsonUtils.java b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/JsonUtils.java
new file mode 100644
index 0000000..9e7f66d
--- /dev/null
+++ b/enlish-framework/enlish-common/src/main/java/com/yinlihupo/framework/common/util/JsonUtils.java
@@ -0,0 +1,92 @@
+package com.yinlihupo.framework.common.util;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import com.fasterxml.jackson.databind.type.CollectionType;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+import lombok.SneakyThrows;
+import org.apache.commons.lang3.StringUtils;
+
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+
+public class JsonUtils {
+
+ private static ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+ static {
+ OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
+ OBJECT_MAPPER.registerModules(new JavaTimeModule()); // 解决 LocalDateTime 的序列化问题
+ }
+
+ /**
+ * 初始化:统一使用 Spring Boot 个性化配置的 ObjectMapper
+ */
+ public static void init(ObjectMapper objectMapper) {
+ OBJECT_MAPPER = objectMapper;
+ }
+
+ /**
+ * 将对象转换为 JSON 字符串
+ */
+ @SneakyThrows
+ public static String toJsonString(Object obj) {
+ return OBJECT_MAPPER.writeValueAsString(obj);
+ }
+
+ /**
+ * 将 JSON 字符串转换为对象
+ */
+ @SneakyThrows
+ public static T parseObject(String jsonStr, Class clazz) {
+ if (StringUtils.isBlank(jsonStr)) {
+ return null;
+ }
+
+ return OBJECT_MAPPER.readValue(jsonStr, clazz);
+ }
+
+ /**
+ * 将 JSON 字符串转换为 Map
+ */
+ public static Map parseMap(String jsonStr, Class keyClass, Class valueClass) throws Exception {
+ // 创建 TypeReference,指定泛型类型
+ TypeReference