+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.annotation;
+
+import top.charles7c.continew.starter.extension.crud.enums.Api;
+
+import java.lang.annotation.*;
+
+/**
+ * CRUD(增删改查)请求映射器注解
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CrudRequestMapping {
+
+ /**
+ * 路径映射 URI(等同于:@RequestMapping("/foo1"))
+ */
+ String value() default "";
+
+ /**
+ * API 列表
+ */
+ Api[] api() default {Api.PAGE, Api.GET, Api.ADD, Api.UPDATE, Api.DELETE, Api.EXPORT};
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/NoResponseAdvice.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/NoResponseAdvice.java
new file mode 100644
index 00000000..3f39c238
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/NoResponseAdvice.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 响应拦截忽略注解
+ *
+ * @author BULL_BCLS
+ * @since 1.0.0
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NoResponseAdvice {}
\ No newline at end of file
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/Query.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/Query.java
new file mode 100644
index 00000000..4f15be77
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/Query.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.annotation;
+
+import top.charles7c.continew.starter.extension.crud.enums.QueryTypeEnum;
+
+import java.lang.annotation.*;
+
+/**
+ * 查询注解
+ *
+ * @author Zheng Jie(ELADMIN)
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Query {
+
+ /**
+ * 属性名(默认和使用该注解的属性的名称一致)
+ */
+ String property() default "";
+
+ /**
+ * 查询类型(等值查询、模糊查询、范围查询等)
+ */
+ QueryTypeEnum type() default QueryTypeEnum.EQUAL;
+
+ /**
+ * 多属性模糊查询,仅支持 String 类型属性
+ *
+ */
+ String[] blurry() default {};
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/TreeField.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/TreeField.java
new file mode 100644
index 00000000..2f81d6ac
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/annotation/TreeField.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.annotation;
+
+import java.lang.annotation.*;
+
+/**
+ * 树结构字段
+ *
+ * @see cn.hutool.core.lang.tree.TreeNodeConfig
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface TreeField {
+
+ /**
+ * ID 字段名
+ *
+ * @return ID 字段名
+ */
+ String value() default "key";
+
+ /**
+ * 父 ID 字段名
+ *
+ * @return 父 ID 字段名
+ */
+ String parentIdKey() default "parentId";
+
+ /**
+ * 名称字段名
+ *
+ * @return 名称字段名
+ */
+ String nameKey() default "title";
+
+ /**
+ * 排序字段名
+ *
+ * @return 排序字段名
+ */
+ String weightKey() default "sort";
+
+ /**
+ * 子列表字段名
+ *
+ * @return 子列表字段名
+ */
+ String childrenKey() default "children";
+
+ /**
+ * 递归深度(< 0 不限制)
+ *
+ * @return 递归深度
+ */
+ int deep() default -1;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/autoconfigure/CrudAutoConfiguration.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/autoconfigure/CrudAutoConfiguration.java
new file mode 100644
index 00000000..f3bacd35
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/autoconfigure/CrudAutoConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.autoconfigure;
+
+import jakarta.annotation.PostConstruct;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.AutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Primary;
+import org.springframework.format.support.FormattingConversionService;
+import org.springframework.web.accept.ContentNegotiationManager;
+import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+import org.springframework.web.servlet.resource.ResourceUrlProvider;
+import top.charles7c.continew.starter.extension.crud.handler.CrudRequestMappingHandlerMapping;
+
+/**
+ * CRUD 自动配置
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Slf4j
+@AutoConfiguration
+public class CrudAutoConfiguration extends DelegatingWebMvcConfiguration {
+
+ /**
+ * CRUD 请求映射器处理器映射器(覆盖默认 RequestMappingHandlerMapping)
+ */
+ @Override
+ public RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
+ return new CrudRequestMappingHandlerMapping();
+ }
+
+ @Bean
+ @Primary
+ @Override
+ public RequestMappingHandlerMapping requestMappingHandlerMapping(
+ @Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
+ @Qualifier("mvcConversionService") FormattingConversionService conversionService,
+ @Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
+ return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService, resourceUrlProvider);
+ }
+
+ @PostConstruct
+ public void postConstruct() {
+ log.info("[ContiNew Starter] - Auto Configuration 'Extension-CRUD' completed initialization.");
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseController.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseController.java
new file mode 100644
index 00000000..9d99e9af
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseController.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 实体类基类
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+public class BaseDO implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @TableId
+ private Long id;
+
+ /**
+ * 创建人
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private Long createUser;
+
+ /**
+ * 创建时间
+ */
+ @TableField(fill = FieldFill.INSERT)
+ private LocalDateTime createTime;
+
+ /**
+ * 修改人
+ */
+ @TableField(fill = FieldFill.UPDATE)
+ private Long updateUser;
+
+ /**
+ * 修改时间
+ */
+ @TableField(fill = FieldFill.UPDATE)
+ private LocalDateTime updateTime;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseDetailResp.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseDetailResp.java
new file mode 100644
index 00000000..5f6d7263
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseDetailResp.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.time.LocalDateTime;
+
+/**
+ * 详情响应基类
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+public class BaseDetailResp extends BaseResp {
+
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 修改人
+ */
+ @JsonIgnore
+ private Long updateUser;
+
+ /**
+ * 修改人
+ */
+ @Schema(description = "修改人", example = "李四")
+ @ExcelProperty(value = "修改人", order = Integer.MAX_VALUE - 2)
+ private String updateUserString;
+
+ /**
+ * 修改时间
+ */
+ @Schema(description = "修改时间", example = "2023-08-08 08:08:08", type = "string")
+ @ExcelProperty(value = "修改时间", order = Integer.MAX_VALUE - 1)
+ private LocalDateTime updateTime;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseMapper.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseMapper.java
new file mode 100644
index 00000000..b451f082
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseMapper.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 请求基类
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+public class BaseReq implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseResp.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseResp.java
new file mode 100644
index 00000000..ed6304d1
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseResp.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * 响应基类
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+public class BaseResp implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * ID
+ */
+ @Schema(description = "ID", example = "1")
+ @ExcelProperty(value = "ID", order = 1)
+ private Long id;
+
+ /**
+ * 创建人
+ */
+ @JsonIgnore
+ private Long createUser;
+
+ /**
+ * 创建人
+ */
+ @Schema(description = "创建人", example = "超级管理员")
+ @ExcelProperty(value = "创建人", order = Integer.MAX_VALUE - 4)
+ private String createUserString;
+
+ /**
+ * 创建时间
+ */
+ @Schema(description = "创建时间", example = "2023-08-08 08:08:08", type = "string")
+ @ExcelProperty(value = "创建时间", order = Integer.MAX_VALUE - 3)
+ private LocalDateTime createTime;
+
+ /**
+ * 是否禁用修改
+ */
+ @Schema(description = "是否禁用修改", example = "true")
+ @JsonInclude(JsonInclude.Include.NON_NULL)
+ private Boolean disabled;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseService.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseService.java
new file mode 100644
index 00000000..4e45db6f
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/BaseService.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+/**
+ * 公共用户业务接口
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+public interface CommonUserService {
+
+ /**
+ * 根据 ID 查询昵称
+ *
+ * @param id
+ * ID
+ * @return 昵称
+ */
+ String getNicknameById(Long id);
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/IBaseEnum.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/IBaseEnum.java
new file mode 100644
index 00000000..ae38f3d2
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/IBaseEnum.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+import java.io.Serializable;
+
+/**
+ * 枚举接口
+ *
+ * @param
+ * value 类型
+ * @author Charles7c
+ * @since 1.0.0
+ */
+public interface IBaseEnum extends IEnum {
+
+ /**
+ * 枚举描述
+ *
+ * @return 枚举描述
+ */
+ String getDescription();
+
+ /**
+ * 颜色
+ *
+ * @return 颜色
+ */
+ default String getColor() {
+ return null;
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/ValidateGroup.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/ValidateGroup.java
new file mode 100644
index 00000000..1b06fa70
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/base/ValidateGroup.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.base;
+
+import jakarta.validation.groups.Default;
+
+/**
+ * 分组校验
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+public interface ValidateGroup extends Default {
+
+ /**
+ * 分组校验-增删改查
+ */
+ interface Crud extends ValidateGroup {
+ /**
+ * 分组校验-创建
+ */
+ interface Add extends Crud {}
+
+ /**
+ * 分组校验-修改
+ */
+ interface Update extends Crud {}
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/Api.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/Api.java
new file mode 100644
index 00000000..69dc8c84
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/Api.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.enums;
+
+/**
+ * API 类型枚举
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+public enum Api {
+
+ /**
+ * 所有 API
+ */
+ ALL,
+ /**
+ * 分页
+ */
+ PAGE,
+ /**
+ * 树列表
+ */
+ TREE,
+ /**
+ * 列表
+ */
+ LIST,
+ /**
+ * 详情
+ */
+ GET,
+ /**
+ * 新增
+ */
+ ADD,
+ /**
+ * 修改
+ */
+ UPDATE,
+ /**
+ * 删除
+ */
+ DELETE,
+ /**
+ * 导出
+ */
+ EXPORT,
+}
\ No newline at end of file
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/QueryTypeEnum.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/QueryTypeEnum.java
new file mode 100644
index 00000000..e86eea84
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/enums/QueryTypeEnum.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.enums;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import top.charles7c.continew.starter.extension.crud.base.IBaseEnum;
+
+/**
+ * 查询类型枚举
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Getter
+@RequiredArgsConstructor
+public enum QueryTypeEnum implements IBaseEnum {
+
+ /**
+ * 等值查询,例如:WHERE `age` = 18
+ */
+ EQUAL(1, "="),
+ /**
+ * 非等值查询,例如:WHERE `age` != 18
+ */
+ NOT_EQUAL(2, "!="),
+ /**
+ * 大于查询,例如:WHERE `age` > 18
+ */
+ GREATER_THAN(3, ">"),
+ /**
+ * 小于查询,例如:WHERE `age` < 18
+ */
+ LESS_THAN(4, "<"),
+ /**
+ * 大于等于查询,例如:WHERE `age` >= 18
+ */
+ GREATER_THAN_OR_EQUAL(5, ">="),
+ /**
+ * 小于等于查询,例如:WHERE `age` <= 18
+ */
+ LESS_THAN_OR_EQUAL(6, "<="),
+ /**
+ * 范围查询,例如:WHERE `age` BETWEEN 10 AND 18
+ */
+ BETWEEN(7, "BETWEEN"),
+ /**
+ * 左模糊查询,例如:WHERE `nickname` LIKE '%s'
+ */
+ LEFT_LIKE(8, "LIKE '%s'"),
+ /**
+ * 中模糊查询,例如:WHERE `nickname` LIKE '%s%'
+ */
+ INNER_LIKE(9, "LIKE '%s%'"),
+ /**
+ * 右模糊查询,例如:WHERE `nickname` LIKE 's%'
+ */
+ RIGHT_LIKE(10, "LIKE 's%'"),
+ /**
+ * 包含查询,例如:WHERE `age` IN (10, 20, 30)
+ */
+ IN(11, "IN"),
+ /**
+ * 不包含查询,例如:WHERE `age` NOT IN (20, 30)
+ */
+ NOT_IN(12, "NOT IN"),
+ /**
+ * 空查询,例如:WHERE `email` IS NULL
+ */
+ IS_NULL(13, "IS NULL"),
+ /**
+ * 非空查询,例如:WHERE `email` IS NOT NULL
+ */
+ IS_NOT_NULL(14, "IS NOT NULL"),;
+
+ private final Integer value;
+ private final String description;
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BadRequestException.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BadRequestException.java
new file mode 100644
index 00000000..32aacde1
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BadRequestException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.exception;
+
+import lombok.NoArgsConstructor;
+import top.charles7c.continew.starter.core.exception.BaseException;
+
+/**
+ * 自定义验证异常-错误请求
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@NoArgsConstructor
+public class BadRequestException extends BaseException {
+
+ public BadRequestException(String message) {
+ super(message);
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BusinessException.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BusinessException.java
new file mode 100644
index 00000000..e24ea14b
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/exception/BusinessException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.exception;
+
+import lombok.NoArgsConstructor;
+import top.charles7c.continew.starter.core.exception.BaseException;
+
+/**
+ * 业务异常
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@NoArgsConstructor
+public class BusinessException extends BaseException {
+
+ public BusinessException(String message) {
+ super(message);
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/handler/CrudRequestMappingHandlerMapping.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/handler/CrudRequestMappingHandlerMapping.java
new file mode 100644
index 00000000..114efee2
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/handler/CrudRequestMappingHandlerMapping.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.handler;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import org.springframework.lang.NonNull;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
+import org.springframework.web.util.pattern.PathPatternParser;
+import top.charles7c.continew.starter.core.util.ExceptionUtils;
+import top.charles7c.continew.starter.extension.crud.annotation.CrudRequestMapping;
+import top.charles7c.continew.starter.extension.crud.enums.Api;
+
+import java.lang.reflect.Method;
+
+/**
+ * CRUD 请求映射器处理器映射器
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+public class CrudRequestMappingHandlerMapping extends RequestMappingHandlerMapping {
+
+ @Override
+ protected RequestMappingInfo getMappingForMethod(@NonNull Method method, @NonNull Class> handlerType) {
+ RequestMappingInfo requestMappingInfo = super.getMappingForMethod(method, handlerType);
+ if (null == requestMappingInfo) {
+ return null;
+ }
+ // 如果没有声明 @CrudRequestMapping 注解,直接返回
+ if (!handlerType.isAnnotationPresent(CrudRequestMapping.class)) {
+ return requestMappingInfo;
+ }
+ // 获取 @CrudRequestMapping 注解信息
+ CrudRequestMapping crudRequestMapping = handlerType.getDeclaredAnnotation(CrudRequestMapping.class);
+ // 拼接路径前缀(合并了 @RequestMapping 的部分能力)
+ String pathPrefix = crudRequestMapping.value();
+ if (StrUtil.isNotBlank(pathPrefix)) {
+ /*
+ * 问题:RequestMappingInfo.paths(pathPrefix) 返回的 RequestMappingInfo 对象里 pathPatternsCondition = null
+ * 导致 combine() 方法抛出断言异常! 修复:创建 options 对象,并设置 PatternParser
+ */
+ RequestMappingInfo.BuilderConfiguration options = new RequestMappingInfo.BuilderConfiguration();
+ options.setPatternParser(PathPatternParser.defaultInstance);
+ requestMappingInfo =
+ RequestMappingInfo.paths(pathPrefix).options(options).build().combine(requestMappingInfo);
+ }
+ // 过滤 API
+ Api[] apiArr = crudRequestMapping.api();
+ // 如果非本类中定义,且 API 列表中不包含,则忽略
+ Api api = ExceptionUtils.exToNull(() -> Api.valueOf(method.getName().toUpperCase()));
+ if (method.getDeclaringClass() != handlerType && !ArrayUtil.containsAny(apiArr, Api.ALL, api)) {
+ return null;
+ }
+ return requestMappingInfo;
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/PageQuery.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/PageQuery.java
new file mode 100644
index 00000000..603f5ed4
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/PageQuery.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.model.query;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.metadata.OrderItem;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Min;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.hibernate.validator.constraints.Range;
+import org.springdoc.core.annotations.ParameterObject;
+import org.springframework.data.domain.Sort;
+
+import java.io.Serial;
+
+/**
+ * 分页查询条件
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+@ParameterObject
+@NoArgsConstructor
+@Schema(description = "分页查询条件")
+public class PageQuery extends SortQuery {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+ /** 默认页码:1 */
+ private static final int DEFAULT_PAGE = 1;
+ /** 默认每页条数:10 */
+ private static final int DEFAULT_SIZE = 10;
+
+ /**
+ * 页码
+ */
+ @Schema(description = "页码", example = "1")
+ @Min(value = 1, message = "页码最小值为 {value}")
+ private Integer page = DEFAULT_PAGE;
+
+ /**
+ * 每页条数
+ */
+ @Schema(description = "每页条数", example = "10")
+ @Range(min = 1, max = 1000, message = "每页条数(取值范围 {min}-{max})")
+ private Integer size = DEFAULT_SIZE;
+
+ /**
+ * 基于分页查询条件转换为 MyBatis Plus 分页条件
+ *
+ * @param
+ * 列表数据类型
+ * @return MyBatis Plus 分页条件
+ */
+ public IPage toPage() {
+ Page mybatisPage = new Page<>(this.getPage(), this.getSize());
+ Sort pageSort = this.getSort();
+ if (CollUtil.isNotEmpty(pageSort)) {
+ for (Sort.Order order : pageSort) {
+ OrderItem orderItem = new OrderItem();
+ orderItem.setAsc(order.isAscending());
+ orderItem.setColumn(StrUtil.toUnderlineCase(order.getProperty()));
+ mybatisPage.addOrder(orderItem);
+ }
+ }
+ return mybatisPage;
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/SortQuery.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/SortQuery.java
new file mode 100644
index 00000000..770309ad
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/query/SortQuery.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.model.query;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.StrUtil;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.data.domain.Sort;
+import top.charles7c.continew.starter.core.constant.StringConstants;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 排序查询条件
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+@Schema(description = "排序查询条件")
+public class SortQuery implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 排序条件
+ */
+ @Schema(description = "排序条件", example = "createTime,desc")
+ private String[] sort;
+
+ /**
+ * 解析排序条件为 Spring 分页排序实体
+ *
+ * @return Spring 分页排序实体
+ */
+ public Sort getSort() {
+ if (ArrayUtil.isEmpty(sort)) {
+ return Sort.unsorted();
+ }
+
+ List orders = new ArrayList<>(sort.length);
+ if (StrUtil.contains(sort[0], StringConstants.COMMA)) {
+ // e.g "sort=createTime,desc&sort=name,asc"
+ for (String s : sort) {
+ List sortList = StrUtil.splitTrim(s, StringConstants.COMMA);
+ Sort.Order order =
+ new Sort.Order(Sort.Direction.valueOf(sortList.get(1).toUpperCase()), sortList.get(0));
+ orders.add(order);
+ }
+ } else {
+ // e.g "sort=createTime,desc"
+ Sort.Order order = new Sort.Order(Sort.Direction.valueOf(sort[1].toUpperCase()), sort[0]);
+ orders.add(order);
+ }
+ return Sort.by(orders);
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/PageDataResp.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/PageDataResp.java
new file mode 100644
index 00000000..4d8b9ef0
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/PageDataResp.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.model.resp;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 分页信息
+ *
+ * @param
+ * 列表数据类型
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+@Schema(description = "分页信息")
+public class PageDataResp implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * 列表数据
+ */
+ @Schema(description = "列表数据")
+ private List list;
+
+ /**
+ * 总记录数
+ */
+ @Schema(description = "总记录数", example = "10")
+ private long total;
+
+ /**
+ * 基于 MyBatis Plus 分页数据构建分页信息,并将源数据转换为指定类型数据
+ *
+ * @param page
+ * MyBatis Plus 分页数据
+ * @param targetClass
+ * 目标类型 Class 对象
+ * @param
+ * 源列表数据类型
+ * @param
+ * 目标列表数据类型
+ * @return 分页信息
+ */
+ public static PageDataResp build(IPage page, Class targetClass) {
+ if (null == page) {
+ return empty();
+ }
+ PageDataResp pageDataResp = new PageDataResp<>();
+ pageDataResp.setList(BeanUtil.copyToList(page.getRecords(), targetClass));
+ pageDataResp.setTotal(page.getTotal());
+ return pageDataResp;
+ }
+
+ /**
+ * 基于 MyBatis Plus 分页数据构建分页信息
+ *
+ * @param page
+ * MyBatis Plus 分页数据
+ * @param
+ * 列表数据类型
+ * @return 分页信息
+ */
+ public static PageDataResp build(IPage page) {
+ if (null == page) {
+ return empty();
+ }
+ PageDataResp pageDataResp = new PageDataResp<>();
+ pageDataResp.setList(page.getRecords());
+ pageDataResp.setTotal(page.getTotal());
+ return pageDataResp;
+ }
+
+ /**
+ * 基于列表数据构建分页信息
+ *
+ * @param page
+ * 页码
+ * @param size
+ * 每页条数
+ * @param list
+ * 列表数据
+ * @param
+ * 列表数据类型
+ * @return 分页信息
+ */
+ public static PageDataResp build(int page, int size, List list) {
+ if (CollUtil.isEmpty(list)) {
+ return empty();
+ }
+ PageDataResp pageDataResp = new PageDataResp<>();
+ pageDataResp.setTotal(list.size());
+ // 对列表数据进行分页
+ int fromIndex = (page - 1) * size;
+ int toIndex = page * size + size;
+ if (fromIndex > list.size()) {
+ pageDataResp.setList(new ArrayList<>(0));
+ } else if (toIndex >= list.size()) {
+ pageDataResp.setList(list.subList(fromIndex, list.size()));
+ } else {
+ pageDataResp.setList(list.subList(fromIndex, toIndex));
+ }
+ return pageDataResp;
+ }
+
+ /**
+ * 空分页信息
+ *
+ * @param
+ * 列表数据类型
+ * @return 分页信息
+ */
+ private static PageDataResp empty() {
+ PageDataResp pageDataResp = new PageDataResp<>();
+ pageDataResp.setList(new ArrayList<>(0));
+ return pageDataResp;
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/R.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/R.java
new file mode 100644
index 00000000..f010ce66
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/model/resp/R.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package top.charles7c.continew.starter.extension.crud.model.resp;
+
+import cn.hutool.core.date.DateUtil;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AccessLevel;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.http.HttpStatus;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 响应信息
+ *
+ * @author Charles7c
+ * @since 1.0.0
+ */
+@Data
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+@Schema(description = "响应信息")
+public class R implements Serializable {
+
+ @Serial
+ private static final long serialVersionUID = 1L;
+
+ /** 是否成功 */
+ @Schema(description = "是否成功", example = "true")
+ private boolean success;
+
+ /** 业务状态码 */
+ @Schema(description = "业务状态码", example = "200")
+ private int code;
+
+ /** 业务状态信息 */
+ @Schema(description = "业务状态信息", example = "操作成功")
+ private String msg;
+
+ /** 响应数据 */
+ @Schema(description = "响应数据")
+ private T data;
+
+ /** 时间戳 */
+ @Schema(description = "时间戳", example = "1691453288")
+ private long timestamp = DateUtil.currentSeconds();
+
+ /** 成功状态码 */
+ private static final int SUCCESS_CODE = HttpStatus.OK.value();
+ /** 失败状态码 */
+ private static final int FAIL_CODE = HttpStatus.INTERNAL_SERVER_ERROR.value();
+
+ private R(boolean success, int code, String msg, T data) {
+ this.success = success;
+ this.code = code;
+ this.msg = msg;
+ this.data = data;
+ }
+
+ public static R ok() {
+ return new R<>(true, SUCCESS_CODE, "操作成功", null);
+ }
+
+ public static R ok(T data) {
+ return new R<>(true, SUCCESS_CODE, "操作成功", data);
+ }
+
+ public static R ok(String msg) {
+ return new R<>(true, SUCCESS_CODE, msg, null);
+ }
+
+ public static R ok(String msg, T data) {
+ return new R<>(true, SUCCESS_CODE, msg, data);
+ }
+
+ public static R fail() {
+ return new R<>(false, FAIL_CODE, "操作失败", null);
+ }
+
+ public static R fail(String msg) {
+ return new R<>(false, FAIL_CODE, msg, null);
+ }
+
+ public static R fail(T data) {
+ return new R<>(false, FAIL_CODE, "操作失败", data);
+ }
+
+ public static R fail(String msg, T data) {
+ return new R<>(false, FAIL_CODE, msg, data);
+ }
+
+ public static R fail(int code, String msg) {
+ return new R<>(false, code, msg, null);
+ }
+}
diff --git a/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/util/QueryHelper.java b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/util/QueryHelper.java
new file mode 100644
index 00000000..4347e805
--- /dev/null
+++ b/continew-starter-extension/continew-starter-extension-crud/src/main/java/top/charles7c/continew/starter/extension/crud/util/QueryHelper.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
+ *
+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *